Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 : : /****************************************************************************** 3 : : * 4 : : * Module Name: psutils - Parser miscellaneous utilities (Parser only) 5 : : * 6 : : * Copyright (C) 2000 - 2020, Intel Corp. 7 : : * 8 : : *****************************************************************************/ 9 : : 10 : : #include <acpi/acpi.h> 11 : : #include "accommon.h" 12 : : #include "acparser.h" 13 : : #include "amlcode.h" 14 : : #include "acconvert.h" 15 : : 16 : : #define _COMPONENT ACPI_PARSER 17 : : ACPI_MODULE_NAME("psutils") 18 : : 19 : : /******************************************************************************* 20 : : * 21 : : * FUNCTION: acpi_ps_create_scope_op 22 : : * 23 : : * PARAMETERS: None 24 : : * 25 : : * RETURN: A new Scope object, null on failure 26 : : * 27 : : * DESCRIPTION: Create a Scope and associated namepath op with the root name 28 : : * 29 : : ******************************************************************************/ 30 : 219 : union acpi_parse_object *acpi_ps_create_scope_op(u8 *aml) 31 : : { 32 : 219 : union acpi_parse_object *scope_op; 33 : : 34 : 219 : scope_op = acpi_ps_alloc_op(AML_SCOPE_OP, aml); 35 [ + - ]: 219 : if (!scope_op) { 36 : : return (NULL); 37 : : } 38 : : 39 : 219 : scope_op->named.name = ACPI_ROOT_NAME; 40 : 219 : return (scope_op); 41 : : } 42 : : 43 : : /******************************************************************************* 44 : : * 45 : : * FUNCTION: acpi_ps_init_op 46 : : * 47 : : * PARAMETERS: op - A newly allocated Op object 48 : : * opcode - Opcode to store in the Op 49 : : * 50 : : * RETURN: None 51 : : * 52 : : * DESCRIPTION: Initialize a parse (Op) object 53 : : * 54 : : ******************************************************************************/ 55 : : 56 : 49524 : void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) 57 : : { 58 : 49524 : ACPI_FUNCTION_ENTRY(); 59 : : 60 : 49524 : op->common.descriptor_type = ACPI_DESC_TYPE_PARSER; 61 : 49524 : op->common.aml_opcode = opcode; 62 : : 63 : : ACPI_DISASM_ONLY_MEMBERS(acpi_ut_safe_strncpy(op->common.aml_op_name, 64 : : (acpi_ps_get_opcode_info 65 : : (opcode))->name, 66 : : sizeof(op->common. 67 : 49524 : aml_op_name))); 68 : 9954 : } 69 : : 70 : : /******************************************************************************* 71 : : * 72 : : * FUNCTION: acpi_ps_alloc_op 73 : : * 74 : : * PARAMETERS: opcode - Opcode that will be stored in the new Op 75 : : * aml - Address of the opcode 76 : : * 77 : : * RETURN: Pointer to the new Op, null on failure 78 : : * 79 : : * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on 80 : : * opcode. A cache of opcodes is available for the pure 81 : : * GENERIC_OP, since this is by far the most commonly used. 82 : : * 83 : : ******************************************************************************/ 84 : : 85 : 39570 : union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml) 86 : : { 87 : 39570 : union acpi_parse_object *op; 88 : 39570 : const struct acpi_opcode_info *op_info; 89 : 39570 : u8 flags = ACPI_PARSEOP_GENERIC; 90 : : 91 : 39570 : ACPI_FUNCTION_ENTRY(); 92 : : 93 : 39570 : op_info = acpi_ps_get_opcode_info(opcode); 94 : : 95 : : /* Determine type of parse_op required */ 96 : : 97 [ + + ]: 39570 : if (op_info->flags & AML_DEFER) { 98 : : flags = ACPI_PARSEOP_DEFERRED; 99 [ + + ]: 38316 : } else if (op_info->flags & AML_NAMED) { 100 : : flags = ACPI_PARSEOP_NAMED_OBJECT; 101 [ + + ]: 36798 : } else if (opcode == AML_INT_BYTELIST_OP) { 102 : : flags = ACPI_PARSEOP_BYTELIST; 103 : : } 104 : : 105 : : /* Allocate the minimum required size object */ 106 : : 107 : 36711 : if (flags == ACPI_PARSEOP_GENERIC) { 108 : : 109 : : /* The generic op (default) is by far the most common (16 to 1) */ 110 : : 111 : 36711 : op = acpi_os_acquire_object(acpi_gbl_ps_node_cache); 112 : : } else { 113 : : /* Extended parseop */ 114 : : 115 : 2859 : op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache); 116 : : } 117 : : 118 : : /* Initialize the Op */ 119 : : 120 [ + - ]: 39570 : if (op) { 121 : 39570 : acpi_ps_init_op(op, opcode); 122 : 39570 : op->common.aml = aml; 123 : 39570 : op->common.flags = flags; 124 : 39570 : ASL_CV_CLEAR_OP_COMMENTS(op); 125 : : 126 [ + + ]: 39570 : if (opcode == AML_SCOPE_OP) { 127 : 315 : acpi_gbl_current_scope = op; 128 : : } 129 : : 130 : 39570 : if (acpi_gbl_capture_comments) { 131 : 39570 : ASL_CV_TRANSFER_COMMENTS(op); 132 : : } 133 : : } 134 : : 135 : 39570 : return (op); 136 : : } 137 : : 138 : : /******************************************************************************* 139 : : * 140 : : * FUNCTION: acpi_ps_free_op 141 : : * 142 : : * PARAMETERS: op - Op to be freed 143 : : * 144 : : * RETURN: None. 145 : : * 146 : : * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list 147 : : * or actually free it. 148 : : * 149 : : ******************************************************************************/ 150 : : 151 : 39570 : void acpi_ps_free_op(union acpi_parse_object *op) 152 : : { 153 : 39570 : ACPI_FUNCTION_NAME(ps_free_op); 154 : : 155 : 39570 : ASL_CV_CLEAR_OP_COMMENTS(op); 156 : 39570 : if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 157 : : ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 158 : 39570 : "Free retval op: %p\n", op)); 159 : : } 160 : : 161 [ + + ]: 39570 : if (op->common.flags & ACPI_PARSEOP_GENERIC) { 162 : 36711 : (void)acpi_os_release_object(acpi_gbl_ps_node_cache, op); 163 : : } else { 164 : 2859 : (void)acpi_os_release_object(acpi_gbl_ps_node_ext_cache, op); 165 : : } 166 : 39570 : } 167 : : 168 : : /******************************************************************************* 169 : : * 170 : : * FUNCTION: Utility functions 171 : : * 172 : : * DESCRIPTION: Low level character and object functions 173 : : * 174 : : ******************************************************************************/ 175 : : 176 : : /* 177 : : * Is "c" a namestring lead character? 178 : : */ 179 : 3048 : u8 acpi_ps_is_leading_char(u32 c) 180 : : { 181 : 3048 : return ((u8) (c == '_' || (c >= 'A' && c <= 'Z'))); 182 : : } 183 : : 184 : : /* 185 : : * Get op's name (4-byte name segment) or 0 if unnamed 186 : : */ 187 : 0 : u32 acpi_ps_get_name(union acpi_parse_object * op) 188 : : { 189 : : 190 : : /* The "generic" object has no name associated with it */ 191 : : 192 [ # # ]: 0 : if (op->common.flags & ACPI_PARSEOP_GENERIC) { 193 : : return (0); 194 : : } 195 : : 196 : : /* Only the "Extended" parse objects have a name */ 197 : : 198 : 0 : return (op->named.name); 199 : : } 200 : : 201 : : /* 202 : : * Set op's name 203 : : */ 204 : 267 : void acpi_ps_set_name(union acpi_parse_object *op, u32 name) 205 : : { 206 : : 207 : : /* The "generic" object has no name associated with it */ 208 : : 209 [ + - ]: 267 : if (op->common.flags & ACPI_PARSEOP_GENERIC) { 210 : : return; 211 : : } 212 : : 213 : 267 : op->named.name = name; 214 : : }