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