We're in the process of updating the ACPICA code, moving from 20160529 to the latest release to fix some deadlock issues and have discovered several systems whose ACPI tables now generate warnings that look like the following:
ACPI Error: Result stack is empty! State=fffffe2528f55e88 (20180629/dswstate-218)
ACPI Error: AE_AML_NO_RETURN_VALUE, Missing or null operand (20180629/dsutils-809)
ACPI Error: AE_AML_NO_RETURN_VALUE, While creating Arg 0 (20180629/dsutils-937)
We've been able to narrow this further down and it appears that all in cases the encoding of OperationRegion is using a Method to calculate the Offset with AML that looks something like the following when decompiled with iasl 20160108-64:
...
Name (PMBV, 0x00)
Method (PMB1, 0, NotSerialized)
{
If ((PMBV == 0x00))
{
PMBV = (\_SB.PC00.PMC1.ACBA << 0x08)
}
Return (PMBV) /* \PMBV */
}
Name (PWRV, 0x00)
Method (PWRM, 0, NotSerialized)
{
If ((PWRV == 0x00))
{
PWRV = (\_SB.PC00.PMC1.PWBA << 0x0C)
}
Return (PWRV) /* \PWRV */
}
OperationRegion (PMIO, SystemIO, PMB1 (), 0x80)
Field (PMIO, ByteAcc, NoLock, Preserve)
{
Offset (0x01),
PBSS, 1,
Offset (0x40),
, 17,
GPEC, 1
}
OperationRegion (PMLP, SystemIO, (PMB1 () + 0x80), 0x20)
Field (PMLP, ByteAcc, NoLock, Preserve)
{
Offset (0x10),
Offset (0x11),
GE08, 1,
, 8,
GE17, 1,
, 17,
GE35, 1,
, 9,
GE45, 1,
Offset (0x16),
GE48, 1,
, 2,
GE51, 1,
Offset (0x20)
}
...
If we look at the stack trace from the kernel where the error occurs we see the following ACPICA functions:
fffffffffbc97a30 acpica`AcpiError+0x1f()
fffffffffbc97ab0 acpica`AcpiDsResultPop+0x15f(fffffffffbc97ae8, fffffe2528f55e88)
fffffffffbc97b40 acpica`AcpiDsCreateOperand+0x92(fffffe2528f55e88, fffffe256185f978, 0)
fffffffffbc97c00 acpica`AcpiDsCreateOperands+0x11e(fffffe2528f55e88, fffffe256185f978)
fffffffffbc97c60 acpica`AcpiDsExecEndOp+0x143(fffffe2528f55e88)
fffffffffbc97ce0 acpica`AcpiPsParseLoop+0x231(fffffe2528f55e88)
fffffffffbc97d60 acpica`AcpiPsParseAml+0x20b(fffffe2528f55e88)
fffffffffbc97db0 acpica`AcpiPsExecuteTable+0x125(fffffe25446cdf88)
fffffffffbc97e40 acpica`AcpiNsExecuteTable+0x170(1, fffffffffc118640)
fffffffffbc97e90 acpica`AcpiNsParseTable+0x65(1, fffffffffc118640)
fffffffffbc97ed0 acpica`AcpiNsLoadTable+0xb2(1, fffffffffc118640)
fffffffffbc97f30 acpica`AcpiTbLoadNamespace+0x112()
fffffffffbc97f50 acpica`AcpiLoadTables+0x3d()
<OS-specific functions follow>
Looking further, if I print out the argument types that we seemed to have parsed and stored in AcpiDsCreateOperands(), the first argument, at index 1 is a byte const value which represents the Length. If we print the ACPI_PARSE_OBJECT structure for that, we see:
[0]> 0xfffffe256185f900::print ACPI_PARSE_OBJECT
{
Common = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0xa
Aml = 0xfffffe226ce44548
Next = 0
Node = 0
Value = {
Integer = 0x20
Size = 0x20
String = 0x20
Buffer = 0x20
Name = 0x20
Arg = 0x20
Tag = {
BitOffset = 0x20
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "ByteConst" ]
}
Named = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0xa
Aml = 0xfffffe226ce44548
Next = 0
Node = 0
Value = {
Integer = 0x20
Size = 0x20
String = 0x20
Buffer = 0x20
Name = 0x20
Arg = 0x20
Tag = {
BitOffset = 0x20
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "ByteConst" ]
Path = 0xbaddcafebaddcabb
Data = 0x5649feedface
Length = 0x61876988
Name = 0xfffffe25
}
Asl = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0xa
Aml = 0xfffffe226ce44548
Next = 0
Node = 0
Value = {
Integer = 0x20
Size = 0x20
String = 0x20
Buffer = 0x20
Name = 0x20
Arg = 0x20
Tag = {
BitOffset = 0x20
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "ByteConst" ]
Child = 0xbaddcafebaddcabb
ParentMethod = 0x5649feedface
Filename = 0xfffffe2561876988
FileChanged = 0x65
ParentFilename = 0x58
ExternalName = 0xfffffe256185f450
Namepath = 0xcacacacacacaca01
NameSeg = [ '\312', '\312', '\312', '\312' ]
ExtraValue = 0xcacacaca
Column = 0xcacacaca
LineNumber = 0xcacacaca
LogicalLineNumber = 0xcacacaca
LogicalByteOffset = 0xcacacaca
EndLine = 0xcacacaca
EndLogicalLine = 0xcacacaca
AcpiBtype = 0xcacacaca
AmlLength = 0xcacacaca
AmlSubtreeLength = 0xcacacaca
FinalAmlLength = 0xcacacaca
FinalAmlOffset = 0xcacacaca
CompileFlags = 0xcacacaca
ParseOpcode = 0xcaca
AmlOpcodeLength = 0xca
AmlPkgLenBytes = 0xca
Extra = 0xca
ParseOpName = [ '\312', '\312', '\312', '\273', '\312', '\335', '\272', '\376', '\312', '\335', '\272', '\316', '\372', '\355', '\376', 'I', 'V', '\0', '\0', '\260' ]
}
}
However, when we look at the index zero entry, it appears to strictly be an AML return type:
[0]> <rsi::print ACPI_PARSE_OBJECT
{
Common = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0x36
Aml = 0xfffffe226ce44540
Next = 0xfffffe256185f900
Node = 0
Value = {
Integer = 0
Size = 0
String = 0
Buffer = 0
Name = 0
Arg = 0
Tag = {
BitOffset = 0
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "-Return Value-" ]
}
Named = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0x36
Aml = 0xfffffe226ce44540
Next = 0xfffffe256185f900
Node = 0
Value = {
Integer = 0
Size = 0
String = 0
Buffer = 0
Name = 0
Arg = 0
Tag = {
BitOffset = 0
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "-Return Value-" ]
Path = 0xbaddcafebaddcabb
Data = 0x5649feedface
Length = 0x44745ce8
Name = 0xfffffe25
}
Asl = {
Parent = 0xfffffe25615ef788
DescriptorType = 0xd
Flags = 0x1
AmlOpcode = 0x36
Aml = 0xfffffe226ce44540
Next = 0xfffffe256185f900
Node = 0
Value = {
Integer = 0
Size = 0
String = 0
Buffer = 0
Name = 0
Arg = 0
Tag = {
BitOffset = 0
BitLength = 0
}
}
ArgListLength = 0
DisasmFlags = 0
DisasmOpcode = 0
OperatorSymbol = 0
AmlOpName = [ "-Return Value-" ]
Child = 0xbaddcafebaddcabb
ParentMethod = 0x5649feedface
Filename = 0xfffffe2544745ce8 ""
FileChanged = 0x5
ParentFilename = 0x58
ExternalName = 0xfffffe25446cd718
Namepath = 0xcacacacacacaca01
NameSeg = [ '\312', '\312', '\312', '\312' ]
ExtraValue = 0xcacacaca
Column = 0xcacacaca
LineNumber = 0xcacacaca
LogicalLineNumber = 0xcacacaca
LogicalByteOffset = 0xcacacaca
EndLine = 0xcacacaca
EndLogicalLine = 0xcacacaca
AcpiBtype = 0xcacacaca
AmlLength = 0xcacacaca
AmlSubtreeLength = 0xcacacaca
FinalAmlLength = 0xcacacaca
FinalAmlOffset = 0xcacacaca
CompileFlags = 0xcacacaca
ParseOpcode = 0xcaca
AmlOpcodeLength = 0xca
AmlPkgLenBytes = 0xca
Extra = 0xca
ParseOpName = [ '\312', '\312', '\312', '\273', '\312', '\335', '\272', '\376', '\312', '\335', '\272', '\316', '\372', '\355', '\376', 'I', 'V', '\0', '\0', '\020' ]
}
}
When we double check the next pointer, it does seem to point to the right entry point. I suspect that what's happening here is that for some reason we're not getting the full method translation into the arguments structure and only the return of the method. Beacuse the only other argument is the constant argument indicating the length to the create region, it would make sense that an operand pop would fail.
Looking at the change log, there doesn't appear to be anything obvious that would correspond go this change in behavior; however, I could have easily overlooked something. Was there a change in recent ACPI code that would have led to this processing being problematic or perhaps is it exposing an issue in some tables from vendors that we're testing against? If it helps to look at intermediate releases, I can try and take a look.