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
31 #define _COMPONENT ACPI_EXECUTER
32 MODULE_NAME ("amnames")
35 /* AML Package Length encodings */
37 #define ACPI_AML_PACKAGE_TYPE1 0x40
38 #define ACPI_AML_PACKAGE_TYPE2 0x4000
39 #define ACPI_AML_PACKAGE_TYPE3 0x400000
40 #define ACPI_AML_PACKAGE_TYPE4 0x40000000
43 /*******************************************************************************
45 * FUNCTION: Acpi_aml_allocate_name_string
47 * PARAMETERS: Prefix_count - Count of parent levels. Special cases:
48 * (-1) = root, 0 = none
49 * Num_name_segs - count of 4-character name segments
51 * RETURN: A pointer to the allocated string segment. This segment must
52 * be deleted by the caller.
54 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
55 * string is long enough, and set up prefix if any.
57 ******************************************************************************/
60 acpi_aml_allocate_name_string (
64 NATIVE_CHAR
*temp_ptr
;
65 NATIVE_CHAR
*name_string
;
70 * Allow room for all \ and ^ prefixes, all segments, and a Multi_name_prefix.
71 * Also, one byte for the null terminator.
72 * This may actually be somewhat longer than needed.
75 if (prefix_count
== (u32
) -1) {
76 /* Special case for root */
78 size_needed
= 1 + (ACPI_NAME_SIZE
* num_name_segs
) + 2 + 1;
81 size_needed
= prefix_count
+ (ACPI_NAME_SIZE
* num_name_segs
) + 2 + 1;
85 * Allocate a buffer for the name.
86 * This buffer must be deleted by the caller!
89 name_string
= acpi_cm_allocate (size_needed
);
91 REPORT_ERROR (("Aml_allocate_name_string: name allocation failure\n"));
95 temp_ptr
= name_string
;
97 /* Set up Root or Parent prefixes if needed */
99 if (prefix_count
== (u32
) -1) {
100 *temp_ptr
++ = AML_ROOT_PREFIX
;
104 while (prefix_count
--) {
105 *temp_ptr
++ = AML_PARENT_PREFIX
;
110 /* Set up Dual or Multi prefixes if needed */
112 if (num_name_segs
> 2) {
113 /* Set up multi prefixes */
115 *temp_ptr
++ = AML_MULTI_NAME_PREFIX_OP
;
116 *temp_ptr
++ = (char) num_name_segs
;
119 else if (2 == num_name_segs
) {
120 /* Set up dual prefixes */
122 *temp_ptr
++ = AML_DUAL_NAME_PREFIX
;
126 * Terminate string following prefixes. Acpi_aml_exec_name_segment() will
127 * append the segment(s)
132 return (name_string
);
135 /*******************************************************************************
137 * FUNCTION: Acpi_aml_exec_name_segment
139 * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec)
143 * DESCRIPTION: Execute a name segment (4 bytes)
145 ******************************************************************************/
148 acpi_aml_exec_name_segment (
150 NATIVE_CHAR
*name_string
)
152 u8
*aml_address
= *in_aml_address
;
153 ACPI_STATUS status
= AE_OK
;
155 NATIVE_CHAR char_buf
[5];
159 * If first character is a digit, then we know that we aren't looking at a
163 char_buf
[0] = *aml_address
;
165 if ('0' <= char_buf
[0] && char_buf
[0] <= '9') {
166 return (AE_CTRL_PENDING
);
170 (index
> 0) && (acpi_cm_valid_acpi_character (*aml_address
));
172 char_buf
[4 - index
] = *aml_address
++;
176 /* Valid name segment */
179 /* Found 4 valid characters */
184 STRCAT (name_string
, char_buf
);
189 else if (4 == index
) {
191 * First character was not a valid name character,
192 * so we are looking at something other than a name.
194 status
= AE_CTRL_PENDING
;
198 /* Segment started with one or more valid characters, but fewer than 4 */
200 status
= AE_AML_BAD_NAME
;
203 *in_aml_address
= aml_address
;
209 /*******************************************************************************
211 * FUNCTION: Acpi_aml_get_name_string
213 * PARAMETERS: Data_type - Data type to be associated with this name
217 * DESCRIPTION: Get a name, including any prefixes.
219 ******************************************************************************/
223 acpi_aml_get_name_string (
224 OBJECT_TYPE_INTERNAL data_type
,
226 NATIVE_CHAR
**out_name_string
,
227 u32
*out_name_length
)
229 ACPI_STATUS status
= AE_OK
;
230 u8
*aml_address
= in_aml_address
;
231 NATIVE_CHAR
*name_string
= NULL
;
233 u32 prefix_count
= 0;
235 u8 has_prefix
= FALSE
;
238 if (INTERNAL_TYPE_DEF_FIELD
== data_type
||
239 INTERNAL_TYPE_BANK_FIELD
== data_type
||
240 INTERNAL_TYPE_INDEX_FIELD
== data_type
) {
241 /* Disallow prefixes for types associated with field names */
243 name_string
= acpi_aml_allocate_name_string (0, 1);
245 status
= AE_NO_MEMORY
;
248 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
254 * Data_type is not a field name.
255 * Examine first character of name for root or parent prefix operators
258 switch (*aml_address
) {
260 case AML_ROOT_PREFIX
:
262 prefix
= *aml_address
++;
264 * Remember that we have a Root_prefix --
265 * see comment in Acpi_aml_allocate_name_string()
267 prefix_count
= (u32
) -1;
272 case AML_PARENT_PREFIX
:
274 /* Increment past possibly multiple parent prefixes */
277 prefix
= *aml_address
++;
280 } while (*aml_address
== AML_PARENT_PREFIX
);
291 /* Examine first character of name for name segment prefix operator */
293 switch (*aml_address
) {
295 case AML_DUAL_NAME_PREFIX
:
297 prefix
= *aml_address
++;
298 name_string
= acpi_aml_allocate_name_string (prefix_count
, 2);
300 status
= AE_NO_MEMORY
;
304 /* Indicate that we processed a prefix */
307 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
308 if (ACPI_SUCCESS (status
)) {
309 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
314 case AML_MULTI_NAME_PREFIX_OP
:
316 prefix
= *aml_address
++;
317 /* Fetch count of segments remaining in name path */
319 num_segments
= *aml_address
++;
321 name_string
= acpi_aml_allocate_name_string (prefix_count
, num_segments
);
323 status
= AE_NO_MEMORY
;
327 /* Indicate that we processed a prefix */
330 while (num_segments
&&
331 (status
= acpi_aml_exec_name_segment (&aml_address
, name_string
)) == AE_OK
) {
340 /* Null_name valid as of 8-12-98 ASL/AML Grammar Update */
343 /* Consume the NULL byte */
346 name_string
= acpi_aml_allocate_name_string (prefix_count
, 0);
348 status
= AE_NO_MEMORY
;
357 /* Name segment string */
359 name_string
= acpi_aml_allocate_name_string (prefix_count
, 1);
361 status
= AE_NO_MEMORY
;
365 status
= acpi_aml_exec_name_segment (&aml_address
, name_string
);
368 } /* Switch (Peek_op ()) */
372 if (AE_CTRL_PENDING
== status
&& has_prefix
) {
373 /* Ran out of segments after processing a prefix */
376 ("Aml_do_name: Malformed Name at %p\n", name_string
));
377 status
= AE_AML_BAD_NAME
;
381 *out_name_string
= name_string
;
382 *out_name_length
= (u32
) (aml_address
- in_aml_address
);