- Linus: drop support for old-style Makefiles entirely. Big.
[davej-history.git] / drivers / acpi / tables / tbtable.c
blobfe006bf2ebb8349337de1da5b48413cd271ffd9d
1 /******************************************************************************
3 * Module Name: tbtable - ACPI tables: FACP, FACS, and RSDP utilities
4 * $Revision: 24 $
6 *****************************************************************************/
8 /*
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
27 #include "acpi.h"
28 #include "achware.h"
29 #include "actables.h"
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
42 * RETURN: Status
44 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
46 ******************************************************************************/
48 ACPI_STATUS
49 acpi_tb_get_table_rsdt (
50 u32 *number_of_tables)
52 ACPI_STATUS status = AE_OK;
53 ACPI_TABLE_DESC table_info;
56 /* Get the RSDP */
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)) {
68 return (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,
79 &table_info);
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");
89 return (status);
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)) {
101 return (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 *));
122 return (status);
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 ******************************************************************************/
139 u8 *
140 acpi_tb_scan_memory_for_rsdp (
141 u8 *start_address,
142 u32 length)
144 u32 offset;
145 u8 *mem_rover;
148 /* Search from given start addr for the requested length */
150 for (offset = 0, mem_rover = start_address;
151 offset < length;
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 */
163 return (mem_rover);
167 /* Searched entire block, no RSDP was found */
169 return (NULL);
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
181 * RETURN: Status
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 ******************************************************************************/
192 ACPI_STATUS
193 acpi_tb_find_rsdp (
194 ACPI_TABLE_DESC *table_info)
196 u8 *table_ptr;
197 u8 *mem_rover;
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)) {
210 return (status);
213 if (!table_ptr) {
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;
245 return (AE_OK);
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)) {
256 return (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;
273 return (AE_OK);
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)) {
289 return (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;
302 return (AE_OK);
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
324 * RETURN: Status
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 *****************************************************************************/
333 ACPI_STATUS
334 acpi_tb_get_table_facs (
335 ACPI_TABLE_HEADER *buffer_ptr,
336 ACPI_TABLE_DESC *table_info)
338 void *table_ptr = NULL;
339 u32 size;
340 u8 allocation;
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);
351 if (buffer_ptr) {
353 * Getting table from a file -- allocate a buffer and
354 * read the table.
356 table_ptr = acpi_cm_allocate (size);
357 if(!table_ptr) {
358 return (AE_NO_MEMORY);
361 MEMCPY (table_ptr, buffer_ptr, size);
363 /* Save allocation type */
365 allocation = ACPI_MEM_ALLOCATED;
368 else {
369 /* Just map the physical memory to our address space */
371 status = acpi_tb_map_acpi_table ((void *) acpi_gbl_FACP->firmware_ctrl,
372 &size, &table_ptr);
373 if (ACPI_FAILURE(status)) {
374 return (status);
377 /* Save allocation type */
379 allocation = ACPI_MEM_MAPPED;
383 /* Return values */
385 table_info->pointer = table_ptr;
386 table_info->length = size;
387 table_info->allocation = allocation;
388 table_info->base_pointer = table_ptr;
390 return (status);