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 - 2023, 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 union acpi_parse_object *acpi_ps_create_scope_op(u8 *aml) 31 { 32 union acpi_parse_object *scope_op; 33 34 scope_op = acpi_ps_alloc_op(AML_SCOPE_OP, aml); 35 if (!scope_op) { 36 return (NULL); 37 } 38 39 scope_op->named.name = ACPI_ROOT_NAME; 40 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 void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) 57 { 58 ACPI_FUNCTION_ENTRY(); 59 60 op->common.descriptor_type = ACPI_DESC_TYPE_PARSER; 61 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 aml_op_name))); 68 } 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 union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml) 86 { 87 union acpi_parse_object *op; 88 const struct acpi_opcode_info *op_info; 89 u8 flags = ACPI_PARSEOP_GENERIC; 90 91 ACPI_FUNCTION_ENTRY(); 92 93 op_info = acpi_ps_get_opcode_info(opcode); 94 95 /* Determine type of parse_op required */ 96 97 if (op_info->flags & AML_DEFER) { 98 flags = ACPI_PARSEOP_DEFERRED; 99 } else if (op_info->flags & AML_NAMED) { 100 flags = ACPI_PARSEOP_NAMED_OBJECT; 101 } else if (opcode == AML_INT_BYTELIST_OP) { 102 flags = ACPI_PARSEOP_BYTELIST; 103 } 104 105 /* Allocate the minimum required size object */ 106 107 if (flags == ACPI_PARSEOP_GENERIC) { 108 109 /* The generic op (default) is by far the most common (16 to 1) */ 110 111 op = acpi_os_acquire_object(acpi_gbl_ps_node_cache); 112 } else { 113 /* Extended parseop */ 114 115 op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache); 116 } 117 118 /* Initialize the Op */ 119 120 if (op) { 121 acpi_ps_init_op(op, opcode); 122 op->common.aml = aml; 123 op->common.flags = flags; 124 ASL_CV_CLEAR_OP_COMMENTS(op); 125 126 if (opcode == AML_SCOPE_OP) { 127 acpi_gbl_current_scope = op; 128 } 129 130 if (acpi_gbl_capture_comments) { 131 ASL_CV_TRANSFER_COMMENTS(op); 132 } 133 } 134 135 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 void acpi_ps_free_op(union acpi_parse_object *op) 152 { 153 ACPI_FUNCTION_NAME(ps_free_op); 154 155 ASL_CV_CLEAR_OP_COMMENTS(op); 156 if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 157 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 158 "Free retval op: %p\n", op)); 159 } 160 161 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 162 (void)acpi_os_release_object(acpi_gbl_ps_node_cache, op); 163 } else { 164 (void)acpi_os_release_object(acpi_gbl_ps_node_ext_cache, op); 165 } 166 } 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 u8 acpi_ps_is_leading_char(u32 c) 180 { 181 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 u32 acpi_ps_get_name(union acpi_parse_object * op) 188 { 189 190 /* The "generic" object has no name associated with it */ 191 192 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 193 return (0); 194 } 195 196 /* Only the "Extended" parse objects have a name */ 197 198 return (op->named.name); 199 } 200 201 /* 202 * Set op's name 203 */ 204 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 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 210 return; 211 } 212 213 op->named.name = name; 214 } 215