ACPI _DSM

来源:互联网 发布:网络博客行业 编辑:程序博客网 时间:2024/05/21 11:17
_DSM的全程是Device-Specific Method,简单说就是kernel中调用bios中的函数做事情的一种方式,bios中的函数是以runtime service的方式存在的。
例如加入kernel 要调用bios中的函数可能告知gpio,由于dsm是一uuid的方式区分的。
首先定义uuid
{4F248F40-D5E2-499F-834C-27758EA1CD3F}
bios中的asl的code 如下:
// _DSM Device Specific Method
     //
     // Arg0: UUID Unique function identifier
     // Arg1: Integer Revision Level
     // Arg2: Integer Function Index
     //   0 : Return Supported Functions bit mask
     //   1 : Reset Sequence
     //    Arg3[0] : reset type (1:dsaf; 2:ppe; 3:xge core; 4:xge; 5: ge; 6:dchan; 7:RoCE)
     //    Arg3[1] : port index in dsaf
     //    Arg3[2] : 0 reset, 1 cancle reset
     //   2 : Set Serdes Loopback
     //    Arg3[0] : port
     //    Arg3[1] : 0 disable, 1 enable
     //   3 : LED op set
     //    Arg3[0] : op type
     //    Arg3[1] : port
     //    Arg3[2] : para
     //   4 : Get port type (GE or XGE)
     //    Arg3[0] : port index in dsaf
     //    Return : 0 GE, 1 XGE
     //   5 : Get sfp status
     //    Arg3[0] : port index in dsaf
     //    Return : 0 no sfp, 1 have sfp
     // Arg3: Package Parameters
     Method (_DSM, 4, Serialized)
     {
       If (LEqual(Arg0,ToUUID("1A85AA1A-E293-415E-8E28-8D690A0F820A")))
       {
         If (LEqual (Arg1, 0x00))
         {
           Switch (ToInteger(Arg2))
           {
             case (0x0)
             {
               Return (Buffer () {0x3F})
             }
 
             //Reset Sequence
             case (0x1)
             {
               Store (DeRefOf (Index (Arg3, 0)), Local0)
               Store (DeRefOf (Index (Arg3, 1)), Local1)
               Store (DeRefOf (Index (Arg3, 2)), Local2)
               DRST (Local0, Local1, Local2)
        }

    }

在kernel中就可以按照下面的刚是来调用
    hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
                   HNS_DSAF_CHN_RESET_FUNC,
                   msk, dereset);
const u8 hns_dsaf_acpi_dsm_uuid[] = {
    0x1A, 0xAA, 0x85, 0x1A, 0x93, 0xE2, 0x5E, 0x41,
    0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A
};

static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type,
                       u32 port_type, u32 port, u32 val)
{
    union acpi_object *obj;
    union acpi_object obj_args[3], argv4;

    obj_args[0].integer.type = ACPI_TYPE_INTEGER;
    obj_args[0].integer.value = port_type;
    obj_args[1].integer.type = ACPI_TYPE_INTEGER;
    obj_args[1].integer.value = port;
    obj_args[2].integer.type = ACPI_TYPE_INTEGER;
    obj_args[2].integer.value = val;

    argv4.type = ACPI_TYPE_PACKAGE;
    argv4.package.count = 3;
    argv4.package.elements = obj_args;

    obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
                hns_dsaf_acpi_dsm_uuid, 0, op_type, &argv4);
    if (!obj) {
        dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
             port_type, port);
        return;
    }

    ACPI_FREE(obj);
}

可见kernel 要调用bios提供的dsm 必须和bios协商好.
union acpi_object *
acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
          union acpi_object *argv4)
{
    acpi_status ret;
    struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
    union acpi_object params[4];
    struct acpi_object_list input = {
        .count = 4,
        .pointer = params,
    };

    params[0].type = ACPI_TYPE_BUFFER;
    params[0].buffer.length = 16;
    params[0].buffer.pointer = (char *)uuid;
    params[1].type = ACPI_TYPE_INTEGER;
    params[1].integer.value = rev;
    params[2].type = ACPI_TYPE_INTEGER;
    params[2].integer.value = func;
    if (argv4) {
        params[3] = *argv4;
    } else {
        params[3].type = ACPI_TYPE_PACKAGE;
        params[3].package.count = 0;
        params[3].package.elements = NULL;
    }

    ret = acpi_evaluate_object(handle, "_DSM", &input, &buf);
    if (ACPI_SUCCESS(ret))
        return (union acpi_object *)buf.pointer;

    if (ret != AE_NOT_FOUND)
        acpi_handle_warn(handle,
                "failed to evaluate _DSM (0x%x)\n", ret);

    return NULL;
}
原来kernel中最终是通过acpi_evaluate_object 来调用bios中在asl中定义好的函数啊
哈哈哈
原创粉丝点击