kernel: Sync ACPICA with Intel's version 20140325.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / tables / tbxface.c
1 /******************************************************************************
2  *
3  * Module Name: tbxface - ACPI table-oriented external interfaces
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
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 #define __TBXFACE_C__
45 #define EXPORT_ACPI_INTERFACES
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "actables.h"
50
51 #define _COMPONENT          ACPI_TABLES
52         ACPI_MODULE_NAME    ("tbxface")
53
54
55 /*******************************************************************************
56  *
57  * FUNCTION:    AcpiAllocateRootTable
58  *
59  * PARAMETERS:  InitialTableCount   - Size of InitialTableArray, in number of
60  *                                    ACPI_TABLE_DESC structures
61  *
62  * RETURN:      Status
63  *
64  * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
65  *              AcpiInitializeTables.
66  *
67  ******************************************************************************/
68
69 ACPI_STATUS
70 AcpiAllocateRootTable (
71     UINT32                  InitialTableCount)
72 {
73
74     AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
75     AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
76
77     return (AcpiTbResizeRootTableList ());
78 }
79
80
81 /*******************************************************************************
82  *
83  * FUNCTION:    AcpiInitializeTables
84  *
85  * PARAMETERS:  InitialTableArray   - Pointer to an array of pre-allocated
86  *                                    ACPI_TABLE_DESC structures. If NULL, the
87  *                                    array is dynamically allocated.
88  *              InitialTableCount   - Size of InitialTableArray, in number of
89  *                                    ACPI_TABLE_DESC structures
90  *              AllowResize         - Flag to tell Table Manager if resize of
91  *                                    pre-allocated array is allowed. Ignored
92  *                                    if InitialTableArray is NULL.
93  *
94  * RETURN:      Status
95  *
96  * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
97  *
98  * NOTE:        Allows static allocation of the initial table array in order
99  *              to avoid the use of dynamic memory in confined environments
100  *              such as the kernel boot sequence where it may not be available.
101  *
102  *              If the host OS memory managers are initialized, use NULL for
103  *              InitialTableArray, and the table will be dynamically allocated.
104  *
105  ******************************************************************************/
106
107 ACPI_STATUS
108 AcpiInitializeTables (
109     ACPI_TABLE_DESC         *InitialTableArray,
110     UINT32                  InitialTableCount,
111     BOOLEAN                 AllowResize)
112 {
113     ACPI_PHYSICAL_ADDRESS   RsdpAddress;
114     ACPI_STATUS             Status;
115
116
117     ACPI_FUNCTION_TRACE (AcpiInitializeTables);
118
119
120     /*
121      * Setup the Root Table Array and allocate the table array
122      * if requested
123      */
124     if (!InitialTableArray)
125     {
126         Status = AcpiAllocateRootTable (InitialTableCount);
127         if (ACPI_FAILURE (Status))
128         {
129             return_ACPI_STATUS (Status);
130         }
131     }
132     else
133     {
134         /* Root Table Array has been statically allocated by the host */
135
136         ACPI_MEMSET (InitialTableArray, 0,
137             (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
138
139         AcpiGbl_RootTableList.Tables = InitialTableArray;
140         AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
141         AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
142         if (AllowResize)
143         {
144             AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
145         }
146     }
147
148     /* Get the address of the RSDP */
149
150     RsdpAddress = AcpiOsGetRootPointer ();
151     if (!RsdpAddress)
152     {
153         return_ACPI_STATUS (AE_NOT_FOUND);
154     }
155
156     /*
157      * Get the root table (RSDT or XSDT) and extract all entries to the local
158      * Root Table Array. This array contains the information of the RSDT/XSDT
159      * in a common, more useable format.
160      */
161     Status = AcpiTbParseRootTable (RsdpAddress);
162     return_ACPI_STATUS (Status);
163 }
164
165 ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeTables)
166
167
168 /*******************************************************************************
169  *
170  * FUNCTION:    AcpiReallocateRootTable
171  *
172  * PARAMETERS:  None
173  *
174  * RETURN:      Status
175  *
176  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
177  *              root list from the previously provided scratch area. Should
178  *              be called once dynamic memory allocation is available in the
179  *              kernel.
180  *
181  ******************************************************************************/
182
183 ACPI_STATUS
184 AcpiReallocateRootTable (
185     void)
186 {
187     ACPI_STATUS             Status;
188
189
190     ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
191
192
193     /*
194      * Only reallocate the root table if the host provided a static buffer
195      * for the table array in the call to AcpiInitializeTables.
196      */
197     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
198     {
199         return_ACPI_STATUS (AE_SUPPORT);
200     }
201
202     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
203
204     Status = AcpiTbResizeRootTableList ();
205     return_ACPI_STATUS (Status);
206 }
207
208 ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
209
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    AcpiGetTableHeader
214  *
215  * PARAMETERS:  Signature           - ACPI signature of needed table
216  *              Instance            - Which instance (for SSDTs)
217  *              OutTableHeader      - The pointer to the table header to fill
218  *
219  * RETURN:      Status and pointer to mapped table header
220  *
221  * DESCRIPTION: Finds an ACPI table header.
222  *
223  * NOTE:        Caller is responsible in unmapping the header with
224  *              AcpiOsUnmapMemory
225  *
226  ******************************************************************************/
227
228 ACPI_STATUS
229 AcpiGetTableHeader (
230     char                    *Signature,
231     UINT32                  Instance,
232     ACPI_TABLE_HEADER       *OutTableHeader)
233 {
234     UINT32                  i;
235     UINT32                  j;
236     ACPI_TABLE_HEADER       *Header;
237
238
239     /* Parameter validation */
240
241     if (!Signature || !OutTableHeader)
242     {
243         return (AE_BAD_PARAMETER);
244     }
245
246     /* Walk the root table list */
247
248     for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
249     {
250         if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
251                     Signature))
252         {
253             continue;
254         }
255
256         if (++j < Instance)
257         {
258             continue;
259         }
260
261         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
262         {
263             if ((AcpiGbl_RootTableList.Tables[i].Flags &
264                     ACPI_TABLE_ORIGIN_MASK) ==
265                 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
266             {
267                 Header = AcpiOsMapMemory (
268                             AcpiGbl_RootTableList.Tables[i].Address,
269                             sizeof (ACPI_TABLE_HEADER));
270                 if (!Header)
271                 {
272                     return (AE_NO_MEMORY);
273                 }
274
275                 ACPI_MEMCPY (OutTableHeader, Header,
276                     sizeof (ACPI_TABLE_HEADER));
277                 AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
278             }
279             else
280             {
281                 return (AE_NOT_FOUND);
282             }
283         }
284         else
285         {
286             ACPI_MEMCPY (OutTableHeader,
287                 AcpiGbl_RootTableList.Tables[i].Pointer,
288                 sizeof (ACPI_TABLE_HEADER));
289         }
290
291         return (AE_OK);
292     }
293
294     return (AE_NOT_FOUND);
295 }
296
297 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
298
299
300 /*******************************************************************************
301  *
302  * FUNCTION:    AcpiGetTable
303  *
304  * PARAMETERS:  Signature           - ACPI signature of needed table
305  *              Instance            - Which instance (for SSDTs)
306  *              OutTable            - Where the pointer to the table is returned
307  *
308  * RETURN:      Status and pointer to the requested table
309  *
310  * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
311  *              RSDT/XSDT.
312  *
313  ******************************************************************************/
314
315 ACPI_STATUS
316 AcpiGetTable (
317     char                    *Signature,
318     UINT32                  Instance,
319     ACPI_TABLE_HEADER       **OutTable)
320 {
321     UINT32                  i;
322     UINT32                  j;
323     ACPI_STATUS             Status;
324
325
326     /* Parameter validation */
327
328     if (!Signature || !OutTable)
329     {
330         return (AE_BAD_PARAMETER);
331     }
332
333     /* Walk the root table list */
334
335     for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
336     {
337         if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
338                 Signature))
339         {
340             continue;
341         }
342
343         if (++j < Instance)
344         {
345             continue;
346         }
347
348         Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
349         if (ACPI_SUCCESS (Status))
350         {
351             *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
352         }
353
354         return (Status);
355     }
356
357     return (AE_NOT_FOUND);
358 }
359
360 ACPI_EXPORT_SYMBOL (AcpiGetTable)
361
362
363 /*******************************************************************************
364  *
365  * FUNCTION:    AcpiGetTableByIndex
366  *
367  * PARAMETERS:  TableIndex          - Table index
368  *              Table               - Where the pointer to the table is returned
369  *
370  * RETURN:      Status and pointer to the requested table
371  *
372  * DESCRIPTION: Obtain a table by an index into the global table list. Used
373  *              internally also.
374  *
375  ******************************************************************************/
376
377 ACPI_STATUS
378 AcpiGetTableByIndex (
379     UINT32                  TableIndex,
380     ACPI_TABLE_HEADER       **Table)
381 {
382     ACPI_STATUS             Status;
383
384
385     ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
386
387
388     /* Parameter validation */
389
390     if (!Table)
391     {
392         return_ACPI_STATUS (AE_BAD_PARAMETER);
393     }
394
395     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
396
397     /* Validate index */
398
399     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
400     {
401         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
402         return_ACPI_STATUS (AE_BAD_PARAMETER);
403     }
404
405     if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
406     {
407         /* Table is not mapped, map it */
408
409         Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
410         if (ACPI_FAILURE (Status))
411         {
412             (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
413             return_ACPI_STATUS (Status);
414         }
415     }
416
417     *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
418     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
419     return_ACPI_STATUS (AE_OK);
420 }
421
422 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
423
424
425 /*******************************************************************************
426  *
427  * FUNCTION:    AcpiInstallTableHandler
428  *
429  * PARAMETERS:  Handler         - Table event handler
430  *              Context         - Value passed to the handler on each event
431  *
432  * RETURN:      Status
433  *
434  * DESCRIPTION: Install a global table event handler.
435  *
436  ******************************************************************************/
437
438 ACPI_STATUS
439 AcpiInstallTableHandler (
440     ACPI_TABLE_HANDLER      Handler,
441     void                    *Context)
442 {
443     ACPI_STATUS             Status;
444
445
446     ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
447
448
449     if (!Handler)
450     {
451         return_ACPI_STATUS (AE_BAD_PARAMETER);
452     }
453
454     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
455     if (ACPI_FAILURE (Status))
456     {
457         return_ACPI_STATUS (Status);
458     }
459
460     /* Don't allow more than one handler */
461
462     if (AcpiGbl_TableHandler)
463     {
464         Status = AE_ALREADY_EXISTS;
465         goto Cleanup;
466     }
467
468     /* Install the handler */
469
470     AcpiGbl_TableHandler = Handler;
471     AcpiGbl_TableHandlerContext = Context;
472
473 Cleanup:
474     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
475     return_ACPI_STATUS (Status);
476 }
477
478 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
479
480
481 /*******************************************************************************
482  *
483  * FUNCTION:    AcpiRemoveTableHandler
484  *
485  * PARAMETERS:  Handler         - Table event handler that was installed
486  *                                previously.
487  *
488  * RETURN:      Status
489  *
490  * DESCRIPTION: Remove a table event handler
491  *
492  ******************************************************************************/
493
494 ACPI_STATUS
495 AcpiRemoveTableHandler (
496     ACPI_TABLE_HANDLER      Handler)
497 {
498     ACPI_STATUS             Status;
499
500
501     ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
502
503
504     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
505     if (ACPI_FAILURE (Status))
506     {
507         return_ACPI_STATUS (Status);
508     }
509
510     /* Make sure that the installed handler is the same */
511
512     if (!Handler ||
513         Handler != AcpiGbl_TableHandler)
514     {
515         Status = AE_BAD_PARAMETER;
516         goto Cleanup;
517     }
518
519     /* Remove the handler */
520
521     AcpiGbl_TableHandler = NULL;
522
523 Cleanup:
524     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
525     return_ACPI_STATUS (Status);
526 }
527
528 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)