1 /******************************************************************************
3 * Module Name: tbtable - ACPI tables: FACP, FACS, and RSDP utilities
6 *****************************************************************************/
9 * Copyright (C) 2000 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #define _COMPONENT TABLE_MANAGER
33 MODULE_NAME ("tbtable")
36 /*******************************************************************************
38 * FUNCTION: Acpi_tb_get_table_rsdt
40 * PARAMETERS: Number_of_tables - Where the table count is placed
44 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
46 ******************************************************************************/
49 acpi_tb_get_table_rsdt (
50 u32
*number_of_tables
)
52 ACPI_STATUS status
= AE_OK
;
53 ACPI_TABLE_DESC table_info
;
58 status
= acpi_tb_find_rsdp (&table_info
);
59 if (ACPI_FAILURE (status
)) {
60 REPORT_WARNING ("RSDP structure not found");
61 return (AE_NO_ACPI_TABLES
);
64 /* Save the table pointers and allocation info */
66 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP
, &table_info
);
67 if (ACPI_FAILURE (status
)) {
71 acpi_gbl_RSDP
= (ROOT_SYSTEM_DESCRIPTOR_POINTER
*) table_info
.pointer
;
75 * RSDP structure was found; Now get the RSDT
78 status
= acpi_tb_get_table ((void *) acpi_gbl_RSDP
->rsdt_physical_address
, NULL
,
80 if (ACPI_FAILURE (status
)) {
81 if (status
== AE_BAD_SIGNATURE
) {
82 /* Invalid RSDT signature */
84 REPORT_ERROR ("Invalid signature where RSDP indicates RSDT should be located");
87 REPORT_ERROR ("Unable to locate RSDT");
93 /* Always delete the RSDP mapping */
95 acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP
);
97 /* Save the table pointers and allocation info */
99 status
= acpi_tb_init_table_descriptor (ACPI_TABLE_RSDT
, &table_info
);
100 if (ACPI_FAILURE (status
)) {
104 acpi_gbl_RSDT
= (ROOT_SYSTEM_DESCRIPTION_TABLE
*) table_info
.pointer
;
107 /* Valid RSDT signature, verify the checksum */
109 status
= acpi_tb_verify_table_checksum ((ACPI_TABLE_HEADER
*) acpi_gbl_RSDT
);
112 * Determine the number of tables pointed to by the RSDT.
113 * This is defined by the ACPI Specification to be the number of
114 * pointers contained within the RSDT. The size of the pointers
115 * is architecture-dependent.
118 *number_of_tables
= ((acpi_gbl_RSDT
->header
.length
-
119 sizeof (ACPI_TABLE_HEADER
)) / sizeof (void *));
126 /*******************************************************************************
128 * FUNCTION: Acpi_tb_scan_memory_for_rsdp
130 * PARAMETERS: Start_address - Starting pointer for search
131 * Length - Maximum length to search
133 * RETURN: Pointer to the RSDP if found, otherwise NULL.
135 * DESCRIPTION: Search a block of memory for the RSDP signature
137 ******************************************************************************/
140 acpi_tb_scan_memory_for_rsdp (
148 /* Search from given start addr for the requested length */
150 for (offset
= 0, mem_rover
= start_address
;
152 offset
+= RSDP_SCAN_STEP
, mem_rover
+= RSDP_SCAN_STEP
)
155 /* The signature and checksum must both be correct */
157 if (STRNCMP ((NATIVE_CHAR
*) mem_rover
, RSDP_SIG
, sizeof (RSDP_SIG
)-1) == 0 &&
158 acpi_tb_checksum (mem_rover
,
159 sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
)) == 0)
161 /* If so, we have found the RSDP */
167 /* Searched entire block, no RSDP was found */
173 /*******************************************************************************
175 * FUNCTION: Acpi_tb_find_rsdp
177 * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer
178 * rather than searching memory
179 * *Table_info - Where the table info is returned
183 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
184 * pointer structure. If it is found, set *RSDP to point to it.
186 * NOTE: The RSDP must be either in the first 1_k of the Extended
187 * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
188 * 5.2.2; assertion #421).
190 ******************************************************************************/
194 ACPI_TABLE_DESC
*table_info
)
198 ACPI_STATUS status
= AE_OK
;
200 if (acpi_gbl_acpi_init_data
.RSDP_physical_address
) {
202 * RSDP address was supplied as part of the initialization data
205 status
= acpi_os_map_memory(acpi_gbl_acpi_init_data
.RSDP_physical_address
,
206 sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
),
207 (void **)&table_ptr
);
209 if (ACPI_FAILURE (status
)) {
214 return (AE_NO_MEMORY
);
218 * The signature and checksum must both be correct
221 if (STRNCMP ((NATIVE_CHAR
*) table_ptr
, RSDP_SIG
, sizeof (RSDP_SIG
)-1) != 0) {
222 /* Nope, BAD Signature */
223 acpi_os_unmap_memory (table_ptr
, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
));
224 return (AE_BAD_SIGNATURE
);
227 /* The signature and checksum must both be correct */
229 if (acpi_tb_checksum (table_ptr
,
230 sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
)) != 0)
232 /* Nope, BAD Checksum */
233 acpi_os_unmap_memory (table_ptr
, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
));
234 return (AE_BAD_CHECKSUM
);
237 /* RSDP supplied is OK */
238 /* If so, we have found the RSDP */
240 table_info
->pointer
= (ACPI_TABLE_HEADER
*) table_ptr
;
241 table_info
->length
= sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER
);
242 table_info
->allocation
= ACPI_MEM_MAPPED
;
243 table_info
->base_pointer
= table_ptr
;
249 * Search memory for RSDP. First map low physical memory.
252 status
= acpi_os_map_memory (LO_RSDP_WINDOW_BASE
, LO_RSDP_WINDOW_SIZE
,
253 (void **)&table_ptr
);
255 if (ACPI_FAILURE (status
)) {
260 * 1) Search EBDA (low memory) paragraphs
263 if (NULL
!= (mem_rover
= acpi_tb_scan_memory_for_rsdp (table_ptr
,
264 LO_RSDP_WINDOW_SIZE
)))
266 /* Found it, return pointer and don't delete the mapping */
268 table_info
->pointer
= (ACPI_TABLE_HEADER
*) mem_rover
;
269 table_info
->length
= LO_RSDP_WINDOW_SIZE
;
270 table_info
->allocation
= ACPI_MEM_MAPPED
;
271 table_info
->base_pointer
= table_ptr
;
276 /* This mapping is no longer needed */
278 acpi_os_unmap_memory (table_ptr
, LO_RSDP_WINDOW_SIZE
);
282 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
285 status
= acpi_os_map_memory (HI_RSDP_WINDOW_BASE
, HI_RSDP_WINDOW_SIZE
,
286 (void **)&table_ptr
);
288 if (ACPI_FAILURE (status
)) {
292 if (NULL
!= (mem_rover
= acpi_tb_scan_memory_for_rsdp (table_ptr
,
293 HI_RSDP_WINDOW_SIZE
)))
295 /* Found it, return pointer and don't delete the mapping */
297 table_info
->pointer
= (ACPI_TABLE_HEADER
*) mem_rover
;
298 table_info
->length
= HI_RSDP_WINDOW_SIZE
;
299 table_info
->allocation
= ACPI_MEM_MAPPED
;
300 table_info
->base_pointer
= table_ptr
;
305 /* This mapping is no longer needed */
307 acpi_os_unmap_memory (table_ptr
, HI_RSDP_WINDOW_SIZE
);
310 /* RSDP signature was not found */
312 return (AE_NOT_FOUND
);
316 /******************************************************************************
318 * FUNCTION: Acpi_tb_get_table_facs
320 * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from
321 * buffer rather than searching memory
322 * *Table_info - Where the table info is returned
326 * DESCRIPTION: Returns a pointer to the FACS as defined in FACP. This
327 * function assumes the global variable FACP has been
328 * correctly initialized. The value of FACP->Firmware_ctrl
329 * into a far pointer which is returned.
331 *****************************************************************************/
334 acpi_tb_get_table_facs (
335 ACPI_TABLE_HEADER
*buffer_ptr
,
336 ACPI_TABLE_DESC
*table_info
)
338 void *table_ptr
= NULL
;
341 ACPI_STATUS status
= AE_OK
;
344 /* Must have a valid FACP pointer */
346 if (!acpi_gbl_FACP
) {
347 return (AE_NO_ACPI_TABLES
);
350 size
= sizeof (FIRMWARE_ACPI_CONTROL_STRUCTURE
);
353 * Getting table from a file -- allocate a buffer and
356 table_ptr
= acpi_cm_allocate (size
);
358 return (AE_NO_MEMORY
);
361 MEMCPY (table_ptr
, buffer_ptr
, size
);
363 /* Save allocation type */
365 allocation
= ACPI_MEM_ALLOCATED
;
369 /* Just map the physical memory to our address space */
371 status
= acpi_tb_map_acpi_table ((void *) acpi_gbl_FACP
->firmware_ctrl
,
373 if (ACPI_FAILURE(status
)) {
377 /* Save allocation type */
379 allocation
= ACPI_MEM_MAPPED
;
385 table_info
->pointer
= table_ptr
;
386 table_info
->length
= size
;
387 table_info
->allocation
= allocation
;
388 table_info
->base_pointer
= table_ptr
;