Windows Phone 8.1 driver development-how to call ACPI Method and drive acpi Development

Source: Internet
Author: User

Windows Phone 8.1 driver development-how to call ACPI Method and drive acpi Development
Today, we will explain how to call the Method defined in the ACPI configuration table in KMDF (Kernel-Mode Driver Framework. In ACPI, all methods starting with an underscore (such as _ STA) are pre-defined methods, which are called by Windows OS, other user-defined methods are called by the driver.


ACPI Method

First, let's take a look at the Method defined in ACPI:

//Global BufferName(DATA, Buffer(0x4) { 0x00, 0x00, 0x00, 0x00})Device (TEST){    Name (_HID, "TEST001")    Name (_UID, 1)...    Method(GETD, 0x0, NotSerialized)    {        return (DATA)    }    Method(SETD, 0x1, NotSerialized)    {        Store(Arg0, DATA)    }...}
The Code shows that the TEST device provides two methods: GETD () and SETD (). The global variable DATA is a 4-byte array. The GETD () method is used to read DATA and send it to the driver. The SETD () method is used to write the DATA transmitted by the driver into the DATA. To describe them in the C language, you can write them as follows: uchar * GETD (void); and void SETD (uchar * data );


IOCTL_ACPI_EVAL_METHOD request

The driver can call the ACPI Method by calling the WdfIoTargetSendIoctlSynchronously () function and sending the IOCTL_ACPI_EVAL_METHOD request to the ACPI driver. For more information about IOCTL, refer to the MSDN documentation:IOCTL_ACPI_EVAL_METHOD control code

Before writing the KMDF driver, we need to understand the following four structures:

ACPI_EVAL_INPUT_BUFFER

ACPI_EVAL_INPUT_BUFFER_COMPLEX

ACPI_EVAL_OUTPUT_BUFFER

ACPI_METHOD_ARGUMENT


ACPI_EVAL_INPUT_BUFFER struct

Struct is defined as follows:

typedef struct _ACPI_EVAL_INPUT_BUFFER {  ULONG Signature;  union {    UCHAR MethodName[4];    ULONG MethodNameAsUlong;  };} ACPI_EVAL_INPUT_BUFFER, *PACPI_EVAL_INPUT_BUFFER;
This struct is used to call an ACPI Method without input parameters. Assume that the Method to be accessed is GETD (). Before sending an IOCTL_ACPI_EVAL_METHOD request, you need to set its member variables as follows:
  • Set SignatureACPI_EVAL_INPUT_BUFFER_SIGNATURE
  • Set MethodName'Getd'Or set MethodNameAsUlong(ULONG) ('dteg ')
For more details about this struct, refer to the MSDN documentation: ACPI_EVAL_INPUT_BUFFER structure


ACPI_EVAL_INPUT_BUFFER_COMPLEX struct

Struct is defined as follows:

typedef struct _ACPI_EVAL_INPUT_BUFFER_COMPLEX {  ULONG                Signature;  union {    UCHAR MethodName[4];    ULONG MethodNameAsUlong;  };  ULONG                Size;  ULONG                ArgumentCount;  ACPI_METHOD_ARGUMENT Argument[ANYSIZE_ARRAY];} ACPI_EVAL_INPUT_BUFFER_COMPLEX, *PACPI_EVAL_INPUT_BUFFER_COMPLEX;
This struct is used to call an ACPI Method with input parameters to pass the input parameters. Assume that the Method to be accessed is SETD (), before sending the IOCTL_ACPI_EVAL_METHOD request, you need to set its member variables as follows:
  • Set SignatureACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
  • Set MethodName'Setd'Or set MethodNameAsUlong(ULONG) ('dtes ')
  • Sets the Size value, which indicates the byte Size of the entire array of Argument [ANYSIZE_ARRAY]
  • Set the value of ArgumentCount. Here it is 1
  • Assign a value to the structure member Argument and set the input parameters.
For more details about this struct, refer to the MSDN documentation: ACPI_EVAL_INPUT_BUFFER_COMPLEX structure


ACPI_EVAL_OUTPUT_BUFFER struct

Struct is defined as follows:

typedef struct _ACPI_EVAL_OUTPUT_BUFFER {  ULONG                Signature;  ULONG                Length;  ULONG                Count;  ACPI_METHOD_ARGUMENT Argument[ANYSIZE_ARRAY];} ACPI_EVAL_OUTPUT_BUFFER;

This struct is used to return the output parameters after the ACPI Method is executed. The output parameters are saved in the Argument member variables, and the value of Signature must beACPI_EVAL_OUTPUT_BUFFER_SIGNATURELength indicates the byte size of the entire ACPI_EVAL_OUTPUT_BUFFER struct, and Count records the number of Argument members. For more details about this struct, refer to the MSDN documentation:ACPI_EVAL_OUTPUT_BUFFER structure


ACPI_METHOD_ARGUMENT struct

Struct is defined as follows:

typedef struct _ACPI_METHOD_ARGUMENT  USHORT Type;  USHORT DataLength;  union {    ULONG Argument;    UCHAR Data[ANYSIZE_ARRAY];  };} ACPI_METHOD_ARGUMENT;

This struct is where the input and output parameters are actually stored. Where

Type defines the parameter Type, which has the following values:

ACPI_METHOD_ARGUMENT_INTEGER

ACPI_METHOD_ARGUMENT_STRING

ACPI_METHOD_ARGUMENT_BUFFER

ACPI_METHOD_ARGUMENT_PACKAGE

DataLength is the byte size of the array Data.

For more details about this struct, refer to the MSDN documentation:ACPI_METHOD_ARGUMENT structure


Sample Code

Access ACPI Method without input parameters:
NTSTATUS ACPIGetData(WDFDEVICE FxDevice, void *pBuffer){    NTSTATUS                 Status;    WDF_MEMORY_DESCRIPTOR    InputDescriptor;    WDF_MEMORY_DESCRIPTOR    OutputDescriptor;    ACPI_EVAL_INPUT_BUFFER   InputBuffer;    ACPI_EVAL_OUTPUT_BUFFER  OutputBuffer;    WDFIOTARGET              IoTarget;    ULONG                    SizeReturned;    USHORT                   DataLength;    PAGED_CODE();    //    // Signature and Method name in reverse    //    InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;    InputBuffer.MethodNameAsUlong = (ULONG) ('DTEG');    //    // Use following WDF method to initialize memory descriptor    // The memory descriptor is initialized with the input buffer we have defined.    //    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&InputDescriptor,                                     (PVOID)&InputBuffer,                                     sizeof(ACPI_EVAL_INPUT_BUFFER));    RtlZeroMemory(&OutputBuffer, sizeof(OutputBuffer));    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&OutputDescriptor,                                     (PVOID)&OutputBuffer,                                     sizeof(ACPI_EVAL_OUTPUT_BUFFER));    //    // Get handle for underlying ACPI layer    //    IoTarget = WdfDeviceGetIoTarget(FxDevice);    //    // Send synchronous request    //    Status = WdfIoTargetSendIoctlSynchronously(IoTarget,                                       NULL,                                               IOCTL_ACPI_EVAL_METHOD,                                               &InputDescriptor,                                               &OutputDescriptor,                                               NULL,                                               &SizeReturned);    if (!NT_SUCCESS(Status)) {       return Status;    }    //    // Verify output signature and length    //    if ((OutputBuffer.Signature == ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)    && (OutputBuffer.Argument[0].Type == ACPI_METHOD_ARGUMENT_BUFFER))    {//// Extract data from buffer//DataLength =  OutputBuffer.Argument[0].DataLength;memcpy_s((UINT8*)pBuffer,                 (DataLength * sizeof(UINT8)),                 (UINT8*)OutputBuffer.Argument[0].Data,                 (DataLength * sizeof(UINT8)));        Status = STATUS_SUCCESS;    }    else    {        Status = STATUS_ACPI_INVALID_DATA;    }exit:    return Status;}


Access ACPI Method with input parameters:

NTSTATUS ACPISetData(WDFDEVICE FxDevice, void *pBuffer){    NTSTATUS                        Status;    WDF_MEMORY_DESCRIPTOR            InputDescriptor;    WDF_MEMORY_DESCRIPTOR            OutputDescriptor;    ACPI_EVAL_INPUT_BUFFER_COMPLEX   InputBuffer;    ACPI_EVAL_OUTPUT_BUFFER        OutputBuffer;    WDFIOTARGET                        IoTarget;    ULONG                            SizeReturned;    PAGED_CODE();    //    // Signature and Method name in reverse    //    InputBuffer.MethodNameAsUlong = (ULONG)('DTES');    InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;    InputBuffer.ArgumentCount = 1;    InputBuffer.Size = InputBuffer.ArgumentCount * sizeof(ACPI_METHOD_ARGUMENT);    InputBuffer.Argument[0].Type = ACPI_METHOD_ARGUMENT_BUFFER;    InputBuffer.Argument[0].DataLength = 4;memcpy_s(InputBuffer.Argument[0].Data, InputBuffer.Argument[0].DataLength,      pBuffer, InputBuffer.Argument[0].DataLength);    //    // Use following WDF method to initialize memory descriptor    // The memory descriptor is initialized with the input buffer we have defined.    //    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&InputDescriptor,        (PVOID)&InputBuffer,        sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX));    RtlZeroMemory(&OutputBuffer, sizeof(OutputBuffer));    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&OutputDescriptor,        (PVOID)&OutputBuffer,        sizeof(ACPI_EVAL_OUTPUT_BUFFER));    //    // Get handle for underlying ACPI layer    //    IoTarget = WdfDeviceGetIoTarget(FxDevice);    //    // Send synchronous request    //    Status = WdfIoTargetSendIoctlSynchronously(IoTarget,        NULL,        IOCTL_ACPI_EVAL_METHOD,        &InputDescriptor,        &OutputDescriptor,        NULL,        &SizeReturned);    if (!NT_SUCCESS(Status))    {goto exit;    }    else    {        //        // Verify output signature and length        //        if ( (OutputBuffer.Signature == ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)            && (OutputBuffer.Argument[0].Type == ACPI_METHOD_ARGUMENT_BUFFER))        {            Status = STATUS_SUCCESS;        }        else        {            Status = STATUS_ACPI_INVALID_DATA;        }    }exit:    return Status;}


For more detailed usage of ACPI Control Method, refer to the official MSDN documentation:Evaluating ACPI Control Methods Synchronously



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.