Estou tentando entender o seguinte método NVOP a partir das tabelas ACPI para um Acer Aspire 4830TG com um sistema gráfico híbrido Nvidia Optimus. O método NVOP no topo define um monte de instruções que podem ser usadas mais tarde no método _DSM. Qual método devo chamar com o módulo acpi_call ou o módulo byo-switcheroo para ligar / desligar o cartão sob demanda?
Veja o código abaixo:
Method (NVOP, 4, Serialized)
{
Name (_T_0, Zero)
Store ("------- NV OPTIMUS DSM --------", Debug)
If (LNotEqual (Arg1, 0x0100))
{
Return (0x80000001)
}
While (One)
{
Store (ToInteger (Arg2), _T_0)
If (LEqual (_T_0, Zero))
{
Store (Buffer (0x04)
{
0x61, 0x00, 0x01, 0x0C
}, Local0)
Return (Local0)
}
Else
{
If (LEqual (_T_0, 0x05))
{
Name (TMP5, Buffer (0x04)
{
0x00, 0x00, 0x00, 0x00
})
CreateField (TMP5, Zero, 0x04, DAVF)
CreateField (TMP5, 0x04, One, LIDF)
CreateField (TMP5, 0x08, 0x06, TOGN)
CreateField (Arg3, 0x1F, One, NCSM)
CreateField (Arg3, 0x19, 0x05, NCSN)
CreateField (Arg3, 0x18, One, DIMK)
CreateField (Arg3, 0x0C, 0x0C, ACTD)
CreateField (Arg3, Zero, 0x0C, ATTD)
If (ToInteger (NCSM))
{
Store (ToInteger (NCSN), TOGN)
}
Else
{
If (ToInteger (DIMK))
{
GETD (ToInteger (ATTD), ToInteger (ACTD))
Store (\_SB.PCI0.PEG0.PEGP.NTOI, TOGN)
Store (One, DAVF)
}
}
Return (TMP5)
}
Else
{
If (LEqual (_T_0, 0x06))
{
Name (TMP6, Package (0x0F)
{
Ones,
0x2C,
Ones,
0x2C,
Ones,
0x2C,
Ones,
Ones,
0x2C,
Ones,
Ones,
0x2C,
Ones,
Ones,
0x2C
})
Store (\_SB.PCI0.GFX0.IDI2, Index (TMP6, Zero))
Store (\_SB.PCI0.GFX0.IDI1, Index (TMP6, 0x02))
Store (\_SB.PCI0.GFX0.IDI4, Index (TMP6, 0x04))
Store (\_SB.PCI0.GFX0.IDI2, Index (TMP6, 0x06))
Store (\_SB.PCI0.GFX0.IDI1, Index (TMP6, 0x07))
Store (\_SB.PCI0.GFX0.IDI2, Index (TMP6, 0x09))
Store (\_SB.PCI0.GFX0.IDI4, Index (TMP6, 0x0A))
Store (\_SB.PCI0.GFX0.IDI1, Index (TMP6, 0x0C))
Store (\_SB.PCI0.GFX0.IDI4, Index (TMP6, 0x0D))
Return (TMP6)
}
Else
{
If (LEqual (_T_0, 0x10))
{
Return (\_SB.PCI0.PEG0.PEGP.GOBT (Arg3))
}
Else
{
If (LEqual (_T_0, 0x1A))
{
CreateField (Arg3, 0x18, 0x02, OPCE)
CreateField (Arg3, Zero, One, FLCH)
If (ToInteger (FLCH))
{
Store (ToInteger (OPCE), OMPR)
}
Name (RBUF, Buffer (0x04)
{
0x00, 0x00, 0x00, 0x00
})
CreateField (RBUF, Zero, One, OPEN)
CreateField (RBUF, 0x03, 0x02, CGCS)
CreateField (RBUF, 0x06, One, SHPC)
CreateField (RBUF, 0x18, 0x03, DGPC)
CreateField (RBUF, 0x1B, 0x02, HDAC)
Store (One, OPEN)
Store (One, SHPC)
Store (0x02, HDAC)
Store (One, DGPC)
If (\_SB.PCI0.PEG0.PEGP.GSTA ())
{
Store (0x03, CGCS)
}
Else
{
Store (Zero, CGCS)
}
Return (RBUF)
}
Else
{
If (LEqual (_T_0, 0x1B))
{
Store (Arg3, Local0)
CreateField (Local0, Zero, One, OPFL)
CreateField (Local0, One, One, OPVL)
If (ToInteger (OPVL))
{
Store (Zero, OPTF)
If (ToInteger (OPFL))
{
Store (One, OPTF)
}
}
Store (OPTF, Local0)
Return (Local0)
}
Else
{
Return (0x80000002)
}
}
}
}
}
}
Break
}
}
Method (GOBT, 1, NotSerialized)
{
Name (OPVK, Buffer (0xE2)
{
/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0008 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0010 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0018 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0020 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0028 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0030 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0038 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0040 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0048 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0050 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0058 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0060 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0068 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0070 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0078 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0080 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0088 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0090 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0098 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00B0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00B8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00C0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00C8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00D8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 00E0 */ 0x00, 0x00
})
CreateWordField (Arg0, 0x02, USRG)
If (LEqual (USRG, 0x564B))
{
Return (OPVK)
}
Return (Zero)
}
Method (_INI, 0, NotSerialized)
{
Store (Zero, \_SB.PCI0.PEG0.PEGP._ADR)
}
Method (GSTA, 0, Serialized)
{
If (LEqual (\_SB.PCI0.PEG0.PEGP.PI17, One))
{
Return (One)
}
Else
{
Return (Zero)
}
}
Method (_ON, 0, Serialized)
{
\_SB.PCI0.PEG0.PEGP.PWRE ()
Store (Zero, LNKD)
While (LLess (LNKS, 0x07))
{
Sleep (One)
}
Store (Zero, CMDR)
Store (VGAB, VGAR)
Store (0x06, CMDR)
}
Method (_OFF, 0, Serialized)
{
Store (VGAR, VGAB)
Store (One, LNKD)
While (LNotEqual (LNKS, Zero))
{
Sleep (One)
}
\_SB.PCI0.PEG0.PEGP.PWRD ()
}
Method (_PS0, 0, NotSerialized)
{
If (DGOS)
{
GLSC ()
\_SB.PCI0.PEG0.PEGP._ON ()
GLSR ()
Store (Zero, DGOS)
Store (Zero, MLTF)
Store (Zero, \_SB.PCI0.LPCB.EC0.DSPM)
}
}
Method (_PS3, 0, NotSerialized)
{
If (LEqual (\_SB.PCI0.PEG0.PEGP.OMPR, 0x03))
{
GLSC ()
\_SB.PCI0.PEG0.PEGP._OFF ()
GLSR ()
Store (One, DGOS)
Store (0x02, \_SB.PCI0.PEG0.PEGP.OMPR)
Store (One, \_SB.PCI0.LPCB.EC0.DSPM)
}
}
Method (_STA, 0, Serialized)
{
Return (0x0F)
}
Method (_ROM, 2, NotSerialized)
{
Store (Arg0, Local0)
Store (Arg1, Local1)
If (LGreater (Local1, 0x1000))
{
Store (0x1000, Local1)
}
If (LGreater (Local0, 0x00010000))
{
Return (Buffer (Local1)
{
0x00
})
}
If (LGreater (Local0, RVBS))
{
Return (Buffer (Local1)
{
0x00
})
}
Multiply (Local1, 0x08, Local3)
Name (ROM1, Buffer (0x8000)
{
0x00
})
Name (ROM2, Buffer (Local1)
{
0x00
})
If (LLess (Local0, 0x8000))
{
Store (RBF1, ROM1)
}
Else
{
Subtract (Local0, 0x8000, Local0)
Store (RBF2, ROM1)
}
Multiply (Local0, 0x08, Local2)
CreateField (ROM1, Local2, Local3, TMPB)
Store (TMPB, ROM2)
Return (ROM2)
}
Method (MXMX, 1, Serialized)
{
If (LEqual (Arg0, One))
{
P8XH (One, 0x99, P8XH (Zero, One, Return (One), Return (Zero)))
}
}
Name (MXM3, Buffer (0x45)
{
/* 0000 */ 0x4D, 0x58, 0x4D, 0x5F, 0x03, 0x00, 0x3D, 0x00,
/* 0008 */ 0x30, 0x10, 0xB8, 0xFF, 0xF9, 0x3E, 0x00, 0x00,
/* 0010 */ 0x00, 0x01, 0x8A, 0xFF, 0xF9, 0x3E, 0x00, 0x00,
/* 0018 */ 0x60, 0x79, 0xD0, 0xFE, 0xF9, 0x3E, 0x00, 0x00,
/* 0020 */ 0x20, 0x2B, 0xE2, 0xFE, 0xF9, 0x3E, 0x00, 0x00,
/* 0028 */ 0x60, 0x6C, 0xEA, 0xFE, 0xF9, 0x3E, 0x00, 0x00,
/* 0030 */ 0x01, 0x90, 0x01, 0x00, 0x03, 0x00, 0x90, 0x01,
/* 0038 */ 0x13, 0x00, 0x90, 0x01, 0xE5, 0x0D, 0x01, 0x01,
/* 0040 */ 0x01, 0x00, 0x00, 0x00, 0x96
})
Method (_DSM, 4, Serialized)
{
Name (_T_0, Zero)
If (LEqual (Arg0, Buffer (0x10)
{
/* 0000 */ 0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47,
/* 0008 */ 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0
}))
{
Return (\_SB.PCI0.PEG0.PEGP.NVOP (Arg0, Arg1, Arg2, Arg3))
}
If (LEqual (Arg0, Buffer (0x10)
{
/* 0000 */ 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C,
/* 0008 */ 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
}))
{
While (One)
{
Store (ToInteger (Arg2), _T_0)
If (LEqual (_T_0, Zero))
{
Return (Buffer (0x04)
{
0x01, 0x00, 0x01, 0x01
})
}
Else
{
If (LEqual (_T_0, 0x18))
{
Return (Buffer (0x04)
{
0x00, 0x03, 0x00, 0x00
})
}
Else
{
If (LEqual (_T_0, 0x10))
{
If (LEqual (Arg1, 0x0300))
{
Return (MXM3)
}
}
}
}
Break
}
Return (0x80000002)
}
Return (0x80000001)
}
As tabelas originais da ACPI estão disponíveis aqui:
link
link
link