Blame view
drivers/acpi/acpica/tbxfroot.c
8.18 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/****************************************************************************** * * Module Name: tbxfroot - Find the root ACPI table (RSDT) * *****************************************************************************/ /* |
75a44ce00 ACPICA: update In... |
8 |
* Copyright (C) 2000 - 2008, Intel Corp. |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ |
1da177e4c Linux-2.6.12-rc2 |
43 |
#include <acpi/acpi.h> |
e2f7a7772 ACPICA: hide priv... |
44 45 |
#include "accommon.h" #include "actables.h" |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
1da177e4c Linux-2.6.12-rc2 |
47 |
#define _COMPONENT ACPI_TABLES |
4be44fcd3 [ACPI] Lindent al... |
48 |
ACPI_MODULE_NAME("tbxfroot") |
1da177e4c Linux-2.6.12-rc2 |
49 |
|
44f6c0124 ACPICA 20050408 f... |
50 |
/* Local prototypes */ |
4be44fcd3 [ACPI] Lindent al... |
51 |
static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); |
1da177e4c Linux-2.6.12-rc2 |
52 |
|
f3d2e7865 ACPICA: Implement... |
53 |
static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); |
1da177e4c Linux-2.6.12-rc2 |
54 55 |
/******************************************************************************* * |
f9f4601f3 ACPICA 20050708 f... |
56 57 |
* FUNCTION: acpi_tb_validate_rsdp * |
f3d2e7865 ACPICA: Implement... |
58 |
* PARAMETERS: Rsdp - Pointer to unvalidated RSDP |
f9f4601f3 ACPICA 20050708 f... |
59 60 61 62 63 64 |
* * RETURN: Status * * DESCRIPTION: Validate the RSDP (ptr) * ******************************************************************************/ |
f3d2e7865 ACPICA: Implement... |
65 |
static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) |
f9f4601f3 ACPICA 20050708 f... |
66 |
{ |
4be44fcd3 [ACPI] Lindent al... |
67 |
ACPI_FUNCTION_ENTRY(); |
f9f4601f3 ACPICA 20050708 f... |
68 69 |
/* |
f3d2e7865 ACPICA: Implement... |
70 71 72 73 |
* The signature and checksum must both be correct * * Note: Sometimes there exists more than one RSDP in memory; the valid * RSDP has a valid checksum, all others have an invalid checksum. |
f9f4601f3 ACPICA 20050708 f... |
74 |
*/ |
ec41f193e ACPICA: Formattin... |
75 76 |
if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) != 0) { |
52fc0b026 [ACPI] ACPICA 200... |
77 |
|
f9f4601f3 ACPICA 20050708 f... |
78 79 80 81 82 83 |
/* Nope, BAD Signature */ return (AE_BAD_SIGNATURE); } /* Check the standard checksum */ |
f3d2e7865 ACPICA: Implement... |
84 |
if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { |
f9f4601f3 ACPICA 20050708 f... |
85 86 87 88 89 90 |
return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((rsdp->revision >= 2) && |
f3d2e7865 ACPICA: Implement... |
91 |
(acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { |
f9f4601f3 ACPICA 20050708 f... |
92 93 94 95 96 |
return (AE_BAD_CHECKSUM); } return (AE_OK); } |
f9f4601f3 ACPICA 20050708 f... |
97 98 |
/******************************************************************************* * |
239665a3b ACPI: tables: com... |
99 |
* FUNCTION: acpi_find_root_pointer |
1da177e4c Linux-2.6.12-rc2 |
100 |
* |
f3d2e7865 ACPICA: Implement... |
101 |
* PARAMETERS: table_address - Where the table pointer is returned |
1da177e4c Linux-2.6.12-rc2 |
102 |
* |
f3d2e7865 ACPICA: Implement... |
103 |
* RETURN: Status, RSDP physical address |
1da177e4c Linux-2.6.12-rc2 |
104 |
* |
f3d2e7865 ACPICA: Implement... |
105 106 |
* DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor * pointer structure. If it is found, set *RSDP to point to it. |
1da177e4c Linux-2.6.12-rc2 |
107 |
* |
f3d2e7865 ACPICA: Implement... |
108 109 110 |
* NOTE1: The RSDP must be either in the first 1_k of the Extended * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) * Only a 32-bit physical address is necessary. |
1da177e4c Linux-2.6.12-rc2 |
111 |
* |
f3d2e7865 ACPICA: Implement... |
112 113 |
* NOTE2: This function is always available, regardless of the * initialization state of the rest of ACPI. |
1da177e4c Linux-2.6.12-rc2 |
114 115 |
* ******************************************************************************/ |
67a119f99 ACPICA: Eliminate... |
116 |
acpi_status acpi_find_root_pointer(acpi_size *table_address) |
1da177e4c Linux-2.6.12-rc2 |
117 |
{ |
f3d2e7865 ACPICA: Implement... |
118 119 120 |
u8 *table_ptr; u8 *mem_rover; u32 physical_address; |
1da177e4c Linux-2.6.12-rc2 |
121 |
|
f3d2e7865 ACPICA: Implement... |
122 |
ACPI_FUNCTION_TRACE(acpi_find_root_pointer); |
1da177e4c Linux-2.6.12-rc2 |
123 |
|
f3d2e7865 ACPICA: Implement... |
124 |
/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ |
1da177e4c Linux-2.6.12-rc2 |
125 |
|
f3d2e7865 ACPICA: Implement... |
126 127 128 129 130 131 132 |
table_ptr = acpi_os_map_memory((acpi_physical_address) ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH); if (!table_ptr) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X for length %X", ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
4be44fcd3 [ACPI] Lindent al... |
134 |
return_ACPI_STATUS(AE_NO_MEMORY); |
1da177e4c Linux-2.6.12-rc2 |
135 |
} |
f3d2e7865 ACPICA: Implement... |
136 |
ACPI_MOVE_16_TO_32(&physical_address, table_ptr); |
1da177e4c Linux-2.6.12-rc2 |
137 |
|
f3d2e7865 ACPICA: Implement... |
138 |
/* Convert segment part to physical address */ |
1da177e4c Linux-2.6.12-rc2 |
139 |
|
f3d2e7865 ACPICA: Implement... |
140 141 |
physical_address <<= 4; acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); |
1da177e4c Linux-2.6.12-rc2 |
142 |
|
f3d2e7865 ACPICA: Implement... |
143 |
/* EBDA present? */ |
1da177e4c Linux-2.6.12-rc2 |
144 |
|
f3d2e7865 ACPICA: Implement... |
145 |
if (physical_address > 0x400) { |
73459f73e ACPICA 20050617-0... |
146 |
/* |
f3d2e7865 ACPICA: Implement... |
147 148 |
* 1b) Search EBDA paragraphs (EBDA is required to be a * minimum of 1_k length) |
73459f73e ACPICA 20050617-0... |
149 |
*/ |
67a119f99 ACPICA: Eliminate... |
150 |
table_ptr = acpi_os_map_memory((acpi_physical_address) |
f3d2e7865 ACPICA: Implement... |
151 152 153 154 155 156 |
physical_address, ACPI_EBDA_WINDOW_SIZE); if (!table_ptr) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X for length %X", physical_address, ACPI_EBDA_WINDOW_SIZE)); |
1da177e4c Linux-2.6.12-rc2 |
157 |
|
f3d2e7865 ACPICA: Implement... |
158 |
return_ACPI_STATUS(AE_NO_MEMORY); |
1da177e4c Linux-2.6.12-rc2 |
159 |
} |
f3d2e7865 ACPICA: Implement... |
160 161 162 163 |
mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_EBDA_WINDOW_SIZE); acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
164 |
|
f3d2e7865 ACPICA: Implement... |
165 |
if (mem_rover) { |
52fc0b026 [ACPI] ACPICA 200... |
166 |
|
f3d2e7865 ACPICA: Implement... |
167 |
/* Return the physical address */ |
1da177e4c Linux-2.6.12-rc2 |
168 |
|
f3d2e7865 ACPICA: Implement... |
169 170 |
physical_address += (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); |
1da177e4c Linux-2.6.12-rc2 |
171 |
|
f3d2e7865 ACPICA: Implement... |
172 173 |
*table_address = physical_address; return_ACPI_STATUS(AE_OK); |
1da177e4c Linux-2.6.12-rc2 |
174 175 |
} } |
f3d2e7865 ACPICA: Implement... |
176 177 178 179 180 181 |
/* * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ table_ptr = acpi_os_map_memory((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
182 |
|
f3d2e7865 ACPICA: Implement... |
183 184 185 186 187 |
if (!table_ptr) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X for length %X", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); |
1da177e4c Linux-2.6.12-rc2 |
188 |
|
f3d2e7865 ACPICA: Implement... |
189 |
return_ACPI_STATUS(AE_NO_MEMORY); |
88ac00f5a ACPICA 20050526 f... |
190 |
} |
1da177e4c Linux-2.6.12-rc2 |
191 |
|
f3d2e7865 ACPICA: Implement... |
192 193 194 |
mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
195 |
|
f3d2e7865 ACPICA: Implement... |
196 |
if (mem_rover) { |
1da177e4c Linux-2.6.12-rc2 |
197 |
|
f3d2e7865 ACPICA: Implement... |
198 |
/* Return the physical address */ |
1da177e4c Linux-2.6.12-rc2 |
199 |
|
f3d2e7865 ACPICA: Implement... |
200 201 202 |
physical_address = (u32) (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF(mem_rover, table_ptr)); |
1da177e4c Linux-2.6.12-rc2 |
203 |
|
f3d2e7865 ACPICA: Implement... |
204 205 |
*table_address = physical_address; return_ACPI_STATUS(AE_OK); |
1da177e4c Linux-2.6.12-rc2 |
206 |
} |
f3d2e7865 ACPICA: Implement... |
207 208 209 210 |
/* A valid RSDP was not found */ ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); return_ACPI_STATUS(AE_NOT_FOUND); |
1da177e4c Linux-2.6.12-rc2 |
211 |
} |
1da177e4c Linux-2.6.12-rc2 |
212 213 214 215 216 217 218 219 220 221 222 223 |
/******************************************************************************* * * FUNCTION: acpi_tb_scan_memory_for_rsdp * * PARAMETERS: start_address - Starting pointer for search * Length - Maximum length to search * * RETURN: Pointer to the RSDP if found, otherwise NULL. * * DESCRIPTION: Search a block of memory for the RSDP signature * ******************************************************************************/ |
4be44fcd3 [ACPI] Lindent al... |
224 |
static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) |
1da177e4c Linux-2.6.12-rc2 |
225 |
{ |
4be44fcd3 [ACPI] Lindent al... |
226 227 228 |
acpi_status status; u8 *mem_rover; u8 *end_address; |
1da177e4c Linux-2.6.12-rc2 |
229 |
|
b229cf92e ACPI: ACPICA 2006... |
230 |
ACPI_FUNCTION_TRACE(tb_scan_memory_for_rsdp); |
1da177e4c Linux-2.6.12-rc2 |
231 232 233 234 235 236 |
end_address = start_address + length; /* Search from given start address for the requested length */ for (mem_rover = start_address; mem_rover < end_address; |
4be44fcd3 [ACPI] Lindent al... |
237 |
mem_rover += ACPI_RSDP_SCAN_STEP) { |
52fc0b026 [ACPI] ACPICA 200... |
238 |
|
f9f4601f3 ACPICA 20050708 f... |
239 |
/* The RSDP signature and checksum must both be correct */ |
1da177e4c Linux-2.6.12-rc2 |
240 |
|
4be44fcd3 [ACPI] Lindent al... |
241 242 |
status = acpi_tb_validate_rsdp(ACPI_CAST_PTR |
f3d2e7865 ACPICA: Implement... |
243 |
(struct acpi_table_rsdp, mem_rover)); |
4be44fcd3 [ACPI] Lindent al... |
244 |
if (ACPI_SUCCESS(status)) { |
52fc0b026 [ACPI] ACPICA 200... |
245 |
|
f9f4601f3 ACPICA 20050708 f... |
246 |
/* Sig and checksum valid, we have found a real RSDP */ |
1da177e4c Linux-2.6.12-rc2 |
247 |
|
4be44fcd3 [ACPI] Lindent al... |
248 249 250 251 252 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP located at physical address %p ", mem_rover)); return_PTR(mem_rover); |
1da177e4c Linux-2.6.12-rc2 |
253 |
} |
f9f4601f3 ACPICA 20050708 f... |
254 |
/* No sig match or bad checksum, keep searching */ |
1da177e4c Linux-2.6.12-rc2 |
255 256 257 |
} /* Searched entire block, no RSDP was found */ |
4be44fcd3 [ACPI] Lindent al... |
258 259 260 261 262 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Searched entire block from %p, valid RSDP was not found ", start_address)); return_PTR(NULL); |
1da177e4c Linux-2.6.12-rc2 |
263 |
} |