Bug 93778 - [NVE7] Noveau GeForce GT 640M vbios error
Summary: [NVE7] Noveau GeForce GT 640M vbios error
Status: RESOLVED FIXED
Alias: None
Product: xorg
Classification: Unclassified
Component: Driver/nouveau (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Nouveau Project
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-19 17:52 UTC by Pawel Kozlowski
Modified: 2017-01-11 23:17 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
acpidump (262.83 KB, text/plain)
2016-01-19 17:52 UTC, Pawel Kozlowski
no flags Details
Extracted using kernel 3.16 (65.50 KB, application/octet-stream)
2017-01-11 23:08 UTC, ralala
no flags Details

Description Pawel Kozlowski 2016-01-19 17:52:49 UTC
Created attachment 121140 [details]
acpidump

Noveau fails to load, yielding error messages in dmesg suggesting problems with vbios:
nouveau: probe of 0000:01:00.0 failed with error -22
[   17.520208] nouveau 0000:01:00.0: devinit: 0x9b29[0]: unknown opcode 0x00
Comment 1 Ilia Mirkin 2016-01-19 18:24:24 UTC
I think the issue is a buggy _ROM method. Instead of Add (Arg0, Arg1, Local2) it should be Add(Local0, Local1, Local2) :(

It clamps the read length to 0x1000, which is common. But then it goes ahead and sets the length to the total length - offset if the offset + original length (not the clamped length) is too big. No idea how negatives are handled in ACPI either.

Our first request is offset = 0, length = 0x1000, so that should be good. However our second request is offset = 0x1000 length = round_up(remainder, 0x1000). I think this will hit the issue outlined above. Instead of the length being clamped to 0x1000, it will determine that we're overflowing and reset the length to total - offset, which will be way bigger than 0x1000. Since it has the vbios data in multiple 32K regions, this won't return the correct data.

Ben, thoughts on how to detect this?

    Scope (\_SB.PCI0.PEG0.PEGP)
    {
        OperationRegion (VBOR, SystemMemory, 0x9AF9C018, 0x00016004)
        Field (VBOR, DWordAcc, Lock, Preserve)
        {
            RVBS,   32, 
            VBS1,   262144, 
            VBS2,   262144, 
            VBS3,   196608, 
            VBS4,   0
        }
    }


        Method (_ROM, 2, NotSerialized)  // _ROM: Read-Only Memory
        {
            Store (Arg0, Local0)
            Store (Arg1, Local1)
            Name (VROM, Buffer (Local1)
            {
                 0x00                                             /* . */
            })
            If (LGreater (Local1, 0x1000))
            {
                Store (0x1000, Local1)
            }

            If (LGreater (Arg0, RVBS))
            {
                Return (VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
            }

            Add (Arg0, Arg1, Local2)
            If (LGreater (Local2, RVBS))
            {
                Subtract (RVBS, Local0, Local1)
            }

            If (LLess (Local0, 0x8000))
            {
                Mid (VBS1, Local0, Local1, VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
            }
            Else
            {
                Subtract (Local0, 0x8000, Local0)
                If (LLess (Local0, 0x8000))
                {
                    Mid (VBS2, Local0, Local1, VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
                }
                Else
                {
                    Subtract (Local0, 0x8000, Local0)
                    If (LLess (Local0, 0x8000))
                    {
                        Mid (VBS3, Local0, Local1, VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
                    }
                    Else
                    {
                        Subtract (Local0, 0x8000, Local0)
                        If (LLess (Local0, 0x8000))
                        {
                            Mid (VBS4, Local0, Local1, VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
                        }
                    }
                }
            }

            Return (VROM) /* \_SB_.PCI0.PEG0.PEGP._ROM.VROM */
        }
Comment 2 Ilia Mirkin 2016-01-20 14:31:28 UTC
Over IRC, the OP reported that commenting out the fast acpi method does indeed make nouveau load properly.
Comment 3 ralala 2017-01-11 23:08:16 UTC
Created attachment 128903 [details]
Extracted using kernel 3.16

Nouveau works successfully on kernel 3.16.
I copied the bios from /sys/kernel/debug/dri/1/vbios.rom.
Comment 4 Ilia Mirkin 2017-01-11 23:17:39 UTC
This bug was fixed by 5dc7f4aa9d84ea94b54a9bfcef095f0289f1ebda, part of kernel 4.10-rc1 (and potentially some earlier commits also addressed this). Should backport pretty cleanly.

Pawel, if you still have issues, please reopen. If ANYONE OTHER THAN Pawel has issues that look like this, open a fresh issue.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.