aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser/psargs.c')
-rw-r--r--drivers/acpi/parser/psargs.c352
1 files changed, 179 insertions, 173 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 5858188f94a6..3c37cd0ecd80 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore 8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
45#include <acpi/acparser.h> 45#include <acpi/acparser.h>
46#include <acpi/amlcode.h> 46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h> 47#include <acpi/acnamesp.h>
48#include <acpi/acdispat.h>
48 49
49#define _COMPONENT ACPI_PARSER 50#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("psargs") 51ACPI_MODULE_NAME("psargs")
@@ -62,61 +63,51 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
62 * 63 *
63 * PARAMETERS: parser_state - Current parser state object 64 * PARAMETERS: parser_state - Current parser state object
64 * 65 *
65 * RETURN: Decoded package length. On completion, the AML pointer points 66 * RETURN: Decoded package length. On completion, the AML pointer points
66 * past the length byte or bytes. 67 * past the length byte or bytes.
67 * 68 *
68 * DESCRIPTION: Decode and return a package length field 69 * DESCRIPTION: Decode and return a package length field.
70 * Note: Largest package length is 28 bits, from ACPI specification
69 * 71 *
70 ******************************************************************************/ 72 ******************************************************************************/
71 73
72static u32 74static u32
73acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 75acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
74{ 76{
75 u32 encoded_length; 77 u8 *aml = parser_state->aml;
76 u32 length = 0; 78 u32 package_length = 0;
79 acpi_native_uint byte_count;
80 u8 byte_zero_mask = 0x3F; /* Default [0:5] */
77 81
78 ACPI_FUNCTION_TRACE("ps_get_next_package_length"); 82 ACPI_FUNCTION_TRACE("ps_get_next_package_length");
79 83
80 encoded_length = (u32) ACPI_GET8(parser_state->aml); 84 /*
81 parser_state->aml++; 85 * Byte 0 bits [6:7] contain the number of additional bytes
82 86 * used to encode the package length, either 0,1,2, or 3
83 switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */ 87 */
84 case 0: /* 1-byte encoding (bits 0-5) */ 88 byte_count = (aml[0] >> 6);
85 89 parser_state->aml += (byte_count + 1);
86 length = (encoded_length & 0x3F);
87 break;
88
89 case 1: /* 2-byte encoding (next byte + bits 0-3) */
90
91 length = ((ACPI_GET8(parser_state->aml) << 04) |
92 (encoded_length & 0x0F));
93 parser_state->aml++;
94 break;
95
96 case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
97
98 length = ((ACPI_GET8(parser_state->aml + 1) << 12) |
99 (ACPI_GET8(parser_state->aml) << 04) |
100 (encoded_length & 0x0F));
101 parser_state->aml += 2;
102 break;
103 90
104 case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ 91 /* Get bytes 3, 2, 1 as needed */
105 92
106 length = ((ACPI_GET8(parser_state->aml + 2) << 20) | 93 while (byte_count) {
107 (ACPI_GET8(parser_state->aml + 1) << 12) | 94 /*
108 (ACPI_GET8(parser_state->aml) << 04) | 95 * Final bit positions for the package length bytes:
109 (encoded_length & 0x0F)); 96 * Byte3->[20:27]
110 parser_state->aml += 3; 97 * Byte2->[12:19]
111 break; 98 * Byte1->[04:11]
112 99 * Byte0->[00:03]
113 default: 100 */
101 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
114 102
115 /* Can't get here, only 2 bits / 4 cases */ 103 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
116 break; 104 byte_count--;
117 } 105 }
118 106
119 return_VALUE(length); 107 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
108
109 package_length |= (aml[0] & byte_zero_mask);
110 return_UINT32(package_length);
120} 111}
121 112
122/******************************************************************************* 113/*******************************************************************************
@@ -135,16 +126,15 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
135u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) 126u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
136{ 127{
137 u8 *start = parser_state->aml; 128 u8 *start = parser_state->aml;
138 acpi_native_uint length; 129 u32 package_length;
139 130
140 ACPI_FUNCTION_TRACE("ps_get_next_package_end"); 131 ACPI_FUNCTION_TRACE("ps_get_next_package_end");
141 132
142 /* Function below changes parser_state->Aml */ 133 /* Function below updates parser_state->Aml */
143 134
144 length = 135 package_length = acpi_ps_get_next_package_length(parser_state);
145 (acpi_native_uint) acpi_ps_get_next_package_length(parser_state);
146 136
147 return_PTR(start + length); /* end of package */ 137 return_PTR(start + package_length); /* end of package */
148} 138}
149 139
150/******************************************************************************* 140/*******************************************************************************
@@ -169,17 +159,15 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
169 159
170 ACPI_FUNCTION_TRACE("ps_get_next_namestring"); 160 ACPI_FUNCTION_TRACE("ps_get_next_namestring");
171 161
172 /* Handle multiple prefix characters */ 162 /* Point past any namestring prefix characters (backslash or carat) */
173
174 while (acpi_ps_is_prefix_char(ACPI_GET8(end))) {
175 /* Include prefix '\\' or '^' */
176 163
164 while (acpi_ps_is_prefix_char(*end)) {
177 end++; 165 end++;
178 } 166 }
179 167
180 /* Decode the path */ 168 /* Decode the path prefix character */
181 169
182 switch (ACPI_GET8(end)) { 170 switch (*end) {
183 case 0: 171 case 0:
184 172
185 /* null_name */ 173 /* null_name */
@@ -199,9 +187,9 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
199 187
200 case AML_MULTI_NAME_PREFIX_OP: 188 case AML_MULTI_NAME_PREFIX_OP:
201 189
202 /* Multiple name segments, 4 chars each */ 190 /* Multiple name segments, 4 chars each, count in next byte */
203 191
204 end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE); 192 end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
205 break; 193 break;
206 194
207 default: 195 default:
@@ -212,7 +200,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
212 break; 200 break;
213 } 201 }
214 202
215 parser_state->aml = (u8 *) end; 203 parser_state->aml = end;
216 return_PTR((char *)start); 204 return_PTR((char *)start);
217} 205}
218 206
@@ -224,7 +212,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
224 * Arg - Where the namepath will be stored 212 * Arg - Where the namepath will be stored
225 * arg_count - If the namepath points to a control method 213 * arg_count - If the namepath points to a control method
226 * the method's argument is returned here. 214 * the method's argument is returned here.
227 * method_call - Whether the namepath can possibly be the 215 * possible_method_call - Whether the namepath can possibly be the
228 * start of a method call 216 * start of a method call
229 * 217 *
230 * RETURN: Status 218 * RETURN: Status
@@ -240,11 +228,11 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
240acpi_status 228acpi_status
241acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, 229acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
242 struct acpi_parse_state *parser_state, 230 struct acpi_parse_state *parser_state,
243 union acpi_parse_object *arg, u8 method_call) 231 union acpi_parse_object *arg, u8 possible_method_call)
244{ 232{
245 char *path; 233 char *path;
246 union acpi_parse_object *name_op; 234 union acpi_parse_object *name_op;
247 acpi_status status = AE_OK; 235 acpi_status status;
248 union acpi_operand_object *method_desc; 236 union acpi_operand_object *method_desc;
249 struct acpi_namespace_node *node; 237 struct acpi_namespace_node *node;
250 union acpi_generic_state scope_info; 238 union acpi_generic_state scope_info;
@@ -252,115 +240,127 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
252 ACPI_FUNCTION_TRACE("ps_get_next_namepath"); 240 ACPI_FUNCTION_TRACE("ps_get_next_namepath");
253 241
254 path = acpi_ps_get_next_namestring(parser_state); 242 path = acpi_ps_get_next_namestring(parser_state);
243 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
255 244
256 /* Null path case is allowed */ 245 /* Null path case is allowed, just exit */
257 246
258 if (path) { 247 if (!path) {
259 /* 248 arg->common.value.name = path;
260 * Lookup the name in the internal namespace 249 return_ACPI_STATUS(AE_OK);
261 */ 250 }
262 scope_info.scope.node = NULL;
263 node = parser_state->start_node;
264 if (node) {
265 scope_info.scope.node = node;
266 }
267 251
268 /* 252 /* Setup search scope info */
269 * Lookup object. We don't want to add anything new to the namespace
270 * here, however. So we use MODE_EXECUTE. Allow searching of the
271 * parent tree, but don't open a new scope -- we just want to lookup the
272 * object (MUST BE mode EXECUTE to perform upsearch)
273 */
274 status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY,
275 ACPI_IMODE_EXECUTE,
276 ACPI_NS_SEARCH_PARENT |
277 ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
278 if (ACPI_SUCCESS(status) && method_call) {
279 if (node->type == ACPI_TYPE_METHOD) {
280 /* This name is actually a control method invocation */
281
282 method_desc = acpi_ns_get_attached_object(node);
283 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
284 "Control Method - %p Desc %p Path=%p\n",
285 node, method_desc, path));
286
287 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
288 if (!name_op) {
289 return_ACPI_STATUS(AE_NO_MEMORY);
290 }
291 253
292 /* Change arg into a METHOD CALL and attach name to it */ 254 scope_info.scope.node = NULL;
255 node = parser_state->start_node;
256 if (node) {
257 scope_info.scope.node = node;
258 }
293 259
294 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 260 /*
295 name_op->common.value.name = path; 261 * Lookup the name in the internal namespace. We don't want to add
262 * anything new to the namespace here, however, so we use MODE_EXECUTE.
263 * Allow searching of the parent tree, but don't open a new scope -
264 * we just want to lookup the object (must be mode EXECUTE to perform
265 * the upsearch)
266 */
267 status =
268 acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
269 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
270 NULL, &node);
296 271
297 /* Point METHODCALL/NAME to the METHOD Node */ 272 /*
273 * If this name is a control method invocation, we must
274 * setup the method call
275 */
276 if (ACPI_SUCCESS(status) &&
277 possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
278 /* This name is actually a control method invocation */
298 279
299 name_op->common.node = node; 280 method_desc = acpi_ns_get_attached_object(node);
300 acpi_ps_append_arg(arg, name_op); 281 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
282 "Control Method - %p Desc %p Path=%p\n", node,
283 method_desc, path));
301 284
302 if (!method_desc) { 285 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
303 ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); 286 if (!name_op) {
304 return_ACPI_STATUS(AE_AML_INTERNAL); 287 return_ACPI_STATUS(AE_NO_MEMORY);
305 } 288 }
306 289
307 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 290 /* Change Arg into a METHOD CALL and attach name to it */
308 "Control Method - %p Args %X\n",
309 node,
310 method_desc->method.
311 param_count));
312 291
313 /* Get the number of arguments to expect */ 292 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
293 name_op->common.value.name = path;
314 294
315 walk_state->arg_count = 295 /* Point METHODCALL/NAME to the METHOD Node */
316 method_desc->method.param_count;
317 return_ACPI_STATUS(AE_OK);
318 }
319 296
320 /* 297 name_op->common.node = node;
321 * Else this is normal named object reference. 298 acpi_ps_append_arg(arg, name_op);
322 * Just init the NAMEPATH object with the pathname.
323 * (See code below)
324 */
325 }
326 299
327 if (ACPI_FAILURE(status)) { 300 if (!method_desc) {
328 /* 301 ACPI_REPORT_ERROR(("Control Method %p has no attached object\n", node));
329 * 1) Any error other than NOT_FOUND is always severe 302 return_ACPI_STATUS(AE_AML_INTERNAL);
330 * 2) NOT_FOUND is only important if we are executing a method.
331 * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok.
332 */
333 if ((((walk_state->
334 parse_flags & ACPI_PARSE_MODE_MASK) ==
335 ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND)
336 && (walk_state->op->common.aml_opcode !=
337 AML_COND_REF_OF_OP))
338 || (status != AE_NOT_FOUND)) {
339 ACPI_REPORT_NSERROR(path, status);
340
341 acpi_os_printf
342 ("search_node %p start_node %p return_node %p\n",
343 scope_info.scope.node,
344 parser_state->start_node, node);
345
346 } else {
347 /*
348 * We got a NOT_FOUND during table load or we encountered
349 * a cond_ref_of(x) where the target does not exist.
350 * Either case is ok
351 */
352 status = AE_OK;
353 }
354 } 303 }
304
305 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
306 "Control Method - %p Args %X\n",
307 node, method_desc->method.param_count));
308
309 /* Get the number of arguments to expect */
310
311 walk_state->arg_count = method_desc->method.param_count;
312 return_ACPI_STATUS(AE_OK);
355 } 313 }
356 314
357 /* 315 /*
358 * Regardless of success/failure above, 316 * Special handling if the name was not found during the lookup -
359 * Just initialize the Op with the pathname. 317 * some not_found cases are allowed
360 */ 318 */
361 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 319 if (status == AE_NOT_FOUND) {
362 arg->common.value.name = path; 320 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
321
322 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
323 ACPI_PARSE_EXECUTE) {
324 status = AE_OK;
325 }
326
327 /* 2) not_found during a cond_ref_of(x) is ok by definition */
328
329 else if (walk_state->op->common.aml_opcode ==
330 AML_COND_REF_OF_OP) {
331 status = AE_OK;
332 }
333
334 /*
335 * 3) not_found while building a Package is ok at this point, we
336 * may flag as an error later if slack mode is not enabled.
337 * (Some ASL code depends on allowing this behavior)
338 */
339 else if ((arg->common.parent) &&
340 ((arg->common.parent->common.aml_opcode ==
341 AML_PACKAGE_OP)
342 || (arg->common.parent->common.aml_opcode ==
343 AML_VAR_PACKAGE_OP))) {
344 status = AE_OK;
345 }
346 }
347
348 /* Final exception check (may have been changed from code above) */
363 349
350 if (ACPI_FAILURE(status)) {
351 ACPI_REPORT_NSERROR(path, status);
352
353 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
354 ACPI_PARSE_EXECUTE) {
355 /* Report a control method execution error */
356
357 status = acpi_ds_method_error(status, walk_state);
358 }
359 }
360
361 /* Save the namepath */
362
363 arg->common.value.name = path;
364 return_ACPI_STATUS(status); 364 return_ACPI_STATUS(status);
365} 365}
366 366
@@ -382,59 +382,63 @@ void
382acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 382acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
383 u32 arg_type, union acpi_parse_object *arg) 383 u32 arg_type, union acpi_parse_object *arg)
384{ 384{
385 u32 length;
386 u16 opcode;
387 u8 *aml = parser_state->aml;
385 388
386 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); 389 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);
387 390
388 switch (arg_type) { 391 switch (arg_type) {
389 case ARGP_BYTEDATA: 392 case ARGP_BYTEDATA:
390 393
391 acpi_ps_init_op(arg, AML_BYTE_OP); 394 /* Get 1 byte from the AML stream */
392 arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml); 395
393 parser_state->aml++; 396 opcode = AML_BYTE_OP;
397 arg->common.value.integer = (acpi_integer) * aml;
398 length = 1;
394 break; 399 break;
395 400
396 case ARGP_WORDDATA: 401 case ARGP_WORDDATA:
397 402
398 acpi_ps_init_op(arg, AML_WORD_OP);
399
400 /* Get 2 bytes from the AML stream */ 403 /* Get 2 bytes from the AML stream */
401 404
402 ACPI_MOVE_16_TO_32(&arg->common.value.integer, 405 opcode = AML_WORD_OP;
403 parser_state->aml); 406 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
404 parser_state->aml += 2; 407 length = 2;
405 break; 408 break;
406 409
407 case ARGP_DWORDDATA: 410 case ARGP_DWORDDATA:
408 411
409 acpi_ps_init_op(arg, AML_DWORD_OP);
410
411 /* Get 4 bytes from the AML stream */ 412 /* Get 4 bytes from the AML stream */
412 413
413 ACPI_MOVE_32_TO_32(&arg->common.value.integer, 414 opcode = AML_DWORD_OP;
414 parser_state->aml); 415 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
415 parser_state->aml += 4; 416 length = 4;
416 break; 417 break;
417 418
418 case ARGP_QWORDDATA: 419 case ARGP_QWORDDATA:
419 420
420 acpi_ps_init_op(arg, AML_QWORD_OP);
421
422 /* Get 8 bytes from the AML stream */ 421 /* Get 8 bytes from the AML stream */
423 422
424 ACPI_MOVE_64_TO_64(&arg->common.value.integer, 423 opcode = AML_QWORD_OP;
425 parser_state->aml); 424 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
426 parser_state->aml += 8; 425 length = 8;
427 break; 426 break;
428 427
429 case ARGP_CHARLIST: 428 case ARGP_CHARLIST:
430 429
431 acpi_ps_init_op(arg, AML_STRING_OP); 430 /* Get a pointer to the string, point past the string */
432 arg->common.value.string = (char *)parser_state->aml; 431
432 opcode = AML_STRING_OP;
433 arg->common.value.string = ACPI_CAST_PTR(char, aml);
433 434
434 while (ACPI_GET8(parser_state->aml) != '\0') { 435 /* Find the null terminator */
435 parser_state->aml++; 436
437 length = 0;
438 while (aml[length]) {
439 length++;
436 } 440 }
437 parser_state->aml++; 441 length++;
438 break; 442 break;
439 443
440 case ARGP_NAME: 444 case ARGP_NAME:
@@ -443,14 +447,16 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
443 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 447 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
444 arg->common.value.name = 448 arg->common.value.name =
445 acpi_ps_get_next_namestring(parser_state); 449 acpi_ps_get_next_namestring(parser_state);
446 break; 450 return_VOID;
447 451
448 default: 452 default:
449 453
450 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); 454 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type));
451 break; 455 return_VOID;
452 } 456 }
453 457
458 acpi_ps_init_op(arg, opcode);
459 parser_state->aml += length;
454 return_VOID; 460 return_VOID;
455} 461}
456 462
@@ -540,7 +546,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
540 * access_type is first operand, access_attribute is second 546 * access_type is first operand, access_attribute is second
541 */ 547 */
542 field->common.value.integer = 548 field->common.value.integer =
543 (ACPI_GET8(parser_state->aml) << 8); 549 (((u32) ACPI_GET8(parser_state->aml) << 8));
544 parser_state->aml++; 550 parser_state->aml++;
545 field->common.value.integer |= ACPI_GET8(parser_state->aml); 551 field->common.value.integer |= ACPI_GET8(parser_state->aml);
546 parser_state->aml++; 552 parser_state->aml++;