aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-02-03 01:35:25 -0500
committerLen Brown <len.brown@intel.com>2009-03-26 16:38:19 -0400
commitac5f98db7be34cefc244026f882cf030debb7431 (patch)
tree7746bc75e1a8f4344b8673b5d2b54bc07147ca0f /drivers/acpi/acpica
parent4bbfb85da27c27e9cc9a7fef4bd75df6361152ff (diff)
ACPICA: Allow OS override of all ACPI tables
Previously, the table override mechanism was implemented for the DSDT only. Now, any table in the RSDT/XSDT can be replaced by the host OS. (including the DSDT). Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/acglobal.h1
-rw-r--r--drivers/acpi/acpica/tbutils.c59
-rw-r--r--drivers/acpi/acpica/tbxface.c31
3 files changed, 47 insertions, 44 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5c68fc..634fb0785e7e 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -371,7 +371,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
371ACPI_EXTERN char *acpi_gbl_db_filename; 371ACPI_EXTERN char *acpi_gbl_db_filename;
372ACPI_EXTERN u32 acpi_gbl_db_debug_level; 372ACPI_EXTERN u32 acpi_gbl_db_debug_level;
373ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; 373ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
374ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
375ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; 374ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
376 375
377/* 376/*
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce48985720..e285bedbb989 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -287,7 +287,10 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
287 * 287 *
288 * RETURN: None 288 * RETURN: None
289 * 289 *
290 * DESCRIPTION: Install an ACPI table into the global data structure. 290 * DESCRIPTION: Install an ACPI table into the global data structure. The
291 * table override mechanism is implemented here to allow the host
292 * OS to replace any table before it is installed in the root
293 * table array.
291 * 294 *
292 ******************************************************************************/ 295 ******************************************************************************/
293 296
@@ -295,7 +298,10 @@ void
295acpi_tb_install_table(acpi_physical_address address, 298acpi_tb_install_table(acpi_physical_address address,
296 u8 flags, char *signature, u32 table_index) 299 u8 flags, char *signature, u32 table_index)
297{ 300{
298 struct acpi_table_header *table; 301 acpi_status status;
302 struct acpi_table_header *table_to_install;
303 struct acpi_table_header *mapped_table;
304 struct acpi_table_header *override_table = NULL;
299 305
300 if (!address) { 306 if (!address) {
301 ACPI_ERROR((AE_INFO, 307 ACPI_ERROR((AE_INFO,
@@ -306,41 +312,68 @@ acpi_tb_install_table(acpi_physical_address address,
306 312
307 /* Map just the table header */ 313 /* Map just the table header */
308 314
309 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); 315 mapped_table =
310 if (!table) { 316 acpi_os_map_memory(address, sizeof(struct acpi_table_header));
317 if (!mapped_table) {
311 return; 318 return;
312 } 319 }
313 320
314 /* If a particular signature is expected, signature must match */ 321 /* If a particular signature is expected (DSDT/FACS), it must match */
315 322
316 if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { 323 if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
317 ACPI_ERROR((AE_INFO, 324 ACPI_ERROR((AE_INFO,
318 "Invalid signature 0x%X for ACPI table [%s]", 325 "Invalid signature 0x%X for ACPI table, expected [%s]",
319 *ACPI_CAST_PTR(u32, table->signature), signature)); 326 *ACPI_CAST_PTR(u32, mapped_table->signature),
327 signature));
320 goto unmap_and_exit; 328 goto unmap_and_exit;
321 } 329 }
322 330
331 /*
332 * ACPI Table Override:
333 *
334 * Before we install the table, let the host OS override it with a new
335 * one if desired. Any table within the RSDT/XSDT can be replaced,
336 * including the DSDT which is pointed to by the FADT.
337 */
338 status = acpi_os_table_override(mapped_table, &override_table);
339 if (ACPI_SUCCESS(status) && override_table) {
340 ACPI_INFO((AE_INFO,
341 "%4.4s @ 0x%p Table override, replaced with:",
342 mapped_table->signature, ACPI_CAST_PTR(void,
343 address)));
344
345 acpi_gbl_root_table_list.tables[table_index].pointer =
346 override_table;
347 flags = ACPI_TABLE_ORIGIN_OVERRIDE;
348 address = ACPI_PTR_TO_PHYSADDR(override_table);
349
350 table_to_install = override_table;
351 } else {
352 table_to_install = mapped_table;
353 }
354
323 /* Initialize the table entry */ 355 /* Initialize the table entry */
324 356
325 acpi_gbl_root_table_list.tables[table_index].address = address; 357 acpi_gbl_root_table_list.tables[table_index].address = address;
326 acpi_gbl_root_table_list.tables[table_index].length = table->length; 358 acpi_gbl_root_table_list.tables[table_index].length =
359 table_to_install->length;
327 acpi_gbl_root_table_list.tables[table_index].flags = flags; 360 acpi_gbl_root_table_list.tables[table_index].flags = flags;
328 361
329 ACPI_MOVE_32_TO_32(& 362 ACPI_MOVE_32_TO_32(&
330 (acpi_gbl_root_table_list.tables[table_index]. 363 (acpi_gbl_root_table_list.tables[table_index].
331 signature), table->signature); 364 signature), table_to_install->signature);
332 365
333 acpi_tb_print_table_header(address, table); 366 acpi_tb_print_table_header(address, table_to_install);
334 367
335 if (table_index == ACPI_TABLE_INDEX_DSDT) { 368 if (table_index == ACPI_TABLE_INDEX_DSDT) {
336 369
337 /* Global integer width is based upon revision of the DSDT */ 370 /* Global integer width is based upon revision of the DSDT */
338 371
339 acpi_ut_set_integer_width(table->revision); 372 acpi_ut_set_integer_width(table_to_install->revision);
340 } 373 }
341 374
342 unmap_and_exit: 375 unmap_and_exit:
343 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); 376 acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
344} 377}
345 378
346/******************************************************************************* 379/*******************************************************************************
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index c3e841f3cde9..f3f95e386334 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -491,7 +491,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
491static acpi_status acpi_tb_load_namespace(void) 491static acpi_status acpi_tb_load_namespace(void)
492{ 492{
493 acpi_status status; 493 acpi_status status;
494 struct acpi_table_header *table;
495 u32 i; 494 u32 i;
496 495
497 ACPI_FUNCTION_TRACE(tb_load_namespace); 496 ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -515,41 +514,13 @@ static acpi_status acpi_tb_load_namespace(void)
515 goto unlock_and_exit; 514 goto unlock_and_exit;
516 } 515 }
517 516
518 /* 517 /* A valid DSDT is required */
519 * Find DSDT table
520 */
521 status =
522 acpi_os_table_override(acpi_gbl_root_table_list.
523 tables[ACPI_TABLE_INDEX_DSDT].pointer,
524 &table);
525 if (ACPI_SUCCESS(status) && table) {
526 /*
527 * DSDT table has been found
528 */
529 acpi_tb_delete_table(&acpi_gbl_root_table_list.
530 tables[ACPI_TABLE_INDEX_DSDT]);
531 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
532 table;
533 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
534 table->length;
535 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
536 ACPI_TABLE_ORIGIN_UNKNOWN;
537
538 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
539 acpi_tb_print_table_header(0, table);
540
541 if (no_auto_ssdt == 0) {
542 printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
543 }
544 }
545 518
546 status = 519 status =
547 acpi_tb_verify_table(&acpi_gbl_root_table_list. 520 acpi_tb_verify_table(&acpi_gbl_root_table_list.
548 tables[ACPI_TABLE_INDEX_DSDT]); 521 tables[ACPI_TABLE_INDEX_DSDT]);
549 if (ACPI_FAILURE(status)) { 522 if (ACPI_FAILURE(status)) {
550 523
551 /* A valid DSDT is required */
552
553 status = AE_NO_ACPI_TABLES; 524 status = AE_NO_ACPI_TABLES;
554 goto unlock_and_exit; 525 goto unlock_and_exit;
555 } 526 }