aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbxfroot.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:18 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:21 -0500
commitf3d2e7865c816258c699ff965768e46b50d536d3 (patch)
tree83d21269e506109275b77d3ed161883bba8a39cf /drivers/acpi/tables/tbxfroot.c
parent2e42005bcdb4f63bed1cea7f537a5534d4bd7a57 (diff)
ACPICA: Implement simplified Table Manager
The Table Manager component has been completely redesigned and reimplemented. The new design is much simpler, and reduces the overall code and data size of the kernel-resident ACPICA by approximately 5%. Also, it is now possible to obtain the ACPI tables very early during kernel initialization, even before dynamic memory management is initialized. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables/tbxfroot.c')
-rw-r--r--drivers/acpi/tables/tbxfroot.c550
1 files changed, 90 insertions, 460 deletions
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index da2648bbdbc0..5c6e88251c1a 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -48,16 +48,15 @@
48ACPI_MODULE_NAME("tbxfroot") 48ACPI_MODULE_NAME("tbxfroot")
49 49
50/* Local prototypes */ 50/* Local prototypes */
51static acpi_status
52acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags);
53
54static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); 51static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
55 52
53static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
54
56/******************************************************************************* 55/*******************************************************************************
57 * 56 *
58 * FUNCTION: acpi_tb_validate_rsdp 57 * FUNCTION: acpi_tb_validate_rsdp
59 * 58 *
60 * PARAMETERS: Rsdp - Pointer to unvalidated RSDP 59 * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
61 * 60 *
62 * RETURN: Status 61 * RETURN: Status
63 * 62 *
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
65 * 64 *
66 ******************************************************************************/ 65 ******************************************************************************/
67 66
68acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) 67static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
69{ 68{
70 ACPI_FUNCTION_ENTRY(); 69 ACPI_FUNCTION_ENTRY();
71 70
72 /* 71 /*
73 * The signature and checksum must both be correct 72 * The signature and checksum must both be correct
73 *
74 * Note: Sometimes there exists more than one RSDP in memory; the valid
75 * RSDP has a valid checksum, all others have an invalid checksum.
74 */ 76 */
75 if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { 77 if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
78 != 0) {
76 79
77 /* Nope, BAD Signature */ 80 /* Nope, BAD Signature */
78 81
@@ -81,330 +84,141 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
81 84
82 /* Check the standard checksum */ 85 /* Check the standard checksum */
83 86
84 if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { 87 if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
85 return (AE_BAD_CHECKSUM); 88 return (AE_BAD_CHECKSUM);
86 } 89 }
87 90
88 /* Check extended checksum if table version >= 2 */ 91 /* Check extended checksum if table version >= 2 */
89 92
90 if ((rsdp->revision >= 2) && 93 if ((rsdp->revision >= 2) &&
91 (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { 94 (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
92 return (AE_BAD_CHECKSUM); 95 return (AE_BAD_CHECKSUM);
93 } 96 }
94 97
95 return (AE_OK); 98 return (AE_OK);
96} 99}
97 100
101#if ACPI_MACHINE_WIDTH != 16
102
98/******************************************************************************* 103/*******************************************************************************
99 * 104 *
100 * FUNCTION: acpi_tb_find_table 105 * FUNCTION: acpi_tb_find_rsdp
101 *
102 * PARAMETERS: Signature - String with ACPI table signature
103 * oem_id - String with the table OEM ID
104 * oem_table_id - String with the OEM Table ID
105 * table_ptr - Where the table pointer is returned
106 *
107 * RETURN: Status
108 * 106 *
109 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the 107 * PARAMETERS: table_address - Where the table pointer is returned
110 * Signature, OEM ID and OEM Table ID.
111 * 108 *
112 ******************************************************************************/ 109 * RETURN: Status, RSDP physical address
113
114acpi_status
115acpi_tb_find_table(char *signature,
116 char *oem_id,
117 char *oem_table_id, struct acpi_table_header ** table_ptr)
118{
119 acpi_status status;
120 struct acpi_table_header *table;
121
122 ACPI_FUNCTION_TRACE(tb_find_table);
123
124 /* Validate string lengths */
125
126 if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) ||
127 (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) ||
128 (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) {
129 return_ACPI_STATUS(AE_AML_STRING_LIMIT);
130 }
131
132 if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) {
133 /*
134 * The DSDT pointer is contained in the FADT, not the RSDT.
135 * This code should suffice, because the only code that would perform
136 * a "find" on the DSDT is the data_table_region() AML opcode -- in
137 * which case, the DSDT is guaranteed to be already loaded.
138 * If this becomes insufficient, the FADT will have to be found first.
139 */
140 if (!acpi_gbl_DSDT) {
141 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
142 }
143 table = acpi_gbl_DSDT;
144 } else {
145 /* Find the table */
146
147 status = acpi_get_firmware_table(signature, 1,
148 ACPI_LOGICAL_ADDRESSING,
149 &table);
150 if (ACPI_FAILURE(status)) {
151 return_ACPI_STATUS(status);
152 }
153 }
154
155 /* Check oem_id and oem_table_id */
156
157 if ((oem_id[0] &&
158 ACPI_STRNCMP(oem_id, table->oem_id,
159 sizeof(table->oem_id))) ||
160 (oem_table_id[0] &&
161 ACPI_STRNCMP(oem_table_id, table->oem_table_id,
162 sizeof(table->oem_table_id)))) {
163 return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND);
164 }
165
166 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n",
167 table->signature));
168
169 *table_ptr = table;
170 return_ACPI_STATUS(AE_OK);
171}
172
173/*******************************************************************************
174 *
175 * FUNCTION: acpi_get_firmware_table
176 * 110 *
177 * PARAMETERS: Signature - Any ACPI table signature 111 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
178 * Instance - the non zero instance of the table, allows 112 * pointer structure. If it is found, set *RSDP to point to it.
179 * support for multiple tables of the same type
180 * Flags - Physical/Virtual support
181 * table_pointer - Where a buffer containing the table is
182 * returned
183 * 113 *
184 * RETURN: Status 114 * NOTE1: The RSDP must be either in the first 1_k of the Extended
115 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
116 * Only a 32-bit physical address is necessary.
185 * 117 *
186 * DESCRIPTION: This function is called to get an ACPI table. A buffer is 118 * NOTE2: This function is always available, regardless of the
187 * allocated for the table and returned in table_pointer. 119 * initialization state of the rest of ACPI.
188 * This table will be a complete table including the header.
189 * 120 *
190 ******************************************************************************/ 121 ******************************************************************************/
191 122
192acpi_status 123acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
193acpi_get_firmware_table(acpi_string signature,
194 u32 instance,
195 u32 flags, struct acpi_table_header **table_pointer)
196{ 124{
197 acpi_status status; 125 u8 *table_ptr;
198 struct acpi_pointer address; 126 u8 *mem_rover;
199 struct acpi_table_header *header = NULL; 127 u32 physical_address;
200 struct acpi_table_desc *table_info = NULL;
201 struct acpi_table_desc *rsdt_info;
202 u32 table_count;
203 u32 i;
204 u32 j;
205
206 ACPI_FUNCTION_TRACE(acpi_get_firmware_table);
207
208 /*
209 * Ensure that at least the table manager is initialized. We don't
210 * require that the entire ACPI subsystem is up for this interface.
211 * If we have a buffer, we must have a length too
212 */
213 if ((instance == 0) || (!signature) || (!table_pointer)) {
214 return_ACPI_STATUS(AE_BAD_PARAMETER);
215 }
216
217 /* Ensure that we have a RSDP */
218
219 if (!acpi_gbl_RSDP) {
220
221 /* Get the RSDP */
222
223 status = acpi_os_get_root_pointer(flags, &address);
224 if (ACPI_FAILURE(status)) {
225 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n"));
226 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
227 }
228
229 /* Map and validate the RSDP */
230
231 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
232 status = acpi_os_map_memory(address.pointer.physical,
233 sizeof(struct
234 rsdp_descriptor),
235 (void *)&acpi_gbl_RSDP);
236 if (ACPI_FAILURE(status)) {
237 return_ACPI_STATUS(status);
238 }
239 } else {
240 acpi_gbl_RSDP = address.pointer.logical;
241 }
242
243 /* The RDSP signature and checksum must both be correct */
244
245 status = acpi_tb_validate_rsdp(acpi_gbl_RSDP);
246 if (ACPI_FAILURE(status)) {
247 return_ACPI_STATUS(status);
248 }
249 }
250
251 /* Get the RSDT address via the RSDP */
252
253 acpi_tb_get_rsdt_address(&address);
254 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
255 "RSDP located at %p, RSDT physical=%8.8X%8.8X\n",
256 acpi_gbl_RSDP,
257 ACPI_FORMAT_UINT64(address.pointer.value)));
258 128
259 /* Insert processor_mode flags */ 129 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
260 130
261 address.pointer_type |= flags; 131 /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
262 132
263 /* Get and validate the RSDT */ 133 table_ptr = acpi_os_map_memory((acpi_physical_address)
134 ACPI_EBDA_PTR_LOCATION,
135 ACPI_EBDA_PTR_LENGTH);
136 if (!table_ptr) {
137 ACPI_ERROR((AE_INFO,
138 "Could not map memory at %8.8X for length %X",
139 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
264 140
265 rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc));
266 if (!rsdt_info) {
267 return_ACPI_STATUS(AE_NO_MEMORY); 141 return_ACPI_STATUS(AE_NO_MEMORY);
268 } 142 }
269 143
270 status = acpi_tb_get_table(&address, rsdt_info); 144 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
271 if (ACPI_FAILURE(status)) {
272 goto cleanup;
273 }
274
275 status = acpi_tb_validate_rsdt(rsdt_info->pointer);
276 if (ACPI_FAILURE(status)) {
277 goto cleanup;
278 }
279
280 /* Allocate a scratch table header and table descriptor */
281
282 header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
283 if (!header) {
284 status = AE_NO_MEMORY;
285 goto cleanup;
286 }
287 145
288 table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); 146 /* Convert segment part to physical address */
289 if (!table_info) {
290 status = AE_NO_MEMORY;
291 goto cleanup;
292 }
293 147
294 /* Get the number of table pointers within the RSDT */ 148 physical_address <<= 4;
149 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
295 150
296 table_count = 151 /* EBDA present? */
297 acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer);
298 address.pointer_type = acpi_gbl_table_flags | flags;
299 152
300 /* 153 if (physical_address > 0x400) {
301 * Search the RSDT/XSDT for the correct instance of the
302 * requested table
303 */
304 for (i = 0, j = 0; i < table_count; i++) {
305 /* 154 /*
306 * Get the next table pointer, handle RSDT vs. XSDT 155 * 1b) Search EBDA paragraphs (EBDA is required to be a
307 * RSDT pointers are 32 bits, XSDT pointers are 64 bits 156 * minimum of 1_k length)
308 */ 157 */
309 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { 158 table_ptr = acpi_os_map_memory((acpi_native_uint)
310 address.pointer.value = 159 physical_address,
311 (ACPI_CAST_PTR 160 ACPI_EBDA_WINDOW_SIZE);
312 (struct rsdt_descriptor, 161 if (!table_ptr) {
313 rsdt_info->pointer))->table_offset_entry[i]; 162 ACPI_ERROR((AE_INFO,
314 } else { 163 "Could not map memory at %8.8X for length %X",
315 address.pointer.value = 164 physical_address, ACPI_EBDA_WINDOW_SIZE));
316 (ACPI_CAST_PTR
317 (struct xsdt_descriptor,
318 rsdt_info->pointer))->table_offset_entry[i];
319 }
320
321 /* Get the table header */
322 165
323 status = acpi_tb_get_table_header(&address, header); 166 return_ACPI_STATUS(AE_NO_MEMORY);
324 if (ACPI_FAILURE(status)) {
325 goto cleanup;
326 } 167 }
327 168
328 /* Compare table signatures and table instance */ 169 mem_rover =
329 170 acpi_tb_scan_memory_for_rsdp(table_ptr,
330 if (ACPI_COMPARE_NAME(header->signature, signature)) { 171 ACPI_EBDA_WINDOW_SIZE);
331 172 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
332 /* An instance of the table was found */
333 173
334 j++; 174 if (mem_rover) {
335 if (j >= instance) {
336 175
337 /* Found the correct instance, get the entire table */ 176 /* Return the physical address */
338 177
339 status = 178 physical_address +=
340 acpi_tb_get_table_body(&address, header, 179 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
341 table_info);
342 if (ACPI_FAILURE(status)) {
343 goto cleanup;
344 }
345 180
346 *table_pointer = table_info->pointer; 181 *table_address = physical_address;
347 goto cleanup; 182 return_ACPI_STATUS(AE_OK);
348 }
349 } 183 }
350 } 184 }
351 185
352 /* Did not find the table */ 186 /*
187 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
188 */
189 table_ptr = acpi_os_map_memory((acpi_physical_address)
190 ACPI_HI_RSDP_WINDOW_BASE,
191 ACPI_HI_RSDP_WINDOW_SIZE);
353 192
354 status = AE_NOT_EXIST; 193 if (!table_ptr) {
194 ACPI_ERROR((AE_INFO,
195 "Could not map memory at %8.8X for length %X",
196 ACPI_HI_RSDP_WINDOW_BASE,
197 ACPI_HI_RSDP_WINDOW_SIZE));
355 198
356 cleanup: 199 return_ACPI_STATUS(AE_NO_MEMORY);
357 if (rsdt_info->pointer) {
358 acpi_os_unmap_memory(rsdt_info->pointer,
359 (acpi_size) rsdt_info->pointer->length);
360 } 200 }
361 ACPI_FREE(rsdt_info);
362 201
363 if (header) { 202 mem_rover =
364 ACPI_FREE(header); 203 acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
365 } 204 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
366 if (table_info) {
367 ACPI_FREE(table_info);
368 }
369 return_ACPI_STATUS(status);
370}
371 205
372ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) 206 if (mem_rover) {
373 207
374/* TBD: Move to a new file */ 208 /* Return the physical address */
375#if ACPI_MACHINE_WIDTH != 16
376/*******************************************************************************
377 *
378 * FUNCTION: acpi_find_root_pointer
379 *
380 * PARAMETERS: Flags - Logical/Physical addressing
381 * rsdp_address - Where to place the RSDP address
382 *
383 * RETURN: Status, Physical address of the RSDP
384 *
385 * DESCRIPTION: Find the RSDP
386 *
387 ******************************************************************************/
388acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address)
389{
390 struct acpi_table_desc table_info;
391 acpi_status status;
392
393 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
394 209
395 /* Get the RSDP */ 210 physical_address = (u32)
211 (ACPI_HI_RSDP_WINDOW_BASE +
212 ACPI_PTR_DIFF(mem_rover, table_ptr));
396 213
397 status = acpi_tb_find_rsdp(&table_info, flags); 214 *table_address = physical_address;
398 if (ACPI_FAILURE(status)) { 215 return_ACPI_STATUS(AE_OK);
399 ACPI_EXCEPTION((AE_INFO, status,
400 "RSDP structure not found - Flags=%X", flags));
401
402 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
403 } 216 }
404 217
405 rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; 218 /* A valid RSDP was not found */
406 rsdp_address->pointer.physical = table_info.physical_address; 219
407 return_ACPI_STATUS(AE_OK); 220 ACPI_ERROR((AE_INFO, "A valid RSDP was not found"));
221 return_ACPI_STATUS(AE_NOT_FOUND);
408} 222}
409 223
410ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) 224ACPI_EXPORT_SYMBOL(acpi_find_root_pointer)
@@ -440,7 +254,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
440 254
441 status = 255 status =
442 acpi_tb_validate_rsdp(ACPI_CAST_PTR 256 acpi_tb_validate_rsdp(ACPI_CAST_PTR
443 (struct rsdp_descriptor, mem_rover)); 257 (struct acpi_table_rsdp, mem_rover));
444 if (ACPI_SUCCESS(status)) { 258 if (ACPI_SUCCESS(status)) {
445 259
446 /* Sig and checksum valid, we have found a real RSDP */ 260 /* Sig and checksum valid, we have found a real RSDP */
@@ -462,188 +276,4 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
462 return_PTR(NULL); 276 return_PTR(NULL);
463} 277}
464 278
465/*******************************************************************************
466 *
467 * FUNCTION: acpi_tb_find_rsdp
468 *
469 * PARAMETERS: table_info - Where the table info is returned
470 * Flags - Current memory mode (logical vs.
471 * physical addressing)
472 *
473 * RETURN: Status, RSDP physical address
474 *
475 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
476 * pointer structure. If it is found, set *RSDP to point to it.
477 *
478 * NOTE1: The RSDP must be either in the first 1_k of the Extended
479 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
480 * Only a 32-bit physical address is necessary.
481 *
482 * NOTE2: This function is always available, regardless of the
483 * initialization state of the rest of ACPI.
484 *
485 ******************************************************************************/
486
487static acpi_status
488acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags)
489{
490 u8 *table_ptr;
491 u8 *mem_rover;
492 u32 physical_address;
493 acpi_status status;
494
495 ACPI_FUNCTION_TRACE(tb_find_rsdp);
496
497 /*
498 * Scan supports either logical addressing or physical addressing
499 */
500 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
501
502 /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
503
504 status = acpi_os_map_memory((acpi_physical_address)
505 ACPI_EBDA_PTR_LOCATION,
506 ACPI_EBDA_PTR_LENGTH,
507 (void *)&table_ptr);
508 if (ACPI_FAILURE(status)) {
509 ACPI_ERROR((AE_INFO,
510 "Could not map memory at %8.8X for length %X",
511 ACPI_EBDA_PTR_LOCATION,
512 ACPI_EBDA_PTR_LENGTH));
513
514 return_ACPI_STATUS(status);
515 }
516
517 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
518
519 /* Convert segment part to physical address */
520
521 physical_address <<= 4;
522 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
523
524 /* EBDA present? */
525
526 if (physical_address > 0x400) {
527 /*
528 * 1b) Search EBDA paragraphs (EBDA is required to be a
529 * minimum of 1_k length)
530 */
531 status = acpi_os_map_memory((acpi_physical_address)
532 physical_address,
533 ACPI_EBDA_WINDOW_SIZE,
534 (void *)&table_ptr);
535 if (ACPI_FAILURE(status)) {
536 ACPI_ERROR((AE_INFO,
537 "Could not map memory at %8.8X for length %X",
538 physical_address,
539 ACPI_EBDA_WINDOW_SIZE));
540
541 return_ACPI_STATUS(status);
542 }
543
544 mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr,
545 ACPI_EBDA_WINDOW_SIZE);
546 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
547
548 if (mem_rover) {
549
550 /* Return the physical address */
551
552 physical_address +=
553 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
554
555 table_info->physical_address =
556 (acpi_physical_address) physical_address;
557 return_ACPI_STATUS(AE_OK);
558 }
559 }
560
561 /*
562 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
563 */
564 status = acpi_os_map_memory((acpi_physical_address)
565 ACPI_HI_RSDP_WINDOW_BASE,
566 ACPI_HI_RSDP_WINDOW_SIZE,
567 (void *)&table_ptr);
568
569 if (ACPI_FAILURE(status)) {
570 ACPI_ERROR((AE_INFO,
571 "Could not map memory at %8.8X for length %X",
572 ACPI_HI_RSDP_WINDOW_BASE,
573 ACPI_HI_RSDP_WINDOW_SIZE));
574
575 return_ACPI_STATUS(status);
576 }
577
578 mem_rover =
579 acpi_tb_scan_memory_for_rsdp(table_ptr,
580 ACPI_HI_RSDP_WINDOW_SIZE);
581 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
582
583 if (mem_rover) {
584
585 /* Return the physical address */
586
587 physical_address = (u32)
588 (ACPI_HI_RSDP_WINDOW_BASE +
589 ACPI_PTR_DIFF(mem_rover, table_ptr));
590
591 table_info->physical_address =
592 (acpi_physical_address) physical_address;
593 return_ACPI_STATUS(AE_OK);
594 }
595 }
596
597 /*
598 * Physical addressing
599 */
600 else {
601 /* 1a) Get the location of the EBDA */
602
603 ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION);
604 physical_address <<= 4; /* Convert segment to physical address */
605
606 /* EBDA present? */
607
608 if (physical_address > 0x400) {
609 /*
610 * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of
611 * 1_k length)
612 */
613 mem_rover =
614 acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
615 (physical_address),
616 ACPI_EBDA_WINDOW_SIZE);
617 if (mem_rover) {
618
619 /* Return the physical address */
620
621 table_info->physical_address =
622 ACPI_TO_INTEGER(mem_rover);
623 return_ACPI_STATUS(AE_OK);
624 }
625 }
626
627 /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
628
629 mem_rover =
630 acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
631 (ACPI_HI_RSDP_WINDOW_BASE),
632 ACPI_HI_RSDP_WINDOW_SIZE);
633 if (mem_rover) {
634
635 /* Found it, return the physical address */
636
637 table_info->physical_address =
638 ACPI_TO_INTEGER(mem_rover);
639 return_ACPI_STATUS(AE_OK);
640 }
641 }
642
643 /* A valid RSDP was not found */
644
645 ACPI_ERROR((AE_INFO, "No valid RSDP was found"));
646 return_ACPI_STATUS(AE_NOT_FOUND);
647}
648
649#endif 279#endif