如何在acpiexec提示符下向ACPI控制方法传递buffer参数?
如何在acpiexec中正确传递Buffer对象给ACPI方法?
问题场景
定义了Buffer对象BUF0和用于遍历它的ACPI方法IDXA,ASL代码如下:
DefinitionBlock ("dsdt.asl", "DSDT", 0x02, "", "", 0x0) { Name (BUF0, Buffer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) Method (IDXA, 1) { local0 = sizeof(Arg0) local1 = 0 // use this as the index value printf ("The size of the buffer is %o, Arg0 is: %o", local0, Arg0) while (local0 > local1) { printf ("inside loop:") printf ("%o", DeRefOf(Arg0[local1])) local1++ } } }
编译与运行步骤
- 编译代码:
iasl dsdt.asl - 运行编译后的AML文件:
acpiexec dsdt.aml
错误现象
在acpiexec提示符下尝试直接传递\BUF0调用\IDXA:
- eval \IDXA \BUF0
得到错误输出:
Evaluating \IDXA ACPI Debug: "The size of the buffer is 0000000000000008, Arg0 is: 0000000000000000" ACPI Debug: "inside loop:" ACPI Error: Needed [Buffer/String/Package], found [Integer] 0x555d39f95770 (20190509/exresop-617) ACPI Error: AE_AML_OPERAND_TYPE, While resolving operands for [Index] (20190509/dswexec-500) Failed at AML Offset 00056, Opcode 0088: Index (Arg0, Local1) Initialized Local Variables for Method [IDXA]: Local0: 0x555d39f95840 <Obj> Integer 0000000000000008 Local1: 0x555d39f956f0 <Obj> Integer 0000000000000000 Initialized Arguments for Method [IDXA]: (1 arguments defined for method invocation) Arg0: 0x555d39f95770 <Obj> Integer 0000000000000000 ACPI Error: Aborting method \IDXA due to previous error (AE_AML_OPERAND_TYPE) (20190509/psparse-581) ACPI Error: AE_AML_OPERAND_TYPE, while executing \IDXA from AML Debugger (20190509/dbexec-226) Evaluation of \IDXA failed with status AE_AML_OPERAND_TYPE
错误显示Arg0被识别为整数而非Buffer,导致索引操作失败。但单独访问\BUF0是正常的:
- eval \BUF0 Evaluating \BUF0 Evaluation of \BUF0 returned object 0x55b97b465cd0, external buffer length 28 [Buffer] Length 0A = 0000: 01 02 03 04 05 06 07 00 00 08 // ..........
解决方法
1. 正确的acpiexec调用命令
acpiexec中直接传递对象路径时,不会传递对象本身,而是返回无效整数。需要使用^前缀表示名称引用,将Buffer对象的引用传递给方法:
eval \IDXA ^\BUF0
2. 修正ASL方法中的逻辑错误
原方法中sizeof(Arg0)获取的是引用对象的字节大小(64位系统下为8),而非Buffer的实际长度。需要替换为SizeOfBuffer(DeRefOf(Arg0))来获取Buffer的真实长度,同时调整索引操作的写法:
Method (IDXA, 1) { local0 = SizeOfBuffer(DeRefOf(Arg0)) local1 = 0 // use this as the index value printf ("The size of the buffer is %o", local0) while (local0 > local1) { printf ("inside loop: ") printf ("%o", DeRefOf(Arg0)[local1]) local1++ } }
原理说明
^前缀告诉acpiexec传递的是对象的名称引用,而非尝试解析对象的值,这样Arg0会被正确识别为Buffer类型的引用。DeRefOf()用于解引用获取到Buffer对象本身,SizeOfBuffer()则专门用于获取Buffer的字节长度,替代原有的sizeof()函数(后者对引用类型返回的是引用的大小)。
内容的提问来源于stack exchange,提问作者smwikipedia
相关产品推荐
相关产品推荐

