@@ -35,7 +35,8 @@ acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
acpi_status
acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
- acpi_physical_address address, u8 flags);
+ acpi_physical_address address,
+ u8 flags, struct acpi_table_header *table);
void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
@@ -86,6 +87,7 @@ acpi_tb_release_table(struct acpi_table_header *table,
acpi_status
acpi_tb_install_standard_table(acpi_physical_address address,
u8 flags,
+ struct acpi_table_header *table,
u8 reload, u8 override, u32 *table_index);
void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc);
@@ -95,7 +97,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node);
acpi_status
acpi_tb_install_and_load_table(acpi_physical_address address,
- u8 flags, u8 override, u32 *table_index);
+ u8 flags,
+ struct acpi_table_header *table,
+ u8 override, u32 *table_index);
acpi_status acpi_tb_unload_table(u32 table_index);
@@ -411,7 +411,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
acpi_ex_exit_interpreter();
status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
- TRUE, &table_index);
+ table, TRUE, &table_index);
acpi_ex_enter_interpreter();
if (ACPI_FAILURE(status)) {
@@ -89,14 +89,27 @@ acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
{
/*
- * Initialize the table descriptor. Set the pointer to NULL, since the
- * table is not fully mapped at this time.
+ * Initialize the table descriptor. Set the pointer to NULL for external
+ * tables, since the table is not fully mapped at this time.
*/
memset(table_desc, 0, sizeof(struct acpi_table_desc));
table_desc->address = address;
table_desc->length = table->length;
table_desc->flags = flags;
ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
+
+ switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+ table_desc->pointer = table;
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+ default:
+
+ break;
+ }
}
/*******************************************************************************
@@ -132,9 +145,7 @@ acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
- table = ACPI_CAST_PTR(struct acpi_table_header,
- ACPI_PHYSADDR_TO_PTR(table_desc->
- address));
+ table = table_desc->pointer;
break;
default:
@@ -196,6 +207,8 @@ acpi_tb_release_table(struct acpi_table_header *table,
* PARAMETERS: table_desc - Table descriptor to be acquired
* address - Address of the table
* flags - Allocation flags of the table
+ * table - Pointer to the table (required for virtual
+ * origins, optional for physical)
*
* RETURN: Status
*
@@ -208,49 +221,52 @@ acpi_tb_release_table(struct acpi_table_header *table,
acpi_status
acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
- acpi_physical_address address, u8 flags)
+ acpi_physical_address address,
+ u8 flags, struct acpi_table_header *table)
{
- struct acpi_table_header *table_header;
+ u8 mapped_table = FALSE;
switch (flags & ACPI_TABLE_ORIGIN_MASK) {
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
/* Get the length of the full table from the header */
- table_header =
- acpi_os_map_memory(address,
- sizeof(struct acpi_table_header));
- if (!table_header) {
- return (AE_NO_MEMORY);
+ if (!table) {
+ table =
+ acpi_os_map_memory(address,
+ sizeof(struct
+ acpi_table_header));
+ if (!table) {
+ return (AE_NO_MEMORY);
+ }
+
+ mapped_table = TRUE;
}
- acpi_tb_init_table_descriptor(table_desc, address, flags,
- table_header);
- acpi_os_unmap_memory(table_header,
- sizeof(struct acpi_table_header));
- return (AE_OK);
+ break;
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
- table_header = ACPI_CAST_PTR(struct acpi_table_header,
- ACPI_PHYSADDR_TO_PTR(address));
- if (!table_header) {
- return (AE_NO_MEMORY);
+ if (!table) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- acpi_tb_init_table_descriptor(table_desc, address, flags,
- table_header);
- return (AE_OK);
+ break;
default:
- break;
+ /* Table is not valid yet */
+
+ return (AE_NO_MEMORY);
}
- /* Table is not valid yet */
+ acpi_tb_init_table_descriptor(table_desc, address, flags, table);
+ if (mapped_table) {
+ acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ }
- return (AE_NO_MEMORY);
+ return (AE_OK);
}
/*******************************************************************************
@@ -335,7 +351,19 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
acpi_tb_release_table(table_desc->pointer, table_desc->length,
table_desc->flags);
- table_desc->pointer = NULL;
+
+ switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+ case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+ table_desc->pointer = NULL;
+ break;
+
+ case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+ case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+ default:
+
+ break;
+ }
return_VOID;
}
@@ -959,6 +987,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
*
* PARAMETERS: address - Physical address of the table
* flags - Allocation flags of the table
+ * table - Pointer to the table (required for
+ * virtual origins, optional for
+ * physical)
* override - Whether override should be performed
* table_index - Where table index is returned
*
@@ -970,7 +1001,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
acpi_status
acpi_tb_install_and_load_table(acpi_physical_address address,
- u8 flags, u8 override, u32 *table_index)
+ u8 flags,
+ struct acpi_table_header *table,
+ u8 override, u32 *table_index)
{
acpi_status status;
u32 i;
@@ -979,7 +1012,7 @@ acpi_tb_install_and_load_table(acpi_physical_address address,
/* Install the table and load it into the namespace */
- status = acpi_tb_install_standard_table(address, flags, TRUE,
+ status = acpi_tb_install_standard_table(address, flags, table, TRUE,
override, &i);
if (ACPI_FAILURE(status)) {
goto exit;
@@ -313,7 +313,7 @@ void acpi_tb_parse_fadt(void)
acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT.
Xdsdt,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
- FALSE, TRUE, &acpi_gbl_dsdt_index);
+ NULL, FALSE, TRUE, &acpi_gbl_dsdt_index);
/* If Hardware Reduced flag is set, there is no FACS */
@@ -322,14 +322,14 @@ void acpi_tb_parse_fadt(void)
acpi_tb_install_standard_table((acpi_physical_address)
acpi_gbl_FADT.facs,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
- FALSE, TRUE,
+ NULL, FALSE, TRUE,
&acpi_gbl_facs_index);
}
if (acpi_gbl_FADT.Xfacs) {
acpi_tb_install_standard_table((acpi_physical_address)
acpi_gbl_FADT.Xfacs,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
- FALSE, TRUE,
+ NULL, FALSE, TRUE,
&acpi_gbl_xfacs_index);
}
}
@@ -79,6 +79,8 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
* PARAMETERS: address - Address of the table (might be a virtual
* address depending on the table_flags)
* flags - Flags for the table
+ * table - Pointer to the table (required for virtual
+ * origins, optional for physical)
* reload - Whether reload should be performed
* override - Whether override should be performed
* table_index - Where the table index is returned
@@ -96,6 +98,7 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
acpi_status
acpi_tb_install_standard_table(acpi_physical_address address,
u8 flags,
+ struct acpi_table_header *table,
u8 reload, u8 override, u32 *table_index)
{
u32 i;
@@ -106,7 +109,8 @@ acpi_tb_install_standard_table(acpi_physical_address address,
/* Acquire a temporary table descriptor for validation */
- status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
+ status =
+ acpi_tb_acquire_temp_table(&new_table_desc, address, flags, table);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO,
"Could not acquire table length at %8.8X%8.8X",
@@ -209,7 +213,8 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
if (ACPI_SUCCESS(status) && table) {
acpi_tb_acquire_temp_table(&new_table_desc,
ACPI_PTR_TO_PHYSADDR(table),
- ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
+ ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
+ table);
ACPI_ERROR_ONLY(override_type = "Logical");
goto finish_override;
}
@@ -220,7 +225,8 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
&address, &length);
if (ACPI_SUCCESS(status) && address && length) {
acpi_tb_acquire_temp_table(&new_table_desc, address,
- ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
+ NULL);
ACPI_ERROR_ONLY(override_type = "Physical");
goto finish_override;
}
@@ -289,7 +295,8 @@ void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
- ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
+ ACPI_FREE(table_desc->pointer);
+ table_desc->pointer = NULL;
}
table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
@@ -328,7 +328,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
status = acpi_tb_install_standard_table(address,
ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
- FALSE, TRUE,
+ NULL, FALSE, TRUE,
&table_index);
if (ACPI_SUCCESS(status) &&
@@ -227,9 +227,7 @@ acpi_status acpi_tb_load_namespace(void)
*
* FUNCTION: acpi_install_table
*
- * PARAMETERS: address - Address of the ACPI table to be installed.
- * physical - Whether the address is a physical table
- * address or not
+ * PARAMETERS: table - Pointer to the ACPI table to be installed.
*
* RETURN: Status
*
@@ -240,28 +238,54 @@ acpi_status acpi_tb_load_namespace(void)
******************************************************************************/
acpi_status ACPI_INIT_FUNCTION
-acpi_install_table(acpi_physical_address address, u8 physical)
+acpi_install_table(struct acpi_table_header *table)
{
acpi_status status;
- u8 flags;
u32 table_index;
ACPI_FUNCTION_TRACE(acpi_install_table);
- if (physical) {
- flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
- } else {
- flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
- }
-
- status = acpi_tb_install_standard_table(address, flags,
- FALSE, FALSE, &table_index);
+ status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
+ ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
+ table, FALSE, FALSE,
+ &table_index);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_install_physical_table
+ *
+ * PARAMETERS: address - Address of the ACPI table to be installed.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dynamically install an ACPI table.
+ * Note: This function should only be invoked after
+ * acpi_initialize_tables() and before acpi_load_tables().
+ *
+ ******************************************************************************/
+acpi_status ACPI_INIT_FUNCTION
+acpi_install_physical_table(acpi_physical_address address)
+{
+ acpi_status status;
+ u32 table_index;
+
+ ACPI_FUNCTION_TRACE(acpi_install_physical_table);
+
+ status = acpi_tb_install_standard_table(address,
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
+ NULL, FALSE, FALSE,
+ &table_index);
+
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL_INIT(acpi_install_physical_table)
+
/*******************************************************************************
*
* FUNCTION: acpi_load_table
@@ -298,7 +322,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table, u32 *table_idx)
ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
- FALSE, &table_index);
+ table, FALSE, &table_index);
if (table_idx) {
*table_idx = table_index;
}
@@ -723,7 +723,7 @@ static void __init acpi_table_initrd_scan(void)
/*
* Mark the table to avoid being used in
* acpi_table_initrd_override(). Though this is not possible
- * because override is disabled in acpi_install_table().
+ * because override is disabled in acpi_install_physical_table().
*/
if (test_and_set_bit(table_index, acpi_initrd_installed)) {
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
@@ -734,7 +734,7 @@ static void __init acpi_table_initrd_scan(void)
table->signature, table->oem_id,
table->oem_table_id);
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
- acpi_install_table(acpi_tables_addr + table_offset, TRUE);
+ acpi_install_physical_table(acpi_tables_addr + table_offset);
next_table:
table_offset += table_length;
table_index++;
@@ -454,9 +454,11 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
* ACPI table load/unload interfaces
*/
ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
- acpi_install_table(acpi_physical_address address,
- u8 physical))
+ acpi_install_table(struct acpi_table_header *table))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
+ acpi_install_physical_table(acpi_physical_address
+ address))
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_load_table(struct acpi_table_header *table,
u32 *table_idx))