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.c152
1 files changed, 72 insertions, 80 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 562d0f822ab1..6eae35febccd 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -62,61 +62,51 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
62 * 62 *
63 * PARAMETERS: parser_state - Current parser state object 63 * PARAMETERS: parser_state - Current parser state object
64 * 64 *
65 * RETURN: Decoded package length. On completion, the AML pointer points 65 * RETURN: Decoded package length. On completion, the AML pointer points
66 * past the length byte or bytes. 66 * past the length byte or bytes.
67 * 67 *
68 * DESCRIPTION: Decode and return a package length field 68 * DESCRIPTION: Decode and return a package length field.
69 * Note: Largest package length is 28 bits, from ACPI specification
69 * 70 *
70 ******************************************************************************/ 71 ******************************************************************************/
71 72
72static u32 73static u32
73acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 74acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
74{ 75{
75 u32 encoded_length; 76 u8 *aml = parser_state->aml;
76 u32 length = 0; 77 u32 package_length = 0;
78 acpi_native_uint byte_count;
79 u8 byte_zero_mask = 0x3F; /* Default [0:5] */
77 80
78 ACPI_FUNCTION_TRACE("ps_get_next_package_length"); 81 ACPI_FUNCTION_TRACE("ps_get_next_package_length");
79 82
80 encoded_length = (u32) ACPI_GET8(parser_state->aml); 83 /*
81 parser_state->aml++; 84 * Byte 0 bits [6:7] contain the number of additional bytes
82 85 * used to encode the package length, either 0,1,2, or 3
83 switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */ 86 */
84 case 0: /* 1-byte encoding (bits 0-5) */ 87 byte_count = (aml[0] >> 6);
85 88 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
104 case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
105 89
106 length = ((ACPI_GET8(parser_state->aml + 2) << 20) | 90 /* Get bytes 3, 2, 1 as needed */
107 (ACPI_GET8(parser_state->aml + 1) << 12) |
108 (ACPI_GET8(parser_state->aml) << 04) |
109 (encoded_length & 0x0F));
110 parser_state->aml += 3;
111 break;
112 91
113 default: 92 while (byte_count) {
93 /*
94 * Final bit positions for the package length bytes:
95 * Byte3->[20:27]
96 * Byte2->[12:19]
97 * Byte1->[04:11]
98 * Byte0->[00:03]
99 */
100 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
114 101
115 /* Can't get here, only 2 bits / 4 cases */ 102 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
116 break; 103 byte_count--;
117 } 104 }
118 105
119 return_UINT32(length); 106 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
107
108 package_length |= (aml[0] & byte_zero_mask);
109 return_UINT32(package_length);
120} 110}
121 111
122/******************************************************************************* 112/*******************************************************************************
@@ -135,16 +125,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) 125u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
136{ 126{
137 u8 *start = parser_state->aml; 127 u8 *start = parser_state->aml;
138 acpi_native_uint length; 128 u32 package_length;
139 129
140 ACPI_FUNCTION_TRACE("ps_get_next_package_end"); 130 ACPI_FUNCTION_TRACE("ps_get_next_package_end");
141 131
142 /* Function below changes parser_state->Aml */ 132 /* Function below updates parser_state->Aml */
143 133
144 length = 134 package_length = acpi_ps_get_next_package_length(parser_state);
145 (acpi_native_uint) acpi_ps_get_next_package_length(parser_state);
146 135
147 return_PTR(start + length); /* end of package */ 136 return_PTR(start + package_length); /* end of package */
148} 137}
149 138
150/******************************************************************************* 139/*******************************************************************************
@@ -169,17 +158,15 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
169 158
170 ACPI_FUNCTION_TRACE("ps_get_next_namestring"); 159 ACPI_FUNCTION_TRACE("ps_get_next_namestring");
171 160
172 /* Handle multiple prefix characters */ 161 /* 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 162
163 while (acpi_ps_is_prefix_char(*end)) {
177 end++; 164 end++;
178 } 165 }
179 166
180 /* Decode the path */ 167 /* Decode the path prefix character */
181 168
182 switch (ACPI_GET8(end)) { 169 switch (*end) {
183 case 0: 170 case 0:
184 171
185 /* null_name */ 172 /* null_name */
@@ -199,9 +186,9 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
199 186
200 case AML_MULTI_NAME_PREFIX_OP: 187 case AML_MULTI_NAME_PREFIX_OP:
201 188
202 /* Multiple name segments, 4 chars each */ 189 /* Multiple name segments, 4 chars each, count in next byte */
203 190
204 end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE); 191 end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
205 break; 192 break;
206 193
207 default: 194 default:
@@ -212,7 +199,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
212 break; 199 break;
213 } 200 }
214 201
215 parser_state->aml = (u8 *) end; 202 parser_state->aml = end;
216 return_PTR((char *)start); 203 return_PTR((char *)start);
217} 204}
218 205
@@ -342,7 +329,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
342 ("search_node %p start_node %p return_node %p\n", 329 ("search_node %p start_node %p return_node %p\n",
343 scope_info.scope.node, 330 scope_info.scope.node,
344 parser_state->start_node, node); 331 parser_state->start_node, node);
345
346 } else { 332 } else {
347 /* 333 /*
348 * We got a NOT_FOUND during table load or we encountered 334 * We got a NOT_FOUND during table load or we encountered
@@ -382,59 +368,63 @@ void
382acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 368acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
383 u32 arg_type, union acpi_parse_object *arg) 369 u32 arg_type, union acpi_parse_object *arg)
384{ 370{
371 u32 length;
372 u16 opcode;
373 u8 *aml = parser_state->aml;
385 374
386 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); 375 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);
387 376
388 switch (arg_type) { 377 switch (arg_type) {
389 case ARGP_BYTEDATA: 378 case ARGP_BYTEDATA:
390 379
391 acpi_ps_init_op(arg, AML_BYTE_OP); 380 /* Get 1 byte from the AML stream */
392 arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml); 381
393 parser_state->aml++; 382 opcode = AML_BYTE_OP;
383 arg->common.value.integer = (acpi_integer) * aml;
384 length = 1;
394 break; 385 break;
395 386
396 case ARGP_WORDDATA: 387 case ARGP_WORDDATA:
397 388
398 acpi_ps_init_op(arg, AML_WORD_OP);
399
400 /* Get 2 bytes from the AML stream */ 389 /* Get 2 bytes from the AML stream */
401 390
402 ACPI_MOVE_16_TO_32(&arg->common.value.integer, 391 opcode = AML_WORD_OP;
403 parser_state->aml); 392 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
404 parser_state->aml += 2; 393 length = 2;
405 break; 394 break;
406 395
407 case ARGP_DWORDDATA: 396 case ARGP_DWORDDATA:
408 397
409 acpi_ps_init_op(arg, AML_DWORD_OP);
410
411 /* Get 4 bytes from the AML stream */ 398 /* Get 4 bytes from the AML stream */
412 399
413 ACPI_MOVE_32_TO_32(&arg->common.value.integer, 400 opcode = AML_DWORD_OP;
414 parser_state->aml); 401 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
415 parser_state->aml += 4; 402 length = 4;
416 break; 403 break;
417 404
418 case ARGP_QWORDDATA: 405 case ARGP_QWORDDATA:
419 406
420 acpi_ps_init_op(arg, AML_QWORD_OP);
421
422 /* Get 8 bytes from the AML stream */ 407 /* Get 8 bytes from the AML stream */
423 408
424 ACPI_MOVE_64_TO_64(&arg->common.value.integer, 409 opcode = AML_QWORD_OP;
425 parser_state->aml); 410 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
426 parser_state->aml += 8; 411 length = 8;
427 break; 412 break;
428 413
429 case ARGP_CHARLIST: 414 case ARGP_CHARLIST:
430 415
431 acpi_ps_init_op(arg, AML_STRING_OP); 416 /* Get a pointer to the string, point past the string */
432 arg->common.value.string = (char *)parser_state->aml; 417
418 opcode = AML_STRING_OP;
419 arg->common.value.string = ACPI_CAST_PTR(char, aml);
433 420
434 while (ACPI_GET8(parser_state->aml) != '\0') { 421 /* Find the null terminator */
435 parser_state->aml++; 422
423 length = 0;
424 while (aml[length]) {
425 length++;
436 } 426 }
437 parser_state->aml++; 427 length++;
438 break; 428 break;
439 429
440 case ARGP_NAME: 430 case ARGP_NAME:
@@ -443,14 +433,16 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
443 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 433 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
444 arg->common.value.name = 434 arg->common.value.name =
445 acpi_ps_get_next_namestring(parser_state); 435 acpi_ps_get_next_namestring(parser_state);
446 break; 436 return_VOID;
447 437
448 default: 438 default:
449 439
450 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); 440 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type));
451 break; 441 return_VOID;
452 } 442 }
453 443
444 acpi_ps_init_op(arg, opcode);
445 parser_state->aml += length;
454 return_VOID; 446 return_VOID;
455} 447}
456 448
@@ -540,7 +532,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 532 * access_type is first operand, access_attribute is second
541 */ 533 */
542 field->common.value.integer = 534 field->common.value.integer =
543 (ACPI_GET8(parser_state->aml) << 8); 535 (((u32) ACPI_GET8(parser_state->aml) << 8));
544 parser_state->aml++; 536 parser_state->aml++;
545 field->common.value.integer |= ACPI_GET8(parser_state->aml); 537 field->common.value.integer |= ACPI_GET8(parser_state->aml);
546 parser_state->aml++; 538 parser_state->aml++;