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.c285
1 files changed, 28 insertions, 257 deletions
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 9fb85f38de90..6b1ca9991b90 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -49,8 +49,6 @@
49ACPI_MODULE_NAME("tbutils") 49ACPI_MODULE_NAME("tbutils")
50 50
51/* Local prototypes */ 51/* Local prototypes */
52static acpi_status acpi_tb_validate_xsdt(acpi_physical_address address);
53
54static acpi_physical_address 52static acpi_physical_address
55acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); 53acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
56 54
@@ -178,9 +176,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
178 } 176 }
179 177
180 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); 178 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
181 acpi_tb_delete_table(table_desc); 179 acpi_tb_uninstall_table(table_desc);
182 table_desc->pointer = new_table; 180
183 table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; 181 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
182 tables[ACPI_TABLE_INDEX_DSDT],
183 ACPI_PTR_TO_PHYSADDR(new_table),
184 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
185 new_table);
184 186
185 ACPI_INFO((AE_INFO, 187 ACPI_INFO((AE_INFO,
186 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 188 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
@@ -191,116 +193,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
191 193
192/******************************************************************************* 194/*******************************************************************************
193 * 195 *
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 196 * FUNCTION: acpi_tb_get_root_table_entry
305 * 197 *
306 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry 198 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry
@@ -357,87 +249,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
357 249
358/******************************************************************************* 250/*******************************************************************************
359 * 251 *
360 * FUNCTION: acpi_tb_validate_xsdt
361 *
362 * PARAMETERS: address - Physical address of the XSDT (from RSDP)
363 *
364 * RETURN: Status. AE_OK if the table appears to be valid.
365 *
366 * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does
367 * not contain any NULL entries. A problem that is seen in the
368 * field is that the XSDT exists, but is actually useless because
369 * of one or more (or all) NULL entries.
370 *
371 ******************************************************************************/
372
373static acpi_status acpi_tb_validate_xsdt(acpi_physical_address xsdt_address)
374{
375 struct acpi_table_header *table;
376 u8 *next_entry;
377 acpi_physical_address address;
378 u32 length;
379 u32 entry_count;
380 acpi_status status;
381 u32 i;
382
383 /* Get the XSDT length */
384
385 table =
386 acpi_os_map_memory(xsdt_address, sizeof(struct acpi_table_header));
387 if (!table) {
388 return (AE_NO_MEMORY);
389 }
390
391 length = table->length;
392 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
393
394 /*
395 * Minimum XSDT length is the size of the standard ACPI header
396 * plus one physical address entry
397 */
398 if (length < (sizeof(struct acpi_table_header) + ACPI_XSDT_ENTRY_SIZE)) {
399 return (AE_INVALID_TABLE_LENGTH);
400 }
401
402 /* Map the entire XSDT */
403
404 table = acpi_os_map_memory(xsdt_address, length);
405 if (!table) {
406 return (AE_NO_MEMORY);
407 }
408
409 /* Get the number of entries and pointer to first entry */
410
411 status = AE_OK;
412 next_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header));
413 entry_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
414 ACPI_XSDT_ENTRY_SIZE);
415
416 /* Validate each entry (physical address) within the XSDT */
417
418 for (i = 0; i < entry_count; i++) {
419 address =
420 acpi_tb_get_root_table_entry(next_entry,
421 ACPI_XSDT_ENTRY_SIZE);
422 if (!address) {
423
424 /* Detected a NULL entry, XSDT is invalid */
425
426 status = AE_NULL_ENTRY;
427 break;
428 }
429
430 next_entry += ACPI_XSDT_ENTRY_SIZE;
431 }
432
433 /* Unmap table */
434
435 acpi_os_unmap_memory(table, length);
436 return (status);
437}
438
439/*******************************************************************************
440 *
441 * FUNCTION: acpi_tb_parse_root_table 252 * FUNCTION: acpi_tb_parse_root_table
442 * 253 *
443 * PARAMETERS: rsdp - Pointer to the RSDP 254 * PARAMETERS: rsdp - Pointer to the RSDP
@@ -461,10 +272,10 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
461 u32 table_count; 272 u32 table_count;
462 struct acpi_table_header *table; 273 struct acpi_table_header *table;
463 acpi_physical_address address; 274 acpi_physical_address address;
464 acpi_physical_address rsdt_address;
465 u32 length; 275 u32 length;
466 u8 *table_entry; 276 u8 *table_entry;
467 acpi_status status; 277 acpi_status status;
278 u32 table_index;
468 279
469 ACPI_FUNCTION_TRACE(tb_parse_root_table); 280 ACPI_FUNCTION_TRACE(tb_parse_root_table);
470 281
@@ -489,14 +300,11 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
489 * as per the ACPI specification. 300 * as per the ACPI specification.
490 */ 301 */
491 address = (acpi_physical_address) rsdp->xsdt_physical_address; 302 address = (acpi_physical_address) rsdp->xsdt_physical_address;
492 rsdt_address =
493 (acpi_physical_address) rsdp->rsdt_physical_address;
494 table_entry_size = ACPI_XSDT_ENTRY_SIZE; 303 table_entry_size = ACPI_XSDT_ENTRY_SIZE;
495 } else { 304 } else {
496 /* Root table is an RSDT (32-bit physical addresses) */ 305 /* Root table is an RSDT (32-bit physical addresses) */
497 306
498 address = (acpi_physical_address) rsdp->rsdt_physical_address; 307 address = (acpi_physical_address) rsdp->rsdt_physical_address;
499 rsdt_address = address;
500 table_entry_size = ACPI_RSDT_ENTRY_SIZE; 308 table_entry_size = ACPI_RSDT_ENTRY_SIZE;
501 } 309 }
502 310
@@ -506,24 +314,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
506 */ 314 */
507 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); 315 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
508 316
509 /*
510 * If it is present and used, validate the XSDT for access/size
511 * and ensure that all table entries are at least non-NULL
512 */
513 if (table_entry_size == ACPI_XSDT_ENTRY_SIZE) {
514 status = acpi_tb_validate_xsdt(address);
515 if (ACPI_FAILURE(status)) {
516 ACPI_BIOS_WARNING((AE_INFO,
517 "XSDT is invalid (%s), using RSDT",
518 acpi_format_exception(status)));
519
520 /* Fall back to the RSDT */
521
522 address = rsdt_address;
523 table_entry_size = ACPI_RSDT_ENTRY_SIZE;
524 }
525 }
526
527 /* Map the RSDT/XSDT table header to get the full table length */ 317 /* Map the RSDT/XSDT table header to get the full table length */
528 318
529 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); 319 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
@@ -576,55 +366,36 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
576 /* Initialize the root table array from the RSDT/XSDT */ 366 /* Initialize the root table array from the RSDT/XSDT */
577 367
578 for (i = 0; i < table_count; i++) { 368 for (i = 0; i < table_count; i++) {
579 if (acpi_gbl_root_table_list.current_table_count >=
580 acpi_gbl_root_table_list.max_table_count) {
581
582 /* There is no more room in the root table array, attempt resize */
583
584 status = acpi_tb_resize_root_table_list();
585 if (ACPI_FAILURE(status)) {
586 ACPI_WARNING((AE_INFO,
587 "Truncating %u table entries!",
588 (unsigned) (table_count -
589 (acpi_gbl_root_table_list.
590 current_table_count -
591 2))));
592 break;
593 }
594 }
595 369
596 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 370 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
597 371
598 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. 372 address =
599 current_table_count].address =
600 acpi_tb_get_root_table_entry(table_entry, table_entry_size); 373 acpi_tb_get_root_table_entry(table_entry, table_entry_size);
601 374
602 table_entry += table_entry_size; 375 /* Skip NULL entries in RSDT/XSDT */
603 acpi_gbl_root_table_list.current_table_count++;
604 }
605
606 /*
607 * It is not possible to map more than one entry in some environments,
608 * so unmap the root table here before mapping other tables
609 */
610 acpi_os_unmap_memory(table, length);
611 376
612 /* 377 if (!address) {
613 * Complete the initialization of the root table array by examining 378 goto next_table;
614 * the header of each table 379 }
615 */
616 for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) {
617 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
618 address, NULL, i);
619 380
620 /* Special case for FADT - validate it then get the DSDT and FACS */ 381 status = acpi_tb_install_standard_table(address,
382 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
383 FALSE, TRUE,
384 &table_index);
621 385
622 if (ACPI_COMPARE_NAME 386 if (ACPI_SUCCESS(status) &&
623 (&acpi_gbl_root_table_list.tables[i].signature, 387 ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
624 ACPI_SIG_FADT)) { 388 tables[table_index].signature,
625 acpi_tb_parse_fadt(i); 389 ACPI_SIG_FADT)) {
390 acpi_tb_parse_fadt(table_index);
626 } 391 }
392
393next_table:
394
395 table_entry += table_entry_size;
627 } 396 }
628 397
398 acpi_os_unmap_memory(table, length);
399
629 return_ACPI_STATUS(AE_OK); 400 return_ACPI_STATUS(AE_OK);
630} 401}