diff options
author | Maximilian Luz <luzmaximilian@gmail.com> | 2019-12-06 05:46:00 -0800 |
---|---|---|
committer | Erik Schmauss <erik.schmauss@intel.com> | 2019-12-06 13:55:39 -0800 |
commit | 79a466b64e6af36cc83102f05915e56cb7dd89ab (patch) | |
tree | 83b0fd1ecb74089ca0e0463d7c5c191a5bc9636a /source/components/dispatcher/dsopcode.c | |
parent | 2ffc68d55c8b97c35754719f0879411fea266ea9 (diff) | |
download | acpica-79a466b64e6af36cc83102f05915e56cb7dd89ab.tar.gz |
Dispatcher: always generate buffer objects for ASL CreateField() operator
According to table 19-419 of the ACPI 6.3 specification, BufferFields
created using the ASL CreateField() Operator have been treated as
integers if the BufferField is small enough to fit inside of an ASL
integer (32-bits or 64-bits depending on the definition block
revision). If they are larger, buffer fields are treated as ASL
Buffer objects. However, this is not true for other AML interpreter
implementations.
It has been discovered that other AML interpreters always treat
buffer fields created by CreateField() as a buffer regardless of the
length of the buffer field.
More specifically, the Microsoft AML interpreter always treats buffer
fields created by the CreateField() operator as buffer. ACPICA
currently does this only when the field size is larger than the
maximum integer width. This causes problems with AML code shipped in
Microsoft Surface devices.
More details:
The control methods in these devices determine the success of an ASL
control method execution by examining the type resulting from storing
a buffer field created by a CreateField() operator. On success, a
Buffer object is expected, on failure an Integer containing an error
code. This buffer object is created with a dynamic size via the
CreateField() operator. Due to the difference in behavior, Buffer
values of small size are however converted to Integers and thus
interpreted by the control method as having failed, whereas in
reality it succeeded. Below is an example of a control method called
TEST that illustrates this behavior.
Method (CBUF) // Create a Buffer field
{
/*
* Depending on the value of RAND, ACPICA interpreter will treat
* BF00 as an integer or buffer.
*/
CreateField (BUFF, 0, RAND, BF00)
return (BF00)
}
Method (TEST)
{
/*
* Storing the value returned by CBUF to local0 will result in
* implicit type conversion outlined in the ACPI specification.
*
* ACPICA will treat local0 like an ASL integer if RAND is less
* than or equal to 64 or 32 (depending on the DefinitionBlock
* revision). If RAND is greater, it will be treated like an ASL
* buffer. Other implementations treat local0 like an ASL buffer
* regardless of the value of RAND.
*/
local0 = CBUF()
/*
* ObjectType of 0x03 represents an ASL Buffer
*/
if (ObjectType (Local0) != 0x03)
{
// Error on ACPICA if RAND is small enough
}
else
{
/*
* Success on APICA if RAND is large enough
* Other implementations always take this path because local0
* is always treated as a buffer.
*/
}
}
This change prohibits the previously mentioned integer conversion to
match other AML interpreter implementations (Microsoft) that do not
conform to the ACPI specification.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Signed-off-by: Erik Schmauss <erik.schmauss@intel.com>
Diffstat (limited to 'source/components/dispatcher/dsopcode.c')
-rw-r--r-- | source/components/dispatcher/dsopcode.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/source/components/dispatcher/dsopcode.c b/source/components/dispatcher/dsopcode.c index acf1ff4e1..526fc8470 100644 --- a/source/components/dispatcher/dsopcode.c +++ b/source/components/dispatcher/dsopcode.c @@ -374,6 +374,7 @@ AcpiDsInitBufferField ( } ObjDesc->BufferField.BufferObj = BufferDesc; + ObjDesc->BufferField.IsCreateField = AmlOpcode == AML_CREATE_FIELD_OP; /* Reference count for BufferDesc inherits ObjDesc count */ |