xref: /openbmc/linux/drivers/acpi/acpica/tbutils.c (revision 7490ca1e)
1 /******************************************************************************
2  *
3  * Module Name: tbutils   - table utilities
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "actables.h"
47 
48 #define _COMPONENT          ACPI_TABLES
49 ACPI_MODULE_NAME("tbutils")
50 
51 /* Local prototypes */
52 static void acpi_tb_fix_string(char *string, acpi_size length);
53 
54 static void
55 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
56 			     struct acpi_table_header *header);
57 
58 static acpi_physical_address
59 acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
60 
61 /*******************************************************************************
62  *
63  * FUNCTION:    acpi_tb_check_xsdt
64  *
65  * PARAMETERS:  address                    - Pointer to the XSDT
66  *
67  * RETURN:      status
68  *		AE_OK - XSDT is okay
69  *		AE_NO_MEMORY - can't map XSDT
70  *		AE_INVALID_TABLE_LENGTH - invalid table length
71  *		AE_NULL_ENTRY - XSDT has NULL entry
72  *
73  * DESCRIPTION: validate XSDT
74 ******************************************************************************/
75 
76 static acpi_status
77 acpi_tb_check_xsdt(acpi_physical_address address)
78 {
79 	struct acpi_table_header *table;
80 	u32 length;
81 	u64 xsdt_entry_address;
82 	u8 *table_entry;
83 	u32 table_count;
84 	int i;
85 
86 	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
87 	if (!table)
88 		return AE_NO_MEMORY;
89 
90 	length = table->length;
91 	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
92 	if (length < sizeof(struct acpi_table_header))
93 		return AE_INVALID_TABLE_LENGTH;
94 
95 	table = acpi_os_map_memory(address, length);
96 	if (!table)
97 		return AE_NO_MEMORY;
98 
99 	/* Calculate the number of tables described in XSDT */
100 	table_count =
101 		(u32) ((table->length -
102 		sizeof(struct acpi_table_header)) / sizeof(u64));
103 	table_entry =
104 		ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
105 	for (i = 0; i < table_count; i++) {
106 		ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
107 		if (!xsdt_entry_address) {
108 			/* XSDT has NULL entry */
109 			break;
110 		}
111 		table_entry += sizeof(u64);
112 	}
113 	acpi_os_unmap_memory(table, length);
114 
115 	if (i < table_count)
116 		return AE_NULL_ENTRY;
117 	else
118 		return AE_OK;
119 }
120 
121 /*******************************************************************************
122  *
123  * FUNCTION:    acpi_tb_initialize_facs
124  *
125  * PARAMETERS:  None
126  *
127  * RETURN:      Status
128  *
129  * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
130  *              for accessing the Global Lock and Firmware Waking Vector
131  *
132  ******************************************************************************/
133 
134 acpi_status acpi_tb_initialize_facs(void)
135 {
136 	acpi_status status;
137 
138 	/* If Hardware Reduced flag is set, there is no FACS */
139 
140 	if (acpi_gbl_reduced_hardware) {
141 		acpi_gbl_FACS = NULL;
142 		return (AE_OK);
143 	}
144 
145 	status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
146 					 ACPI_CAST_INDIRECT_PTR(struct
147 								acpi_table_header,
148 								&acpi_gbl_FACS));
149 	return status;
150 }
151 
152 /*******************************************************************************
153  *
154  * FUNCTION:    acpi_tb_tables_loaded
155  *
156  * PARAMETERS:  None
157  *
158  * RETURN:      TRUE if required ACPI tables are loaded
159  *
160  * DESCRIPTION: Determine if the minimum required ACPI tables are present
161  *              (FADT, FACS, DSDT)
162  *
163  ******************************************************************************/
164 
165 u8 acpi_tb_tables_loaded(void)
166 {
167 
168 	if (acpi_gbl_root_table_list.current_table_count >= 3) {
169 		return (TRUE);
170 	}
171 
172 	return (FALSE);
173 }
174 
175 /*******************************************************************************
176  *
177  * FUNCTION:    acpi_tb_fix_string
178  *
179  * PARAMETERS:  String              - String to be repaired
180  *              Length              - Maximum length
181  *
182  * RETURN:      None
183  *
184  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
185  *              with a question mark '?'.
186  *
187  ******************************************************************************/
188 
189 static void acpi_tb_fix_string(char *string, acpi_size length)
190 {
191 
192 	while (length && *string) {
193 		if (!ACPI_IS_PRINT(*string)) {
194 			*string = '?';
195 		}
196 		string++;
197 		length--;
198 	}
199 }
200 
201 /*******************************************************************************
202  *
203  * FUNCTION:    acpi_tb_cleanup_table_header
204  *
205  * PARAMETERS:  out_header          - Where the cleaned header is returned
206  *              Header              - Input ACPI table header
207  *
208  * RETURN:      Returns the cleaned header in out_header
209  *
210  * DESCRIPTION: Copy the table header and ensure that all "string" fields in
211  *              the header consist of printable characters.
212  *
213  ******************************************************************************/
214 
215 static void
216 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
217 			     struct acpi_table_header *header)
218 {
219 
220 	ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header));
221 
222 	acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
223 	acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
224 	acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
225 	acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
226 }
227 
228 /*******************************************************************************
229  *
230  * FUNCTION:    acpi_tb_print_table_header
231  *
232  * PARAMETERS:  Address             - Table physical address
233  *              Header              - Table header
234  *
235  * RETURN:      None
236  *
237  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
238  *
239  ******************************************************************************/
240 
241 void
242 acpi_tb_print_table_header(acpi_physical_address address,
243 			   struct acpi_table_header *header)
244 {
245 	struct acpi_table_header local_header;
246 
247 	/*
248 	 * The reason that the Address is cast to a void pointer is so that we
249 	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
250 	 */
251 	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
252 
253 		/* FACS only has signature and length fields */
254 
255 		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
256 			   header->signature, ACPI_CAST_PTR(void, address),
257 			   header->length));
258 	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
259 
260 		/* RSDP has no common fields */
261 
262 		ACPI_MEMCPY(local_header.oem_id,
263 			    ACPI_CAST_PTR(struct acpi_table_rsdp,
264 					  header)->oem_id, ACPI_OEM_ID_SIZE);
265 		acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
266 
267 		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
268 			   ACPI_CAST_PTR (void, address),
269 			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
270 			    revision >
271 			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
272 					       header)->length : 20,
273 			   ACPI_CAST_PTR(struct acpi_table_rsdp,
274 					 header)->revision,
275 			   local_header.oem_id));
276 	} else {
277 		/* Standard ACPI table with full common header */
278 
279 		acpi_tb_cleanup_table_header(&local_header, header);
280 
281 		ACPI_INFO((AE_INFO,
282 			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
283 			   local_header.signature, ACPI_CAST_PTR(void, address),
284 			   local_header.length, local_header.revision,
285 			   local_header.oem_id, local_header.oem_table_id,
286 			   local_header.oem_revision,
287 			   local_header.asl_compiler_id,
288 			   local_header.asl_compiler_revision));
289 
290 	}
291 }
292 
293 /*******************************************************************************
294  *
295  * FUNCTION:    acpi_tb_validate_checksum
296  *
297  * PARAMETERS:  Table               - ACPI table to verify
298  *              Length              - Length of entire table
299  *
300  * RETURN:      Status
301  *
302  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
303  *              exception on bad checksum.
304  *
305  ******************************************************************************/
306 
307 acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
308 {
309 	u8 checksum;
310 
311 	/* Compute the checksum on the table */
312 
313 	checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
314 
315 	/* Checksum ok? (should be zero) */
316 
317 	if (checksum) {
318 		ACPI_WARNING((AE_INFO,
319 			      "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
320 			      table->signature, table->checksum,
321 			      (u8) (table->checksum - checksum)));
322 
323 #if (ACPI_CHECKSUM_ABORT)
324 
325 		return (AE_BAD_CHECKSUM);
326 #endif
327 	}
328 
329 	return (AE_OK);
330 }
331 
332 /*******************************************************************************
333  *
334  * FUNCTION:    acpi_tb_checksum
335  *
336  * PARAMETERS:  Buffer          - Pointer to memory region to be checked
337  *              Length          - Length of this memory region
338  *
339  * RETURN:      Checksum (u8)
340  *
341  * DESCRIPTION: Calculates circular checksum of memory region.
342  *
343  ******************************************************************************/
344 
345 u8 acpi_tb_checksum(u8 *buffer, u32 length)
346 {
347 	u8 sum = 0;
348 	u8 *end = buffer + length;
349 
350 	while (buffer < end) {
351 		sum = (u8) (sum + *(buffer++));
352 	}
353 
354 	return sum;
355 }
356 
357 /*******************************************************************************
358  *
359  * FUNCTION:    acpi_tb_check_dsdt_header
360  *
361  * PARAMETERS:  None
362  *
363  * RETURN:      None
364  *
365  * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
366  *              if the DSDT has been replaced from outside the OS and/or if
367  *              the DSDT header has been corrupted.
368  *
369  ******************************************************************************/
370 
371 void acpi_tb_check_dsdt_header(void)
372 {
373 
374 	/* Compare original length and checksum to current values */
375 
376 	if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
377 	    acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
378 		ACPI_ERROR((AE_INFO,
379 			    "The DSDT has been corrupted or replaced - old, new headers below"));
380 		acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
381 		acpi_tb_print_table_header(0, acpi_gbl_DSDT);
382 
383 		ACPI_ERROR((AE_INFO,
384 			    "Please send DMI info to linux-acpi@vger.kernel.org\n"
385 			    "If system does not work as expected, please boot with acpi=copy_dsdt"));
386 
387 		/* Disable further error messages */
388 
389 		acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
390 		acpi_gbl_original_dsdt_header.checksum =
391 		    acpi_gbl_DSDT->checksum;
392 	}
393 }
394 
395 /*******************************************************************************
396  *
397  * FUNCTION:    acpi_tb_copy_dsdt
398  *
399  * PARAMETERS:  table_desc          - Installed table to copy
400  *
401  * RETURN:      None
402  *
403  * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
404  *              Some very bad BIOSs are known to either corrupt the DSDT or
405  *              install a new, bad DSDT. This copy works around the problem.
406  *
407  ******************************************************************************/
408 
409 struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
410 {
411 	struct acpi_table_header *new_table;
412 	struct acpi_table_desc *table_desc;
413 
414 	table_desc = &acpi_gbl_root_table_list.tables[table_index];
415 
416 	new_table = ACPI_ALLOCATE(table_desc->length);
417 	if (!new_table) {
418 		ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
419 			    table_desc->length));
420 		return (NULL);
421 	}
422 
423 	ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
424 	acpi_tb_delete_table(table_desc);
425 	table_desc->pointer = new_table;
426 	table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED;
427 
428 	ACPI_INFO((AE_INFO,
429 		   "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
430 		   new_table->length));
431 
432 	return (new_table);
433 }
434 
435 /*******************************************************************************
436  *
437  * FUNCTION:    acpi_tb_install_table
438  *
439  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
440  *              Signature               - Table signature, NULL if no need to
441  *                                        match
442  *              table_index             - Index into root table array
443  *
444  * RETURN:      None
445  *
446  * DESCRIPTION: Install an ACPI table into the global data structure. The
447  *              table override mechanism is implemented here to allow the host
448  *              OS to replace any table before it is installed in the root
449  *              table array.
450  *
451  ******************************************************************************/
452 
453 void
454 acpi_tb_install_table(acpi_physical_address address,
455 		      char *signature, u32 table_index)
456 {
457 	u8 flags;
458 	acpi_status status;
459 	struct acpi_table_header *table_to_install;
460 	struct acpi_table_header *mapped_table;
461 	struct acpi_table_header *override_table = NULL;
462 
463 	if (!address) {
464 		ACPI_ERROR((AE_INFO,
465 			    "Null physical address for ACPI table [%s]",
466 			    signature));
467 		return;
468 	}
469 
470 	/* Map just the table header */
471 
472 	mapped_table =
473 	    acpi_os_map_memory(address, sizeof(struct acpi_table_header));
474 	if (!mapped_table) {
475 		return;
476 	}
477 
478 	/* If a particular signature is expected (DSDT/FACS), it must match */
479 
480 	if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
481 		ACPI_ERROR((AE_INFO,
482 			    "Invalid signature 0x%X for ACPI table, expected [%s]",
483 			    *ACPI_CAST_PTR(u32, mapped_table->signature),
484 			    signature));
485 		goto unmap_and_exit;
486 	}
487 
488 	/*
489 	 * ACPI Table Override:
490 	 *
491 	 * Before we install the table, let the host OS override it with a new
492 	 * one if desired. Any table within the RSDT/XSDT can be replaced,
493 	 * including the DSDT which is pointed to by the FADT.
494 	 */
495 	status = acpi_os_table_override(mapped_table, &override_table);
496 	if (ACPI_SUCCESS(status) && override_table) {
497 		ACPI_INFO((AE_INFO,
498 			   "%4.4s @ 0x%p Table override, replaced with:",
499 			   mapped_table->signature, ACPI_CAST_PTR(void,
500 								  address)));
501 
502 		acpi_gbl_root_table_list.tables[table_index].pointer =
503 		    override_table;
504 		address = ACPI_PTR_TO_PHYSADDR(override_table);
505 
506 		table_to_install = override_table;
507 		flags = ACPI_TABLE_ORIGIN_OVERRIDE;
508 	} else {
509 		table_to_install = mapped_table;
510 		flags = ACPI_TABLE_ORIGIN_MAPPED;
511 	}
512 
513 	/* Initialize the table entry */
514 
515 	acpi_gbl_root_table_list.tables[table_index].address = address;
516 	acpi_gbl_root_table_list.tables[table_index].length =
517 	    table_to_install->length;
518 	acpi_gbl_root_table_list.tables[table_index].flags = flags;
519 
520 	ACPI_MOVE_32_TO_32(&
521 			   (acpi_gbl_root_table_list.tables[table_index].
522 			    signature), table_to_install->signature);
523 
524 	acpi_tb_print_table_header(address, table_to_install);
525 
526 	if (table_index == ACPI_TABLE_INDEX_DSDT) {
527 
528 		/* Global integer width is based upon revision of the DSDT */
529 
530 		acpi_ut_set_integer_width(table_to_install->revision);
531 	}
532 
533       unmap_and_exit:
534 	acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
535 }
536 
537 /*******************************************************************************
538  *
539  * FUNCTION:    acpi_tb_get_root_table_entry
540  *
541  * PARAMETERS:  table_entry         - Pointer to the RSDT/XSDT table entry
542  *              table_entry_size    - sizeof 32 or 64 (RSDT or XSDT)
543  *
544  * RETURN:      Physical address extracted from the root table
545  *
546  * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
547  *              both 32-bit and 64-bit platforms
548  *
549  * NOTE:        acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
550  *              64-bit platforms.
551  *
552  ******************************************************************************/
553 
554 static acpi_physical_address
555 acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
556 {
557 	u64 address64;
558 
559 	/*
560 	 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
561 	 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
562 	 */
563 	if (table_entry_size == sizeof(u32)) {
564 		/*
565 		 * 32-bit platform, RSDT: Return 32-bit table entry
566 		 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
567 		 */
568 		return ((acpi_physical_address)
569 			(*ACPI_CAST_PTR(u32, table_entry)));
570 	} else {
571 		/*
572 		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
573 		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
574 		 *  return 64-bit
575 		 */
576 		ACPI_MOVE_64_TO_64(&address64, table_entry);
577 
578 #if ACPI_MACHINE_WIDTH == 32
579 		if (address64 > ACPI_UINT32_MAX) {
580 
581 			/* Will truncate 64-bit address to 32 bits, issue warning */
582 
583 			ACPI_WARNING((AE_INFO,
584 				      "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
585 				      " truncating",
586 				      ACPI_FORMAT_UINT64(address64)));
587 		}
588 #endif
589 		return ((acpi_physical_address) (address64));
590 	}
591 }
592 
593 /*******************************************************************************
594  *
595  * FUNCTION:    acpi_tb_parse_root_table
596  *
597  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
598  *
599  * RETURN:      Status
600  *
601  * DESCRIPTION: This function is called to parse the Root System Description
602  *              Table (RSDT or XSDT)
603  *
604  * NOTE:        Tables are mapped (not copied) for efficiency. The FACS must
605  *              be mapped and cannot be copied because it contains the actual
606  *              memory location of the ACPI Global Lock.
607  *
608  ******************************************************************************/
609 
610 acpi_status __init
611 acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
612 {
613 	struct acpi_table_rsdp *rsdp;
614 	u32 table_entry_size;
615 	u32 i;
616 	u32 table_count;
617 	struct acpi_table_header *table;
618 	acpi_physical_address address;
619 	acpi_physical_address uninitialized_var(rsdt_address);
620 	u32 length;
621 	u8 *table_entry;
622 	acpi_status status;
623 
624 	ACPI_FUNCTION_TRACE(tb_parse_root_table);
625 
626 	/*
627 	 * Map the entire RSDP and extract the address of the RSDT or XSDT
628 	 */
629 	rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
630 	if (!rsdp) {
631 		return_ACPI_STATUS(AE_NO_MEMORY);
632 	}
633 
634 	acpi_tb_print_table_header(rsdp_address,
635 				   ACPI_CAST_PTR(struct acpi_table_header,
636 						 rsdp));
637 
638 	/* Differentiate between RSDT and XSDT root tables */
639 
640 	if (rsdp->revision > 1 && rsdp->xsdt_physical_address
641 			&& !acpi_rsdt_forced) {
642 		/*
643 		 * Root table is an XSDT (64-bit physical addresses). We must use the
644 		 * XSDT if the revision is > 1 and the XSDT pointer is present, as per
645 		 * the ACPI specification.
646 		 */
647 		address = (acpi_physical_address) rsdp->xsdt_physical_address;
648 		table_entry_size = sizeof(u64);
649 		rsdt_address = (acpi_physical_address)
650 					rsdp->rsdt_physical_address;
651 	} else {
652 		/* Root table is an RSDT (32-bit physical addresses) */
653 
654 		address = (acpi_physical_address) rsdp->rsdt_physical_address;
655 		table_entry_size = sizeof(u32);
656 	}
657 
658 	/*
659 	 * It is not possible to map more than one entry in some environments,
660 	 * so unmap the RSDP here before mapping other tables
661 	 */
662 	acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
663 
664 	if (table_entry_size == sizeof(u64)) {
665 		if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
666 			/* XSDT has NULL entry, RSDT is used */
667 			address = rsdt_address;
668 			table_entry_size = sizeof(u32);
669 			ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, "
670 					"using RSDT"));
671 		}
672 	}
673 	/* Map the RSDT/XSDT table header to get the full table length */
674 
675 	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
676 	if (!table) {
677 		return_ACPI_STATUS(AE_NO_MEMORY);
678 	}
679 
680 	acpi_tb_print_table_header(address, table);
681 
682 	/* Get the length of the full table, verify length and map entire table */
683 
684 	length = table->length;
685 	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
686 
687 	if (length < sizeof(struct acpi_table_header)) {
688 		ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT",
689 			    length));
690 		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
691 	}
692 
693 	table = acpi_os_map_memory(address, length);
694 	if (!table) {
695 		return_ACPI_STATUS(AE_NO_MEMORY);
696 	}
697 
698 	/* Validate the root table checksum */
699 
700 	status = acpi_tb_verify_checksum(table, length);
701 	if (ACPI_FAILURE(status)) {
702 		acpi_os_unmap_memory(table, length);
703 		return_ACPI_STATUS(status);
704 	}
705 
706 	/* Calculate the number of tables described in the root table */
707 
708 	table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
709 			    table_entry_size);
710 	/*
711 	 * First two entries in the table array are reserved for the DSDT
712 	 * and FACS, which are not actually present in the RSDT/XSDT - they
713 	 * come from the FADT
714 	 */
715 	table_entry =
716 	    ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
717 	acpi_gbl_root_table_list.current_table_count = 2;
718 
719 	/*
720 	 * Initialize the root table array from the RSDT/XSDT
721 	 */
722 	for (i = 0; i < table_count; i++) {
723 		if (acpi_gbl_root_table_list.current_table_count >=
724 		    acpi_gbl_root_table_list.max_table_count) {
725 
726 			/* There is no more room in the root table array, attempt resize */
727 
728 			status = acpi_tb_resize_root_table_list();
729 			if (ACPI_FAILURE(status)) {
730 				ACPI_WARNING((AE_INFO,
731 					      "Truncating %u table entries!",
732 					      (unsigned) (table_count -
733 					       (acpi_gbl_root_table_list.
734 							  current_table_count -
735 							  2))));
736 				break;
737 			}
738 		}
739 
740 		/* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
741 
742 		acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
743 						current_table_count].address =
744 		    acpi_tb_get_root_table_entry(table_entry, table_entry_size);
745 
746 		table_entry += table_entry_size;
747 		acpi_gbl_root_table_list.current_table_count++;
748 	}
749 
750 	/*
751 	 * It is not possible to map more than one entry in some environments,
752 	 * so unmap the root table here before mapping other tables
753 	 */
754 	acpi_os_unmap_memory(table, length);
755 
756 	/*
757 	 * Complete the initialization of the root table array by examining
758 	 * the header of each table
759 	 */
760 	for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) {
761 		acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
762 				      address, NULL, i);
763 
764 		/* Special case for FADT - get the DSDT and FACS */
765 
766 		if (ACPI_COMPARE_NAME
767 		    (&acpi_gbl_root_table_list.tables[i].signature,
768 		     ACPI_SIG_FADT)) {
769 			acpi_tb_parse_fadt(i);
770 		}
771 	}
772 
773 	return_ACPI_STATUS(AE_OK);
774 }
775