天杀最近在玩一台X86主机,他发现Dump出来的 DSDT Table 重新编译的时候会碰到标题的错误,更详细的错误信息如下:
SDT.dsl 2644: PARM |= (DerefOf (CDCT [^^MCHK.DCFE]) << 0x15) /* _SB_.PCI0.GFX0.PARM */
Error 6163 - ^ Object is created temporarily in another method and cannot be accessed (^^MCHK.DCFE)
分析代码可以看到
- 出现问题的代码是尝试访问MCHK.DCFE
If ((GESF == 0x07))
{
PARM = GIVD /* \_SB_.PCI0.GFX0.GIVD */
PARM ^= One
PARM |= (GMFN << One)
PARM |= 0x1800
PARM |= (IDMS << 0x11)
PARM |= (DerefOf (CDCT [^^MCHK.DCFE]) << 0x15) /* \_SB_.PCI0.GFX0.PARM */
GESF = One
Return (SUCC) /* \_SB_.PCI0.GFX0.SUCC */
}
2.DCFE定义在MCHK 中
Method (MCHK, 0, Serialized)
{
If ((MADR != 0xFFFFFFFF))
{
OperationRegion (IGMM, SystemMemory, MADR, 0x3000)
Field (IGMM, AnyAcc, NoLock, Preserve)
{
Offset (0x20C8),
, 4,
DCFE, 4
}
}
}
看起来错误的原因是:如果MADR为0xFFFFFFFF,那么DCFE 就不存在,访问不到。
解决方法,修改代码如下:
PARM |= 0x1800
PARM |= (IDMS << 0x11)
//LABZDebug_Start
If ((MADR != 0xFFFFFFFF))
{
OperationRegion (IGMM, SystemMemory, MADR, 0x3000)
Field (IGMM, AnyAcc, NoLock, Preserve)
{
Offset (0x20C8),
, 4,
DCFE, 4
}
PARM |= (DerefOf (CDCT [DCFE]) << 0x15) /* \_SB_.PCI0.GFX0.PARM */
}
//LABZDebug_End
GESF = One
Return (SUCC) /* \_SB_.PCI0.GFX0.SUCC */
再次编译就通过了。
此外,还有一种更简单的方法:使用编译 AML 相同的版本重新编译,这个很容易理解:能够编译生成 AML 就说明至少有一个版本的编译器认可这种编译方法,找到这个版本即可重新编译。
具体的信息可以在 dsdt 的头部看到,比如,另外一个项目上如下位置可以看到编译器版本:

找到这个版本重新编译一个Error甚至Warning 都没有。
当然,这个问题还是给了我们一个提醒:ASL 编译器不同版本之间存在差异。