1/****************************************************************************** 2 * 3 * Module Name: psxface - Parser external interfaces 4 * $Revision: 1.1.1.1 $ 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000, 2001 R. Byron Moore 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 27#include "acpi.h" 28#include "acparser.h" 29#include "acdispat.h" 30#include "acinterp.h" 31#include "amlcode.h" 32#include "acnamesp.h" 33 34 35#define _COMPONENT ACPI_PARSER 36 MODULE_NAME ("psxface") 37 38 39/******************************************************************************* 40 * 41 * FUNCTION: Acpi_psx_execute 42 * 43 * PARAMETERS: Method_node - A method object containing both the AML 44 * address and length. 45 * **Params - List of parameters to pass to method, 46 * terminated by NULL. Params itself may be 47 * NULL if no parameters are being passed. 48 * **Return_obj_desc - Return object from execution of the 49 * method. 50 * 51 * RETURN: Status 52 * 53 * DESCRIPTION: Execute a control method 54 * 55 ******************************************************************************/ 56 57acpi_status 58acpi_psx_execute ( 59 acpi_namespace_node *method_node, 60 acpi_operand_object **params, 61 acpi_operand_object **return_obj_desc) 62{ 63 acpi_status status; 64 acpi_operand_object *obj_desc; 65 u32 i; 66 acpi_parse_object *op; 67 acpi_walk_state *walk_state; 68 69 70 FUNCTION_TRACE ("Psx_execute"); 71 72 73 /* Validate the Node and get the attached object */ 74 75 if (!method_node) { 76 return_ACPI_STATUS (AE_NULL_ENTRY); 77 } 78 79 obj_desc = acpi_ns_get_attached_object (method_node); 80 if (!obj_desc) { 81 return_ACPI_STATUS (AE_NULL_OBJECT); 82 } 83 84 /* Init for new method, wait on concurrency semaphore */ 85 86 status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL); 87 if (ACPI_FAILURE (status)) { 88 return_ACPI_STATUS (status); 89 } 90 91 if (params) { 92 /* 93 * The caller "owns" the parameters, so give each one an extra 94 * reference 95 */ 96 for (i = 0; params[i]; i++) { 97 acpi_ut_add_reference (params[i]); 98 } 99 } 100 101 /* 102 * 1) Perform the first pass parse of the method to enter any 103 * named objects that it creates into the namespace 104 */ 105 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 106 "**** Begin Method Parse **** Entry=%p obj=%p\n", 107 method_node, obj_desc)); 108 109 /* Create and init a Root Node */ 110 111 op = acpi_ps_alloc_op (AML_SCOPE_OP); 112 if (!op) { 113 return_ACPI_STATUS (AE_NO_MEMORY); 114 } 115 116 /* Create and initialize a new walk state */ 117 118 walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, 119 NULL, NULL, NULL); 120 if (!walk_state) { 121 return_ACPI_STATUS (AE_NO_MEMORY); 122 } 123 124 status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, 125 obj_desc->method.aml_length, NULL, NULL, 1); 126 if (ACPI_FAILURE (status)) { 127 /* TBD: delete walk state */ 128 return_ACPI_STATUS (status); 129 } 130 131 /* Parse the AML */ 132 133 status = acpi_ps_parse_aml (walk_state); 134 acpi_ps_delete_parse_tree (op); 135 136 137 /* 138 * 2) Execute the method. Performs second pass parse simultaneously 139 */ 140 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 141 "**** Begin Method Execution **** Entry=%p obj=%p\n", 142 method_node, obj_desc)); 143 144 /* Create and init a Root Node */ 145 146 op = acpi_ps_alloc_op (AML_SCOPE_OP); 147 if (!op) { 148 return_ACPI_STATUS (AE_NO_MEMORY); 149 } 150 151 /* Init new op with the method name and pointer back to the NS node */ 152 153 acpi_ps_set_name (op, method_node->name); 154 op->node = method_node; 155 156 /* Create and initialize a new walk state */ 157 158 walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, 159 NULL, NULL, NULL); 160 if (!walk_state) { 161 return_ACPI_STATUS (AE_NO_MEMORY); 162 } 163 164 status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, 165 obj_desc->method.aml_length, params, return_obj_desc, 3); 166 if (ACPI_FAILURE (status)) { 167 /* TBD: delete walk state */ 168 return_ACPI_STATUS (status); 169 } 170 171 /* 172 * The walk of the parse tree is where we actually execute the method 173 */ 174 status = acpi_ps_parse_aml (walk_state); 175 acpi_ps_delete_parse_tree (op); 176 177 if (params) { 178 /* Take away the extra reference that we gave the parameters above */ 179 180 for (i = 0; params[i]; i++) { 181 acpi_ut_update_object_reference (params[i], REF_DECREMENT); 182 } 183 } 184 185 186 if (ACPI_FAILURE (status)) { 187 DUMP_PATHNAME (method_node, "Ps_execute: method failed -", 188 ACPI_LV_ERROR, _COMPONENT); 189 } 190 191 192 /* 193 * If the method has returned an object, signal this to the caller with 194 * a control exception code 195 */ 196 if (*return_obj_desc) { 197 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method returned Obj_desc=%p\n", 198 *return_obj_desc)); 199 DUMP_STACK_ENTRY (*return_obj_desc); 200 201 status = AE_CTRL_RETURN_VALUE; 202 } 203 204 205 return_ACPI_STATUS (status); 206} 207 208 209