diff options
author | Bob Moore <robert.moore@intel.com> | 2007-02-02 11:48:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:21 -0500 |
commit | f3d2e7865c816258c699ff965768e46b50d536d3 (patch) | |
tree | 83d21269e506109275b77d3ed161883bba8a39cf /drivers/acpi/executer | |
parent | 2e42005bcdb4f63bed1cea7f537a5534d4bd7a57 (diff) |
ACPICA: Implement simplified Table Manager
The Table Manager component has been completely
redesigned and reimplemented. The new design is much
simpler, and reduces the overall code and data size of
the kernel-resident ACPICA by approximately 5%. Also,
it is now possible to obtain the ACPI tables very early
during kernel initialization, even before dynamic memory
management is initialized.
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/executer')
-rw-r--r-- | drivers/acpi/executer/exconfig.c | 85 | ||||
-rw-r--r-- | drivers/acpi/executer/excreate.c | 14 | ||||
-rw-r--r-- | drivers/acpi/executer/exfldio.c | 5 | ||||
-rw-r--r-- | drivers/acpi/executer/exregion.c | 9 |
4 files changed, 52 insertions, 61 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index c8341fa5fe01..dd43b00e18b5 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig") | |||
54 | 54 | ||
55 | /* Local prototypes */ | 55 | /* Local prototypes */ |
56 | static acpi_status | 56 | static acpi_status |
57 | acpi_ex_add_table(struct acpi_table_header *table, | 57 | acpi_ex_add_table(acpi_native_uint table_index, |
58 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
59 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
60 | 60 | ||
@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
74 | ******************************************************************************/ | 74 | ******************************************************************************/ |
75 | 75 | ||
76 | static acpi_status | 76 | static acpi_status |
77 | acpi_ex_add_table(struct acpi_table_header *table, | 77 | acpi_ex_add_table(acpi_native_uint table_index, |
78 | struct acpi_namespace_node *parent_node, | 78 | struct acpi_namespace_node *parent_node, |
79 | union acpi_operand_object **ddb_handle) | 79 | union acpi_operand_object **ddb_handle) |
80 | { | 80 | { |
81 | acpi_status status; | 81 | acpi_status status; |
82 | struct acpi_table_desc table_info; | ||
83 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
84 | 83 | ||
85 | ACPI_FUNCTION_TRACE(ex_add_table); | 84 | ACPI_FUNCTION_TRACE(ex_add_table); |
@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
98 | 97 | ||
99 | /* Install the new table into the local data structures */ | 98 | /* Install the new table into the local data structures */ |
100 | 99 | ||
101 | ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); | 100 | obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); |
102 | |||
103 | table_info.type = ACPI_TABLE_ID_SSDT; | ||
104 | table_info.pointer = table; | ||
105 | table_info.length = (acpi_size) table->length; | ||
106 | table_info.allocation = ACPI_MEM_ALLOCATED; | ||
107 | |||
108 | status = acpi_tb_install_table(&table_info); | ||
109 | obj_desc->reference.object = table_info.installed_desc; | ||
110 | |||
111 | if (ACPI_FAILURE(status)) { | ||
112 | if (status == AE_ALREADY_EXISTS) { | ||
113 | |||
114 | /* Table already exists, just return the handle */ | ||
115 | |||
116 | return_ACPI_STATUS(AE_OK); | ||
117 | } | ||
118 | goto cleanup; | ||
119 | } | ||
120 | 101 | ||
121 | /* Add the table to the namespace */ | 102 | /* Add the table to the namespace */ |
122 | 103 | ||
123 | status = acpi_ns_load_table(table_info.installed_desc, parent_node); | 104 | status = acpi_ns_load_table(table_index, parent_node); |
124 | if (ACPI_FAILURE(status)) { | 105 | if (ACPI_FAILURE(status)) { |
125 | 106 | acpi_ut_remove_reference(obj_desc); | |
126 | /* Uninstall table on error */ | 107 | *ddb_handle = NULL; |
127 | |||
128 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | ||
129 | goto cleanup; | ||
130 | } | 108 | } |
131 | 109 | ||
132 | return_ACPI_STATUS(AE_OK); | ||
133 | |||
134 | cleanup: | ||
135 | acpi_ut_remove_reference(obj_desc); | ||
136 | *ddb_handle = NULL; | ||
137 | return_ACPI_STATUS(status); | 110 | return_ACPI_STATUS(status); |
138 | } | 111 | } |
139 | 112 | ||
@@ -156,11 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
156 | { | 129 | { |
157 | acpi_status status; | 130 | acpi_status status; |
158 | union acpi_operand_object **operand = &walk_state->operands[0]; | 131 | union acpi_operand_object **operand = &walk_state->operands[0]; |
159 | struct acpi_table_header *table; | 132 | acpi_native_uint table_index; |
160 | struct acpi_namespace_node *parent_node; | 133 | struct acpi_namespace_node *parent_node; |
161 | struct acpi_namespace_node *start_node; | 134 | struct acpi_namespace_node *start_node; |
162 | struct acpi_namespace_node *parameter_node = NULL; | 135 | struct acpi_namespace_node *parameter_node = NULL; |
163 | union acpi_operand_object *ddb_handle; | 136 | union acpi_operand_object *ddb_handle; |
137 | struct acpi_table_header *table; | ||
164 | 138 | ||
165 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 139 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
166 | 140 | ||
@@ -182,7 +156,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
182 | 156 | ||
183 | status = acpi_tb_find_table(operand[0]->string.pointer, | 157 | status = acpi_tb_find_table(operand[0]->string.pointer, |
184 | operand[1]->string.pointer, | 158 | operand[1]->string.pointer, |
185 | operand[2]->string.pointer, &table); | 159 | operand[2]->string.pointer, &table_index); |
186 | if (ACPI_FAILURE(status)) { | 160 | if (ACPI_FAILURE(status)) { |
187 | if (status != AE_NOT_FOUND) { | 161 | if (status != AE_NOT_FOUND) { |
188 | return_ACPI_STATUS(status); | 162 | return_ACPI_STATUS(status); |
@@ -245,7 +219,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
245 | 219 | ||
246 | /* Load the table into the namespace */ | 220 | /* Load the table into the namespace */ |
247 | 221 | ||
248 | status = acpi_ex_add_table(table, parent_node, &ddb_handle); | 222 | status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); |
249 | if (ACPI_FAILURE(status)) { | 223 | if (ACPI_FAILURE(status)) { |
250 | return_ACPI_STATUS(status); | 224 | return_ACPI_STATUS(status); |
251 | } | 225 | } |
@@ -266,9 +240,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
266 | } | 240 | } |
267 | } | 241 | } |
268 | 242 | ||
269 | ACPI_INFO((AE_INFO, | 243 | status = acpi_get_table_by_index(table_index, &table); |
270 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | 244 | if (ACPI_SUCCESS(status)) { |
271 | table->signature, table->oem_id, table->oem_table_id)); | 245 | ACPI_INFO((AE_INFO, |
246 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | ||
247 | table->signature, table->oem_id, | ||
248 | table->oem_table_id)); | ||
249 | } | ||
272 | 250 | ||
273 | *return_desc = ddb_handle; | 251 | *return_desc = ddb_handle; |
274 | return_ACPI_STATUS(status); | 252 | return_ACPI_STATUS(status); |
@@ -298,6 +276,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
298 | union acpi_operand_object *ddb_handle; | 276 | union acpi_operand_object *ddb_handle; |
299 | union acpi_operand_object *buffer_desc = NULL; | 277 | union acpi_operand_object *buffer_desc = NULL; |
300 | struct acpi_table_header *table_ptr = NULL; | 278 | struct acpi_table_header *table_ptr = NULL; |
279 | acpi_native_uint table_index; | ||
301 | acpi_physical_address address; | 280 | acpi_physical_address address; |
302 | struct acpi_table_header table_header; | 281 | struct acpi_table_header table_header; |
303 | acpi_integer temp; | 282 | acpi_integer temp; |
@@ -420,8 +399,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
420 | 399 | ||
421 | /* The table must be either an SSDT or a PSDT */ | 400 | /* The table must be either an SSDT or a PSDT */ |
422 | 401 | ||
423 | if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && | 402 | if ((!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_PSDT)) && |
424 | (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { | 403 | (!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_SSDT))) { |
425 | ACPI_ERROR((AE_INFO, | 404 | ACPI_ERROR((AE_INFO, |
426 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", | 405 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", |
427 | table_ptr->signature)); | 406 | table_ptr->signature)); |
@@ -429,9 +408,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
429 | goto cleanup; | 408 | goto cleanup; |
430 | } | 409 | } |
431 | 410 | ||
432 | /* Install the new table into the local data structures */ | 411 | /* |
412 | * Install the new table into the local data structures | ||
413 | */ | ||
414 | status = acpi_tb_add_table(table_ptr, &table_index); | ||
415 | if (ACPI_FAILURE(status)) { | ||
416 | return_ACPI_STATUS(status); | ||
417 | } | ||
433 | 418 | ||
434 | status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); | 419 | status = |
420 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | ||
435 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
436 | 422 | ||
437 | /* On error, table_ptr was deallocated above */ | 423 | /* On error, table_ptr was deallocated above */ |
@@ -477,7 +463,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
477 | { | 463 | { |
478 | acpi_status status = AE_OK; | 464 | acpi_status status = AE_OK; |
479 | union acpi_operand_object *table_desc = ddb_handle; | 465 | union acpi_operand_object *table_desc = ddb_handle; |
480 | struct acpi_table_desc *table_info; | 466 | acpi_native_uint table_index; |
481 | 467 | ||
482 | ACPI_FUNCTION_TRACE(ex_unload_table); | 468 | ACPI_FUNCTION_TRACE(ex_unload_table); |
483 | 469 | ||
@@ -493,19 +479,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
493 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 479 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
494 | } | 480 | } |
495 | 481 | ||
496 | /* Get the actual table descriptor from the ddb_handle */ | 482 | /* Get the table index from the ddb_handle */ |
497 | 483 | ||
498 | table_info = (struct acpi_table_desc *)table_desc->reference.object; | 484 | table_index = (acpi_native_uint) table_desc->reference.object; |
499 | 485 | ||
500 | /* | 486 | /* |
501 | * Delete the entire namespace under this table Node | 487 | * Delete the entire namespace under this table Node |
502 | * (Offset contains the table_id) | 488 | * (Offset contains the table_id) |
503 | */ | 489 | */ |
504 | acpi_ns_delete_namespace_by_owner(table_info->owner_id); | 490 | acpi_tb_delete_namespace_by_owner(table_index); |
505 | 491 | acpi_tb_release_owner_id(table_index); | |
506 | /* Delete the table itself */ | ||
507 | 492 | ||
508 | (void)acpi_tb_uninstall_table(table_info->installed_desc); | 493 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
509 | 494 | ||
510 | /* Delete the table descriptor (ddb_handle) */ | 495 | /* Delete the table descriptor (ddb_handle) */ |
511 | 496 | ||
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 34eec82c1b1e..a4d29b2d086f 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c | |||
@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
359 | union acpi_operand_object **operand = &walk_state->operands[0]; | 359 | union acpi_operand_object **operand = &walk_state->operands[0]; |
360 | union acpi_operand_object *obj_desc; | 360 | union acpi_operand_object *obj_desc; |
361 | struct acpi_namespace_node *node; | 361 | struct acpi_namespace_node *node; |
362 | struct acpi_table_header *table; | ||
363 | union acpi_operand_object *region_obj2; | 362 | union acpi_operand_object *region_obj2; |
363 | acpi_native_uint table_index; | ||
364 | struct acpi_table_header *table; | ||
364 | 365 | ||
365 | ACPI_FUNCTION_TRACE(ex_create_table_region); | 366 | ACPI_FUNCTION_TRACE(ex_create_table_region); |
366 | 367 | ||
@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
380 | 381 | ||
381 | status = acpi_tb_find_table(operand[1]->string.pointer, | 382 | status = acpi_tb_find_table(operand[1]->string.pointer, |
382 | operand[2]->string.pointer, | 383 | operand[2]->string.pointer, |
383 | operand[3]->string.pointer, &table); | 384 | operand[3]->string.pointer, &table_index); |
384 | if (ACPI_FAILURE(status)) { | 385 | if (ACPI_FAILURE(status)) { |
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
395 | region_obj2 = obj_desc->common.next_object; | 396 | region_obj2 = obj_desc->common.next_object; |
396 | region_obj2->extra.region_context = NULL; | 397 | region_obj2->extra.region_context = NULL; |
397 | 398 | ||
399 | status = acpi_get_table_by_index(table_index, &table); | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | return_ACPI_STATUS(status); | ||
402 | } | ||
403 | |||
398 | /* Init the region from the operands */ | 404 | /* Init the region from the operands */ |
399 | 405 | ||
400 | obj_desc->region.space_id = REGION_DATA_TABLE; | 406 | obj_desc->region.space_id = REGION_DATA_TABLE; |
@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start, | |||
553 | 559 | ||
554 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | 560 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); |
555 | if (!obj_desc) { | 561 | if (!obj_desc) { |
556 | return_ACPI_STATUS(AE_NO_MEMORY); | 562 | status = AE_NO_MEMORY; |
563 | goto exit; | ||
557 | } | 564 | } |
558 | 565 | ||
559 | /* Save the method's AML pointer and length */ | 566 | /* Save the method's AML pointer and length */ |
@@ -597,6 +604,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
597 | 604 | ||
598 | acpi_ut_remove_reference(obj_desc); | 605 | acpi_ut_remove_reference(obj_desc); |
599 | 606 | ||
607 | exit: | ||
600 | /* Remove a reference to the operand */ | 608 | /* Remove a reference to the operand */ |
601 | 609 | ||
602 | acpi_ut_remove_reference(operand[1]); | 610 | acpi_ut_remove_reference(operand[1]); |
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 40f0bee6faa5..b3f30d83d50a 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
257 | } | 257 | } |
258 | 258 | ||
259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, | 259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, |
260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", | 260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", |
261 | acpi_ut_get_region_name(rgn_desc->region. | 261 | acpi_ut_get_region_name(rgn_desc->region. |
262 | space_id), | 262 | space_id), |
263 | rgn_desc->region.space_id, | 263 | rgn_desc->region.space_id, |
264 | obj_desc->common_field.access_byte_width, | 264 | obj_desc->common_field.access_byte_width, |
265 | obj_desc->common_field.base_byte_offset, | 265 | obj_desc->common_field.base_byte_offset, |
266 | field_datum_byte_offset, | 266 | field_datum_byte_offset, (void *)address)); |
267 | ACPI_FORMAT_UINT64(address))); | ||
268 | 267 | ||
269 | /* Invoke the appropriate address_space/op_region handler */ | 268 | /* Invoke the appropriate address_space/op_region handler */ |
270 | 269 | ||
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 3cc97ba48b36..496744774859 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c | |||
@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
155 | 155 | ||
156 | /* Create a new mapping starting at the address given */ | 156 | /* Create a new mapping starting at the address given */ |
157 | 157 | ||
158 | status = acpi_os_map_memory(address, window_size, | 158 | mem_info->mapped_logical_address = |
159 | (void **)&mem_info-> | 159 | acpi_os_map_memory((acpi_native_uint) address, window_size); |
160 | mapped_logical_address); | 160 | if (!mem_info->mapped_logical_address) { |
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | 161 | ACPI_ERROR((AE_INFO, |
163 | "Could not map memory at %8.8X%8.8X, size %X", | 162 | "Could not map memory at %8.8X%8.8X, size %X", |
164 | ACPI_FORMAT_UINT64(address), | 163 | ACPI_FORMAT_UINT64(address), |
165 | (u32) window_size)); | 164 | (u32) window_size)); |
166 | mem_info->mapped_length = 0; | 165 | mem_info->mapped_length = 0; |
167 | return_ACPI_STATUS(status); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
168 | } | 167 | } |
169 | 168 | ||
170 | /* Save the physical address and mapping size */ | 169 | /* Save the physical address and mapping size */ |