Re: Asus P8B WS DSDT
Another major task with the DSDT is
PCI device-id injection. I've been thinking about this for quite a while for one very important reasons. The Asus P8B WS has dual Intel 82574L LAN controllers which could use Apple's stock Intel82574L.kext driver rather than hnak's AppleIntelE1000.kext. The only reason this is an attractive option is that hnak's driver does not support VLANs. In every other way the driver is excellent and works extremely well on other Intel E1000 chipsets such as the 82579 controllers often found on Sandy Bridge motherboards.
On the Asus P8B WS, the two 82574L controllers fall under PEX5 and PEX6 in the DSDT. I first started going down this path by applying the LAN0.txt patch in DSDT Editor. This gave me a start but many hours of research today have provided some more answers.
If you look under Device (PEX5), the last Method will be called _PRT. This method and its associated lines can be deleted. Instead, we are going to add LAN0 and eventually LAN1 under PEX6 as well. The full block of code for LAN0 looks like this:
Code:
Device (LAN0)
{
Name (_ADR, Zero)
Method (_DSM, 4, NotSerialized)
{
Store (Package (0x12)
{
"AAPL,slot-name",
Buffer (0x07)
{
"Slot-5"
},
"built-in",
Buffer (One)
{
0x00
},
"location",
Buffer (0x02)
{
"1"
},
"device-id",
Buffer (0x00)
{
0xF6, 0x10, 0x00, 0x00
},
"revision-id",
Buffer (0x08)
{
0x01, 0x00, 0x00, 0x00
},
"subsystem-id",
Buffer (0x2C)
{
0x00, 0x00, 0x00, 0x00
},
"subsystem-vendor-id",
Buffer (0x2C)
{
0x86, 0x80, 0x00, 0x00
},
"device_type",
Buffer (0x14)
{
"Ethernet Controller"
},
"model",
Buffer (0x2B)
{
"Intel 82574L PCI Express Gigabit Ethernet"
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
I will go through each section so it makes sense what is going on. The first line we will look at is "Store (Package (0x12)" and this is the first line where the number of key value items are defined. If you look through the items defined, there are nine of them. Each one is represented by a key and a value which makes 18. The decimal number 18 in hex is 0x12 which is where the value comes from. If you remove key/value information from this block of DSDT code, you would need to decrement 0x12 by two each time you do that. For example removing one block of code would make hex 0x0E which is decimal 16.
Code:
"AAPL,slot-name",
Buffer (0x07)
{
"Slot-5"
},
While the "AAPL,slot-name" key really has nothing to do with actually getting the 82574L controllers to work, it does allow them to show up properly under PCI devices in System Information which makes this process easier. I gleaned this information from a
post by MaLdOn. He apparently found this from a DSDT dump from a real Mac. It doesn't seem to matter what value you use for this property but "Slot-5" made sense to me since this is part of PEX5. In other examples I have seen GIGE and other Slot- values have been used.
The next section is the "built-in" key. Intuitively, this would have a value of 0x01 instead of 0x00 but it seems to show up in IORegistry as 0x00 regularless and MaLdOn's example used 0x00 as well.
Also, I should mention that the Buffer (0x07) values comes from the
PCI config space. I'm not sure that they all need to be correct since I had some wrong and I was still getting the proper information but it's better to be accurate than not.
The next key is "location" which apprently is relevant when you have two ethernet controllers. The "location" value is 1 on LAN0 and 2 on LAN1 in accordance with a
post by kDawg and an
actual DSDT dump from a Mac Pro.
The next four values are the important ones.
Code:
"device-id",
Buffer (0x00)
{
0xF6, 0x10, 0x00, 0x00
},
"revision-id",
Buffer (0x08)
{
0x01, 0x00, 0x00, 0x00
},
"subsystem-id",
Buffer (0x2C)
{
0x00, 0x00, 0x00, 0x00
},
"subsystem-vendor-id",
Buffer (0x2C)
{
0x86, 0x80, 0x00, 0x00
},
The "device-id" key is what we are using to tell the operating system that the 82574L controllers are really a different PCI device-id than they are so that it matches Intel82574L.kext. Intel82574L.kext matches only 0x10f68086 and 0x104b8086. When we are looking at device-id hex strings, the first two bytes are the device-id and the last two are the vendor-id. So the actual device-id values are 0x10f6 and 0x104b. The vendor-id is 0x8086 which happens to be Intel. Also remember that these are little endian values so, for example, 0x8086 is represented as 0x86, 0x80 in the various sections.
In Apple's
"Writing a Driver for a PCI Device" we see that the driver is matched against four possible values: IOPCIMatch, IOPCIPrimaryMatch, IOPCISecondaryMatch, and IOPCIClassMatch. The last of these, IOPCIClassMatch is always the same for network controllers (0x0200) and is not of any concern for this process. The other three are more important.
Read the beginning part of Apple's
"Writing a Driver for a PCI Device" to understand how the matching takes place. In a nutshell, IOPCIMatch will look through primary device-id and vendor-id and then also subsystem device-id and vendor-id to find a match. IOPCIPrimaryMatch only looks at primary device-id and vendor-id and IOPCISecondaryMatch only looks at subsystem device-id and vendor-id.
In the case of the Intel82574L.kext, both IOPCIPrimaryMatch and IOPCISecondaryMatch are used. From the Info.plist inside Intel82574L.kext:
Code:
<key>IOPCIPrimaryMatch</key>
<string>0x104b8086 0x10f68086</string>
<key>IOPCISecondaryMatch</key>
<string>0x00008086 0x00000000</string>
Based on the fact that there is a dual port Apple 82574L card available with the device-id of 0x10f6, I decided to use that PCI device-id. As you can see form the IOPCISecondaryMatch line, only the vendor-id of Intel (0x8086) is matched and so I just decided to zero out subsystem device-id in the DSDT.
The final keys of "device-type" and "model" are just cosmetic and make the controllers look better in System Information.
After quite a bit of head scratching, I finally got it all working. At one point I did do a -f -v boot with Chimera that ended in a waiting for root device hang and I also ran "sudo kextcache -system-caches" from Terminal but I'm not certain if these are actually needed since I was fixing my errors through that process.
Why?
The whole reason to do PCI device-id patching in the DSDT is to keep the system as vanilla as possible. It is very easy to patch the device-id that is matched in Intel82574L.kext but this would have to be re-applied at every update.
Attached are my DSDT-LAN.dsl and DSDT-LAN.aml files. If you want to apply these patches to your own DSDT, I would suggest you look at LAN0 and LAN1 in the PEX5 and PEX6 sections respectively and copy that information to your own DSDT.
DSDT-LAN.dsl
DSDT-LAN.aml
Update: After running System Utilities which rebuilds caches and so forth, LAN stopped working again. Removing the IOPCISecondaryMatch key and value in the Info.plist for Intel82547L.kext returned it to functioning. I am attempting to get the subsystem device-id from an actual Apple card that uses the Intel82574L.kext driver to see how I can fix this in the DSDT. I'm determined to get this functioning because I do not want to have to do any Info.plist editing to get the Intel82574L.kext to match the onboard controllers.