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中定义好的函数啊
哈哈哈
例如加入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中定义好的函数啊
哈哈哈
阅读全文
0 0
- ACPI _DSM
- ACPI
- acpi
- ACPI
- ACPI
- ASL Code中的_DSM方法
- ACPI Wakeup
- linux acpi
- ACPI Overview
- ACPI Tables
- ACPI NameSpace
- ACPI Overview
- Documentation_power_apm-acpi
- Documentation_power_apm-acpi
- ACPI Tables
- ACPI Overview
- ACPI NameSpace
- ACPI Tables
- Oracle 集群概念及原理(转)
- Linux下启动tomcat
- kmeans基于mapreduce的实现
- 异步加载
- 将Tomcat注册成服务
- ACPI _DSM
- web页面html中常用的特殊符号大全-可以直接用到页面里
- 深度学习笔记——深度学习框架TensorFlow(五)[TensorFlow大规模线性模型教程]
- WSDL实例解析
- Change a pointer
- 【math】7、输入一个数字,倒着输出
- 生成本地zip压缩包工具类
- UML关系明确解释
- HDFS文件导出本地合并为一个文件