Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dswload - Dispatcher first pass namespace load callbacks
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "acparser.h"
  47. #include "amlcode.h"
  48. #include "acdispat.h"
  49. #include "acinterp.h"
  50. #include "acnamesp.h"
  51.  
  52. #ifdef ACPI_ASL_COMPILER
  53. #include "acdisasm.h"
  54. #endif
  55.  
  56. #define _COMPONENT          ACPI_DISPATCHER
  57. ACPI_MODULE_NAME("dswload")
  58.  
  59. /*******************************************************************************
  60.  *
  61.  * FUNCTION:    acpi_ds_init_callbacks
  62.  *
  63.  * PARAMETERS:  walk_state      - Current state of the parse tree walk
  64.  *              pass_number     - 1, 2, or 3
  65.  *
  66.  * RETURN:      Status
  67.  *
  68.  * DESCRIPTION: Init walk state callbacks
  69.  *
  70.  ******************************************************************************/
  71. acpi_status
  72. acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
  73. {
  74.  
  75.         switch (pass_number) {
  76.         case 0:
  77.  
  78.                 /* Parse only - caller will setup callbacks */
  79.  
  80.                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  81.                     ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE;
  82.                 walk_state->descending_callback = NULL;
  83.                 walk_state->ascending_callback = NULL;
  84.                 break;
  85.  
  86.         case 1:
  87.  
  88.                 /* Load pass 1 */
  89.  
  90.                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  91.                     ACPI_PARSE_DELETE_TREE;
  92.                 walk_state->descending_callback = acpi_ds_load1_begin_op;
  93.                 walk_state->ascending_callback = acpi_ds_load1_end_op;
  94.                 break;
  95.  
  96.         case 2:
  97.  
  98.                 /* Load pass 2 */
  99.  
  100.                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  101.                     ACPI_PARSE_DELETE_TREE;
  102.                 walk_state->descending_callback = acpi_ds_load2_begin_op;
  103.                 walk_state->ascending_callback = acpi_ds_load2_end_op;
  104.                 break;
  105.  
  106.         case 3:
  107.  
  108.                 /* Execution pass */
  109.  
  110. #ifndef ACPI_NO_METHOD_EXECUTION
  111.                 walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
  112.                     ACPI_PARSE_DELETE_TREE;
  113.                 walk_state->descending_callback = acpi_ds_exec_begin_op;
  114.                 walk_state->ascending_callback = acpi_ds_exec_end_op;
  115. #endif
  116.                 break;
  117.  
  118.         default:
  119.  
  120.                 return (AE_BAD_PARAMETER);
  121.         }
  122.  
  123.         return (AE_OK);
  124. }
  125.  
  126. /*******************************************************************************
  127.  *
  128.  * FUNCTION:    acpi_ds_load1_begin_op
  129.  *
  130.  * PARAMETERS:  walk_state      - Current state of the parse tree walk
  131.  *              out_op          - Where to return op if a new one is created
  132.  *
  133.  * RETURN:      Status
  134.  *
  135.  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
  136.  *
  137.  ******************************************************************************/
  138.  
  139. acpi_status
  140. acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
  141.                        union acpi_parse_object ** out_op)
  142. {
  143.         union acpi_parse_object *op;
  144.         struct acpi_namespace_node *node;
  145.         acpi_status status;
  146.         acpi_object_type object_type;
  147.         char *path;
  148.         u32 flags;
  149.  
  150.         ACPI_FUNCTION_TRACE(ds_load1_begin_op);
  151.  
  152.         op = walk_state->op;
  153.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
  154.                           walk_state));
  155.  
  156.         /* We are only interested in opcodes that have an associated name */
  157.  
  158.         if (op) {
  159.                 if (!(walk_state->op_info->flags & AML_NAMED)) {
  160.                         *out_op = op;
  161.                         return_ACPI_STATUS(AE_OK);
  162.                 }
  163.  
  164.                 /* Check if this object has already been installed in the namespace */
  165.  
  166.                 if (op->common.node) {
  167.                         *out_op = op;
  168.                         return_ACPI_STATUS(AE_OK);
  169.                 }
  170.         }
  171.  
  172.         path = acpi_ps_get_next_namestring(&walk_state->parser_state);
  173.  
  174.         /* Map the raw opcode into an internal object type */
  175.  
  176.         object_type = walk_state->op_info->object_type;
  177.  
  178.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  179.                           "State=%p Op=%p [%s]\n", walk_state, op,
  180.                           acpi_ut_get_type_name(object_type)));
  181.  
  182.         switch (walk_state->opcode) {
  183.         case AML_SCOPE_OP:
  184.                 /*
  185.                  * The target name of the Scope() operator must exist at this point so
  186.                  * that we can actually open the scope to enter new names underneath it.
  187.                  * Allow search-to-root for single namesegs.
  188.                  */
  189.                 status =
  190.                     acpi_ns_lookup(walk_state->scope_info, path, object_type,
  191.                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
  192.                                    walk_state, &(node));
  193. #ifdef ACPI_ASL_COMPILER
  194.                 if (status == AE_NOT_FOUND) {
  195.                         /*
  196.                          * Table disassembly:
  197.                          * Target of Scope() not found. Generate an External for it, and
  198.                          * insert the name into the namespace.
  199.                          */
  200.                         acpi_dm_add_op_to_external_list(op, path,
  201.                                                         ACPI_TYPE_DEVICE, 0, 0);
  202.                         status =
  203.                             acpi_ns_lookup(walk_state->scope_info, path,
  204.                                            object_type, ACPI_IMODE_LOAD_PASS1,
  205.                                            ACPI_NS_SEARCH_PARENT, walk_state,
  206.                                            &node);
  207.                 }
  208. #endif
  209.                 if (ACPI_FAILURE(status)) {
  210.                         ACPI_ERROR_NAMESPACE(path, status);
  211.                         return_ACPI_STATUS(status);
  212.                 }
  213.  
  214.                 /*
  215.                  * Check to make sure that the target is
  216.                  * one of the opcodes that actually opens a scope
  217.                  */
  218.                 switch (node->type) {
  219.                 case ACPI_TYPE_ANY:
  220.                 case ACPI_TYPE_LOCAL_SCOPE:     /* Scope  */
  221.                 case ACPI_TYPE_DEVICE:
  222.                 case ACPI_TYPE_POWER:
  223.                 case ACPI_TYPE_PROCESSOR:
  224.                 case ACPI_TYPE_THERMAL:
  225.  
  226.                         /* These are acceptable types */
  227.                         break;
  228.  
  229.                 case ACPI_TYPE_INTEGER:
  230.                 case ACPI_TYPE_STRING:
  231.                 case ACPI_TYPE_BUFFER:
  232.                         /*
  233.                          * These types we will allow, but we will change the type.
  234.                          * This enables some existing code of the form:
  235.                          *
  236.                          *  Name (DEB, 0)
  237.                          *  Scope (DEB) { ... }
  238.                          *
  239.                          * Note: silently change the type here. On the second pass,
  240.                          * we will report a warning
  241.                          */
  242.                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  243.                                           "Type override - [%4.4s] had invalid type (%s) "
  244.                                           "for Scope operator, changed to type ANY\n",
  245.                                           acpi_ut_get_node_name(node),
  246.                                           acpi_ut_get_type_name(node->type)));
  247.  
  248.                         node->type = ACPI_TYPE_ANY;
  249.                         walk_state->scope_info->common.value = ACPI_TYPE_ANY;
  250.                         break;
  251.  
  252.                 case ACPI_TYPE_METHOD:
  253.                         /*
  254.                          * Allow scope change to root during execution of module-level
  255.                          * code. Root is typed METHOD during this time.
  256.                          */
  257.                         if ((node == acpi_gbl_root_node) &&
  258.                             (walk_state->
  259.                              parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
  260.                                 break;
  261.                         }
  262.  
  263.                         /*lint -fallthrough */
  264.  
  265.                 default:
  266.  
  267.                         /* All other types are an error */
  268.  
  269.                         ACPI_ERROR((AE_INFO,
  270.                                     "Invalid type (%s) for target of "
  271.                                     "Scope operator [%4.4s] (Cannot override)",
  272.                                     acpi_ut_get_type_name(node->type),
  273.                                     acpi_ut_get_node_name(node)));
  274.  
  275.                         return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
  276.                 }
  277.                 break;
  278.  
  279.         default:
  280.                 /*
  281.                  * For all other named opcodes, we will enter the name into
  282.                  * the namespace.
  283.                  *
  284.                  * Setup the search flags.
  285.                  * Since we are entering a name into the namespace, we do not want to
  286.                  * enable the search-to-root upsearch.
  287.                  *
  288.                  * There are only two conditions where it is acceptable that the name
  289.                  * already exists:
  290.                  *    1) the Scope() operator can reopen a scoping object that was
  291.                  *       previously defined (Scope, Method, Device, etc.)
  292.                  *    2) Whenever we are parsing a deferred opcode (op_region, Buffer,
  293.                  *       buffer_field, or Package), the name of the object is already
  294.                  *       in the namespace.
  295.                  */
  296.                 if (walk_state->deferred_node) {
  297.  
  298.                         /* This name is already in the namespace, get the node */
  299.  
  300.                         node = walk_state->deferred_node;
  301.                         status = AE_OK;
  302.                         break;
  303.                 }
  304.  
  305.                 /*
  306.                  * If we are executing a method, do not create any namespace objects
  307.                  * during the load phase, only during execution.
  308.                  */
  309.                 if (walk_state->method_node) {
  310.                         node = NULL;
  311.                         status = AE_OK;
  312.                         break;
  313.                 }
  314.  
  315.                 flags = ACPI_NS_NO_UPSEARCH;
  316.                 if ((walk_state->opcode != AML_SCOPE_OP) &&
  317.                     (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
  318.                         if (walk_state->namespace_override) {
  319.                                 flags |= ACPI_NS_OVERRIDE_IF_FOUND;
  320.                                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  321.                                                   "[%s] Override allowed\n",
  322.                                                   acpi_ut_get_type_name
  323.                                                   (object_type)));
  324.                         } else {
  325.                                 flags |= ACPI_NS_ERROR_IF_FOUND;
  326.                                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  327.                                                   "[%s] Cannot already exist\n",
  328.                                                   acpi_ut_get_type_name
  329.                                                   (object_type)));
  330.                         }
  331.                 } else {
  332.                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  333.                                           "[%s] Both Find or Create allowed\n",
  334.                                           acpi_ut_get_type_name(object_type)));
  335.                 }
  336.  
  337.                 /*
  338.                  * Enter the named type into the internal namespace. We enter the name
  339.                  * as we go downward in the parse tree. Any necessary subobjects that
  340.                  * involve arguments to the opcode must be created as we go back up the
  341.                  * parse tree later.
  342.                  */
  343.                 status =
  344.                     acpi_ns_lookup(walk_state->scope_info, path, object_type,
  345.                                    ACPI_IMODE_LOAD_PASS1, flags, walk_state,
  346.                                    &node);
  347.                 if (ACPI_FAILURE(status)) {
  348.                         if (status == AE_ALREADY_EXISTS) {
  349.  
  350.                                 /* The name already exists in this scope */
  351.  
  352.                                 if (node->flags & ANOBJ_IS_EXTERNAL) {
  353.                                         /*
  354.                                          * Allow one create on an object or segment that was
  355.                                          * previously declared External
  356.                                          */
  357.                                         node->flags &= ~ANOBJ_IS_EXTERNAL;
  358.                                         node->type = (u8) object_type;
  359.  
  360.                                         /* Just retyped a node, probably will need to open a scope */
  361.  
  362.                                         if (acpi_ns_opens_scope(object_type)) {
  363.                                                 status =
  364.                                                     acpi_ds_scope_stack_push
  365.                                                     (node, object_type,
  366.                                                      walk_state);
  367.                                                 if (ACPI_FAILURE(status)) {
  368.                                                         return_ACPI_STATUS
  369.                                                             (status);
  370.                                                 }
  371.                                         }
  372.  
  373.                                         status = AE_OK;
  374.                                 }
  375.                         }
  376.  
  377.                         if (ACPI_FAILURE(status)) {
  378.                                 ACPI_ERROR_NAMESPACE(path, status);
  379.                                 return_ACPI_STATUS(status);
  380.                         }
  381.                 }
  382.                 break;
  383.         }
  384.  
  385.         /* Common exit */
  386.  
  387.         if (!op) {
  388.  
  389.                 /* Create a new op */
  390.  
  391.                 op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
  392.                 if (!op) {
  393.                         return_ACPI_STATUS(AE_NO_MEMORY);
  394.                 }
  395.         }
  396.  
  397.         /* Initialize the op */
  398.  
  399. #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
  400.         op->named.path = ACPI_CAST_PTR(u8, path);
  401. #endif
  402.  
  403.         if (node) {
  404.                 /*
  405.                  * Put the Node in the "op" object that the parser uses, so we
  406.                  * can get it again quickly when this scope is closed
  407.                  */
  408.                 op->common.node = node;
  409.                 op->named.name = node->name.integer;
  410.         }
  411.  
  412.         acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
  413.                            op);
  414.         *out_op = op;
  415.         return_ACPI_STATUS(status);
  416. }
  417.  
  418. /*******************************************************************************
  419.  *
  420.  * FUNCTION:    acpi_ds_load1_end_op
  421.  *
  422.  * PARAMETERS:  walk_state      - Current state of the parse tree walk
  423.  *
  424.  * RETURN:      Status
  425.  *
  426.  * DESCRIPTION: Ascending callback used during the loading of the namespace,
  427.  *              both control methods and everything else.
  428.  *
  429.  ******************************************************************************/
  430.  
  431. acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
  432. {
  433.         union acpi_parse_object *op;
  434.         acpi_object_type object_type;
  435.         acpi_status status = AE_OK;
  436.  
  437.         ACPI_FUNCTION_TRACE(ds_load1_end_op);
  438.  
  439.         op = walk_state->op;
  440.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
  441.                           walk_state));
  442.  
  443.         /* We are only interested in opcodes that have an associated name */
  444.  
  445.         if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
  446.                 return_ACPI_STATUS(AE_OK);
  447.         }
  448.  
  449.         /* Get the object type to determine if we should pop the scope */
  450.  
  451.         object_type = walk_state->op_info->object_type;
  452.  
  453. #ifndef ACPI_NO_METHOD_EXECUTION
  454.         if (walk_state->op_info->flags & AML_FIELD) {
  455.                 /*
  456.                  * If we are executing a method, do not create any namespace objects
  457.                  * during the load phase, only during execution.
  458.                  */
  459.                 if (!walk_state->method_node) {
  460.                         if (walk_state->opcode == AML_FIELD_OP ||
  461.                             walk_state->opcode == AML_BANK_FIELD_OP ||
  462.                             walk_state->opcode == AML_INDEX_FIELD_OP) {
  463.                                 status =
  464.                                     acpi_ds_init_field_objects(op, walk_state);
  465.                         }
  466.                 }
  467.                 return_ACPI_STATUS(status);
  468.         }
  469.  
  470.         /*
  471.          * If we are executing a method, do not create any namespace objects
  472.          * during the load phase, only during execution.
  473.          */
  474.         if (!walk_state->method_node) {
  475.                 if (op->common.aml_opcode == AML_REGION_OP) {
  476.                         status =
  477.                             acpi_ex_create_region(op->named.data,
  478.                                                   op->named.length,
  479.                                                   (acpi_adr_space_type) ((op->
  480.                                                                           common.
  481.                                                                           value.
  482.                                                                           arg)->
  483.                                                                          common.
  484.                                                                          value.
  485.                                                                          integer),
  486.                                                   walk_state);
  487.                         if (ACPI_FAILURE(status)) {
  488.                                 return_ACPI_STATUS(status);
  489.                         }
  490.                 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
  491.                         status =
  492.                             acpi_ex_create_region(op->named.data,
  493.                                                   op->named.length,
  494.                                                   ACPI_ADR_SPACE_DATA_TABLE,
  495.                                                   walk_state);
  496.                         if (ACPI_FAILURE(status)) {
  497.                                 return_ACPI_STATUS(status);
  498.                         }
  499.                 }
  500.         }
  501. #endif
  502.  
  503.         if (op->common.aml_opcode == AML_NAME_OP) {
  504.  
  505.                 /* For Name opcode, get the object type from the argument */
  506.  
  507.                 if (op->common.value.arg) {
  508.                         object_type = (acpi_ps_get_opcode_info((op->common.
  509.                                                                 value.arg)->
  510.                                                                common.
  511.                                                                aml_opcode))->
  512.                             object_type;
  513.  
  514.                         /* Set node type if we have a namespace node */
  515.  
  516.                         if (op->common.node) {
  517.                                 op->common.node->type = (u8) object_type;
  518.                         }
  519.                 }
  520.         }
  521.  
  522.         /*
  523.          * If we are executing a method, do not create any namespace objects
  524.          * during the load phase, only during execution.
  525.          */
  526.         if (!walk_state->method_node) {
  527.                 if (op->common.aml_opcode == AML_METHOD_OP) {
  528.                         /*
  529.                          * method_op pkg_length name_string method_flags term_list
  530.                          *
  531.                          * Note: We must create the method node/object pair as soon as we
  532.                          * see the method declaration. This allows later pass1 parsing
  533.                          * of invocations of the method (need to know the number of
  534.                          * arguments.)
  535.                          */
  536.                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  537.                                           "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
  538.                                           walk_state, op, op->named.node));
  539.  
  540.                         if (!acpi_ns_get_attached_object(op->named.node)) {
  541.                                 walk_state->operands[0] =
  542.                                     ACPI_CAST_PTR(void, op->named.node);
  543.                                 walk_state->num_operands = 1;
  544.  
  545.                                 status =
  546.                                     acpi_ds_create_operands(walk_state,
  547.                                                             op->common.value.
  548.                                                             arg);
  549.                                 if (ACPI_SUCCESS(status)) {
  550.                                         status =
  551.                                             acpi_ex_create_method(op->named.
  552.                                                                   data,
  553.                                                                   op->named.
  554.                                                                   length,
  555.                                                                   walk_state);
  556.                                 }
  557.  
  558.                                 walk_state->operands[0] = NULL;
  559.                                 walk_state->num_operands = 0;
  560.  
  561.                                 if (ACPI_FAILURE(status)) {
  562.                                         return_ACPI_STATUS(status);
  563.                                 }
  564.                         }
  565.                 }
  566.         }
  567.  
  568.         /* Pop the scope stack (only if loading a table) */
  569.  
  570.         if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
  571.                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  572.                                   "(%s): Popping scope for Op %p\n",
  573.                                   acpi_ut_get_type_name(object_type), op));
  574.  
  575.                 status = acpi_ds_scope_stack_pop(walk_state);
  576.         }
  577.  
  578.         return_ACPI_STATUS(status);
  579. }
  580.