1 /******************************************************************************
3 * Module Name: psutils - Parser miscellaneous utilities (Parser only)
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT ACPI_PARSER
32 MODULE_NAME ("psutils")
35 #define PARSEOP_GENERIC 0x01
36 #define PARSEOP_NAMED 0x02
37 #define PARSEOP_DEFERRED 0x03
38 #define PARSEOP_BYTELIST 0x04
39 #define PARSEOP_IN_CACHE 0x80
42 /*******************************************************************************
44 * FUNCTION: Acpi_ps_init_op
46 * PARAMETERS: Op - A newly allocated Op object
47 * Opcode - Opcode to store in the Op
51 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
54 ******************************************************************************/
58 ACPI_PARSE_OBJECT
*op
,
61 ACPI_OPCODE_INFO
*aml_op
;
64 op
->data_type
= ACPI_DESC_TYPE_PARSER
;
67 aml_op
= acpi_ps_get_opcode_info (opcode
);
69 DEBUG_ONLY_MEMBERS (STRNCPY (op
->op_name
, aml_op
->name
,
70 sizeof (op
->op_name
)));
74 /*******************************************************************************
76 * FUNCTION: Acpi_ps_alloc_op
78 * PARAMETERS: Opcode - Opcode that will be stored in the new Op
80 * RETURN: Pointer to the new Op.
82 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
83 * opcode. A cache of opcodes is available for the pure
84 * GENERIC_OP, since this is by far the most commonly used.
86 ******************************************************************************/
92 ACPI_PARSE_OBJECT
*op
= NULL
;
97 /* Allocate the minimum required size object */
99 if (acpi_ps_is_deferred_op (opcode
)) {
100 size
= sizeof (ACPI_PARSE2_OBJECT
);
101 flags
= PARSEOP_DEFERRED
;
104 else if (acpi_ps_is_named_op (opcode
)) {
105 size
= sizeof (ACPI_PARSE2_OBJECT
);
106 flags
= PARSEOP_NAMED
;
109 else if (acpi_ps_is_bytelist_op (opcode
)) {
110 size
= sizeof (ACPI_PARSE2_OBJECT
);
111 flags
= PARSEOP_BYTELIST
;
115 size
= sizeof (ACPI_PARSE_OBJECT
);
116 flags
= PARSEOP_GENERIC
;
120 if (size
== sizeof (ACPI_PARSE_OBJECT
)) {
122 * The generic op is by far the most common (16 to 1), and therefore
123 * the op cache is implemented with this type.
125 * Check if there is an Op already available in the cache
128 acpi_cm_acquire_mutex (ACPI_MTX_CACHES
);
129 acpi_gbl_parse_cache_requests
++;
130 if (acpi_gbl_parse_cache
) {
131 /* Extract an op from the front of the cache list */
133 acpi_gbl_parse_cache_depth
--;
134 acpi_gbl_parse_cache_hits
++;
136 op
= acpi_gbl_parse_cache
;
137 acpi_gbl_parse_cache
= op
->next
;
140 /* Clear the previously used Op */
142 MEMSET (op
, 0, sizeof (ACPI_PARSE_OBJECT
));
145 acpi_cm_release_mutex (ACPI_MTX_CACHES
);
150 * The generic op is by far the most common (16 to 1), and therefore
151 * the op cache is implemented with this type.
153 * Check if there is an Op already available in the cache
156 acpi_cm_acquire_mutex (ACPI_MTX_CACHES
);
157 acpi_gbl_ext_parse_cache_requests
++;
158 if (acpi_gbl_ext_parse_cache
) {
159 /* Extract an op from the front of the cache list */
161 acpi_gbl_ext_parse_cache_depth
--;
162 acpi_gbl_ext_parse_cache_hits
++;
164 op
= (ACPI_PARSE_OBJECT
*) acpi_gbl_ext_parse_cache
;
165 acpi_gbl_ext_parse_cache
= (ACPI_PARSE2_OBJECT
*) op
->next
;
168 /* Clear the previously used Op */
170 MEMSET (op
, 0, sizeof (ACPI_PARSE2_OBJECT
));
173 acpi_cm_release_mutex (ACPI_MTX_CACHES
);
177 /* Allocate a new Op if necessary */
180 op
= acpi_cm_callocate (size
);
183 /* Initialize the Op */
185 acpi_ps_init_op (op
, opcode
);
193 /*******************************************************************************
195 * FUNCTION: Acpi_ps_free_op
197 * PARAMETERS: Op - Op to be freed
201 * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
202 * or actually free it.
204 ******************************************************************************/
208 ACPI_PARSE_OBJECT
*op
)
213 if (op
->flags
== PARSEOP_GENERIC
) {
214 /* Is the cache full? */
216 if (acpi_gbl_parse_cache_depth
< MAX_PARSE_CACHE_DEPTH
) {
217 /* Put a GENERIC_OP back into the cache */
219 /* Clear the previously used Op */
221 MEMSET (op
, 0, sizeof (ACPI_PARSE_OBJECT
));
222 op
->flags
= PARSEOP_IN_CACHE
;
224 acpi_cm_acquire_mutex (ACPI_MTX_CACHES
);
225 acpi_gbl_parse_cache_depth
++;
227 op
->next
= acpi_gbl_parse_cache
;
228 acpi_gbl_parse_cache
= op
;
230 acpi_cm_release_mutex (ACPI_MTX_CACHES
);
236 /* Is the cache full? */
238 if (acpi_gbl_ext_parse_cache_depth
< MAX_EXTPARSE_CACHE_DEPTH
) {
239 /* Put a GENERIC_OP back into the cache */
241 /* Clear the previously used Op */
243 MEMSET (op
, 0, sizeof (ACPI_PARSE2_OBJECT
));
244 op
->flags
= PARSEOP_IN_CACHE
;
246 acpi_cm_acquire_mutex (ACPI_MTX_CACHES
);
247 acpi_gbl_ext_parse_cache_depth
++;
249 op
->next
= (ACPI_PARSE_OBJECT
*) acpi_gbl_ext_parse_cache
;
250 acpi_gbl_ext_parse_cache
= (ACPI_PARSE2_OBJECT
*) op
;
252 acpi_cm_release_mutex (ACPI_MTX_CACHES
);
259 * Not a GENERIC OP, or the cache is full, just free the Op
266 /*******************************************************************************
268 * FUNCTION: Acpi_ps_delete_parse_cache
274 * DESCRIPTION: Free all objects that are on the parse cache list.
276 ******************************************************************************/
279 acpi_ps_delete_parse_cache (
282 ACPI_PARSE_OBJECT
*next
;
285 /* Traverse the global cache list */
287 while (acpi_gbl_parse_cache
) {
288 /* Delete one cached state object */
290 next
= acpi_gbl_parse_cache
->next
;
291 acpi_cm_free (acpi_gbl_parse_cache
);
292 acpi_gbl_parse_cache
= next
;
293 acpi_gbl_parse_cache_depth
--;
296 /* Traverse the global cache list */
298 while (acpi_gbl_ext_parse_cache
) {
299 /* Delete one cached state object */
301 next
= acpi_gbl_ext_parse_cache
->next
;
302 acpi_cm_free (acpi_gbl_ext_parse_cache
);
303 acpi_gbl_ext_parse_cache
= (ACPI_PARSE2_OBJECT
*) next
;
304 acpi_gbl_ext_parse_cache_depth
--;
311 /*******************************************************************************
313 * FUNCTION: Utility functions
315 * DESCRIPTION: Low level functions
318 * 1) Some of these functions should be macros
319 * 2) Some can be simplified
321 ******************************************************************************/
325 * Is "c" a namestring lead character?
330 acpi_ps_is_leading_char (
333 return ((u8
) (c
== '_' || (c
>= 'A' && c
<= 'Z')));
338 * Is "c" a namestring prefix character?
341 acpi_ps_is_prefix_char (
344 return ((u8
) (c
== '\\' || c
== '^'));
349 acpi_ps_is_namespace_object_op (
353 (opcode
== AML_SCOPE_OP
||
354 opcode
== AML_DEVICE_OP
||
355 opcode
== AML_THERMAL_ZONE_OP
||
356 opcode
== AML_METHOD_OP
||
357 opcode
== AML_POWER_RES_OP
||
358 opcode
== AML_PROCESSOR_OP
||
359 opcode
== AML_DEF_FIELD_OP
||
360 opcode
== AML_INDEX_FIELD_OP
||
361 opcode
== AML_BANK_FIELD_OP
||
362 opcode
== AML_NAMEDFIELD_OP
||
363 opcode
== AML_NAME_OP
||
364 opcode
== AML_ALIAS_OP
||
365 opcode
== AML_MUTEX_OP
||
366 opcode
== AML_EVENT_OP
||
367 opcode
== AML_REGION_OP
||
368 opcode
== AML_CREATE_FIELD_OP
||
369 opcode
== AML_BIT_FIELD_OP
||
370 opcode
== AML_BYTE_FIELD_OP
||
371 opcode
== AML_WORD_FIELD_OP
||
372 opcode
== AML_DWORD_FIELD_OP
||
373 opcode
== AML_METHODCALL_OP
||
374 opcode
== AML_NAMEPATH_OP
));
378 acpi_ps_is_namespace_op (
382 (opcode
== AML_SCOPE_OP
||
383 opcode
== AML_DEVICE_OP
||
384 opcode
== AML_THERMAL_ZONE_OP
||
385 opcode
== AML_METHOD_OP
||
386 opcode
== AML_POWER_RES_OP
||
387 opcode
== AML_PROCESSOR_OP
||
388 opcode
== AML_DEF_FIELD_OP
||
389 opcode
== AML_INDEX_FIELD_OP
||
390 opcode
== AML_BANK_FIELD_OP
||
391 opcode
== AML_NAME_OP
||
392 opcode
== AML_ALIAS_OP
||
393 opcode
== AML_MUTEX_OP
||
394 opcode
== AML_EVENT_OP
||
395 opcode
== AML_REGION_OP
||
396 opcode
== AML_NAMEDFIELD_OP
));
401 * Is opcode for a named object Op?
402 * (Includes all named object opcodes)
404 * TBD: [Restructure] Need a better way than this brute force approach!
411 (opcode
== AML_SCOPE_OP
||
412 opcode
== AML_DEVICE_OP
||
413 opcode
== AML_THERMAL_ZONE_OP
||
414 opcode
== AML_METHOD_OP
||
415 opcode
== AML_POWER_RES_OP
||
416 opcode
== AML_PROCESSOR_OP
||
417 opcode
== AML_NAMEDFIELD_OP
||
418 opcode
== AML_NAME_OP
||
419 opcode
== AML_ALIAS_OP
||
420 opcode
== AML_MUTEX_OP
||
421 opcode
== AML_EVENT_OP
||
422 opcode
== AML_REGION_OP
||
425 opcode
== AML_CREATE_FIELD_OP
||
426 opcode
== AML_BIT_FIELD_OP
||
427 opcode
== AML_BYTE_FIELD_OP
||
428 opcode
== AML_WORD_FIELD_OP
||
429 opcode
== AML_DWORD_FIELD_OP
||
430 opcode
== AML_METHODCALL_OP
||
431 opcode
== AML_NAMEPATH_OP
));
436 * Is opcode for a named Op?
439 acpi_ps_is_named_op (
443 (opcode
== AML_SCOPE_OP
||
444 opcode
== AML_DEVICE_OP
||
445 opcode
== AML_THERMAL_ZONE_OP
||
446 opcode
== AML_METHOD_OP
||
447 opcode
== AML_POWER_RES_OP
||
448 opcode
== AML_PROCESSOR_OP
||
449 opcode
== AML_NAME_OP
||
450 opcode
== AML_ALIAS_OP
||
451 opcode
== AML_MUTEX_OP
||
452 opcode
== AML_EVENT_OP
||
453 opcode
== AML_REGION_OP
||
454 opcode
== AML_NAMEDFIELD_OP
));
459 acpi_ps_is_deferred_op (
463 (opcode
== AML_METHOD_OP
||
464 opcode
== AML_CREATE_FIELD_OP
||
465 opcode
== AML_BIT_FIELD_OP
||
466 opcode
== AML_BYTE_FIELD_OP
||
467 opcode
== AML_WORD_FIELD_OP
||
468 opcode
== AML_DWORD_FIELD_OP
||
469 opcode
== AML_REGION_OP
));
474 * Is opcode for a bytelist?
477 acpi_ps_is_bytelist_op (
480 return ((u8
) (opcode
== AML_BYTELIST_OP
));
485 * Is opcode for a Field, Index_field, or Bank_field
488 acpi_ps_is_field_op (
492 (opcode
== AML_CREATE_FIELD_OP
493 || opcode
== AML_DEF_FIELD_OP
494 || opcode
== AML_INDEX_FIELD_OP
495 || opcode
== AML_BANK_FIELD_OP
));
500 * Is field creation op
503 acpi_ps_is_create_field_op (
507 (opcode
== AML_CREATE_FIELD_OP
||
508 opcode
== AML_BIT_FIELD_OP
||
509 opcode
== AML_BYTE_FIELD_OP
||
510 opcode
== AML_WORD_FIELD_OP
||
511 opcode
== AML_DWORD_FIELD_OP
));
516 * Cast an acpi_op to an acpi_extended_op if possible
519 /* TBD: This is very inefficient, fix */
521 acpi_ps_to_extended_op (
522 ACPI_PARSE_OBJECT
*op
)
524 return ((acpi_ps_is_deferred_op (op
->opcode
) || acpi_ps_is_named_op (op
->opcode
) || acpi_ps_is_bytelist_op (op
->opcode
))
525 ? ( (ACPI_PARSE2_OBJECT
*) op
) : NULL
);
530 * Get op's name (4-byte name segment) or 0 if unnamed
534 ACPI_PARSE_OBJECT
*op
)
536 ACPI_PARSE2_OBJECT
*named
= acpi_ps_to_extended_op (op
);
538 return (named
? named
->name
: 0);
547 ACPI_PARSE_OBJECT
*op
,
550 ACPI_PARSE2_OBJECT
*named
= acpi_ps_to_extended_op (op
);