<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body><span class="vcard"><a class="email" href="mailto:imirkin@alum.mit.edu" title="Ilia Mirkin <imirkin@alum.mit.edu>"> <span class="fn">Ilia Mirkin</span></a>
</span> changed
              <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [NVE7] Noveau GeForce GT 640M vbios error"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=93778">bug 93778</a>
          <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Summary</td>
           <td>Noveau GeForce GT 640M vbios error
           </td>
           <td>[NVE7] Noveau GeForce GT 640M vbios error
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [NVE7] Noveau GeForce GT 640M vbios error"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=93778#c1">Comment # 1</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [NVE7] Noveau GeForce GT 640M vbios error"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=93778">bug 93778</a>
              from <span class="vcard"><a class="email" href="mailto:imirkin@alum.mit.edu" title="Ilia Mirkin <imirkin@alum.mit.edu>"> <span class="fn">Ilia Mirkin</span></a>
</span></b>
        <pre>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 */
        }</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>