diff options
Diffstat (limited to 'drivers/acpi/tables/tbxfroot.c')
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 513 |
1 files changed, 258 insertions, 255 deletions
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index dc3c3f6a9f62..3b8a7e063e8a 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -46,22 +46,56 @@ | |||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include <acpi/actables.h> | 47 | #include <acpi/actables.h> |
48 | 48 | ||
49 | |||
50 | #define _COMPONENT ACPI_TABLES | 49 | #define _COMPONENT ACPI_TABLES |
51 | ACPI_MODULE_NAME ("tbxfroot") | 50 | ACPI_MODULE_NAME("tbxfroot") |
52 | 51 | ||
53 | /* Local prototypes */ | 52 | /* Local prototypes */ |
54 | |||
55 | static acpi_status | 53 | static acpi_status |
56 | acpi_tb_find_rsdp ( | 54 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); |
57 | struct acpi_table_desc *table_info, | ||
58 | u32 flags); | ||
59 | 55 | ||
60 | static u8 * | 56 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); |
61 | acpi_tb_scan_memory_for_rsdp ( | ||
62 | u8 *start_address, | ||
63 | u32 length); | ||
64 | 57 | ||
58 | /******************************************************************************* | ||
59 | * | ||
60 | * FUNCTION: acpi_tb_validate_rsdp | ||
61 | * | ||
62 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | ||
63 | * | ||
64 | * RETURN: Status | ||
65 | * | ||
66 | * DESCRIPTION: Validate the RSDP (ptr) | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | ||
71 | { | ||
72 | ACPI_FUNCTION_ENTRY(); | ||
73 | |||
74 | /* | ||
75 | * The signature and checksum must both be correct | ||
76 | */ | ||
77 | if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { | ||
78 | /* Nope, BAD Signature */ | ||
79 | |||
80 | return (AE_BAD_SIGNATURE); | ||
81 | } | ||
82 | |||
83 | /* Check the standard checksum */ | ||
84 | |||
85 | if (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
86 | return (AE_BAD_CHECKSUM); | ||
87 | } | ||
88 | |||
89 | /* Check extended checksum if table version >= 2 */ | ||
90 | |||
91 | if ((rsdp->revision >= 2) && | ||
92 | (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != | ||
93 | 0)) { | ||
94 | return (AE_BAD_CHECKSUM); | ||
95 | } | ||
96 | |||
97 | return (AE_OK); | ||
98 | } | ||
65 | 99 | ||
66 | /******************************************************************************* | 100 | /******************************************************************************* |
67 | * | 101 | * |
@@ -80,28 +114,24 @@ acpi_tb_scan_memory_for_rsdp ( | |||
80 | ******************************************************************************/ | 114 | ******************************************************************************/ |
81 | 115 | ||
82 | acpi_status | 116 | acpi_status |
83 | acpi_tb_find_table ( | 117 | acpi_tb_find_table(char *signature, |
84 | char *signature, | 118 | char *oem_id, |
85 | char *oem_id, | 119 | char *oem_table_id, struct acpi_table_header ** table_ptr) |
86 | char *oem_table_id, | ||
87 | struct acpi_table_header **table_ptr) | ||
88 | { | 120 | { |
89 | acpi_status status; | 121 | acpi_status status; |
90 | struct acpi_table_header *table; | 122 | struct acpi_table_header *table; |
91 | |||
92 | |||
93 | ACPI_FUNCTION_TRACE ("tb_find_table"); | ||
94 | 123 | ||
124 | ACPI_FUNCTION_TRACE("tb_find_table"); | ||
95 | 125 | ||
96 | /* Validate string lengths */ | 126 | /* Validate string lengths */ |
97 | 127 | ||
98 | if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) || | 128 | if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || |
99 | (ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) || | 129 | (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || |
100 | (ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) { | 130 | (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { |
101 | return_ACPI_STATUS (AE_AML_STRING_LIMIT); | 131 | return_ACPI_STATUS(AE_AML_STRING_LIMIT); |
102 | } | 132 | } |
103 | 133 | ||
104 | if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) { | 134 | if (!ACPI_STRNCMP(signature, DSDT_SIG, ACPI_NAME_SIZE)) { |
105 | /* | 135 | /* |
106 | * The DSDT pointer is contained in the FADT, not the RSDT. | 136 | * The DSDT pointer is contained in the FADT, not the RSDT. |
107 | * This code should suffice, because the only code that would perform | 137 | * This code should suffice, because the only code that would perform |
@@ -110,40 +140,36 @@ acpi_tb_find_table ( | |||
110 | * If this becomes insufficient, the FADT will have to be found first. | 140 | * If this becomes insufficient, the FADT will have to be found first. |
111 | */ | 141 | */ |
112 | if (!acpi_gbl_DSDT) { | 142 | if (!acpi_gbl_DSDT) { |
113 | return_ACPI_STATUS (AE_NO_ACPI_TABLES); | 143 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
114 | } | 144 | } |
115 | table = acpi_gbl_DSDT; | 145 | table = acpi_gbl_DSDT; |
116 | } | 146 | } else { |
117 | else { | ||
118 | /* Find the table */ | 147 | /* Find the table */ |
119 | 148 | ||
120 | status = acpi_get_firmware_table (signature, 1, | 149 | status = acpi_get_firmware_table(signature, 1, |
121 | ACPI_LOGICAL_ADDRESSING, &table); | 150 | ACPI_LOGICAL_ADDRESSING, |
122 | if (ACPI_FAILURE (status)) { | 151 | &table); |
123 | return_ACPI_STATUS (status); | 152 | if (ACPI_FAILURE(status)) { |
153 | return_ACPI_STATUS(status); | ||
124 | } | 154 | } |
125 | } | 155 | } |
126 | 156 | ||
127 | /* Check oem_id and oem_table_id */ | 157 | /* Check oem_id and oem_table_id */ |
128 | 158 | ||
129 | if ((oem_id[0] && ACPI_STRNCMP ( | 159 | if ((oem_id[0] && ACPI_STRNCMP(oem_id, table->oem_id, |
130 | oem_id, table->oem_id, | 160 | sizeof(table->oem_id))) || |
131 | sizeof (table->oem_id))) || | 161 | (oem_table_id[0] && ACPI_STRNCMP(oem_table_id, table->oem_table_id, |
132 | 162 | sizeof(table->oem_table_id)))) { | |
133 | (oem_table_id[0] && ACPI_STRNCMP ( | 163 | return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); |
134 | oem_table_id, table->oem_table_id, | ||
135 | sizeof (table->oem_table_id)))) { | ||
136 | return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND); | ||
137 | } | 164 | } |
138 | 165 | ||
139 | ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", | 166 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", |
140 | table->signature)); | 167 | table->signature)); |
141 | 168 | ||
142 | *table_ptr = table; | 169 | *table_ptr = table; |
143 | return_ACPI_STATUS (AE_OK); | 170 | return_ACPI_STATUS(AE_OK); |
144 | } | 171 | } |
145 | 172 | ||
146 | |||
147 | /******************************************************************************* | 173 | /******************************************************************************* |
148 | * | 174 | * |
149 | * FUNCTION: acpi_get_firmware_table | 175 | * FUNCTION: acpi_get_firmware_table |
@@ -164,34 +190,28 @@ acpi_tb_find_table ( | |||
164 | ******************************************************************************/ | 190 | ******************************************************************************/ |
165 | 191 | ||
166 | acpi_status | 192 | acpi_status |
167 | acpi_get_firmware_table ( | 193 | acpi_get_firmware_table(acpi_string signature, |
168 | acpi_string signature, | 194 | u32 instance, |
169 | u32 instance, | 195 | u32 flags, struct acpi_table_header **table_pointer) |
170 | u32 flags, | ||
171 | struct acpi_table_header **table_pointer) | ||
172 | { | 196 | { |
173 | acpi_status status; | 197 | acpi_status status; |
174 | struct acpi_pointer address; | 198 | struct acpi_pointer address; |
175 | struct acpi_table_header *header = NULL; | 199 | struct acpi_table_header *header = NULL; |
176 | struct acpi_table_desc *table_info = NULL; | 200 | struct acpi_table_desc *table_info = NULL; |
177 | struct acpi_table_desc *rsdt_info; | 201 | struct acpi_table_desc *rsdt_info; |
178 | u32 table_count; | 202 | u32 table_count; |
179 | u32 i; | 203 | u32 i; |
180 | u32 j; | 204 | u32 j; |
181 | |||
182 | |||
183 | ACPI_FUNCTION_TRACE ("acpi_get_firmware_table"); | ||
184 | 205 | ||
206 | ACPI_FUNCTION_TRACE("acpi_get_firmware_table"); | ||
185 | 207 | ||
186 | /* | 208 | /* |
187 | * Ensure that at least the table manager is initialized. We don't | 209 | * Ensure that at least the table manager is initialized. We don't |
188 | * require that the entire ACPI subsystem is up for this interface. | 210 | * require that the entire ACPI subsystem is up for this interface. |
189 | * If we have a buffer, we must have a length too | 211 | * If we have a buffer, we must have a length too |
190 | */ | 212 | */ |
191 | if ((instance == 0) || | 213 | if ((instance == 0) || (!signature) || (!table_pointer)) { |
192 | (!signature) || | 214 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
193 | (!table_pointer)) { | ||
194 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
195 | } | 215 | } |
196 | 216 | ||
197 | /* Ensure that we have a RSDP */ | 217 | /* Ensure that we have a RSDP */ |
@@ -199,48 +219,41 @@ acpi_get_firmware_table ( | |||
199 | if (!acpi_gbl_RSDP) { | 219 | if (!acpi_gbl_RSDP) { |
200 | /* Get the RSDP */ | 220 | /* Get the RSDP */ |
201 | 221 | ||
202 | status = acpi_os_get_root_pointer (flags, &address); | 222 | status = acpi_os_get_root_pointer(flags, &address); |
203 | if (ACPI_FAILURE (status)) { | 223 | if (ACPI_FAILURE(status)) { |
204 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); | 224 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); |
205 | return_ACPI_STATUS (AE_NO_ACPI_TABLES); | 225 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
206 | } | 226 | } |
207 | 227 | ||
208 | /* Map and validate the RSDP */ | 228 | /* Map and validate the RSDP */ |
209 | 229 | ||
210 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | 230 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { |
211 | status = acpi_os_map_memory (address.pointer.physical, | 231 | status = acpi_os_map_memory(address.pointer.physical, |
212 | sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP); | 232 | sizeof(struct |
213 | if (ACPI_FAILURE (status)) { | 233 | rsdp_descriptor), |
214 | return_ACPI_STATUS (status); | 234 | (void *)&acpi_gbl_RSDP); |
235 | if (ACPI_FAILURE(status)) { | ||
236 | return_ACPI_STATUS(status); | ||
215 | } | 237 | } |
216 | } | 238 | } else { |
217 | else { | ||
218 | acpi_gbl_RSDP = address.pointer.logical; | 239 | acpi_gbl_RSDP = address.pointer.logical; |
219 | } | 240 | } |
220 | 241 | ||
221 | /* The signature and checksum must both be correct */ | 242 | /* The RDSP signature and checksum must both be correct */ |
222 | |||
223 | if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, | ||
224 | sizeof (RSDP_SIG)-1) != 0) { | ||
225 | /* Nope, BAD Signature */ | ||
226 | 243 | ||
227 | return_ACPI_STATUS (AE_BAD_SIGNATURE); | 244 | status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); |
228 | } | 245 | if (ACPI_FAILURE(status)) { |
229 | 246 | return_ACPI_STATUS(status); | |
230 | if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
231 | /* Nope, BAD Checksum */ | ||
232 | |||
233 | return_ACPI_STATUS (AE_BAD_CHECKSUM); | ||
234 | } | 247 | } |
235 | } | 248 | } |
236 | 249 | ||
237 | /* Get the RSDT address via the RSDP */ | 250 | /* Get the RSDT address via the RSDP */ |
238 | 251 | ||
239 | acpi_tb_get_rsdt_address (&address); | 252 | acpi_tb_get_rsdt_address(&address); |
240 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 253 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
241 | "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", | 254 | "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", |
242 | acpi_gbl_RSDP, | 255 | acpi_gbl_RSDP, |
243 | ACPI_FORMAT_UINT64 (address.pointer.value))); | 256 | ACPI_FORMAT_UINT64(address.pointer.value))); |
244 | 257 | ||
245 | /* Insert processor_mode flags */ | 258 | /* Insert processor_mode flags */ |
246 | 259 | ||
@@ -248,30 +261,30 @@ acpi_get_firmware_table ( | |||
248 | 261 | ||
249 | /* Get and validate the RSDT */ | 262 | /* Get and validate the RSDT */ |
250 | 263 | ||
251 | rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); | 264 | rsdt_info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc)); |
252 | if (!rsdt_info) { | 265 | if (!rsdt_info) { |
253 | return_ACPI_STATUS (AE_NO_MEMORY); | 266 | return_ACPI_STATUS(AE_NO_MEMORY); |
254 | } | 267 | } |
255 | 268 | ||
256 | status = acpi_tb_get_table (&address, rsdt_info); | 269 | status = acpi_tb_get_table(&address, rsdt_info); |
257 | if (ACPI_FAILURE (status)) { | 270 | if (ACPI_FAILURE(status)) { |
258 | goto cleanup; | 271 | goto cleanup; |
259 | } | 272 | } |
260 | 273 | ||
261 | status = acpi_tb_validate_rsdt (rsdt_info->pointer); | 274 | status = acpi_tb_validate_rsdt(rsdt_info->pointer); |
262 | if (ACPI_FAILURE (status)) { | 275 | if (ACPI_FAILURE(status)) { |
263 | goto cleanup; | 276 | goto cleanup; |
264 | } | 277 | } |
265 | 278 | ||
266 | /* Allocate a scratch table header and table descriptor */ | 279 | /* Allocate a scratch table header and table descriptor */ |
267 | 280 | ||
268 | header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header)); | 281 | header = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_header)); |
269 | if (!header) { | 282 | if (!header) { |
270 | status = AE_NO_MEMORY; | 283 | status = AE_NO_MEMORY; |
271 | goto cleanup; | 284 | goto cleanup; |
272 | } | 285 | } |
273 | 286 | ||
274 | table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc)); | 287 | table_info = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_desc)); |
275 | if (!table_info) { | 288 | if (!table_info) { |
276 | status = AE_NO_MEMORY; | 289 | status = AE_NO_MEMORY; |
277 | goto cleanup; | 290 | goto cleanup; |
@@ -279,7 +292,8 @@ acpi_get_firmware_table ( | |||
279 | 292 | ||
280 | /* Get the number of table pointers within the RSDT */ | 293 | /* Get the number of table pointers within the RSDT */ |
281 | 294 | ||
282 | table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer); | 295 | table_count = |
296 | acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); | ||
283 | address.pointer_type = acpi_gbl_table_flags | flags; | 297 | address.pointer_type = acpi_gbl_table_flags | flags; |
284 | 298 | ||
285 | /* | 299 | /* |
@@ -287,35 +301,42 @@ acpi_get_firmware_table ( | |||
287 | * requested table | 301 | * requested table |
288 | */ | 302 | */ |
289 | for (i = 0, j = 0; i < table_count; i++) { | 303 | for (i = 0, j = 0; i < table_count; i++) { |
290 | /* Get the next table pointer, handle RSDT vs. XSDT */ | 304 | /* |
291 | 305 | * Get the next table pointer, handle RSDT vs. XSDT | |
292 | if (acpi_gbl_RSDP->revision < 2) { | 306 | * RSDT pointers are 32 bits, XSDT pointers are 64 bits |
293 | address.pointer.value = (ACPI_CAST_PTR ( | 307 | */ |
294 | RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; | 308 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { |
295 | } | 309 | address.pointer.value = |
296 | else { | 310 | (ACPI_CAST_PTR |
297 | address.pointer.value = (ACPI_CAST_PTR ( | 311 | (RSDT_DESCRIPTOR, |
298 | XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; | 312 | rsdt_info->pointer))->table_offset_entry[i]; |
313 | } else { | ||
314 | address.pointer.value = | ||
315 | (ACPI_CAST_PTR | ||
316 | (XSDT_DESCRIPTOR, | ||
317 | rsdt_info->pointer))->table_offset_entry[i]; | ||
299 | } | 318 | } |
300 | 319 | ||
301 | /* Get the table header */ | 320 | /* Get the table header */ |
302 | 321 | ||
303 | status = acpi_tb_get_table_header (&address, header); | 322 | status = acpi_tb_get_table_header(&address, header); |
304 | if (ACPI_FAILURE (status)) { | 323 | if (ACPI_FAILURE(status)) { |
305 | goto cleanup; | 324 | goto cleanup; |
306 | } | 325 | } |
307 | 326 | ||
308 | /* Compare table signatures and table instance */ | 327 | /* Compare table signatures and table instance */ |
309 | 328 | ||
310 | if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) { | 329 | if (!ACPI_STRNCMP(header->signature, signature, ACPI_NAME_SIZE)) { |
311 | /* An instance of the table was found */ | 330 | /* An instance of the table was found */ |
312 | 331 | ||
313 | j++; | 332 | j++; |
314 | if (j >= instance) { | 333 | if (j >= instance) { |
315 | /* Found the correct instance, get the entire table */ | 334 | /* Found the correct instance, get the entire table */ |
316 | 335 | ||
317 | status = acpi_tb_get_table_body (&address, header, table_info); | 336 | status = |
318 | if (ACPI_FAILURE (status)) { | 337 | acpi_tb_get_table_body(&address, header, |
338 | table_info); | ||
339 | if (ACPI_FAILURE(status)) { | ||
319 | goto cleanup; | 340 | goto cleanup; |
320 | } | 341 | } |
321 | 342 | ||
@@ -329,22 +350,23 @@ acpi_get_firmware_table ( | |||
329 | 350 | ||
330 | status = AE_NOT_EXIST; | 351 | status = AE_NOT_EXIST; |
331 | 352 | ||
332 | 353 | cleanup: | |
333 | cleanup: | 354 | if (rsdt_info->pointer) { |
334 | acpi_os_unmap_memory (rsdt_info->pointer, | 355 | acpi_os_unmap_memory(rsdt_info->pointer, |
335 | (acpi_size) rsdt_info->pointer->length); | 356 | (acpi_size) rsdt_info->pointer->length); |
336 | ACPI_MEM_FREE (rsdt_info); | 357 | } |
358 | ACPI_MEM_FREE(rsdt_info); | ||
337 | 359 | ||
338 | if (header) { | 360 | if (header) { |
339 | ACPI_MEM_FREE (header); | 361 | ACPI_MEM_FREE(header); |
340 | } | 362 | } |
341 | if (table_info) { | 363 | if (table_info) { |
342 | ACPI_MEM_FREE (table_info); | 364 | ACPI_MEM_FREE(table_info); |
343 | } | 365 | } |
344 | return_ACPI_STATUS (status); | 366 | return_ACPI_STATUS(status); |
345 | } | 367 | } |
346 | EXPORT_SYMBOL(acpi_get_firmware_table); | ||
347 | 368 | ||
369 | EXPORT_SYMBOL(acpi_get_firmware_table); | ||
348 | 370 | ||
349 | /* TBD: Move to a new file */ | 371 | /* TBD: Move to a new file */ |
350 | 372 | ||
@@ -363,35 +385,29 @@ EXPORT_SYMBOL(acpi_get_firmware_table); | |||
363 | * | 385 | * |
364 | ******************************************************************************/ | 386 | ******************************************************************************/ |
365 | 387 | ||
366 | acpi_status | 388 | acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) |
367 | acpi_find_root_pointer ( | ||
368 | u32 flags, | ||
369 | struct acpi_pointer *rsdp_address) | ||
370 | { | 389 | { |
371 | struct acpi_table_desc table_info; | 390 | struct acpi_table_desc table_info; |
372 | acpi_status status; | 391 | acpi_status status; |
373 | |||
374 | |||
375 | ACPI_FUNCTION_TRACE ("acpi_find_root_pointer"); | ||
376 | 392 | ||
393 | ACPI_FUNCTION_TRACE("acpi_find_root_pointer"); | ||
377 | 394 | ||
378 | /* Get the RSDP */ | 395 | /* Get the RSDP */ |
379 | 396 | ||
380 | status = acpi_tb_find_rsdp (&table_info, flags); | 397 | status = acpi_tb_find_rsdp(&table_info, flags); |
381 | if (ACPI_FAILURE (status)) { | 398 | if (ACPI_FAILURE(status)) { |
382 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 399 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
383 | "RSDP structure not found, %s Flags=%X\n", | 400 | "RSDP structure not found, %s Flags=%X\n", |
384 | acpi_format_exception (status), flags)); | 401 | acpi_format_exception(status), flags)); |
385 | 402 | ||
386 | return_ACPI_STATUS (AE_NO_ACPI_TABLES); | 403 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
387 | } | 404 | } |
388 | 405 | ||
389 | rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; | 406 | rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; |
390 | rsdp_address->pointer.physical = table_info.physical_address; | 407 | rsdp_address->pointer.physical = table_info.physical_address; |
391 | return_ACPI_STATUS (AE_OK); | 408 | return_ACPI_STATUS(AE_OK); |
392 | } | 409 | } |
393 | 410 | ||
394 | |||
395 | /******************************************************************************* | 411 | /******************************************************************************* |
396 | * | 412 | * |
397 | * FUNCTION: acpi_tb_scan_memory_for_rsdp | 413 | * FUNCTION: acpi_tb_scan_memory_for_rsdp |
@@ -405,68 +421,45 @@ acpi_find_root_pointer ( | |||
405 | * | 421 | * |
406 | ******************************************************************************/ | 422 | ******************************************************************************/ |
407 | 423 | ||
408 | static u8 * | 424 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) |
409 | acpi_tb_scan_memory_for_rsdp ( | ||
410 | u8 *start_address, | ||
411 | u32 length) | ||
412 | { | 425 | { |
413 | u8 *mem_rover; | 426 | acpi_status status; |
414 | u8 *end_address; | 427 | u8 *mem_rover; |
415 | u8 checksum; | 428 | u8 *end_address; |
416 | |||
417 | |||
418 | ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); | ||
419 | 429 | ||
430 | ACPI_FUNCTION_TRACE("tb_scan_memory_for_rsdp"); | ||
420 | 431 | ||
421 | end_address = start_address + length; | 432 | end_address = start_address + length; |
422 | 433 | ||
423 | /* Search from given start address for the requested length */ | 434 | /* Search from given start address for the requested length */ |
424 | 435 | ||
425 | for (mem_rover = start_address; mem_rover < end_address; | 436 | for (mem_rover = start_address; mem_rover < end_address; |
426 | mem_rover += ACPI_RSDP_SCAN_STEP) { | 437 | mem_rover += ACPI_RSDP_SCAN_STEP) { |
427 | /* The signature and checksum must both be correct */ | 438 | /* The RSDP signature and checksum must both be correct */ |
428 | 439 | ||
429 | if (ACPI_STRNCMP ((char *) mem_rover, | 440 | status = |
430 | RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) { | 441 | acpi_tb_validate_rsdp(ACPI_CAST_PTR |
431 | /* No signature match, keep looking */ | 442 | (struct rsdp_descriptor, mem_rover)); |
432 | 443 | if (ACPI_SUCCESS(status)) { | |
433 | continue; | 444 | /* Sig and checksum valid, we have found a real RSDP */ |
434 | } | 445 | |
435 | 446 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | |
436 | /* Signature matches, check the appropriate checksum */ | 447 | "RSDP located at physical address %p\n", |
437 | 448 | mem_rover)); | |
438 | if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) { | 449 | return_PTR(mem_rover); |
439 | /* ACPI version 1.0 */ | ||
440 | |||
441 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH); | ||
442 | } | ||
443 | else { | ||
444 | /* Post ACPI 1.0, use extended_checksum */ | ||
445 | |||
446 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH); | ||
447 | } | 450 | } |
448 | 451 | ||
449 | if (checksum == 0) { | 452 | /* No sig match or bad checksum, keep searching */ |
450 | /* Checksum valid, we have found a valid RSDP */ | ||
451 | |||
452 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | ||
453 | "RSDP located at physical address %p\n", mem_rover)); | ||
454 | return_PTR (mem_rover); | ||
455 | } | ||
456 | |||
457 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | ||
458 | "Found an RSDP at physical address %p, but it has a bad checksum\n", | ||
459 | mem_rover)); | ||
460 | } | 453 | } |
461 | 454 | ||
462 | /* Searched entire block, no RSDP was found */ | 455 | /* Searched entire block, no RSDP was found */ |
463 | 456 | ||
464 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 457 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
465 | "Searched entire block, no valid RSDP was found.\n")); | 458 | "Searched entire block from %p, valid RSDP was not found\n", |
466 | return_PTR (NULL); | 459 | start_address)); |
460 | return_PTR(NULL); | ||
467 | } | 461 | } |
468 | 462 | ||
469 | |||
470 | /******************************************************************************* | 463 | /******************************************************************************* |
471 | * | 464 | * |
472 | * FUNCTION: acpi_tb_find_rsdp | 465 | * FUNCTION: acpi_tb_find_rsdp |
@@ -490,18 +483,14 @@ acpi_tb_scan_memory_for_rsdp ( | |||
490 | ******************************************************************************/ | 483 | ******************************************************************************/ |
491 | 484 | ||
492 | static acpi_status | 485 | static acpi_status |
493 | acpi_tb_find_rsdp ( | 486 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) |
494 | struct acpi_table_desc *table_info, | ||
495 | u32 flags) | ||
496 | { | 487 | { |
497 | u8 *table_ptr; | 488 | u8 *table_ptr; |
498 | u8 *mem_rover; | 489 | u8 *mem_rover; |
499 | u32 physical_address; | 490 | u32 physical_address; |
500 | acpi_status status; | 491 | acpi_status status; |
501 | |||
502 | |||
503 | ACPI_FUNCTION_TRACE ("tb_find_rsdp"); | ||
504 | 492 | ||
493 | ACPI_FUNCTION_TRACE("tb_find_rsdp"); | ||
505 | 494 | ||
506 | /* | 495 | /* |
507 | * Scan supports either logical addressing or physical addressing | 496 | * Scan supports either logical addressing or physical addressing |
@@ -509,23 +498,25 @@ acpi_tb_find_rsdp ( | |||
509 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | 498 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { |
510 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ | 499 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ |
511 | 500 | ||
512 | status = acpi_os_map_memory ( | 501 | status = acpi_os_map_memory((acpi_physical_address) |
513 | (acpi_physical_address) ACPI_EBDA_PTR_LOCATION, | 502 | ACPI_EBDA_PTR_LOCATION, |
514 | ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr); | 503 | ACPI_EBDA_PTR_LENGTH, |
515 | if (ACPI_FAILURE (status)) { | 504 | (void *)&table_ptr); |
516 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 505 | if (ACPI_FAILURE(status)) { |
517 | "Could not map memory at %8.8X for length %X\n", | 506 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
518 | ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); | 507 | "Could not map memory at %8.8X for length %X\n", |
519 | 508 | ACPI_EBDA_PTR_LOCATION, | |
520 | return_ACPI_STATUS (status); | 509 | ACPI_EBDA_PTR_LENGTH)); |
510 | |||
511 | return_ACPI_STATUS(status); | ||
521 | } | 512 | } |
522 | 513 | ||
523 | ACPI_MOVE_16_TO_32 (&physical_address, table_ptr); | 514 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); |
524 | 515 | ||
525 | /* Convert segment part to physical address */ | 516 | /* Convert segment part to physical address */ |
526 | 517 | ||
527 | physical_address <<= 4; | 518 | physical_address <<= 4; |
528 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH); | 519 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); |
529 | 520 | ||
530 | /* EBDA present? */ | 521 | /* EBDA present? */ |
531 | 522 | ||
@@ -534,59 +525,67 @@ acpi_tb_find_rsdp ( | |||
534 | * 1b) Search EBDA paragraphs (EBDa is required to be a | 525 | * 1b) Search EBDA paragraphs (EBDa is required to be a |
535 | * minimum of 1_k length) | 526 | * minimum of 1_k length) |
536 | */ | 527 | */ |
537 | status = acpi_os_map_memory ( | 528 | status = acpi_os_map_memory((acpi_physical_address) |
538 | (acpi_physical_address) physical_address, | 529 | physical_address, |
539 | ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr); | 530 | ACPI_EBDA_WINDOW_SIZE, |
540 | if (ACPI_FAILURE (status)) { | 531 | (void *)&table_ptr); |
541 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 532 | if (ACPI_FAILURE(status)) { |
542 | "Could not map memory at %8.8X for length %X\n", | 533 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
543 | physical_address, ACPI_EBDA_WINDOW_SIZE)); | 534 | "Could not map memory at %8.8X for length %X\n", |
544 | 535 | physical_address, | |
545 | return_ACPI_STATUS (status); | 536 | ACPI_EBDA_WINDOW_SIZE)); |
537 | |||
538 | return_ACPI_STATUS(status); | ||
546 | } | 539 | } |
547 | 540 | ||
548 | mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, | 541 | mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, |
549 | ACPI_EBDA_WINDOW_SIZE); | 542 | ACPI_EBDA_WINDOW_SIZE); |
550 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); | 543 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); |
551 | 544 | ||
552 | if (mem_rover) { | 545 | if (mem_rover) { |
553 | /* Found it, return the physical address */ | 546 | /* Return the physical address */ |
554 | 547 | ||
555 | physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); | 548 | physical_address += |
549 | ACPI_PTR_DIFF(mem_rover, table_ptr); | ||
556 | 550 | ||
557 | table_info->physical_address = | 551 | table_info->physical_address = |
558 | (acpi_physical_address) physical_address; | 552 | (acpi_physical_address) physical_address; |
559 | return_ACPI_STATUS (AE_OK); | 553 | return_ACPI_STATUS(AE_OK); |
560 | } | 554 | } |
561 | } | 555 | } |
562 | 556 | ||
563 | /* | 557 | /* |
564 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | 558 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh |
565 | */ | 559 | */ |
566 | status = acpi_os_map_memory ( | 560 | status = acpi_os_map_memory((acpi_physical_address) |
567 | (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE, | 561 | ACPI_HI_RSDP_WINDOW_BASE, |
568 | ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr); | 562 | ACPI_HI_RSDP_WINDOW_SIZE, |
569 | 563 | (void *)&table_ptr); | |
570 | if (ACPI_FAILURE (status)) { | 564 | |
571 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 565 | if (ACPI_FAILURE(status)) { |
572 | "Could not map memory at %8.8X for length %X\n", | 566 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
573 | ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); | 567 | "Could not map memory at %8.8X for length %X\n", |
574 | 568 | ACPI_HI_RSDP_WINDOW_BASE, | |
575 | return_ACPI_STATUS (status); | 569 | ACPI_HI_RSDP_WINDOW_SIZE)); |
570 | |||
571 | return_ACPI_STATUS(status); | ||
576 | } | 572 | } |
577 | 573 | ||
578 | mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | 574 | mem_rover = |
579 | acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | 575 | acpi_tb_scan_memory_for_rsdp(table_ptr, |
576 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
577 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | ||
580 | 578 | ||
581 | if (mem_rover) { | 579 | if (mem_rover) { |
582 | /* Found it, return the physical address */ | 580 | /* Return the physical address */ |
583 | 581 | ||
584 | physical_address = | 582 | physical_address = |
585 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); | 583 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF(mem_rover, |
584 | table_ptr); | ||
586 | 585 | ||
587 | table_info->physical_address = | 586 | table_info->physical_address = |
588 | (acpi_physical_address) physical_address; | 587 | (acpi_physical_address) physical_address; |
589 | return_ACPI_STATUS (AE_OK); | 588 | return_ACPI_STATUS(AE_OK); |
590 | } | 589 | } |
591 | } | 590 | } |
592 | 591 | ||
@@ -596,8 +595,8 @@ acpi_tb_find_rsdp ( | |||
596 | else { | 595 | else { |
597 | /* 1a) Get the location of the EBDA */ | 596 | /* 1a) Get the location of the EBDA */ |
598 | 597 | ||
599 | ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION); | 598 | ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); |
600 | physical_address <<= 4; /* Convert segment to physical address */ | 599 | physical_address <<= 4; /* Convert segment to physical address */ |
601 | 600 | ||
602 | /* EBDA present? */ | 601 | /* EBDA present? */ |
603 | 602 | ||
@@ -606,34 +605,38 @@ acpi_tb_find_rsdp ( | |||
606 | * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of | 605 | * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of |
607 | * 1_k length) | 606 | * 1_k length) |
608 | */ | 607 | */ |
609 | mem_rover = acpi_tb_scan_memory_for_rsdp ( | 608 | mem_rover = |
610 | ACPI_PHYSADDR_TO_PTR (physical_address), | 609 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR |
611 | ACPI_EBDA_WINDOW_SIZE); | 610 | (physical_address), |
611 | ACPI_EBDA_WINDOW_SIZE); | ||
612 | if (mem_rover) { | 612 | if (mem_rover) { |
613 | /* Found it, return the physical address */ | 613 | /* Return the physical address */ |
614 | 614 | ||
615 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); | 615 | table_info->physical_address = |
616 | return_ACPI_STATUS (AE_OK); | 616 | ACPI_TO_INTEGER(mem_rover); |
617 | return_ACPI_STATUS(AE_OK); | ||
617 | } | 618 | } |
618 | } | 619 | } |
619 | 620 | ||
620 | /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ | 621 | /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ |
621 | 622 | ||
622 | mem_rover = acpi_tb_scan_memory_for_rsdp ( | 623 | mem_rover = |
623 | ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), | 624 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR |
624 | ACPI_HI_RSDP_WINDOW_SIZE); | 625 | (ACPI_HI_RSDP_WINDOW_BASE), |
626 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
625 | if (mem_rover) { | 627 | if (mem_rover) { |
626 | /* Found it, return the physical address */ | 628 | /* Found it, return the physical address */ |
627 | 629 | ||
628 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); | 630 | table_info->physical_address = |
629 | return_ACPI_STATUS (AE_OK); | 631 | ACPI_TO_INTEGER(mem_rover); |
632 | return_ACPI_STATUS(AE_OK); | ||
630 | } | 633 | } |
631 | } | 634 | } |
632 | 635 | ||
633 | /* RSDP signature was not found */ | 636 | /* A valid RSDP was not found */ |
634 | 637 | ||
635 | return_ACPI_STATUS (AE_NOT_FOUND); | 638 | ACPI_REPORT_ERROR(("No valid RSDP was found\n")); |
639 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
636 | } | 640 | } |
637 | 641 | ||
638 | #endif | 642 | #endif |
639 | |||