tbxfroot.c revision 192384
1/******************************************************************************
2 *
3 * Module Name: tbxfroot - Find the root ACPI table (RSDT)
4 *              $Revision: 1.105 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117#define __TBXFROOT_C__
118
119#include <contrib/dev/acpica/acpi.h>
120#include <contrib/dev/acpica/actables.h>
121
122
123#define _COMPONENT          ACPI_TABLES
124        ACPI_MODULE_NAME    ("tbxfroot")
125
126/* Local prototypes */
127
128static UINT8 *
129AcpiTbScanMemoryForRsdp (
130    UINT8                   *StartAddress,
131    UINT32                  Length);
132
133static ACPI_STATUS
134AcpiTbValidateRsdp (
135    ACPI_TABLE_RSDP         *Rsdp);
136
137
138/*******************************************************************************
139 *
140 * FUNCTION:    AcpiTbValidateRsdp
141 *
142 * PARAMETERS:  Rsdp                - Pointer to unvalidated RSDP
143 *
144 * RETURN:      Status
145 *
146 * DESCRIPTION: Validate the RSDP (ptr)
147 *
148 ******************************************************************************/
149
150static ACPI_STATUS
151AcpiTbValidateRsdp (
152    ACPI_TABLE_RSDP         *Rsdp)
153{
154    ACPI_FUNCTION_ENTRY ();
155
156
157    /*
158     * The signature and checksum must both be correct
159     *
160     * Note: Sometimes there exists more than one RSDP in memory; the valid
161     * RSDP has a valid checksum, all others have an invalid checksum.
162     */
163    if (ACPI_STRNCMP ((char *) Rsdp, ACPI_SIG_RSDP, sizeof (ACPI_SIG_RSDP)-1) != 0)
164    {
165        /* Nope, BAD Signature */
166
167        return (AE_BAD_SIGNATURE);
168    }
169
170    /* Check the standard checksum */
171
172    if (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
173    {
174        return (AE_BAD_CHECKSUM);
175    }
176
177    /* Check extended checksum if table version >= 2 */
178
179    if ((Rsdp->Revision >= 2) &&
180        (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0))
181    {
182        return (AE_BAD_CHECKSUM);
183    }
184
185    return (AE_OK);
186}
187
188
189/*******************************************************************************
190 *
191 * FUNCTION:    AcpiTbFindRsdp
192 *
193 * PARAMETERS:  TableAddress            - Where the table pointer is returned
194 *
195 * RETURN:      Status, RSDP physical address
196 *
197 * DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor
198 *              pointer structure.  If it is found, set *RSDP to point to it.
199 *
200 * NOTE1:       The RSDP must be either in the first 1K of the Extended
201 *              BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
202 *              Only a 32-bit physical address is necessary.
203 *
204 * NOTE2:       This function is always available, regardless of the
205 *              initialization state of the rest of ACPI.
206 *
207 ******************************************************************************/
208
209ACPI_STATUS
210AcpiFindRootPointer (
211    ACPI_NATIVE_UINT        *TableAddress)
212{
213    UINT8                   *TablePtr;
214    UINT8                   *MemRover;
215    UINT32                  PhysicalAddress;
216
217
218    ACPI_FUNCTION_TRACE (AcpiFindRootPointer);
219
220
221    /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
222
223    TablePtr = AcpiOsMapMemory (
224                (ACPI_PHYSICAL_ADDRESS) ACPI_EBDA_PTR_LOCATION,
225                ACPI_EBDA_PTR_LENGTH);
226    if (!TablePtr)
227    {
228        ACPI_ERROR ((AE_INFO,
229            "Could not map memory at %8.8X for length %X",
230            ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
231
232        return_ACPI_STATUS (AE_NO_MEMORY);
233    }
234
235    ACPI_MOVE_16_TO_32 (&PhysicalAddress, TablePtr);
236
237    /* Convert segment part to physical address */
238
239    PhysicalAddress <<= 4;
240    AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_PTR_LENGTH);
241
242    /* EBDA present? */
243
244    if (PhysicalAddress > 0x400)
245    {
246        /*
247         * 1b) Search EBDA paragraphs (EBDA is required to be a
248         *     minimum of 1K length)
249         */
250        TablePtr = AcpiOsMapMemory (
251                    (ACPI_NATIVE_UINT) PhysicalAddress,
252                    ACPI_EBDA_WINDOW_SIZE);
253        if (!TablePtr)
254        {
255            ACPI_ERROR ((AE_INFO,
256                "Could not map memory at %8.8X for length %X",
257                PhysicalAddress, ACPI_EBDA_WINDOW_SIZE));
258
259            return_ACPI_STATUS (AE_NO_MEMORY);
260        }
261
262        MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_EBDA_WINDOW_SIZE);
263        AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_WINDOW_SIZE);
264
265        if (MemRover)
266        {
267            /* Return the physical address */
268
269            PhysicalAddress += (UINT32) ACPI_PTR_DIFF (MemRover, TablePtr);
270
271            *TableAddress = PhysicalAddress;
272            return_ACPI_STATUS (AE_OK);
273        }
274    }
275
276    /*
277     * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
278     */
279    TablePtr = AcpiOsMapMemory (
280                (ACPI_PHYSICAL_ADDRESS) ACPI_HI_RSDP_WINDOW_BASE,
281                ACPI_HI_RSDP_WINDOW_SIZE);
282
283    if (!TablePtr)
284    {
285        ACPI_ERROR ((AE_INFO,
286            "Could not map memory at %8.8X for length %X",
287            ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
288
289        return_ACPI_STATUS (AE_NO_MEMORY);
290    }
291
292    MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE);
293    AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE);
294
295    if (MemRover)
296    {
297        /* Return the physical address */
298
299        PhysicalAddress = (UINT32)
300            (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (MemRover, TablePtr));
301
302        *TableAddress = PhysicalAddress;
303        return_ACPI_STATUS (AE_OK);
304    }
305
306    /* A valid RSDP was not found */
307
308    ACPI_ERROR ((AE_INFO, "A valid RSDP was not found"));
309    return_ACPI_STATUS (AE_NOT_FOUND);
310}
311
312ACPI_EXPORT_SYMBOL (AcpiFindRootPointer)
313
314
315/*******************************************************************************
316 *
317 * FUNCTION:    AcpiTbScanMemoryForRsdp
318 *
319 * PARAMETERS:  StartAddress        - Starting pointer for search
320 *              Length              - Maximum length to search
321 *
322 * RETURN:      Pointer to the RSDP if found, otherwise NULL.
323 *
324 * DESCRIPTION: Search a block of memory for the RSDP signature
325 *
326 ******************************************************************************/
327
328static UINT8 *
329AcpiTbScanMemoryForRsdp (
330    UINT8                   *StartAddress,
331    UINT32                  Length)
332{
333    ACPI_STATUS             Status;
334    UINT8                   *MemRover;
335    UINT8                   *EndAddress;
336
337
338    ACPI_FUNCTION_TRACE (TbScanMemoryForRsdp);
339
340
341    EndAddress = StartAddress + Length;
342
343    /* Search from given start address for the requested length */
344
345    for (MemRover = StartAddress; MemRover < EndAddress;
346         MemRover += ACPI_RSDP_SCAN_STEP)
347    {
348        /* The RSDP signature and checksum must both be correct */
349
350        Status = AcpiTbValidateRsdp (ACPI_CAST_PTR (ACPI_TABLE_RSDP, MemRover));
351        if (ACPI_SUCCESS (Status))
352        {
353            /* Sig and checksum valid, we have found a real RSDP */
354
355            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
356                "RSDP located at physical address %p\n", MemRover));
357            return_PTR (MemRover);
358        }
359
360        /* No sig match or bad checksum, keep searching */
361    }
362
363    /* Searched entire block, no RSDP was found */
364
365    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
366        "Searched entire block from %p, valid RSDP was not found\n",
367        StartAddress));
368    return_PTR (NULL);
369}
370
371