diff options
Diffstat (limited to 'drivers/acpi/acpica/tbutils.c')
-rw-r--r-- | drivers/acpi/acpica/tbutils.c | 171 |
1 files changed, 21 insertions, 150 deletions
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index a4702eee91a8..6c31d77cece0 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -178,9 +178,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); | 180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); |
181 | acpi_tb_delete_table(table_desc); | 181 | acpi_tb_uninstall_table(table_desc); |
182 | table_desc->pointer = new_table; | 182 | |
183 | table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 183 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
184 | tables[ACPI_TABLE_INDEX_DSDT], | ||
185 | ACPI_PTR_TO_PHYSADDR(new_table), | ||
186 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
187 | new_table); | ||
184 | 188 | ||
185 | ACPI_INFO((AE_INFO, | 189 | ACPI_INFO((AE_INFO, |
186 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", | 190 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", |
@@ -191,116 +195,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
191 | 195 | ||
192 | /******************************************************************************* | 196 | /******************************************************************************* |
193 | * | 197 | * |
194 | * FUNCTION: acpi_tb_install_table | ||
195 | * | ||
196 | * PARAMETERS: address - Physical address of DSDT or FACS | ||
197 | * signature - Table signature, NULL if no need to | ||
198 | * match | ||
199 | * table_index - Index into root table array | ||
200 | * | ||
201 | * RETURN: None | ||
202 | * | ||
203 | * DESCRIPTION: Install an ACPI table into the global data structure. The | ||
204 | * table override mechanism is called to allow the host | ||
205 | * OS to replace any table before it is installed in the root | ||
206 | * table array. | ||
207 | * | ||
208 | ******************************************************************************/ | ||
209 | |||
210 | void | ||
211 | acpi_tb_install_table(acpi_physical_address address, | ||
212 | char *signature, u32 table_index) | ||
213 | { | ||
214 | struct acpi_table_header *table; | ||
215 | struct acpi_table_header *final_table; | ||
216 | struct acpi_table_desc *table_desc; | ||
217 | |||
218 | if (!address) { | ||
219 | ACPI_ERROR((AE_INFO, | ||
220 | "Null physical address for ACPI table [%s]", | ||
221 | signature)); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | /* Map just the table header */ | ||
226 | |||
227 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
228 | if (!table) { | ||
229 | ACPI_ERROR((AE_INFO, | ||
230 | "Could not map memory for table [%s] at %p", | ||
231 | signature, ACPI_CAST_PTR(void, address))); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
236 | |||
237 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | ||
238 | ACPI_BIOS_ERROR((AE_INFO, | ||
239 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
240 | *ACPI_CAST_PTR(u32, table->signature), | ||
241 | signature)); | ||
242 | goto unmap_and_exit; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Initialize the table entry. Set the pointer to NULL, since the | ||
247 | * table is not fully mapped at this time. | ||
248 | */ | ||
249 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
250 | |||
251 | table_desc->address = address; | ||
252 | table_desc->pointer = NULL; | ||
253 | table_desc->length = table->length; | ||
254 | table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
255 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
256 | |||
257 | /* | ||
258 | * ACPI Table Override: | ||
259 | * | ||
260 | * Before we install the table, let the host OS override it with a new | ||
261 | * one if desired. Any table within the RSDT/XSDT can be replaced, | ||
262 | * including the DSDT which is pointed to by the FADT. | ||
263 | * | ||
264 | * NOTE: If the table is overridden, then final_table will contain a | ||
265 | * mapped pointer to the full new table. If the table is not overridden, | ||
266 | * or if there has been a physical override, then the table will be | ||
267 | * fully mapped later (in verify table). In any case, we must | ||
268 | * unmap the header that was mapped above. | ||
269 | */ | ||
270 | final_table = acpi_tb_table_override(table, table_desc); | ||
271 | if (!final_table) { | ||
272 | final_table = table; /* There was no override */ | ||
273 | } | ||
274 | |||
275 | acpi_tb_print_table_header(table_desc->address, final_table); | ||
276 | |||
277 | /* Set the global integer width (based upon revision of the DSDT) */ | ||
278 | |||
279 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | ||
280 | acpi_ut_set_integer_width(final_table->revision); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * If we have a physical override during this early loading of the ACPI | ||
285 | * tables, unmap the table for now. It will be mapped again later when | ||
286 | * it is actually used. This supports very early loading of ACPI tables, | ||
287 | * before virtual memory is fully initialized and running within the | ||
288 | * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE | ||
289 | * flag set and will not be deleted below. | ||
290 | */ | ||
291 | if (final_table != table) { | ||
292 | acpi_tb_delete_table(table_desc); | ||
293 | } | ||
294 | |||
295 | unmap_and_exit: | ||
296 | |||
297 | /* Always unmap the table header that we mapped above */ | ||
298 | |||
299 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
300 | } | ||
301 | |||
302 | /******************************************************************************* | ||
303 | * | ||
304 | * FUNCTION: acpi_tb_get_root_table_entry | 198 | * FUNCTION: acpi_tb_get_root_table_entry |
305 | * | 199 | * |
306 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry | 200 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry |
@@ -464,6 +358,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
464 | u32 length; | 358 | u32 length; |
465 | u8 *table_entry; | 359 | u8 *table_entry; |
466 | acpi_status status; | 360 | acpi_status status; |
361 | u32 table_index; | ||
467 | 362 | ||
468 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | 363 | ACPI_FUNCTION_TRACE(tb_parse_root_table); |
469 | 364 | ||
@@ -573,31 +468,24 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
573 | /* Initialize the root table array from the RSDT/XSDT */ | 468 | /* Initialize the root table array from the RSDT/XSDT */ |
574 | 469 | ||
575 | for (i = 0; i < table_count; i++) { | 470 | for (i = 0; i < table_count; i++) { |
576 | if (acpi_gbl_root_table_list.current_table_count >= | ||
577 | acpi_gbl_root_table_list.max_table_count) { | ||
578 | |||
579 | /* There is no more room in the root table array, attempt resize */ | ||
580 | |||
581 | status = acpi_tb_resize_root_table_list(); | ||
582 | if (ACPI_FAILURE(status)) { | ||
583 | ACPI_WARNING((AE_INFO, | ||
584 | "Truncating %u table entries!", | ||
585 | (unsigned) (table_count - | ||
586 | (acpi_gbl_root_table_list. | ||
587 | current_table_count - | ||
588 | 2)))); | ||
589 | break; | ||
590 | } | ||
591 | } | ||
592 | 471 | ||
593 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ | 472 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ |
594 | 473 | ||
595 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | 474 | status = |
596 | current_table_count].address = | 475 | acpi_tb_install_standard_table(acpi_tb_get_root_table_entry |
597 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); | 476 | (table_entry, |
477 | table_entry_size), | ||
478 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, | ||
479 | FALSE, TRUE, &table_index); | ||
480 | |||
481 | if (ACPI_SUCCESS(status) && | ||
482 | ACPI_COMPARE_NAME(&acpi_gbl_root_table_list. | ||
483 | tables[table_index].signature, | ||
484 | ACPI_SIG_FADT)) { | ||
485 | acpi_tb_parse_fadt(table_index); | ||
486 | } | ||
598 | 487 | ||
599 | table_entry += table_entry_size; | 488 | table_entry += table_entry_size; |
600 | acpi_gbl_root_table_list.current_table_count++; | ||
601 | } | 489 | } |
602 | 490 | ||
603 | /* | 491 | /* |
@@ -606,22 +494,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
606 | */ | 494 | */ |
607 | acpi_os_unmap_memory(table, length); | 495 | acpi_os_unmap_memory(table, length); |
608 | 496 | ||
609 | /* | ||
610 | * Complete the initialization of the root table array by examining | ||
611 | * the header of each table | ||
612 | */ | ||
613 | for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
614 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | ||
615 | address, NULL, i); | ||
616 | |||
617 | /* Special case for FADT - validate it then get the DSDT and FACS */ | ||
618 | |||
619 | if (ACPI_COMPARE_NAME | ||
620 | (&acpi_gbl_root_table_list.tables[i].signature, | ||
621 | ACPI_SIG_FADT)) { | ||
622 | acpi_tb_parse_fadt(i); | ||
623 | } | ||
624 | } | ||
625 | |||
626 | return_ACPI_STATUS(AE_OK); | 497 | return_ACPI_STATUS(AE_OK); |
627 | } | 498 | } |