• Erik Kaneda's avatar
    ACPI: PRM: implement OperationRegion handler for the PlatformRtMechanism subtype · cefc7ca4
    Erik Kaneda authored
    Platform Runtime Mechanism (PRM) is a firmware interface that exposes
    a set of binary executables that can either be called from the AML
    interpreter or device drivers by bypassing the AML interpreter.
    This change implements the AML interpreter path.
    
    According to the specification [1], PRM services are listed in an
    ACPI table called the PRMT. This patch parses module and handler
    information listed in the PRMT and registers the PlatformRtMechanism
    OpRegion handler before ACPI tables are loaded.
    
    Each service is defined by a 16-byte GUID and called from writing a
    26-byte ASL buffer containing the identifier to a FieldUnit object
    defined inside a PlatformRtMechanism OperationRegion.
    
        OperationRegion (PRMR, PlatformRtMechanism, 0, 26)
        Field (PRMR, BufferAcc, NoLock, Preserve)
        {
            PRMF, 208 // Write to this field to invoke the OperationRegion Handler
        }
    
    The 26-byte ASL buffer is defined as the following:
    
    Byte Offset   Byte Length    Description
    =============================================================
         0             1         PRM OperationRegion handler status
         1             8         PRM service status
         9             1         PRM command
        10            16         PRM handler GUID
    
    The ASL caller fills out a 26-byte buffer containing the PRM command
    and the PRM handler GUID like so:
    
        /* Local0 is the PRM data buffer */
        Local0 = buffer (26){}
    
        /* Create byte fields over the buffer */
        CreateByteField (Local0, 0x9, CMD)
        CreateField (Local0, 0x50, 0x80, GUID)
    
        /* Fill in the command and data fields of the data buffer */
        CMD = 0 // run command
        GUID = ToUUID("xxxx-xx-xxx-xxxx")
    
        /*
         * Invoke PRM service with an ID that matches GUID and save the
         * result.
         */
        Local0 = (\_SB.PRMT.PRMF = Local0)
    
    Byte offset 0 - 8 are written by the handler as a status passed back to AML
    and used by ASL like so:
    
        /* Create byte fields over the buffer */
        CreateByteField (Local0, 0x0, PSTA)
        CreateQWordField (Local0, 0x1, USTA)
    
    In this ASL code, PSTA contains a status from the OperationRegion and
    USTA contains a status from the PRM service.
    
    The 26-byte buffer is recieved by acpi_platformrt_space_handler. This
    handler will look at the command value and the handler guid and take
    the approperiate actions.
    
    Command value    Action
    =====================================================================
        0            Run the PRM service indicated by the PRM handler
                     GUID (bytes 10-26)
    
        1            Prevent PRM runtime updates from happening to the
                     service's parent module
    
        2            Allow PRM updates from happening to the service's parent module
    
    This patch enables command value 0.
    
    Link: https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mechanism%20-%20with%20legal%20notice.pdf # [1]
    Signed-off-by: default avatarErik Kaneda <erik.kaneda@intel.com>
    [ rjw: Subject and changelog edits ]
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    cefc7ca4
bus.c 35.4 KB