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