Solved ACPI Error: "Excess arguments - ASL declared 5, ACPI requires 4"

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:

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.
 
Hi,

I've installed LinuxMint 20.1 on my (older) desktop pc and also have your mentioned ACPI error messages.
A google search brought me to your thread here. Can you help fix my ACPI please?

I just tried your mentioned solution but getting already errors with the first command:

# acpidump -dt > DSDT.asl
# Illegal option: -d

Did the acpidump arguments change?

System info and my errors:
Bash:
$ inxi -F && dmesg | grep -i error
System:    Host: amelie-pc Kernel: 5.4.0-66-generic x86_64 bits: 64 Desktop: Cinnamon 4.8.6
           Distro: Linux Mint 20.1 Ulyssa
Machine:   Type: Desktop System: Hewlett-Packard product: HP Compaq dc7800p Small Form Factor v: N/A
           serial: <superuser/root required>
           Mobo: Hewlett-Packard model: 0AA8h serial: <superuser/root required> BIOS: Hewlett-Packard
           v: 786F1 v01.04 date: 07/18/2007
CPU:       Topology: Dual Core model: Intel Core2 Duo E6750 bits: 64 type: MCP L2 cache: 4096 KiB
           Speed: 1995 MHz min/max: 1998/2667 MHz Core speeds (MHz): 1: 1995 2: 1995
Graphics:  Device-1: AMD RV710 [Radeon HD 4350/4550] driver: radeon v: kernel
           Display: x11 server: X.Org 1.20.9 driver: ati,radeon unloaded: fbdev,modesetting,vesa
           resolution: 1280x1024~60Hz
           OpenGL: renderer: AMD RV710 (DRM 2.50.0 / 5.4.0-66-generic LLVM 11.0.0) v: 3.3 Mesa 20.2.6
Audio:     Device-1: Intel 82801I HD Audio driver: snd_hda_intel
           Device-2: AMD RV710/730 HDMI Audio [Radeon HD 4000 series] driver: snd_hda_intel
           Sound Server: ALSA v: k5.4.0-66-generic
Network:   Device-1: Intel 82566DM-2 Gigabit Network driver: e1000e
           IF: enp0s25 state: down mac: 00:21:5a:0f:7e:3e
           Device-2: Ralink RT2501/RT2573 Wireless Adapter type: USB driver: rt73usb
           IF: wlx8e2f0065f3c1 state: up mac: 06:d1:b3:d5:1e:48
Drives:    Local Storage: total: 1.19 TiB used: 14.84 GiB (1.2%)
           ID-1: /dev/sda vendor: Samsung model: HD103SJ size: 931.51 GiB
           ID-2: /dev/sdb vendor: SanDisk model: SDSSDP064G size: 58.69 GiB
           ID-3: /dev/sdc vendor: Hitachi model: HCS725025VLA380 size: 232.89 GiB
Partition: ID-1: / size: 57.52 GiB used: 14.84 GiB (25.8%) fs: ext4 dev: /dev/sdb1
Sensors:   System Temperatures: cpu: 25.0 C mobo: N/A gpu: radeon temp: 56 C
           Fan Speeds (RPM): N/A
Info:      Processes: 195 Uptime: 17m Memory: 3.77 GiB used: 1.26 GiB (33.5%) Shell: bash inxi: 3.0.38
[    0.294078] ACPI BIOS Error (bug): \_SB.PCI0._OSC: Excess arguments - ASL declared 5, ACPI requires 4 (20190816/nsarguments-160)
[    0.294177] ACPI BIOS Error (bug): Failure creating named object [\_SB.PCI0._OSC.CAPD], AE_ALREADY_EXISTS (20190816/dsfield-182)
[    0.294185] ACPI Error: AE_ALREADY_EXISTS, CreateBufferField failure (20190816/dswload2-477)
[    0.294217] ACPI Error: Aborting method \_SB.PCI0._OSC due to previous error (AE_ALREADY_EXISTS) (20190816/psparse-529)
[    0.864447] tpm tpm0: [Hardware Error]: Adjusting reported timeouts: A 750->750000us B 2000->2000000us C 750->750000us D 750->750000us
[    2.280546] RAS: Correctable Errors collector initialized.
[    7.703286] EXT4-fs (sdb1): re-mounted. Opts: errors=remount-ro
 
You have two options: a) contact the manufacturer for an update, b) fix the ASL yourself.

FreeBSD has good manpages, install it. You might even like it.
 
The syntax changed a bit - I have now a rebuild dsdt.aml file
Code:
# acpidump > acpi.log
# acpixtract acpi.log
# iasl -d *.dat
<changed dsdt.dsl file>
# iasl -f dsdt.dsl
So the only thing left now is to set the machine to use the override next boot, by editing /boot/loader.conf
I don't have this loader.conf file - should I touch it or is the way with linux mint a little different to load that new ACPI blob on next boot?

My dsl file looked like:
Code:
    Scope (\_SB.PCI0)
    {
        Method (_OSC, 5, NotSerialized)  // _OSC: Operating System Capabilities
        {
            Local0 = (Arg2 - 0x01)
            Name (CAPB, Buffer ((Arg2 * 0x04)){})
            CAPB = Arg3
            Local1 = One
            CreateDWordField (CAPB, Zero, CAPF)
            While (Local0)
            {
                CreateDWordField (CAPB, Local1, CAPD)
                If ((CAPF & 0x01))
                {
I've only changed that
Code:
Method (_OSC, 5, NotSerialized)  // _OSC: Operating System Capabilities
to
Code:
Method (_OSC, 4, NotSerialized)  // _OSC: Operating System Capabilities
rest looked, ok!?
 
You realize that Linux and FreeBSD are not only different cups of tea but more like a cup and a stein?
 
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.
How do I run acpidump when FreeBSD doesn't even start, but stops whining about some ASL error?
Can I do that using any live Linux CD?

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.
I'd actually prefer not to need to hack BIOS.
It's about a particular Gigabyte Phenom II mobo which I used as tester for various hardware using various DOS/Windows/Linux variants.

None of that ever complained.
I only learned about its incorrect (?) ASL when trying FreeBSD on it.
I found particularly annoying that FreeBSD seems the only OS that gets stuck trying to boot.
So I'd highly appreciate if that can get fixed...
 
Wasn't there a boot option/sysctrl/loader tunable to disable all ACPI? Maybe that will boot it.
 
Back
Top