aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/tbutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/tbutils.c')
-rw-r--r--drivers/acpi/acpica/tbutils.c171
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
210void
211acpi_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
295unmap_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}