Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: psutils - Parser miscellaneous utilities (Parser only)
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "amlcode.h"
0014 #include "acconvert.h"
0015 
0016 #define _COMPONENT          ACPI_PARSER
0017 ACPI_MODULE_NAME("psutils")
0018 
0019 /*******************************************************************************
0020  *
0021  * FUNCTION:    acpi_ps_create_scope_op
0022  *
0023  * PARAMETERS:  None
0024  *
0025  * RETURN:      A new Scope object, null on failure
0026  *
0027  * DESCRIPTION: Create a Scope and associated namepath op with the root name
0028  *
0029  ******************************************************************************/
0030 union acpi_parse_object *acpi_ps_create_scope_op(u8 *aml)
0031 {
0032     union acpi_parse_object *scope_op;
0033 
0034     scope_op = acpi_ps_alloc_op(AML_SCOPE_OP, aml);
0035     if (!scope_op) {
0036         return (NULL);
0037     }
0038 
0039     scope_op->named.name = ACPI_ROOT_NAME;
0040     return (scope_op);
0041 }
0042 
0043 /*******************************************************************************
0044  *
0045  * FUNCTION:    acpi_ps_init_op
0046  *
0047  * PARAMETERS:  op              - A newly allocated Op object
0048  *              opcode          - Opcode to store in the Op
0049  *
0050  * RETURN:      None
0051  *
0052  * DESCRIPTION: Initialize a parse (Op) object
0053  *
0054  ******************************************************************************/
0055 
0056 void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode)
0057 {
0058     ACPI_FUNCTION_ENTRY();
0059 
0060     op->common.descriptor_type = ACPI_DESC_TYPE_PARSER;
0061     op->common.aml_opcode = opcode;
0062 
0063     ACPI_DISASM_ONLY_MEMBERS(acpi_ut_safe_strncpy(op->common.aml_op_name,
0064                               (acpi_ps_get_opcode_info
0065                                (opcode))->name,
0066                               sizeof(op->common.
0067                                  aml_op_name)));
0068 }
0069 
0070 /*******************************************************************************
0071  *
0072  * FUNCTION:    acpi_ps_alloc_op
0073  *
0074  * PARAMETERS:  opcode          - Opcode that will be stored in the new Op
0075  *              aml             - Address of the opcode
0076  *
0077  * RETURN:      Pointer to the new Op, null on failure
0078  *
0079  * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
0080  *              opcode. A cache of opcodes is available for the pure
0081  *              GENERIC_OP, since this is by far the most commonly used.
0082  *
0083  ******************************************************************************/
0084 
0085 union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml)
0086 {
0087     union acpi_parse_object *op;
0088     const struct acpi_opcode_info *op_info;
0089     u8 flags = ACPI_PARSEOP_GENERIC;
0090 
0091     ACPI_FUNCTION_ENTRY();
0092 
0093     op_info = acpi_ps_get_opcode_info(opcode);
0094 
0095     /* Determine type of parse_op required */
0096 
0097     if (op_info->flags & AML_DEFER) {
0098         flags = ACPI_PARSEOP_DEFERRED;
0099     } else if (op_info->flags & AML_NAMED) {
0100         flags = ACPI_PARSEOP_NAMED_OBJECT;
0101     } else if (opcode == AML_INT_BYTELIST_OP) {
0102         flags = ACPI_PARSEOP_BYTELIST;
0103     }
0104 
0105     /* Allocate the minimum required size object */
0106 
0107     if (flags == ACPI_PARSEOP_GENERIC) {
0108 
0109         /* The generic op (default) is by far the most common (16 to 1) */
0110 
0111         op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
0112     } else {
0113         /* Extended parseop */
0114 
0115         op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
0116     }
0117 
0118     /* Initialize the Op */
0119 
0120     if (op) {
0121         acpi_ps_init_op(op, opcode);
0122         op->common.aml = aml;
0123         op->common.flags = flags;
0124         ASL_CV_CLEAR_OP_COMMENTS(op);
0125 
0126         if (opcode == AML_SCOPE_OP) {
0127             acpi_gbl_current_scope = op;
0128         }
0129 
0130         if (acpi_gbl_capture_comments) {
0131             ASL_CV_TRANSFER_COMMENTS(op);
0132         }
0133     }
0134 
0135     return (op);
0136 }
0137 
0138 /*******************************************************************************
0139  *
0140  * FUNCTION:    acpi_ps_free_op
0141  *
0142  * PARAMETERS:  op              - Op to be freed
0143  *
0144  * RETURN:      None.
0145  *
0146  * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
0147  *              or actually free it.
0148  *
0149  ******************************************************************************/
0150 
0151 void acpi_ps_free_op(union acpi_parse_object *op)
0152 {
0153     ACPI_FUNCTION_NAME(ps_free_op);
0154 
0155     ASL_CV_CLEAR_OP_COMMENTS(op);
0156     if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
0157         ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0158                   "Free retval op: %p\n", op));
0159     }
0160 
0161     if (op->common.flags & ACPI_PARSEOP_GENERIC) {
0162         (void)acpi_os_release_object(acpi_gbl_ps_node_cache, op);
0163     } else {
0164         (void)acpi_os_release_object(acpi_gbl_ps_node_ext_cache, op);
0165     }
0166 }
0167 
0168 /*******************************************************************************
0169  *
0170  * FUNCTION:    Utility functions
0171  *
0172  * DESCRIPTION: Low level character and object functions
0173  *
0174  ******************************************************************************/
0175 
0176 /*
0177  * Is "c" a namestring lead character?
0178  */
0179 u8 acpi_ps_is_leading_char(u32 c)
0180 {
0181     return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
0182 }
0183 
0184 /*
0185  * Get op's name (4-byte name segment) or 0 if unnamed
0186  */
0187 u32 acpi_ps_get_name(union acpi_parse_object * op)
0188 {
0189 
0190     /* The "generic" object has no name associated with it */
0191 
0192     if (op->common.flags & ACPI_PARSEOP_GENERIC) {
0193         return (0);
0194     }
0195 
0196     /* Only the "Extended" parse objects have a name */
0197 
0198     return (op->named.name);
0199 }
0200 
0201 /*
0202  * Set op's name
0203  */
0204 void acpi_ps_set_name(union acpi_parse_object *op, u32 name)
0205 {
0206 
0207     /* The "generic" object has no name associated with it */
0208 
0209     if (op->common.flags & ACPI_PARSEOP_GENERIC) {
0210         return;
0211     }
0212 
0213     op->named.name = name;
0214 }