summaryrefslogtreecommitdiff
path: root/source/components/dispatcher/dsopcode.c
diff options
context:
space:
mode:
authorMaximilian Luz <luzmaximilian@gmail.com>2019-12-06 05:46:00 -0800
committerErik Schmauss <erik.schmauss@intel.com>2019-12-06 13:55:39 -0800
commit79a466b64e6af36cc83102f05915e56cb7dd89ab (patch)
tree83b0fd1ecb74089ca0e0463d7c5c191a5bc9636a /source/components/dispatcher/dsopcode.c
parent2ffc68d55c8b97c35754719f0879411fea266ea9 (diff)
downloadacpica-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.c1
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 */