0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "acdispat.h"
0014 #include "acinterp.h"
0015 #include "actables.h"
0016 #include "acnamesp.h"
0017
0018 #define _COMPONENT ACPI_PARSER
0019 ACPI_MODULE_NAME("psxface")
0020
0021
0022 static void
0023 acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 acpi_status
0042 acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)
0043 {
0044 acpi_status status;
0045
0046 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0047 if (ACPI_FAILURE(status)) {
0048 return (status);
0049 }
0050
0051 acpi_gbl_trace_method_name = name;
0052 acpi_gbl_trace_flags = flags;
0053 acpi_gbl_trace_dbg_level = debug_level;
0054 acpi_gbl_trace_dbg_layer = debug_layer;
0055 status = AE_OK;
0056
0057 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0058 return (status);
0059 }
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
0085 {
0086 acpi_status status;
0087 union acpi_parse_object *op;
0088 struct acpi_walk_state *walk_state;
0089
0090 ACPI_FUNCTION_TRACE(ps_execute_method);
0091
0092
0093
0094 acpi_tb_check_dsdt_header();
0095
0096
0097
0098 if (!info || !info->node) {
0099 return_ACPI_STATUS(AE_NULL_ENTRY);
0100 }
0101
0102
0103
0104 status =
0105 acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
0106 if (ACPI_FAILURE(status)) {
0107 return_ACPI_STATUS(status);
0108 }
0109
0110
0111
0112
0113 acpi_ps_update_parameter_list(info, REF_INCREMENT);
0114
0115
0116
0117
0118 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
0119 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
0120 info->node->name.ascii, info->node, info->obj_desc));
0121
0122
0123
0124 op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
0125 if (!op) {
0126 status = AE_NO_MEMORY;
0127 goto cleanup;
0128 }
0129
0130
0131
0132 info->pass_number = ACPI_IMODE_EXECUTE;
0133 walk_state =
0134 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
0135 NULL, NULL);
0136 if (!walk_state) {
0137 status = AE_NO_MEMORY;
0138 goto cleanup;
0139 }
0140
0141 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
0142 info->obj_desc->method.aml_start,
0143 info->obj_desc->method.aml_length, info,
0144 info->pass_number);
0145 if (ACPI_FAILURE(status)) {
0146 acpi_ds_delete_walk_state(walk_state);
0147 goto cleanup;
0148 }
0149
0150 walk_state->method_pathname = info->full_pathname;
0151 walk_state->method_is_nested = FALSE;
0152
0153 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
0154 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
0155 }
0156
0157
0158
0159 if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
0160 status =
0161 info->obj_desc->method.dispatch.implementation(walk_state);
0162 info->return_object = walk_state->return_desc;
0163
0164
0165
0166 acpi_ds_scope_stack_clear(walk_state);
0167 acpi_ps_cleanup_scope(&walk_state->parser_state);
0168 acpi_ds_terminate_control_method(walk_state->method_desc,
0169 walk_state);
0170 acpi_ds_delete_walk_state(walk_state);
0171 goto cleanup;
0172 }
0173
0174
0175
0176
0177
0178 if (acpi_gbl_enable_interpreter_slack) {
0179 walk_state->implicit_return_obj =
0180 acpi_ut_create_integer_object((u64) 0);
0181 if (!walk_state->implicit_return_obj) {
0182 status = AE_NO_MEMORY;
0183 acpi_ds_delete_walk_state(walk_state);
0184 goto cleanup;
0185 }
0186 }
0187
0188
0189
0190 status = acpi_ps_parse_aml(walk_state);
0191
0192
0193
0194 cleanup:
0195 acpi_ps_delete_parse_tree(op);
0196
0197
0198
0199 acpi_ps_update_parameter_list(info, REF_DECREMENT);
0200
0201
0202
0203 if (ACPI_FAILURE(status)) {
0204 return_ACPI_STATUS(status);
0205 }
0206
0207
0208
0209
0210
0211 if (info->return_object) {
0212 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
0213 info->return_object));
0214 ACPI_DUMP_STACK_ENTRY(info->return_object);
0215
0216 status = AE_CTRL_RETURN_VALUE;
0217 }
0218
0219 return_ACPI_STATUS(status);
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)
0240 {
0241 acpi_status status;
0242 union acpi_parse_object *op = NULL;
0243 struct acpi_walk_state *walk_state = NULL;
0244
0245 ACPI_FUNCTION_TRACE(ps_execute_table);
0246
0247
0248
0249 op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
0250 if (!op) {
0251 status = AE_NO_MEMORY;
0252 goto cleanup;
0253 }
0254
0255
0256
0257 walk_state =
0258 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
0259 NULL, NULL);
0260 if (!walk_state) {
0261 status = AE_NO_MEMORY;
0262 goto cleanup;
0263 }
0264
0265 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
0266 info->obj_desc->method.aml_start,
0267 info->obj_desc->method.aml_length, info,
0268 info->pass_number);
0269 if (ACPI_FAILURE(status)) {
0270 goto cleanup;
0271 }
0272
0273 walk_state->method_pathname = info->full_pathname;
0274 walk_state->method_is_nested = FALSE;
0275
0276 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
0277 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
0278 }
0279
0280
0281
0282 if (info->node && info->node != acpi_gbl_root_node) {
0283 status =
0284 acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,
0285 walk_state);
0286 if (ACPI_FAILURE(status)) {
0287 goto cleanup;
0288 }
0289 }
0290
0291
0292
0293
0294 acpi_ex_enter_interpreter();
0295 status = acpi_ps_parse_aml(walk_state);
0296 acpi_ex_exit_interpreter();
0297 walk_state = NULL;
0298
0299 cleanup:
0300 if (walk_state) {
0301 acpi_ds_delete_walk_state(walk_state);
0302 }
0303 if (op) {
0304 acpi_ps_delete_parse_tree(op);
0305 }
0306 return_ACPI_STATUS(status);
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 static void
0324 acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
0325 {
0326 u32 i;
0327
0328 if (info->parameters) {
0329
0330
0331
0332 for (i = 0; info->parameters[i]; i++) {
0333
0334
0335
0336 (void)acpi_ut_update_object_reference(info->
0337 parameters[i],
0338 action);
0339 }
0340 }
0341 }