• Maximilian Luz's avatar
    ACPICA: Dispatcher: always generate buffer objects for ASL create_field() operator · 6d232b29
    Maximilian Luz authored
    ACPICA commit 79a466b64e6af36cc83102f05915e56cb7dd89ab
    
    According to table 19-419 of the ACPI 6.3 specification, buffer_fields
    created using the ASL create_field() Operator have been treated as
    integers if the buffer_field 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 create_field() as a buffer regardless of the
    length of the buffer field.
    
    More specifically, the Microsoft AML interpreter always treats buffer
    fields created by the create_field() 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 create_field() 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
    create_field() 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.
         */
        create_field (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 definition_block
         * 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()
    
        /*
         * object_type of 0x03 represents an ASL Buffer
         */
        if (object_type (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.
    
    Link: https://github.com/acpica/acpica/commit/79a466b6Signed-off-by: default avatarMaximilian Luz <luzmaximilian@gmail.com>
    Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
    Signed-off-by: default avatarErik Kaneda <erik.kaneda@intel.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    6d232b29
exfield.c 12.3 KB