I fixed an ACPI problem with an old motherboard. Here, I document the steps I used to repair it:
Trying FreeBSD 12.0 on an old Pentium 4 machine, with Intel D915GAV motherboard, latest BIOS version. Everything seems to be working OK except that I have an ACPI error report in dmesg(8) on boot. The specific error is:
This seems to indicate a problem with the ASL code stored in the BIOS for part of the PCI bridge. The board is from 2005, and odds of this getting fixed by Intel are exactly zero at this point, so I'd like to try to remedy it myself using the ACPI tools, and see if this is a bug to kick to maintainers or not. Reference this similar report on Linux kernel.org: https://bugzilla.kernel.org/show_bug.cgi?id=198003
---
Here is how I managed to solve this problem:
Dump the firmware and decompile it. The command used was:
Examine the PCI0._OSC function from the code. It looks like this:
As it says, the Method is expecting 5 arguments, but ACPI spec is supposed to send only 4 to this method.
Attempt to repair the buggy code: Based on this ACPI spec from Intel (https://www.intel.com/content/dam/w...cessor-vendor-specific-acpi-specification.pdf), the _OSC method is supposed to take 4 arguments, of the form:
Since the Arg3 in the original function looks like a value, and the Arg4 some kind of buffer (based on the assignments), I'm gonna guess the coder screwed this up in an off-by-one. So I change the method to this:
Rebuild the DSDT.aml file: Recompile with
Reboot the system: Everything seemed to start up OK. (Actually, I had an error the first time when I put the wrong file at /boot/DSDT.aml, and got a crash at boot. You can bypass this by changing the boot options in the boot menu to disable ACPI for one run, then fix your mistake).
Check dmesg: The lines showing an error before are gone! The bug is fixed.
Next steps: FreeBSD ACPI devs ask that you forward issues like this to them, in case there is some deficiency in the spec that can be worked around in the ACPI parser/loader. I'm not going to bother, since this seems to be directly caused by an error in the BIOS code, not an issue with the ACPI loader itself.
If I'm feeling really brave, I might take a crack at editing the latest Intel BIOS update and replacing the ASL blob with my new one, permanently fixing the problem with the board. For now, I can live with this workaround.
Trying FreeBSD 12.0 on an old Pentium 4 machine, with Intel D915GAV motherboard, latest BIOS version. Everything seems to be working OK except that I have an ACPI error report in dmesg(8) on boot. The specific error is:
Code:
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
Firmware Error (ACPI): \134_SB.PCI0._OSC: Excess arguments - ASL declared 5, ACPI requires 4 (20181003/nsarguments-309)
pcib0: _OSC failed: AE_BUFFER_OVERFLOW
pci0: <ACPI PCI bus> on pcib0
This seems to indicate a problem with the ASL code stored in the BIOS for part of the PCI bridge. The board is from 2005, and odds of this getting fixed by Intel are exactly zero at this point, so I'd like to try to remedy it myself using the ACPI tools, and see if this is a bug to kick to maintainers or not. Reference this similar report on Linux kernel.org: https://bugzilla.kernel.org/show_bug.cgi?id=198003
---
Here is how I managed to solve this problem:
Dump the firmware and decompile it. The command used was:
acpidump -dt > DSDT.asl
Examine the PCI0._OSC function from the code. It looks like this:
C-like:
Scope (\_SB.PCI0)
{
Method (_OSC, 5, NotSerialized) // _OSC: Operating System Capabilities
{
Local0 = Arg3
Local1 = (Local0 * 0x04)
Name (BUF1, Buffer (Local1){})
BUF1 = Arg4
Local3 = 0x03
CreateDWordField (BUF1, 0x00, CAPB)
If ((CAPB && 0x02))
{
Local3 &= 0x0E
}
If ((CAPB && 0x08))
{
Local3 &= 0x0D
\_SB.PCI0.SBRG.GPMD (0x00)
}
\_SB.PCI0.PEX1.SCIC (0x00, Local3)
\_SB.PCI0.PEX2.SCIC (0x01, Local3)
\_SB.PCI0.PEX3.SCIC (0x02, Local3)
\_SB.PCI0.PEX4.SCIC (0x03, Local3)
\_SB.PCI0.PEGP.SCIC (0x08, Local3)
Return (BUF1) /* \_SB_.PCI0._OSC.BUF1 */
}
}
As it says, the Method is expecting 5 arguments, but ACPI spec is supposed to send only 4 to this method.
Attempt to repair the buggy code: Based on this ACPI spec from Intel (https://www.intel.com/content/dam/w...cessor-vendor-specific-acpi-specification.pdf), the _OSC method is supposed to take 4 arguments, of the form:
Code:
Arg0 (Buffer): UUID
Arg1 (Integer): Revision ID
Arg2 (Integer): Count
Arg3 (Buffer): Capabilities Buffer
Since the Arg3 in the original function looks like a value, and the Arg4 some kind of buffer (based on the assignments), I'm gonna guess the coder screwed this up in an off-by-one. So I change the method to this:
C-like:
Scope (\_SB.PCI0)
{
Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
{
Local0 = Arg2
Local1 = (Local0 * 0x04)
Name (BUF1, Buffer (Local1){})
BUF1 = Arg3
Local3 = 0x03
...
Rebuild the DSDT.aml file: Recompile with
iasl -f DSDT.asl
and it produces a new ACPI blob for use in my next boot (in my case, 22506 bytes). Copied the produced DSDT.aml file to /boot/DSDT.aml. Then set the machine to use the override next boot, by editing /boot/loader.conf according to these steps from the Handbook (https://www.freebsd.org/doc/handbook/acpi-overview.html):
Code:
acpi_dsdt_load="YES"
acpi_dsdt_name="/boot/DSDT.aml"
Reboot the system: Everything seemed to start up OK. (Actually, I had an error the first time when I put the wrong file at /boot/DSDT.aml, and got a crash at boot. You can bypass this by changing the boot options in the boot menu to disable ACPI for one run, then fix your mistake).
Check dmesg: The lines showing an error before are gone! The bug is fixed.
Code:
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
Next steps: FreeBSD ACPI devs ask that you forward issues like this to them, in case there is some deficiency in the spec that can be worked around in the ACPI parser/loader. I'm not going to bother, since this seems to be directly caused by an error in the BIOS code, not an issue with the ACPI loader itself.
If I'm feeling really brave, I might take a crack at editing the latest Intel BIOS update and replacing the ASL blob with my new one, permanently fixing the problem with the board. For now, I can live with this workaround.