0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "acparser.h"
0014 #include "acdispat.h"
0015 #include "actables.h"
0016 #include "acinterp.h"
0017
0018 #define _COMPONENT ACPI_NAMESPACE
0019 ACPI_MODULE_NAME("nsparse")
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 acpi_status
0044 acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
0045 {
0046 acpi_status status;
0047 struct acpi_table_header *table;
0048 acpi_owner_id owner_id;
0049 struct acpi_evaluate_info *info = NULL;
0050 u32 aml_length;
0051 u8 *aml_start;
0052 union acpi_operand_object *method_obj = NULL;
0053
0054 ACPI_FUNCTION_TRACE(ns_execute_table);
0055
0056 status = acpi_get_table_by_index(table_index, &table);
0057 if (ACPI_FAILURE(status)) {
0058 return_ACPI_STATUS(status);
0059 }
0060
0061
0062
0063 if (table->length < sizeof(struct acpi_table_header)) {
0064 return_ACPI_STATUS(AE_BAD_HEADER);
0065 }
0066
0067 aml_start = (u8 *)table + sizeof(struct acpi_table_header);
0068 aml_length = table->length - sizeof(struct acpi_table_header);
0069
0070 status = acpi_tb_get_owner_id(table_index, &owner_id);
0071 if (ACPI_FAILURE(status)) {
0072 return_ACPI_STATUS(status);
0073 }
0074
0075
0076
0077 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
0078 if (!method_obj) {
0079 return_ACPI_STATUS(AE_NO_MEMORY);
0080 }
0081
0082
0083
0084 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
0085 if (!info) {
0086 status = AE_NO_MEMORY;
0087 goto cleanup;
0088 }
0089
0090 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
0091 "%s: Create table pseudo-method for [%4.4s] @%p, method %p\n",
0092 ACPI_GET_FUNCTION_NAME, table->signature, table,
0093 method_obj));
0094
0095 method_obj->method.aml_start = aml_start;
0096 method_obj->method.aml_length = aml_length;
0097 method_obj->method.owner_id = owner_id;
0098 method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
0099
0100 info->pass_number = ACPI_IMODE_EXECUTE;
0101 info->node = start_node;
0102 info->obj_desc = method_obj;
0103 info->node_flags = info->node->flags;
0104 info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
0105 if (!info->full_pathname) {
0106 status = AE_NO_MEMORY;
0107 goto cleanup;
0108 }
0109
0110
0111
0112 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
0113 "%-26s: (Definition Block level)\n",
0114 "Module-level evaluation"));
0115
0116 status = acpi_ps_execute_table(info);
0117
0118
0119
0120 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
0121 "%-26s: (Definition Block level)\n",
0122 "Module-level complete"));
0123
0124 cleanup:
0125 if (info) {
0126 ACPI_FREE(info->full_pathname);
0127 info->full_pathname = NULL;
0128 }
0129 ACPI_FREE(info);
0130 acpi_ut_remove_reference(method_obj);
0131 return_ACPI_STATUS(status);
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 acpi_status
0148 acpi_ns_one_complete_parse(u32 pass_number,
0149 u32 table_index,
0150 struct acpi_namespace_node *start_node)
0151 {
0152 union acpi_parse_object *parse_root;
0153 acpi_status status;
0154 u32 aml_length;
0155 u8 *aml_start;
0156 struct acpi_walk_state *walk_state;
0157 struct acpi_table_header *table;
0158 acpi_owner_id owner_id;
0159
0160 ACPI_FUNCTION_TRACE(ns_one_complete_parse);
0161
0162 status = acpi_get_table_by_index(table_index, &table);
0163 if (ACPI_FAILURE(status)) {
0164 return_ACPI_STATUS(status);
0165 }
0166
0167
0168
0169 if (table->length < sizeof(struct acpi_table_header)) {
0170 return_ACPI_STATUS(AE_BAD_HEADER);
0171 }
0172
0173 aml_start = (u8 *)table + sizeof(struct acpi_table_header);
0174 aml_length = table->length - sizeof(struct acpi_table_header);
0175
0176 status = acpi_tb_get_owner_id(table_index, &owner_id);
0177 if (ACPI_FAILURE(status)) {
0178 return_ACPI_STATUS(status);
0179 }
0180
0181
0182
0183 parse_root = acpi_ps_create_scope_op(aml_start);
0184 if (!parse_root) {
0185 return_ACPI_STATUS(AE_NO_MEMORY);
0186 }
0187
0188
0189
0190 walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
0191 if (!walk_state) {
0192 acpi_ps_free_op(parse_root);
0193 return_ACPI_STATUS(AE_NO_MEMORY);
0194 }
0195
0196 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
0197 aml_start, aml_length, NULL,
0198 (u8)pass_number);
0199 if (ACPI_FAILURE(status)) {
0200 acpi_ds_delete_walk_state(walk_state);
0201 goto cleanup;
0202 }
0203
0204
0205
0206 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) &&
0207 pass_number == ACPI_IMODE_LOAD_PASS1) {
0208 walk_state->namespace_override = TRUE;
0209 }
0210
0211
0212
0213 if (start_node && start_node != acpi_gbl_root_node) {
0214 status =
0215 acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
0216 walk_state);
0217 if (ACPI_FAILURE(status)) {
0218 acpi_ds_delete_walk_state(walk_state);
0219 goto cleanup;
0220 }
0221 }
0222
0223
0224
0225 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
0226 "*PARSE* pass %u parse\n", pass_number));
0227 acpi_ex_enter_interpreter();
0228 status = acpi_ps_parse_aml(walk_state);
0229 acpi_ex_exit_interpreter();
0230
0231 cleanup:
0232 acpi_ps_delete_parse_tree(parse_root);
0233 return_ACPI_STATUS(status);
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 acpi_status
0250 acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
0251 {
0252 acpi_status status;
0253
0254 ACPI_FUNCTION_TRACE(ns_parse_table);
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
0265 "%s: **** Start table execution pass\n",
0266 ACPI_GET_FUNCTION_NAME));
0267
0268 status = acpi_ns_execute_table(table_index, start_node);
0269
0270 return_ACPI_STATUS(status);
0271 }