1 /******************************************************************************
3 * Module Name: tbrsdt - ACPI RSDT table utilities
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2005, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
45 #include <acpi/acpi.h>
46 #include <acpi/actables.h>
49 #define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbrsdt")
53 /*******************************************************************************
55 * FUNCTION: acpi_tb_verify_rsdp
57 * PARAMETERS: Address - RSDP (Pointer to RSDT)
61 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
63 ******************************************************************************/
67 struct acpi_pointer
*address
)
69 struct acpi_table_desc table_info
;
71 struct rsdp_descriptor
*rsdp
;
74 ACPI_FUNCTION_TRACE ("tb_verify_rsdp");
77 switch (address
->pointer_type
) {
78 case ACPI_LOGICAL_POINTER
:
80 rsdp
= address
->pointer
.logical
;
83 case ACPI_PHYSICAL_POINTER
:
85 * Obtain access to the RSDP structure
87 status
= acpi_os_map_memory (address
->pointer
.physical
,
88 sizeof (struct rsdp_descriptor
),
90 if (ACPI_FAILURE (status
)) {
91 return_ACPI_STATUS (status
);
96 return_ACPI_STATUS (AE_BAD_PARAMETER
);
100 * The signature and checksum must both be correct
102 if (ACPI_STRNCMP ((char *) rsdp
, RSDP_SIG
, sizeof (RSDP_SIG
)-1) != 0) {
103 /* Nope, BAD Signature */
105 status
= AE_BAD_SIGNATURE
;
109 /* Check the standard checksum */
111 if (acpi_tb_checksum (rsdp
, ACPI_RSDP_CHECKSUM_LENGTH
) != 0) {
112 status
= AE_BAD_CHECKSUM
;
116 /* Check extended checksum if table version >= 2 */
118 if (rsdp
->revision
>= 2) {
119 if (acpi_tb_checksum (rsdp
, ACPI_RSDP_XCHECKSUM_LENGTH
) != 0) {
120 status
= AE_BAD_CHECKSUM
;
125 /* The RSDP supplied is OK */
127 table_info
.pointer
= ACPI_CAST_PTR (struct acpi_table_header
, rsdp
);
128 table_info
.length
= sizeof (struct rsdp_descriptor
);
129 table_info
.allocation
= ACPI_MEM_MAPPED
;
131 /* Save the table pointers and allocation info */
133 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP
, &table_info
);
134 if (ACPI_FAILURE (status
)) {
138 /* Save the RSDP in a global for easy access */
140 acpi_gbl_RSDP
= ACPI_CAST_PTR (struct rsdp_descriptor
, table_info
.pointer
);
141 return_ACPI_STATUS (status
);
147 if (acpi_gbl_table_flags
& ACPI_PHYSICAL_POINTER
) {
148 acpi_os_unmap_memory (rsdp
, sizeof (struct rsdp_descriptor
));
150 return_ACPI_STATUS (status
);
154 /*******************************************************************************
156 * FUNCTION: acpi_tb_get_rsdt_address
158 * PARAMETERS: out_address - Where the address is returned
160 * RETURN: None, Address
162 * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
163 * version of the RSDP
165 ******************************************************************************/
168 acpi_tb_get_rsdt_address (
169 struct acpi_pointer
*out_address
)
172 ACPI_FUNCTION_ENTRY ();
175 out_address
->pointer_type
= acpi_gbl_table_flags
| ACPI_LOGICAL_ADDRESSING
;
178 * For RSDP revision 0 or 1, we use the RSDT.
179 * For RSDP revision 2 (and above), we use the XSDT
181 if (acpi_gbl_RSDP
->revision
< 2) {
182 out_address
->pointer
.value
= acpi_gbl_RSDP
->rsdt_physical_address
;
185 out_address
->pointer
.value
=
186 acpi_gbl_RSDP
->xsdt_physical_address
;
191 /*******************************************************************************
193 * FUNCTION: acpi_tb_validate_rsdt
195 * PARAMETERS: table_ptr - Addressable pointer to the RSDT.
199 * DESCRIPTION: Validate signature for the RSDT or XSDT
201 ******************************************************************************/
204 acpi_tb_validate_rsdt (
205 struct acpi_table_header
*table_ptr
)
210 ACPI_FUNCTION_NAME ("tb_validate_rsdt");
214 * For RSDP revision 0 or 1, we use the RSDT.
215 * For RSDP revision 2 and above, we use the XSDT
217 if (acpi_gbl_RSDP
->revision
< 2) {
218 no_match
= ACPI_STRNCMP ((char *) table_ptr
, RSDT_SIG
,
219 sizeof (RSDT_SIG
) -1);
222 no_match
= ACPI_STRNCMP ((char *) table_ptr
, XSDT_SIG
,
223 sizeof (XSDT_SIG
) -1);
227 /* Invalid RSDT or XSDT signature */
230 "Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
232 ACPI_DUMP_BUFFER (acpi_gbl_RSDP
, 20);
234 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR
,
235 "RSDT/XSDT signature at %X (%p) is invalid\n",
236 acpi_gbl_RSDP
->rsdt_physical_address
,
237 (void *) (acpi_native_uint
) acpi_gbl_RSDP
->rsdt_physical_address
));
239 if (acpi_gbl_RSDP
->revision
< 2) {
240 ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
243 ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
246 ACPI_DUMP_BUFFER ((char *) table_ptr
, 48);
248 return (AE_BAD_SIGNATURE
);
255 /*******************************************************************************
257 * FUNCTION: acpi_tb_get_table_rsdt
263 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
265 ******************************************************************************/
268 acpi_tb_get_table_rsdt (
271 struct acpi_table_desc table_info
;
273 struct acpi_pointer address
;
276 ACPI_FUNCTION_TRACE ("tb_get_table_rsdt");
279 /* Get the RSDT/XSDT via the RSDP */
281 acpi_tb_get_rsdt_address (&address
);
283 table_info
.type
= ACPI_TABLE_XSDT
;
284 status
= acpi_tb_get_table (&address
, &table_info
);
285 if (ACPI_FAILURE (status
)) {
286 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Could not get the RSDT/XSDT, %s\n",
287 acpi_format_exception (status
)));
289 return_ACPI_STATUS (status
);
292 ACPI_DEBUG_PRINT ((ACPI_DB_INFO
,
293 "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
295 ACPI_FORMAT_UINT64 (address
.pointer
.value
)));
297 /* Check the RSDT or XSDT signature */
299 status
= acpi_tb_validate_rsdt (table_info
.pointer
);
300 if (ACPI_FAILURE (status
)) {
301 return_ACPI_STATUS (status
);
304 /* Get the number of tables defined in the RSDT or XSDT */
306 acpi_gbl_rsdt_table_count
= acpi_tb_get_table_count (acpi_gbl_RSDP
,
309 /* Convert and/or copy to an XSDT structure */
311 status
= acpi_tb_convert_to_xsdt (&table_info
);
312 if (ACPI_FAILURE (status
)) {
313 return_ACPI_STATUS (status
);
316 /* Save the table pointers and allocation info */
318 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT
, &table_info
);
319 if (ACPI_FAILURE (status
)) {
320 return_ACPI_STATUS (status
);
323 acpi_gbl_XSDT
= ACPI_CAST_PTR (XSDT_DESCRIPTOR
, table_info
.pointer
);
325 ACPI_DEBUG_PRINT ((ACPI_DB_INFO
, "XSDT located at %p\n", acpi_gbl_XSDT
));
326 return_ACPI_STATUS (status
);