215 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************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_PARSER17ACPI_MODULE_NAME("psutils")18 19/*******************************************************************************20 *21 * FUNCTION: acpi_ps_create_scope_op22 *23 * PARAMETERS: None24 *25 * RETURN: A new Scope object, null on failure26 *27 * DESCRIPTION: Create a Scope and associated namepath op with the root name28 *29 ******************************************************************************/30union 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_op46 *47 * PARAMETERS: op - A newly allocated Op object48 * opcode - Opcode to store in the Op49 *50 * RETURN: None51 *52 * DESCRIPTION: Initialize a parse (Op) object53 *54 ******************************************************************************/55 56void 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_info65 (opcode))->name,66 sizeof(op->common.67 aml_op_name)));68}69 70/*******************************************************************************71 *72 * FUNCTION: acpi_ps_alloc_op73 *74 * PARAMETERS: opcode - Opcode that will be stored in the new Op75 * aml - Address of the opcode76 *77 * RETURN: Pointer to the new Op, null on failure78 *79 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on80 * opcode. A cache of opcodes is available for the pure81 * GENERIC_OP, since this is by far the most commonly used.82 *83 ******************************************************************************/84 85union 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_op141 *142 * PARAMETERS: op - Op to be freed143 *144 * RETURN: None.145 *146 * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list147 * or actually free it.148 *149 ******************************************************************************/150 151void 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 functions171 *172 * DESCRIPTION: Low level character and object functions173 *174 ******************************************************************************/175 176/*177 * Is "c" a namestring lead character?178 */179u8 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 unnamed186 */187u32 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 name203 */204void 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