2 /******************************************************************************
4 * Module Name: amnames - interpreter/scanner name load/execute
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #define _COMPONENT ACPI_EXECUTER
34 MODULE_NAME ("amnames")
37 /* AML Package Length encodings */
39 #define ACPI_AML_PACKAGE_TYPE1 0x40
40 #define ACPI_AML_PACKAGE_TYPE2 0x4000
41 #define ACPI_AML_PACKAGE_TYPE3 0x400000
42 #define ACPI_AML_PACKAGE_TYPE4 0x40000000
45 /*******************************************************************************
47 * FUNCTION: Acpi_aml_allocate_name_string
49 * PARAMETERS: Prefix_count - Count of parent levels. Special cases:
50 * (-1) = root, 0 = none
51 * Num_name_segs - count of 4-character name segments
53 * RETURN: A pointer to the allocated string segment. This segment must
54 * be deleted by the caller.
56 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
57 * string is long enough, and set up prefix if any.
59 ******************************************************************************/
62 acpi_aml_allocate_name_string (
66 NATIVE_CHAR
*temp_ptr
;
67 NATIVE_CHAR
*name_string
;
72 * Allow room for all \ and ^ prefixes, all segments, and a Multi_name_prefix.
73 * Also, one byte for the null terminator.
74 * This may actually be somewhat longer than needed.
77 if (prefix_count
== (u32
) -1) {
78 /* Special case for root */
80 size_needed
= 1 + (ACPI_NAME_SIZE
* num_name_segs
) + 2 + 1;
83 size_needed
= prefix_count
+ (ACPI_NAME_SIZE
* num_name_segs
) + 2 + 1;
87 * Allocate a buffer for the name.
88 * This buffer must be deleted by the caller!
91 name_string
= acpi_cm_allocate (size_needed
);
93 REPORT_ERROR (("Aml_allocate_name_string: name allocation failure\n"));
97 temp_ptr
= name_string
;
99 /* Set up Root or Parent prefixes if needed */
101 if (prefix_count
== (u32
) -1) {
102 *temp_ptr
++ = AML_ROOT_PREFIX
;
106 while (prefix_count
--) {
107 *temp_ptr
++ = AML_PARENT_PREFIX
;
112 /* Set up Dual or Multi prefixes if needed */
114 if (num_name_segs
> 2) {
115 /* Set up multi prefixes */
117 *temp_ptr
++ = AML_MULTI_NAME_PREFIX_OP
;
118 *temp_ptr
++ = (char) num_name_segs
;
121 else if (2 == num_name_segs
) {
122 /* Set up dual prefixes */
124 *temp_ptr
++ = AML_DUAL_NAME_PREFIX
;
128 * Terminate string following prefixes. Acpi_aml_exec_name_segment() will
129 * append the segment(s)
134 return (name_string
);
137 /*******************************************************************************
139 * FUNCTION: Acpi_aml_exec_name_segment
141 * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec)
145 * DESCRIPTION: Execute a name segment (4 bytes)
147 ******************************************************************************/
150 acpi_aml_exec_name_segment (
152 NATIVE_CHAR
*name_string
)
154 u8
*aml_address
= *in_aml_address
;
155 ACPI_STATUS status
= AE_OK
;
157 NATIVE_CHAR char_buf
[5];
161 * If first character is a digit, then we know that we aren't looking at a
165 char_buf
[0] = *aml_address
;
167 if ('0' <= char_buf
[0] && char_buf
[0] <= '9') {
168 return (AE_CTRL_PENDING
);
172 (index
> 0) && (acpi_cm_valid_acpi_character (*aml_address
));
174 char_buf
[4 - index
] = *aml_address
++;
178 /* Valid name segment */
181 /* Found 4 valid characters */
186 STRCAT (name_string
, char_buf
);
191 else if (4 == index
) {
193 * First character was not a valid name character,
194 * so we are looking at something other than a name.
196 status
= AE_CTRL_PENDING
;
200 /* Segment started with one or more valid characters, but fewer than 4 */
202 status
= AE_AML_BAD_NAME
;
205 *in_aml_address
= aml_address
;
211 /*******************************************************************************
213 * FUNCTION: Acpi_aml_get_name_string
215 * PARAMETERS: Data_type - Data type to be associated with this name
219 * DESCRIPTION: Get a name, including any prefixes.
221 ******************************************************************************/
225 acpi_aml_get_name_string (
226 OBJECT_TYPE_INTERNAL data_type
,
228 NATIVE_CHAR
**out_name_string
,
229 u32
*out_name_length
)
231 ACPI_STATUS status
= AE_OK
;
232 u8
*aml_address
= in_aml_address
;
233 NATIVE_CHAR
*name_string
= NULL
;
235 u32 prefix_count
= 0;
237 u8 has_prefix
= FALSE
;
240 if (INTERNAL_TYPE_DEF_FIELD
== data_type
||
241 INTERNAL_TYPE_BANK_FIELD
== data_type
||
242 INTERNAL_TYPE_INDEX_FIELD
== data_type
) {
243 /* Disallow prefixes for types associated with field names */
245 name_string
= acpi_aml_allocate_name_string (0, 1);
247 status
= AE_NO_MEMORY
;
250 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
256 * Data_type is not a field name.
257 * Examine first character of name for root or parent prefix operators
260 switch (*aml_address
) {
262 case AML_ROOT_PREFIX
:
264 prefix
= *aml_address
++;
266 * Remember that we have a Root_prefix --
267 * see comment in Acpi_aml_allocate_name_string()
269 prefix_count
= (u32
) -1;
274 case AML_PARENT_PREFIX
:
276 /* Increment past possibly multiple parent prefixes */
279 prefix
= *aml_address
++;
282 } while (*aml_address
== AML_PARENT_PREFIX
);
293 /* Examine first character of name for name segment prefix operator */
295 switch (*aml_address
) {
297 case AML_DUAL_NAME_PREFIX
:
299 prefix
= *aml_address
++;
300 name_string
= acpi_aml_allocate_name_string (prefix_count
, 2);
302 status
= AE_NO_MEMORY
;
306 /* Indicate that we processed a prefix */
309 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
310 if (ACPI_SUCCESS (status
)) {
311 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
316 case AML_MULTI_NAME_PREFIX_OP
:
318 prefix
= *aml_address
++;
319 /* Fetch count of segments remaining in name path */
321 num_segments
= *aml_address
++;
323 name_string
= acpi_aml_allocate_name_string (prefix_count
, num_segments
);
325 status
= AE_NO_MEMORY
;
329 /* Indicate that we processed a prefix */
332 while (num_segments
&&
333 (status
= acpi_aml_exec_name_segment (&aml_address
, name_string
)) == AE_OK
) {
342 /* Null_name valid as of 8-12-98 ASL/AML Grammar Update */
345 /* Consume the NULL byte */
348 name_string
= acpi_aml_allocate_name_string (prefix_count
, 0);
350 status
= AE_NO_MEMORY
;
359 /* Name segment string */
361 name_string
= acpi_aml_allocate_name_string (prefix_count
, 1);
363 status
= AE_NO_MEMORY
;
367 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
370 } /* Switch (Peek_op ()) */
374 if (AE_CTRL_PENDING
== status
&& has_prefix
) {
375 /* Ran out of segments after processing a prefix */
378 ("Aml_do_name: Malformed Name at %p\n", name_string
));
379 status
= AE_AML_BAD_NAME
;
383 *out_name_string
= name_string
;
384 *out_name_length
= (u32
) (aml_address
- in_aml_address
);