2 /******************************************************************************
4 * Module Name: amnames - interpreter/scanner name load/execute
7 *****************************************************************************/
10 * Copyright (C) 2000 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 INTERPRETER
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
));
175 char_buf
[4 - index
] = *aml_address
++;
179 /* Valid name segment */
182 /* Found 4 valid characters */
187 STRCAT (name_string
, char_buf
);
192 else if (4 == index
) {
194 * First character was not a valid name character,
195 * so we are looking at something other than a name.
197 status
= AE_CTRL_PENDING
;
201 /* Segment started with one or more valid characters, but fewer than 4 */
203 status
= AE_AML_BAD_NAME
;
206 *in_aml_address
= aml_address
;
212 /*******************************************************************************
214 * FUNCTION: Acpi_aml_get_name_string
216 * PARAMETERS: Data_type - Data type to be associated with this name
220 * DESCRIPTION: Get a name, including any prefixes.
222 ******************************************************************************/
226 acpi_aml_get_name_string (
227 OBJECT_TYPE_INTERNAL data_type
,
229 NATIVE_CHAR
**out_name_string
,
230 u32
*out_name_length
)
232 ACPI_STATUS status
= AE_OK
;
233 u8
*aml_address
= in_aml_address
;
234 NATIVE_CHAR
*name_string
= NULL
;
236 u32 prefix_count
= 0;
238 u8 has_prefix
= FALSE
;
241 if (INTERNAL_TYPE_DEF_FIELD
== data_type
||
242 INTERNAL_TYPE_BANK_FIELD
== data_type
||
243 INTERNAL_TYPE_INDEX_FIELD
== data_type
)
245 /* Disallow prefixes for types associated with field names */
247 name_string
= acpi_aml_allocate_name_string (0, 1);
249 status
= AE_NO_MEMORY
;
252 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
258 * Data_type is not a field name.
259 * Examine first character of name for root or parent prefix operators
262 switch (*aml_address
)
265 case AML_ROOT_PREFIX
:
267 prefix
= *aml_address
++;
269 * Remember that we have a Root_prefix --
270 * see comment in Acpi_aml_allocate_name_string()
272 prefix_count
= (u32
) -1;
277 case AML_PARENT_PREFIX
:
279 /* Increment past possibly multiple parent prefixes */
283 prefix
= *aml_address
++;
286 } while (*aml_address
== AML_PARENT_PREFIX
);
297 /* Examine first character of name for name segment prefix operator */
299 switch (*aml_address
)
302 case AML_DUAL_NAME_PREFIX
:
304 prefix
= *aml_address
++;
305 name_string
= acpi_aml_allocate_name_string (prefix_count
, 2);
307 status
= AE_NO_MEMORY
;
311 /* Indicate that we processed a prefix */
314 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
315 if (ACPI_SUCCESS (status
)) {
316 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
321 case AML_MULTI_NAME_PREFIX_OP
:
323 prefix
= *aml_address
++;
324 /* Fetch count of segments remaining in name path */
326 num_segments
= *aml_address
++;
328 name_string
= acpi_aml_allocate_name_string (prefix_count
, num_segments
);
330 status
= AE_NO_MEMORY
;
334 /* Indicate that we processed a prefix */
337 while (num_segments
&&
338 (status
= acpi_aml_exec_name_segment (&aml_address
, name_string
)) == AE_OK
)
348 /* Null_name valid as of 8-12-98 ASL/AML Grammar Update */
351 /* Consume the NULL byte */
354 name_string
= acpi_aml_allocate_name_string (prefix_count
, 0);
356 status
= AE_NO_MEMORY
;
365 /* Name segment string */
367 name_string
= acpi_aml_allocate_name_string (prefix_count
, 1);
369 status
= AE_NO_MEMORY
;
373 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
376 } /* Switch (Peek_op ()) */
380 if (AE_CTRL_PENDING
== status
&& has_prefix
) {
381 /* Ran out of segments after processing a prefix */
384 ("Aml_do_name: Malformed Name at %p\n", name_string
));
385 status
= AE_AML_BAD_NAME
;
389 *out_name_string
= name_string
;
390 *out_name_length
= (u32
) (aml_address
- in_aml_address
);