at v2.6.13 306 lines 7.9 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: psutils - Parser miscellaneous utilities (Parser only) 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2005, R. Byron Moore 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45#include <acpi/acpi.h> 46#include <acpi/acparser.h> 47#include <acpi/amlcode.h> 48 49#define _COMPONENT ACPI_PARSER 50 ACPI_MODULE_NAME ("psutils") 51 52 53/******************************************************************************* 54 * 55 * FUNCTION: acpi_ps_create_scope_op 56 * 57 * PARAMETERS: None 58 * 59 * RETURN: A new Scope object, null on failure 60 * 61 * DESCRIPTION: Create a Scope and associated namepath op with the root name 62 * 63 ******************************************************************************/ 64 65union acpi_parse_object * 66acpi_ps_create_scope_op ( 67 void) 68{ 69 union acpi_parse_object *scope_op; 70 71 72 scope_op = acpi_ps_alloc_op (AML_SCOPE_OP); 73 if (!scope_op) { 74 return (NULL); 75 } 76 77 scope_op->named.name = ACPI_ROOT_NAME; 78 return (scope_op); 79} 80 81 82/******************************************************************************* 83 * 84 * FUNCTION: acpi_ps_init_op 85 * 86 * PARAMETERS: Op - A newly allocated Op object 87 * Opcode - Opcode to store in the Op 88 * 89 * RETURN: None 90 * 91 * DESCRIPTION: Initialize a parse (Op) object 92 * 93 ******************************************************************************/ 94 95void 96acpi_ps_init_op ( 97 union acpi_parse_object *op, 98 u16 opcode) 99{ 100 ACPI_FUNCTION_ENTRY (); 101 102 103 op->common.data_type = ACPI_DESC_TYPE_PARSER; 104 op->common.aml_opcode = opcode; 105 106 ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name, 107 (acpi_ps_get_opcode_info (opcode))->name, 108 sizeof (op->common.aml_op_name))); 109} 110 111 112/******************************************************************************* 113 * 114 * FUNCTION: acpi_ps_alloc_op 115 * 116 * PARAMETERS: Opcode - Opcode that will be stored in the new Op 117 * 118 * RETURN: Pointer to the new Op, null on failure 119 * 120 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on 121 * opcode. A cache of opcodes is available for the pure 122 * GENERIC_OP, since this is by far the most commonly used. 123 * 124 ******************************************************************************/ 125 126union acpi_parse_object* 127acpi_ps_alloc_op ( 128 u16 opcode) 129{ 130 union acpi_parse_object *op; 131 const struct acpi_opcode_info *op_info; 132 u8 flags = ACPI_PARSEOP_GENERIC; 133 134 135 ACPI_FUNCTION_ENTRY (); 136 137 138 op_info = acpi_ps_get_opcode_info (opcode); 139 140 /* Determine type of parse_op required */ 141 142 if (op_info->flags & AML_DEFER) { 143 flags = ACPI_PARSEOP_DEFERRED; 144 } 145 else if (op_info->flags & AML_NAMED) { 146 flags = ACPI_PARSEOP_NAMED; 147 } 148 else if (opcode == AML_INT_BYTELIST_OP) { 149 flags = ACPI_PARSEOP_BYTELIST; 150 } 151 152 /* Allocate the minimum required size object */ 153 154 if (flags == ACPI_PARSEOP_GENERIC) { 155 /* The generic op (default) is by far the most common (16 to 1) */ 156 157 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE); 158 } 159 else { 160 /* Extended parseop */ 161 162 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT); 163 } 164 165 /* Initialize the Op */ 166 167 if (op) { 168 acpi_ps_init_op (op, opcode); 169 op->common.flags = flags; 170 } 171 172 return (op); 173} 174 175 176/******************************************************************************* 177 * 178 * FUNCTION: acpi_ps_free_op 179 * 180 * PARAMETERS: Op - Op to be freed 181 * 182 * RETURN: None. 183 * 184 * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list 185 * or actually free it. 186 * 187 ******************************************************************************/ 188 189void 190acpi_ps_free_op ( 191 union acpi_parse_object *op) 192{ 193 ACPI_FUNCTION_NAME ("ps_free_op"); 194 195 196 if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 197 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", op)); 198 } 199 200 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 201 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op); 202 } 203 else { 204 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op); 205 } 206} 207 208 209#ifdef ACPI_ENABLE_OBJECT_CACHE 210/******************************************************************************* 211 * 212 * FUNCTION: acpi_ps_delete_parse_cache 213 * 214 * PARAMETERS: None 215 * 216 * RETURN: None 217 * 218 * DESCRIPTION: Free all objects that are on the parse cache list. 219 * 220 ******************************************************************************/ 221 222void 223acpi_ps_delete_parse_cache ( 224 void) 225{ 226 ACPI_FUNCTION_TRACE ("ps_delete_parse_cache"); 227 228 229 acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE); 230 acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT); 231 return_VOID; 232} 233#endif 234 235 236/******************************************************************************* 237 * 238 * FUNCTION: Utility functions 239 * 240 * DESCRIPTION: Low level character and object functions 241 * 242 ******************************************************************************/ 243 244 245/* 246 * Is "c" a namestring lead character? 247 */ 248u8 249acpi_ps_is_leading_char ( 250 u32 c) 251{ 252 return ((u8) (c == '_' || (c >= 'A' && c <= 'Z'))); 253} 254 255 256/* 257 * Is "c" a namestring prefix character? 258 */ 259u8 260acpi_ps_is_prefix_char ( 261 u32 c) 262{ 263 return ((u8) (c == '\\' || c == '^')); 264} 265 266 267/* 268 * Get op's name (4-byte name segment) or 0 if unnamed 269 */ 270#ifdef ACPI_FUTURE_USAGE 271u32 272acpi_ps_get_name ( 273 union acpi_parse_object *op) 274{ 275 276 /* The "generic" object has no name associated with it */ 277 278 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 279 return (0); 280 } 281 282 /* Only the "Extended" parse objects have a name */ 283 284 return (op->named.name); 285} 286#endif /* ACPI_FUTURE_USAGE */ 287 288 289/* 290 * Set op's name 291 */ 292void 293acpi_ps_set_name ( 294 union acpi_parse_object *op, 295 u32 name) 296{ 297 298 /* The "generic" object has no name associated with it */ 299 300 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 301 return; 302 } 303 304 op->named.name = name; 305} 306