Beispiel #1
0
        /// <summary>
        /// Called as callback when a root device is found
        /// </summary>
        /// <param name="Object">The object</param>
        /// <param name="NestingLevel">Nesting level</param>
        /// <param name="Context">User context</param>
        /// <param name="ReturnValue">Return value if early returned</param>
        /// <returns>Status</returns>
        private static int onRootDevice(void *Object, uint NestingLevel, void *Context, void **ReturnValue)
        {
            // Get routing table
            AcpiObjects.Buffer buffer;
            buffer.Length = Acpica.ACPI_ALLOCATE_BUFFER;
            int status = Acpica.AcpiGetIrqRoutingTable(Object, &buffer);

            if (status != Acpica.AE_OK)
            {
                Panic.DoPanic("[PCI] Couldn't get ACPI IRQ Routing Table");
            }

            // The last entry will have Length 0
            Acpica.PCIRoutingTable *table = (Acpica.PCIRoutingTable *)buffer.Pointer;
            while (table->Length > 0)
            {
                // No reference source
                if (table->Source[0] == 0)
                {
                    uint slot = (uint)(table->Address >> 16);
                    addIRQ(slot, table->Pin, table->SourceIndex, 0, 0);
                }
                // Source is not null, that means we need to lookup the reference resource
                else
                {
                    void *handle = null;
                    status = Acpica.AcpiGetHandle(Object, Util.CharPtrToString(table->Source), &handle);
                    if (status != Acpica.AE_OK)
                    {
                        Panic.DoPanic("[PCI] Couldn't load references handle");
                    }

                    status = Acpica.AcpiWalkResources(handle, Acpica.METHOD_NAME__CRS, onIRQResource, table);
                    if (status != Acpica.AE_OK)
                    {
                        Panic.DoPanic("[PCI] Couldn't process resources for IRQ");
                    }
                }

                // Next entry
                table = (Acpica.PCIRoutingTable *)((byte *)table + table->Length);
            }

            // The object returned should be freed by us
            Acpica.AcpiOsFree(buffer.Pointer);

            return(Acpica.AE_OK);
        }
Beispiel #2
0
        /// <summary>
        /// Handles IRQ resources
        /// </summary>
        /// <param name="Resource">The resource</param>
        /// <param name="Context">User context</param>
        /// <returns>Status</returns>
        private static int onIRQResource(AcpiObjects.Resource *Resource, void *Context)
        {
            Acpica.PCIRoutingTable *table = (Acpica.PCIRoutingTable *)Context;
            uint slot = (uint)(table->Address >> 16);

            if (Resource->Type == AcpiObjects.ResourceType.IRQ)
            {
                AcpiObjects.ResourceIRQ *irq = (AcpiObjects.ResourceIRQ *)((byte *)Resource + sizeof(AcpiObjects.Resource));
                byte *interrupts             = (byte *)irq + sizeof(AcpiObjects.ResourceIRQ);
                addIRQ(slot, table->Pin, interrupts[table->SourceIndex], irq->Polarity, irq->Trigger);
            }
            else if (Resource->Type == AcpiObjects.ResourceType.EXTENDED_IRQ)
            {
                AcpiObjects.ResourceExtendedIRQ *irq = (AcpiObjects.ResourceExtendedIRQ *)((byte *)Resource + sizeof(AcpiObjects.Resource));
                uint *interrupts = (uint *)((byte *)irq + sizeof(AcpiObjects.ResourceExtendedIRQ));
                addIRQ(slot, table->Pin, interrupts[table->SourceIndex], irq->Polarity, irq->Trigger);
            }

            return(Acpica.AE_OK);
        }