Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / acpi / tables / tbxfroot.c
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