← Back to team overview

hybrid-graphics-linux team mailing list archive

Re: Proper ON method for PEGP _DSM ACPI calls?

 

Hi Eric,

I'm attaching my notes for digging in my own tables as well as the
disassembled tables you sent me before.
The TableID of SSDT5.dsl is OptTabl (OptimusTable?) and the methods and
devices in it suggests that it is relevant.

A quick overview on that views revealed some interesting methods:

- \_SB.PCI0.PEG0.PEGP._DSM calls \_SB.PCI0.GFX0.HDSM (Arg0, Arg1, Arg2,
Arg3) and returns the return value from that method
- \_SB.PCI0.GFX0.HDSM
If arg 0 equals to the buffer
    0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47, 0xA7, 0x2B, 0x60, 0x42,
0xA6, 0xB5, 0xBE, 0xE0
then OPCI becomes One.

If OPCI is One OR if SGCI or NBCI are One (which is never the case), the
next continues:

If arg1 (the revision number) does not equal 0x100 0x80000002 is returned
(which is btw the value returned on errors).

Arg 2 is the function, func 0 returns a 4-byte buffer depending on some
register values
func 1 returns a buffer with four 0x0 (in this case)
... there are other methods but I'm not going to analyse all of them for
now..
func 0x03 is what we're looking for.

Arg3 is converted to an integer, taking the first 8 bytes of the buffer as
an integer (forming a 64-bit one). On that integer, the least two bits are
significant.
if it's 0, \_SB.PCI0.PEG0.PEGP.SGST is called (status?),
if it's 1, \_SB.PCI0.PEG0.PEGP.SGON is called (turn something on?),
if it's 2,  \_SB.PCI0.PEG0.PEGP.SGOFF is called (turn sth. off?)

After that, if the result of \_SB.PCI0.PEG0.PEGP.SGST equals 0x0F, a buffer
of 0x0, 0x2, 0x0, 0x0 is returned. Otherwise, a buffer of 4 zeros is
returned.

The method becomes:
\_SB.PCI0.PEG0.PEGP._DSM
{0xF8,0xD8,0x86,0xA4,0xDA,0x0B,0x1B,0x47,0xA7,0x2B,0x60,0x42,0xA6,0xB5,0xBE,0xE0}
0x100 0x3 {0x00,0x00,0x0,0x1}
The above is for turning it n, replace the last 0x1 by 0x2 for turning it
off (theoretically)

Some methods may return a Package as result ("Object type 0x4"). If you
encounter that, use acpi_call from
https://github.com/Bumblebee-Project/acpi_call. I'll soon make it available
in the bumblebee/testing PPA.

I wish there was a register/ method documentation somewhere, that would help
a lot with analysing.

Regards,
Lekensteyn

On Sun, Oct 23, 2011 at 5:56 AM, Eric Appleman <erappleman@xxxxxxxxx> wrote:

> Consult the following for background and logs:
> https://github.com/Bumblebee-**Project/Bumblebee/issues/133<https://github.com/Bumblebee-Project/Bumblebee/issues/133>
>
> Is there anyone here who is well-versed in ACPI who'd be willing to look at
> my tables as well as those of similarly arranged machines?
>
> Thanks in advance.
>
> - Eric Appleman, Bumblebee Project
>
> ______________________________**_________________
> Mailing list: https://launchpad.net/~hybrid-**graphics-linux<https://launchpad.net/%7Ehybrid-graphics-linux>
> Post to     : hybrid-graphics-linux@lists.**launchpad.net<hybrid-graphics-linux@xxxxxxxxxxxxxxxxxxx>
> Unsubscribe : https://launchpad.net/~hybrid-**graphics-linux<https://launchpad.net/%7Ehybrid-graphics-linux>
> More help   : https://help.launchpad.net/**ListHelp<https://help.launchpad.net/ListHelp>
>
The GNVS field in DSDT possibly groups registers for nVidia graphics stuff


ACPI-WMI thing calls
\_SB.PCI0.P0P2.PEGP._DSM calls
\_SB.PCI0.GFX0._DSM (MUID, REVS, SFNC, ARGD)
    (note: arg names come from SSDT table)
    MUID - Buffer containing UUID
    REVS - Integer containing revision ID (specific to UUID)
    SFNC - Integer containing Function index (should start at 1)
    ARGD - Package that contains function-specific arguments

Terminology
- KBC - Keyboard Controller
- EC - Embedded Controller
- GNVS - Global Non-Volatile Storage (guessed)
- PEGP - PCI Express Graphics Port (guessed)

\_SB.PCI0.LPCB.EC.RINF
- \ - Root
- _SB - System Bus
- PCI0 - PCI Bus
- LPCB - Low Pin Count bus, see http://www.intel.com/design/chipsets/industry/lpc.htm
- EC - Embedded Controller (I/O slave, Bus Master)
- RINF - ??? redundancy information signal ???


\_SB.LID0._LID // line 6870
if \_SB.PCI0.LPCB.EC.ECOK
    return \_SB.PCI0.LPCB.EC.LIDS
else
    return 1
According to the acpi spec page 343, non-zero = open lid, zero = closed lid
\_SB.LID0._PSW // DSDT line 6887
    if \_SB.PCI0.LPCB.EC.ECOK
        Store Arg0 in \_SB.PCI0.LPCB.EC.LWKE
_PSW 1 = enable device wake capabilities, 0 = disable


It looks like \_SB.PCI0.LPCB.EC.ECOK checks whether the embedded controller is ready


\_SB.PCI0.GFX0._DSM // line 515

My Clevo B7130 accepts two possible values for MUID.

If there is no match, the below is returned:
    0x02, 0x00, 0x00, 0x80

If MUID matches:
{ 0xD3, 0x73, 0xD8, 0x7E, 0xD0, 0xC2, 0x4F, 0x4E,
  0xA8, 0x54, 0x0F, 0x13, 0x17, 0xB0, 0x1C, 0x2C }
then One is always returned

===================================================
If MUID matches:
{ 0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47,
  0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0 }
then

If REVS does not match 0x0100, then the below is returned:
{ 0x02, 0x00, 0x00, 0x80 }
(observation: perhaps it means "invalid argument"?)


My SSDT aliases SFNC (Arg2) as _T_0
If SFNC matches Zero, then it returns:
    { 0x01, 0x00, 0x03, 0x04 }

If SFNC matches 0x11, the if-conditions are skipped and the above
"If there is no match, ..." is applied, meaning that the below is returned:
{ 0x02, 0x00, 0x00, 0x80 }

If SFNC matches 0x10, then
    ARGD (Arg3) is aliased as NVVK
    If ARGD equals 0x564B, then it returns something based on the 32-bit
    register \NVID. If the \NVID register value does not match one of the
    comparisons, the buffer from "If there is no match, ..." is returned:
    { 0x02, 0x00, 0x00, 0x80 }
    Otherwise, a buffer of size 226 (0xE2) or 230 (0xE6) is returned which may
    also be based on \_SB.PCI0.P0P2.SSID

**possible power management stuff ahead**
If SFNC matches 0x1A, then // line 596
    If And(\OEMF, One), then // register OEMF is in field GNVS in SystemMemory
(I now consider ARGD[n] as the n-th element in buffer ARGD (Arg3) with n>=0)
        UPFG = ARGD[1]
        OPCE = ARGD[3]
        if And(UPFG, One) OPCE = And(OPD3, One) // store right-most bit of OPD3
                                                // in OPCE
        TEMP = { 0x01, 0x00, 0x00, 0x09 }
        if And(\OEMF, 0x10), then
            if \_SB.PCI0.LPCB.EC.ECOK // XXX please tell me what this is?
                if And(\_SB.PCI0.LPCB.EC.RINF, 0x02)// XXX what register is it?
                    TEMP[0] = 0x19
                else
                    TEMP[0] = One
        else
            TEMP[3] = Zero
        return TEMP
    return { 0x00 } // note, buffer size is 4! So probably {0x00,0x00,0x00,x00}

===================================================

Attachment: W150HRM.tar.gz
Description: GNU Zip compressed data


Follow ups

References