Making sense of ACPI(CA)
Making sense of ACPI(CA)
OK, so I have ACPICA working (with debug support), but the interface is cludgy and not delivering what I want.
What I basically want is:
1. A function to map a PCI address to an IRQ on IO-APIC.
2. A function which returns a list of devices, not with callbacks, but with an index #, and then allows easy retrieval of IRQ, IO-range and memory-range.
3. A function that returns a list of PCI-devices, with an index #, and that allows easy retrieval of IRQs and possibly IO and memory-ranges
4. A function that returns a description of a device
What I get is:
1. Name-space walks
2. Retrieval of resource-objects in ways that are not readable in the debugger (nor easily dereferenced in C either).
So, what I have done is:
1. Created my own object-vector with a name-space walk
2. Created my own device-vector with a name-space walk
3. Created the resource descriptions by using a number of lists of real objects instead of worthless unions.
4. Created my own PCI irq-vector with a name-space walk
What I will do shortly is:
1. Add a command-line option to display devices (once I have the RdosGetDevice), along with description, IRQ and IO/memory ranges
2. Add a command-line option to display PCI-device, along with bus, device, function, IRQ and IO/memory ranges
However, I still don't think I properly understand some central concepts in ACPICA.
For instance:
1. How do you find the PCI device(s)?
2. Which methods are typically used/required with which devices? My listing of namespace objects is huge, but how do I know that my next machine has the same ones? Especially since neither the ACPICA document, nor the ACPI document, is clear on how typical devices should be represented.
3. Is there any use in reading-out the base address for keyboard controller, PIT, PIC, PCI? Wouldn't any new design that changed these settings be so broken that nobody would want it? Isn't the chance bigger that any deviation in these values would be errors in the ACPI tables rather than a genuine difference?
What I basically want is:
1. A function to map a PCI address to an IRQ on IO-APIC.
2. A function which returns a list of devices, not with callbacks, but with an index #, and then allows easy retrieval of IRQ, IO-range and memory-range.
3. A function that returns a list of PCI-devices, with an index #, and that allows easy retrieval of IRQs and possibly IO and memory-ranges
4. A function that returns a description of a device
What I get is:
1. Name-space walks
2. Retrieval of resource-objects in ways that are not readable in the debugger (nor easily dereferenced in C either).
So, what I have done is:
1. Created my own object-vector with a name-space walk
2. Created my own device-vector with a name-space walk
3. Created the resource descriptions by using a number of lists of real objects instead of worthless unions.
4. Created my own PCI irq-vector with a name-space walk
What I will do shortly is:
1. Add a command-line option to display devices (once I have the RdosGetDevice), along with description, IRQ and IO/memory ranges
2. Add a command-line option to display PCI-device, along with bus, device, function, IRQ and IO/memory ranges
However, I still don't think I properly understand some central concepts in ACPICA.
For instance:
1. How do you find the PCI device(s)?
2. Which methods are typically used/required with which devices? My listing of namespace objects is huge, but how do I know that my next machine has the same ones? Especially since neither the ACPICA document, nor the ACPI document, is clear on how typical devices should be represented.
3. Is there any use in reading-out the base address for keyboard controller, PIT, PIC, PCI? Wouldn't any new design that changed these settings be so broken that nobody would want it? Isn't the chance bigger that any deviation in these values would be errors in the ACPI tables rather than a genuine difference?
Re: Making sense of ACPI(CA)
I just found out that the reason one of my machines doesn't boot properly is because of bugs in ACPICA. It trashes memory by using unitialized memory when there is buggy AML-code. They simply cannot have tested it against various buggy ACPIs. I discovered this by changing the allocator to allocate one GDT per request.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Making sense of ACPI(CA)
ACPICA is used by Linux, FreeBSD, Solaris, and various other operating systems. I know how much time the Linux developers have spent dealing with AML bugs; I somehow suspect have bugs your usage of ACPICA, or in your compiler are more probable than bugs in ACPICA itself.rdos wrote:I just found out that the reason one of my machines doesn't boot properly is because of bugs in ACPICA. It trashes memory by using unitialized memory when there is buggy AML-code. They simply cannot have tested it against various buggy ACPIs. I discovered this by changing the allocator to allocate one GDT per request.
Re: Making sense of ACPI(CA)
It is possible it is some problem in the environment. The most probable cause of the problem is that Next pointer in the WalkState variable contains junk. It is when code follows this pointer it does random writes. Since it is this type of problem, the code sometimes actually works (when the junk is the "right" junk). When the code is run at boot-time it seems like it corrupts some important data, and thus everything simply stops.Owen wrote:ACPICA is used by Linux, FreeBSD, Solaris, and various other operating systems. I know how much time the Linux developers have spent dealing with AML bugs; I somehow suspect have bugs your usage of ACPICA, or in your compiler are more probable than bugs in ACPICA itself.rdos wrote:I just found out that the reason one of my machines doesn't boot properly is because of bugs in ACPICA. It trashes memory by using unitialized memory when there is buggy AML-code. They simply cannot have tested it against various buggy ACPIs. I discovered this by changing the allocator to allocate one GDT per request.
I'm not sure if the problem would be solved if all allocated memory blocks were zeroed out, but it is one possibilty.
This description from the ACPICA reference manual about AcpiOsAllocate makes it most likely that it is the AML code itself that is at error:
IOW, the OS should not need to zero-out allocated memory-blocks, but this is left-up to ACPICA itself to ensure.This function dynamically allocates memory. The returned memory is not assumed to be initialized
to any particular value or values.
Re: Making sense of ACPI(CA)
ACPICA basically implements it's own calloc call by calling AcpiOsAllocate and then an internal memset. Personally I'd put a write watch on next field of the WalkState and find out what exactly is trashing it's values and go on from there.
Reserved for OEM use.
Re: Making sense of ACPI(CA)
OK, so I have managed to collect a list of PCI devices from ACPI. For my 2-core AMD it looks like this:
Now I only need to determined their IRQs.
Code: Select all
\_SB_.PCI0.SMB0, Bus: 0, Device: 20, Function: 0
\_SB_.PCI0.USB0, Bus: 0, Device: 19, Function: 0
\_SB_.PCI0.USB1, Bus: 0, Device: 19, Function: 1
\_SB_.PCI0.USB2, Bus: 0, Device: 19, Function: 2
\_SB_.PCI0.USB3, Bus: 0, Device: 19, Function: 3
\_SB_.PCI0.USB4, Bus: 0, Device: 19, Function: 4
\_SB_.PCI0.USB5, Bus: 0, Device: 19, Function: 5
\_SB_.PCI0.AZAL, Bus: 0, Device: 20, Function: 2
\_SB_.PCI0.LPC0, Bus: 0, Device: 20, Function: 3
\_SB_.PCI0.P2P_, Bus: 0, Device: 20, Function: 4
\_SB_.PCI0.IDE_, Bus: 0, Device: 20, Function: 1
\_SB_.PCI0.SAT0, Bus: 0, Device: 18, Function: 0
\_SB_.PCI0.PCE2, Bus: 0, Device: 2, Function: 0
\_SB_.PCI0.PCE3, Bus: 0, Device: 3, Function: 0
\_SB_.PCI0.PCE4, Bus: 0, Device: 4, Function: 0
\_SB_.PCI0.PCE5, Bus: 0, Device: 5, Function: 0
\_SB_.PCI0.PCE6, Bus: 0, Device: 6, Function: 0
\_SB_.PCI0.PCE7, Bus: 0, Device: 7, Function: 0
\_SB_.PCI0.PCE8, Bus: 0, Device: 8, Function: 0
\_SB_.PCI0.AGP_, Bus: 0, Device: 1, Function: 0
Re: Making sense of ACPI(CA)
Updated list with IRQs for the 4 possible PCI pins:
However, this does not correspond to the interrupt settings in Windows XP! OTOH, they don't conflict with anything either, so maybe those are valid defaults?
My new 6-core AMD looks like this (it has two IO-APICs, but the default routing doesn't seem to use any IO-APIC specific ints either):
Code: Select all
\_SB_.PCI0.SMB0, Bus: 0, Device: 20, Function: 0, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB0, Bus: 0, Device: 19, Function: 0, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB1, Bus: 0, Device: 19, Function: 1, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB2, Bus: 0, Device: 19, Function: 2, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB3, Bus: 0, Device: 19, Function: 3, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB4, Bus: 0, Device: 19, Function: 4, IRQ: 3, 11, 5, 10
\_SB_.PCI0.USB5, Bus: 0, Device: 19, Function: 5, IRQ: 3, 11, 5, 10
\_SB_.PCI0.AZAL, Bus: 0, Device: 20, Function: 2, IRQ: 3, 11, 5, 10
\_SB_.PCI0.LPC0, Bus: 0, Device: 20, Function: 3, IRQ: 3, 11, 5, 10
\_SB_.PCI0.P2P_, Bus: 0, Device: 20, Function: 4, IRQ: 3, 11, 5, 10
\_SB_.PCI0.IDE_, Bus: 0, Device: 20, Function: 1, IRQ: 3, 11, 5, 10
\_SB_.PCI0.SAT0, Bus: 0, Device: 18, Function: 0, IRQ: 11, 11, 11, 11
\_SB_.PCI0.PCE2, Bus: 0, Device: 2, Function: 0, IRQ: 5, 5, 5, 5
\_SB_.PCI0.PCE3, Bus: 0, Device: 3, Function: 0, IRQ: 10, 10, 10, 10
\_SB_.PCI0.PCE4, Bus: 0, Device: 4, Function: 0, IRQ: 3, 3, 3, 3
\_SB_.PCI0.PCE5, Bus: 0, Device: 5, Function: 0, IRQ: 11, 11, 11, 11
\_SB_.PCI0.PCE6, Bus: 0, Device: 6, Function: 0, IRQ: 5, 5, 5, 5
\_SB_.PCI0.PCE7, Bus: 0, Device: 7, Function: 0, IRQ: 10, 10, 10, 10
\_SB_.PCI0.PCE8, Bus: 0, Device: 8, Function: 0, IRQ: 3, 3, 3, 3
\_SB_.PCI0.AGP_, Bus: 0, Device: 1, Function: 0
My new 6-core AMD looks like this (it has two IO-APICs, but the default routing doesn't seem to use any IO-APIC specific ints either):
Code: Select all
\_SB_.PCI0.SMBS, Bus: 0, Device: 20, Function: 0, IRQ: 10, 7, 7, 3
\_SB_.PCI0.IDEC, Bus: 0, Device: 20, Function: 1, IRQ: 10, 7, 7, 3
\_SB_.PCI0.SBAZ, Bus: 0, Device: 20, Function: 2, IRQ: 10, 7, 7, 3
\_SB_.PCI0.SBRG, Bus: 0, Device: 20, Function: 3, IRQ: 10, 7, 7, 3
\_SB_.PCI0.P0PC, Bus: 0, Device: 20, Function: 4, IRQ: 10, 7, 7, 3
\_SB_.PCI0.UHC1, Bus: 0, Device: 18, Function: 0, IRQ: 7, 7
\_SB_.PCI0.UHC2, Bus: 0, Device: 18, Function: 2, IRQ: 7, 7
\_SB_.PCI0.USB3, Bus: 0, Device: 19, Function: 0, IRQ: 11, 10
\_SB_.PCI0.UHC4, Bus: 0, Device: 19, Function: 2, IRQ: 11, 10
\_SB_.PCI0.USB5, Bus: 0, Device: 22, Function: 0, IRQ: 11, 11
\_SB_.PCI0.UHC6, Bus: 0, Device: 22, Function: 2, IRQ: 11, 11
\_SB_.PCI0.UHC7, Bus: 0, Device: 20, Function: 5, IRQ: 10, 7, 7, 3
\_SB_.PCI0.SATA, Bus: 0, Device: 17, Function: 0, IRQ: 3
\_SB_.PCI0.PE20, Bus: 0, Device: 21, Function: 0, IRQ: 10, 7, 7, 3
\_SB_.PCI0.PE21, Bus: 0, Device: 21, Function: 1, IRQ: 10, 7, 7, 3
\_SB_.PCI0.PE22, Bus: 0, Device: 21, Function: 2, IRQ: 10, 7, 7, 3
\_SB_.PCI0.PE23, Bus: 0, Device: 21, Function: 3, IRQ: 10, 7, 7, 3
\_SB_.PCI0.IOMA, Bus: 0, Device: 0, Function: 2, IRQ: 10
\_SB_.PCI0.RD8A, Bus: 0, Device: 0, Function: 0, IRQ: 10
\_SB_.PCI0.PC02, Bus: 0, Device: 2, Function: 0, IRQ: 11
\_SB_.PCI0.PC03, Bus: 0, Device: 3, Function: 0, IRQ: 11
\_SB_.PCI0.PC04, Bus: 0, Device: 4, Function: 0, IRQ: 11
\_SB_.PCI0.PC05, Bus: 0, Device: 5, Function: 0, IRQ: 11
\_SB_.PCI0.PC06, Bus: 0, Device: 6, Function: 0, IRQ: 10
\_SB_.PCI0.PC07, Bus: 0, Device: 7, Function: 0, IRQ: 10
\_SB_.PCI0.PC09, Bus: 0, Device: 9, Function: 0, IRQ: 10
\_SB_.PCI0.PC0A, Bus: 0, Device: 10, Function: 0, IRQ: 11
\_SB_.PCI0.PC0B, Bus: 0, Device: 11, Function: 0, IRQ: 11
\_SB_.PCI0.PC0C, Bus: 0, Device: 12, Function: 0, IRQ: 11
\_SB_.PCI0.PC0D, Bus: 0, Device: 13, Function: 0, IRQ: 11
Re: Making sense of ACPI(CA)
I know why it doesn't work. In order to enable APIC-mode in ACPICA, there is a need to execute a special method just before any interrupt information is retrieved.
It looks like this:
This code could be placed in the AcpiEnableSubsystem procedure just before initializing the SCI handler.
It's really strange that the documentation says nothing about this.
It looks like this:
Code: Select all
ACPI_OBJECT_LIST Params;
ACPI_OBJECT Obj;
Params.Count = 1;
Params.Pointer = &Obj;
Obj.Type = ACPI_TYPE_INTEGER;
Obj.Integer.Value = 1; // 0 = PIC, 1 = APIC
AcpiEvaluateObject(NULL, "\\_PIC", &Params, NULL);
It's really strange that the documentation says nothing about this.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Making sense of ACPI(CA)
Thats not ACPICA. Thats ACPI.
Seriously. This is all documented in the (admittedly large) ACPI specification. You have to tell the firmware what mode you require before it can tell you the interrupt map you want.
Seriously. This is all documented in the (admittedly large) ACPI specification. You have to tell the firmware what mode you require before it can tell you the interrupt map you want.
Re: Making sense of ACPI(CA)
Well, the major problem is that you need to insert this in the middle of the AcpiEnableSubsystem, because otherwise the SCI might be initialized with a PIC setting! You cannot do it before the AcpiEnableSubsystem, because then some hardware state is uninitialized.Owen wrote:Thats not ACPICA. Thats ACPI.
Seriously. This is all documented in the (admittedly large) ACPI specification. You have to tell the firmware what mode you require before it can tell you the interrupt map you want.
Re: Making sense of ACPI(CA)
Some more progress in PCI IRQ identification, but it still doesn't give the same results as Windows XP.
First, my code only seems to identify IRQs on bus 0 (the PCI root bus). Secondly, some of the USB interrupts differ between Windows XP and my code.
There must be some additional PCI devices (probably the PCI-PCI bridges), that has additional IRQ information for other bus numbers.
When the APIC is used, there are no link-devices it seems, rather the IRQ information is directly coded in the returned IRQ routing resource. One issue is that the IRQ routings are per-device (and not function), and specifies the pin-number instead of function number. When the pin-number is read-out from various PCI-devices, it sometimes seems undefined, or has a higher than allowed value. Maybe Windows XP assigns the pin-numbers such that different functions within a devices gets different pins (all zero-functions have the correct IRQs)? That could explain why the USB-devices does not have the same IRQ in my system compared to Windows (some of the non-zero functions differ). The big question is if programming the PCI pin number setting changes the IRQ-mapping directly, unlike programing the IRQ, which has no effect. Or do Windows XP do this in some other way?
Code: Select all
ACPI Name Vendor/dev Class Bus Dev Func IRQ WinXP
\_SB_.PCI0.SMBS 1002 4385 0C05 0 20 0 16 none (SMBus)
\_SB_.PCI0.IDEC 1002 439C 0C05 0 20 1 16 none (PCI IDE)
\_SB_.PCI0.SBAZ 1002 4383 0C05 0 20 2 16 16 (UAA HD audio)
\_SB_.PCI0.SBRG 1002 439D 0C05 0 20 3 16 none (ISA bridge)
\_SB_.PCI0.P0PC 1002 4384 0C05 0 20 4 16 none (PCI-PCI bridge)
\_SB_.PCI0.UHC1 1002 4397 0C03 0 18 0 18 18 (OHCI USB)
\_SB_.PCI0.UHC2 1002 4396 0C03 0 18 2 18 17 (EHCI USB)
\_SB_.PCI0.USB3 1002 4397 0C03 0 19 0 20 20 (OHCI USB)
\_SB_.PCI0.UHC4 1002 4396 0C03 0 19 2 20 21 (EHCI USB)
\_SB_.PCI0.USB5 1002 4397 0C03 0 22 0 22 22 (OHCI USB)
\_SB_.PCI0.UHC6 1002 4396 0C03 0 22 2 22 23 (EHCI USB)
\_SB_.PCI0.UHC7 1002 4399 0C05 0 20 5 16 18 (OHCI USB)
\_SB_.PCI0.SATA 1002 4390 0101 0 17 0 0 19 (PCI IDE)
\_SB_.PCI0.RD8A 1002 5A14 FFFF 0 0 0 55 none (PCI standard host bridge)
\_SB_.PCI0.PC02 1002 5A16 0604 0 2 0 52 52 (PCI-PCI bridge)
\_SB_.PCI0.PC04 1002 5A18 0604 0 4 0 52 52 (PCI-PCI bridge)
\_SB_.PCI0.PC05 1002 5A19 0604 0 5 0 52 52 (PCI-PCI bridge)
\_SB_.PCI0.PC06 1002 5A1A 0604 0 6 0 53 53 (PCI-PCI bridge)
\_SB_.PCI0.PC07 1002 5A1B 0604 0 7 0 53 53 (PCI-PCI bridge)
\_SB_.PCI0.PC0A 1002 5A1D 0604 0 10 0 54 54 (PCI-PCI bridge)
1 0 0 24 (ATI Radeon HD 5450)
1 0 1 25 (UAA HD Audio)
2 0 0 44 (Realtek PCIe)
3 0 0 46 (XHCI USB)
4 0 0 51 (KMicron SCSI)
5 0 0 50 (XHCI USB)
6 0 0 47 (KMicron SCSI)
7 6 0 21 (1394)
There must be some additional PCI devices (probably the PCI-PCI bridges), that has additional IRQ information for other bus numbers.
When the APIC is used, there are no link-devices it seems, rather the IRQ information is directly coded in the returned IRQ routing resource. One issue is that the IRQ routings are per-device (and not function), and specifies the pin-number instead of function number. When the pin-number is read-out from various PCI-devices, it sometimes seems undefined, or has a higher than allowed value. Maybe Windows XP assigns the pin-numbers such that different functions within a devices gets different pins (all zero-functions have the correct IRQs)? That could explain why the USB-devices does not have the same IRQ in my system compared to Windows (some of the non-zero functions differ). The big question is if programming the PCI pin number setting changes the IRQ-mapping directly, unlike programing the IRQ, which has no effect. Or do Windows XP do this in some other way?
Re: Making sense of ACPI(CA)
Solved the IRQ matching issue. I read the interrupt line instead of interrupt pin, which was not a good idea. I also clobbered the PCI function in the loop, which gave the wrong class-codes.
So, here is the correct PCI mapping from ACPI:
Now I only need to fetch the IRQ-mappings for other buses. I think how this is done is by inspecting the class-code of each PCI-device, and if it is 0604 it is a PCI-PCI bridge, and then read the secondary bus register in PCI configuration space, and the PCI IRQ entries from ACPI, assigning them to the new bus.
So, here is the correct PCI mapping from ACPI:
Code: Select all
ACPI Name Vendor/dev Class Bus Dev Func IRQ
\_SB_.PCI0.SMBS 1002 4385 0C05 0 20 0 0
\_SB_.PCI0.IDEC 1002 439C 0101 0 20 1 17
\_SB_.PCI0.SBAZ 1002 4383 0403 0 20 2 16
\_SB_.PCI0.SBRG 1002 439D 0601 0 20 3 0
\_SB_.PCI0.P0PC 1002 4384 0604 0 20 4 0
\_SB_.PCI0.UHC1 1002 4397 0C03 0 18 0 18
\_SB_.PCI0.UHC2 1002 4396 0C03 0 18 2 17
\_SB_.PCI0.USB3 1002 4397 0C03 0 19 0 20
\_SB_.PCI0.UHC4 1002 4396 0C03 0 19 2 21
\_SB_.PCI0.USB5 1002 4397 0C03 0 22 0 22
\_SB_.PCI0.UHC6 1002 4396 0C03 0 22 2 23
\_SB_.PCI0.UHC7 1002 4399 0C03 0 20 5 18
\_SB_.PCI0.SATA 1002 4390 0101 0 17 0 19
\_SB_.PCI0.RD8A 1002 5A14 0600 0 0 0 0
\_SB_.PCI0.PC02 1002 5A16 0604 0 2 0 52
\_SB_.PCI0.PC04 1002 5A18 0604 0 4 0 52
\_SB_.PCI0.PC05 1002 5A19 0604 0 5 0 52
\_SB_.PCI0.PC06 1002 5A1A 0604 0 6 0 53
\_SB_.PCI0.PC07 1002 5A1B 0604 0 7 0 53
\_SB_.PCI0.PC0A 1002 5A1D 0604 0 10 0 54
Re: Making sense of ACPI(CA)
New results from the PCI command-line:
Now the extra buses are visible (the previous method to check for PCI-PCI bridge worked). However, only the SCI devices (JMB0) are available in ACPI configuration space. The other devices are not managed by ACPI. For instance, the RTL 8168 (bus 2) is integrated behind a PCI-PCI bridge on the motherboard, and is not enumrated by ACPI. The XHCI USB is also not in ACPI. The video card could not be part of ACPI since it is an add-on board.
The devices above that are preceeded with "PCI-PCI" are not listed as ACPI devices in the name-space, but has to be added as pseudo-devices instead in order to record them. They are listed in the _PRT table for the PCI-PCI bridge, but those entries only contain a device, not a function #. There is one missing PCI function above which Windows XP has. It has bus 1, device 0, function 1. I need to add additional code to handle non-zero functions for non-ACPI listed devices. I need to check that all the PCI-devices I have found are listed.
Code: Select all
ACPI Name Vendor/dev Class Bus Dev Func IRQ
\_SB_.PCI0.SMBS 1002 4385 0C05 0 20 0
\_SB_.PCI0.IDEC 1002 439C 0101 0 20 1 17
\_SB_.PCI0.SBAZ 1002 4383 0403 0 20 2 16
\_SB_.PCI0.SBRG 1002 439D 0601 0 20 3
\_SB_.PCI0.P0PC 1002 4384 0604 0 20 4
\_SB_.PCI0.UHC1 1002 4397 0C03 0 18 0 18
\_SB_.PCI0.UHC2 1002 4396 0C03 0 18 2 17
\_SB_.PCI0.USB3 1002 4397 0C03 0 19 0 20
\_SB_.PCI0.UHC4 1002 4396 0C03 0 19 2 21
\_SB_.PCI0.USB5 1002 4397 0C03 0 22 0 22
\_SB_.PCI0.UHC6 1002 4396 0C03 0 22 2 23
\_SB_.PCI0.UHC7 1002 4399 0C03 0 20 5 18
\_SB_.PCI0.SATA 1002 4390 0101 0 17 0 19
\_SB_.PCI0.RD8A 1002 5A14 0600 0 0 0
\_SB_.PCI0.PC02 1002 5A16 0604 0 2 0 52
\_SB_.PCI0.PC04 1002 5A18 0604 0 4 0 52
\_SB_.PCI0.PC05 1002 5A19 0604 0 5 0 52
\_SB_.PCI0.PC06 1002 5A1A 0604 0 6 0 53
\_SB_.PCI0.PC07 1002 5A1B 0604 0 7 0 53
\_SB_.PCI0.PC0A 1002 5A1D 0604 0 10 0 54
\_SB_.PCI0.PC06.JMB0 197B 2362 0101 4 0 0 51
\_SB_.PCI0.PC0A.JMB0 197B 2362 0101 6 0 0 47
PCI-PCI P0PC 1409 7168 0700 7 5 0 20
PCI-PCI P0PC 1106 3044 0C00 7 6 0 21
PCI-PCI PC02 1002 68F9 0300 1 0 0 24
PCI-PCI PC04 10EC 8168 0200 2 0 0 44
PCI-PCI PC05 1B21 1042 0C03 3 0 0 46
PCI-PCI PC07 1B21 1042 0C03 5 0 0 50
The devices above that are preceeded with "PCI-PCI" are not listed as ACPI devices in the name-space, but has to be added as pseudo-devices instead in order to record them. They are listed in the _PRT table for the PCI-PCI bridge, but those entries only contain a device, not a function #. There is one missing PCI function above which Windows XP has. It has bus 1, device 0, function 1. I need to add additional code to handle non-zero functions for non-ACPI listed devices. I need to check that all the PCI-devices I have found are listed.
Re: Making sense of ACPI(CA)
This is the final list for the PCI-devices, and their IRQs on the 6-core AMD:
Surpsingly, the motherboard has support for 8 serial ports, and also has 8 OHCI-controllers, 7 EHCI controllers and 2 XHCI controllers.
Using this information, it should be fairly easy to implement the GetPciIrq procedure that has an PCI-address as input, and an IRQ-number as output.
Edit: Now I now why global interrupt numbers up to 53 can be present in ACPI. This machine has a primary IO-APIC with 24 channels, and a secondary IO-APIC with 32 channels, making a total of 56 channels.
Code: Select all
ACPI Name Vendor/dev Class Bus Dev Func IRQ
\_SB_.PCI0.SMBS 1002 4385 0C05 0 20 0
\_SB_.PCI0.IDEC 1002 439C 0101 0 20 1 17
\_SB_.PCI0.SBAZ 1002 4383 0403 0 20 2 16
\_SB_.PCI0.SBRG 1002 439D 0601 0 20 3
\_SB_.PCI0.P0PC 1002 4384 0604 0 20 4
\_SB_.PCI0.UHC1 1002 4397 0C03 0 18 0 18
\_SB_.PCI0.UHC2 1002 4396 0C03 0 18 2 17
\_SB_.PCI0.USB3 1002 4397 0C03 0 19 0 20
\_SB_.PCI0.UHC4 1002 4396 0C03 0 19 2 21
\_SB_.PCI0.USB5 1002 4397 0C03 0 22 0 22
\_SB_.PCI0.UHC6 1002 4396 0C03 0 22 2 23
\_SB_.PCI0.UHC7 1002 4399 0C03 0 20 5 18
\_SB_.PCI0.SATA 1002 4390 0101 0 17 0 19
\_SB_.PCI0.RD8A 1002 5A14 0600 0 0 0
\_SB_.PCI0.PC02 1002 5A16 0604 0 2 0 52
\_SB_.PCI0.PC04 1002 5A18 0604 0 4 0 52
\_SB_.PCI0.PC05 1002 5A19 0604 0 5 0 52
\_SB_.PCI0.PC06 1002 5A1A 0604 0 6 0 53
\_SB_.PCI0.PC07 1002 5A1B 0604 0 7 0 53
\_SB_.PCI0.PC0A 1002 5A1D 0604 0 10 0 54
\_SB_.PCI0.PC06.JMB0 197B 2362 0101 4 0 0 51
\_SB_.PCI0.PC0A.JMB0 197B 2362 0101 6 0 0 47
PCI-PCI P0PC 1409 7168 0700 7 5 0 20
PCI-PCI P0PC 1409 7168 0700 7 5 1 20
PCI-PCI P0PC 1409 7168 0700 7 5 2 20
PCI-PCI P0PC 1409 7168 0700 7 5 3 20
PCI-PCI P0PC 1409 7168 0700 7 5 4 20
PCI-PCI P0PC 1409 7168 0700 7 5 5 20
PCI-PCI P0PC 1409 7168 0700 7 5 6 20
PCI-PCI P0PC 1409 7168 0700 7 5 7 20
PCI-PCI P0PC 1106 3044 0C00 7 6 0 21
PCI-PCI P0PC 1106 3044 0C00 7 6 1 21
PCI-PCI P0PC 1106 3044 0C00 7 6 2 21
PCI-PCI P0PC 1106 3044 0C00 7 6 3 21
PCI-PCI P0PC 1106 3044 0C00 7 6 4 21
PCI-PCI P0PC 1106 3044 0C00 7 6 5 21
PCI-PCI P0PC 1106 3044 0C00 7 6 6 21
PCI-PCI P0PC 1106 3044 0C00 7 6 7 21
PCI-PCI PC02 1002 68F9 0300 1 0 0 24
PCI-PCI PC02 1002 AA68 0403 1 0 1 25
PCI-PCI PC04 10EC 8168 0200 2 0 0 44
PCI-PCI PC05 1B21 1042 0C03 3 0 0 46
PCI-PCI PC07 1B21 1042 0C03 5 0 0 50
1022 1200 0600 0 24 0
1022 1201 0600 0 24 1
1022 1202 0600 0 24 2
1022 1203 0600 0 24 3
1022 1204 0600 0 24 4
Using this information, it should be fairly easy to implement the GetPciIrq procedure that has an PCI-address as input, and an IRQ-number as output.
Edit: Now I now why global interrupt numbers up to 53 can be present in ACPI. This machine has a primary IO-APIC with 24 channels, and a secondary IO-APIC with 32 channels, making a total of 56 channels.