tbxface.c revision 1.4.6.2 1 /******************************************************************************
2 *
3 * Module Name: tbxface - Public interfaces to the ACPI subsystem
4 * ACPI table oriented interfaces
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45 #define __TBXFACE_C__
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "acnamesp.h"
50 #include "actables.h"
51
52 #define _COMPONENT ACPI_TABLES
53 ACPI_MODULE_NAME ("tbxface")
54
55 /* Local prototypes */
56
57 static ACPI_STATUS
58 AcpiTbLoadNamespace (
59 void);
60
61
62 /*******************************************************************************
63 *
64 * FUNCTION: AcpiAllocateRootTable
65 *
66 * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of
67 * ACPI_TABLE_DESC structures
68 *
69 * RETURN: Status
70 *
71 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
72 * AcpiInitializeTables.
73 *
74 ******************************************************************************/
75
76 ACPI_STATUS
77 AcpiAllocateRootTable (
78 UINT32 InitialTableCount)
79 {
80
81 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
82 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
83
84 return (AcpiTbResizeRootTableList ());
85 }
86
87
88 /*******************************************************************************
89 *
90 * FUNCTION: AcpiInitializeTables
91 *
92 * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated
93 * ACPI_TABLE_DESC structures. If NULL, the
94 * array is dynamically allocated.
95 * InitialTableCount - Size of InitialTableArray, in number of
96 * ACPI_TABLE_DESC structures
97 * AllowRealloc - Flag to tell Table Manager if resize of
98 * pre-allocated array is allowed. Ignored
99 * if InitialTableArray is NULL.
100 *
101 * RETURN: Status
102 *
103 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
104 *
105 * NOTE: Allows static allocation of the initial table array in order
106 * to avoid the use of dynamic memory in confined environments
107 * such as the kernel boot sequence where it may not be available.
108 *
109 * If the host OS memory managers are initialized, use NULL for
110 * InitialTableArray, and the table will be dynamically allocated.
111 *
112 ******************************************************************************/
113
114 ACPI_STATUS
115 AcpiInitializeTables (
116 ACPI_TABLE_DESC *InitialTableArray,
117 UINT32 InitialTableCount,
118 BOOLEAN AllowResize)
119 {
120 ACPI_PHYSICAL_ADDRESS RsdpAddress;
121 ACPI_STATUS Status;
122
123
124 ACPI_FUNCTION_TRACE (AcpiInitializeTables);
125
126
127 /*
128 * Set up the Root Table Array
129 * Allocate the table array if requested
130 */
131 if (!InitialTableArray)
132 {
133 Status = AcpiAllocateRootTable (InitialTableCount);
134 if (ACPI_FAILURE (Status))
135 {
136 return_ACPI_STATUS (Status);
137 }
138 }
139 else
140 {
141 /* Root Table Array has been statically allocated by the host */
142
143 ACPI_MEMSET (InitialTableArray, 0,
144 (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
145
146 AcpiGbl_RootTableList.Tables = InitialTableArray;
147 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
148 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
149 if (AllowResize)
150 {
151 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
152 }
153 }
154
155 /* Get the address of the RSDP */
156
157 RsdpAddress = AcpiOsGetRootPointer ();
158 if (!RsdpAddress)
159 {
160 return_ACPI_STATUS (AE_NOT_FOUND);
161 }
162
163 /*
164 * Get the root table (RSDT or XSDT) and extract all entries to the local
165 * Root Table Array. This array contains the information of the RSDT/XSDT
166 * in a common, more useable format.
167 */
168 Status = AcpiTbParseRootTable (RsdpAddress);
169 return_ACPI_STATUS (Status);
170 }
171
172 ACPI_EXPORT_SYMBOL (AcpiInitializeTables)
173
174
175 /*******************************************************************************
176 *
177 * FUNCTION: AcpiReallocateRootTable
178 *
179 * PARAMETERS: None
180 *
181 * RETURN: Status
182 *
183 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
184 * root list from the previously provided scratch area. Should
185 * be called once dynamic memory allocation is available in the
186 * kernel
187 *
188 ******************************************************************************/
189
190 ACPI_STATUS
191 AcpiReallocateRootTable (
192 void)
193 {
194 ACPI_TABLE_DESC *Tables;
195 ACPI_SIZE NewSize;
196 ACPI_SIZE CurrentSize;
197
198
199 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
200
201
202 /*
203 * Only reallocate the root table if the host provided a static buffer
204 * for the table array in the call to AcpiInitializeTables.
205 */
206 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
207 {
208 return_ACPI_STATUS (AE_SUPPORT);
209 }
210
211 /*
212 * Get the current size of the root table and add the default
213 * increment to create the new table size.
214 */
215 CurrentSize = (ACPI_SIZE)
216 AcpiGbl_RootTableList.CurrentTableCount * sizeof (ACPI_TABLE_DESC);
217
218 NewSize = CurrentSize +
219 (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
220
221 /* Create new array and copy the old array */
222
223 Tables = ACPI_ALLOCATE_ZEROED (NewSize);
224 if (!Tables)
225 {
226 return_ACPI_STATUS (AE_NO_MEMORY);
227 }
228
229 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
230
231 /*
232 * Update the root table descriptor. The new size will be the current
233 * number of tables plus the increment, independent of the reserved
234 * size of the original table list.
235 */
236 AcpiGbl_RootTableList.Tables = Tables;
237 AcpiGbl_RootTableList.MaxTableCount =
238 AcpiGbl_RootTableList.CurrentTableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
239 AcpiGbl_RootTableList.Flags =
240 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
241
242 return_ACPI_STATUS (AE_OK);
243 }
244
245 ACPI_EXPORT_SYMBOL (AcpiReallocateRootTable)
246
247
248 /*******************************************************************************
249 *
250 * FUNCTION: AcpiGetTableHeader
251 *
252 * PARAMETERS: Signature - ACPI signature of needed table
253 * Instance - Which instance (for SSDTs)
254 * OutTableHeader - The pointer to the table header to fill
255 *
256 * RETURN: Status and pointer to mapped table header
257 *
258 * DESCRIPTION: Finds an ACPI table header.
259 *
260 ******************************************************************************/
261
262 ACPI_STATUS
263 AcpiGetTableHeader (
264 ACPI_CONST_STRING Signature,
265 UINT32 Instance,
266 ACPI_TABLE_HEADER *OutTableHeader)
267 {
268 UINT32 i;
269 UINT32 j;
270 ACPI_TABLE_HEADER *Header;
271 ACPI_STRING USignature = __UNCONST(Signature);
272
273 /* Parameter validation */
274
275 if (!Signature || !OutTableHeader)
276 {
277 return (AE_BAD_PARAMETER);
278 }
279
280 /* Walk the root table list */
281
282 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
283 {
284 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
285 USignature))
286 {
287 continue;
288 }
289
290 if (++j < Instance)
291 {
292 continue;
293 }
294
295 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
296 {
297 if ((AcpiGbl_RootTableList.Tables[i].Flags &
298 ACPI_TABLE_ORIGIN_MASK) ==
299 ACPI_TABLE_ORIGIN_MAPPED)
300 {
301 Header = AcpiOsMapMemory (
302 AcpiGbl_RootTableList.Tables[i].Address,
303 sizeof (ACPI_TABLE_HEADER));
304 if (!Header)
305 {
306 return AE_NO_MEMORY;
307 }
308
309 ACPI_MEMCPY (OutTableHeader, Header, sizeof(ACPI_TABLE_HEADER));
310 AcpiOsUnmapMemory (Header, sizeof(ACPI_TABLE_HEADER));
311 }
312 else
313 {
314 return AE_NOT_FOUND;
315 }
316 }
317 else
318 {
319 ACPI_MEMCPY (OutTableHeader,
320 AcpiGbl_RootTableList.Tables[i].Pointer,
321 sizeof(ACPI_TABLE_HEADER));
322 }
323
324 return (AE_OK);
325 }
326
327 return (AE_NOT_FOUND);
328 }
329
330 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
331
332
333 /*******************************************************************************
334 *
335 * FUNCTION: AcpiGetTable
336 *
337 * PARAMETERS: Signature - ACPI signature of needed table
338 * Instance - Which instance (for SSDTs)
339 * OutTable - Where the pointer to the table is returned
340 *
341 * RETURN: Status and pointer to table
342 *
343 * DESCRIPTION: Finds and verifies an ACPI table.
344 *
345 ******************************************************************************/
346
347 ACPI_STATUS
348 AcpiGetTable (
349 ACPI_CONST_STRING Signature,
350 UINT32 Instance,
351 ACPI_TABLE_HEADER **OutTable)
352 {
353 UINT32 i;
354 UINT32 j;
355 ACPI_STATUS Status;
356 ACPI_STRING USignature = __UNCONST(Signature);
357
358 /* Parameter validation */
359
360 if (!Signature || !OutTable)
361 {
362 return (AE_BAD_PARAMETER);
363 }
364
365 /* Walk the root table list */
366
367 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
368 {
369 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
370 USignature))
371 {
372 continue;
373 }
374
375 if (++j < Instance)
376 {
377 continue;
378 }
379
380 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
381 if (ACPI_SUCCESS (Status))
382 {
383 *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
384 }
385
386 return (Status);
387 }
388
389 return (AE_NOT_FOUND);
390 }
391
392 ACPI_EXPORT_SYMBOL (AcpiGetTable)
393
394
395 /*******************************************************************************
396 *
397 * FUNCTION: AcpiGetTableByIndex
398 *
399 * PARAMETERS: TableIndex - Table index
400 * Table - Where the pointer to the table is returned
401 *
402 * RETURN: Status and pointer to the table
403 *
404 * DESCRIPTION: Obtain a table by an index into the global table list.
405 *
406 ******************************************************************************/
407
408 ACPI_STATUS
409 AcpiGetTableByIndex (
410 UINT32 TableIndex,
411 ACPI_TABLE_HEADER **Table)
412 {
413 ACPI_STATUS Status;
414
415
416 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
417
418
419 /* Parameter validation */
420
421 if (!Table)
422 {
423 return_ACPI_STATUS (AE_BAD_PARAMETER);
424 }
425
426 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
427
428 /* Validate index */
429
430 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
431 {
432 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
433 return_ACPI_STATUS (AE_BAD_PARAMETER);
434 }
435
436 if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
437 {
438 /* Table is not mapped, map it */
439
440 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
441 if (ACPI_FAILURE (Status))
442 {
443 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
444 return_ACPI_STATUS (Status);
445 }
446 }
447
448 *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
449 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
450 return_ACPI_STATUS (AE_OK);
451 }
452
453 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
454
455
456 /*******************************************************************************
457 *
458 * FUNCTION: AcpiTbLoadNamespace
459 *
460 * PARAMETERS: None
461 *
462 * RETURN: Status
463 *
464 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
465 * the RSDT/XSDT.
466 *
467 ******************************************************************************/
468
469 static ACPI_STATUS
470 AcpiTbLoadNamespace (
471 void)
472 {
473 ACPI_STATUS Status;
474 UINT32 i;
475 ACPI_TABLE_HEADER *NewDsdt;
476
477
478 ACPI_FUNCTION_TRACE (TbLoadNamespace);
479
480
481 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
482
483 /*
484 * Load the namespace. The DSDT is required, but any SSDT and
485 * PSDT tables are optional. Verify the DSDT.
486 */
487 if (!AcpiGbl_RootTableList.CurrentTableCount ||
488 !ACPI_COMPARE_NAME (
489 &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
490 ACPI_SIG_DSDT) ||
491 ACPI_FAILURE (AcpiTbVerifyTable (
492 &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
493 {
494 Status = AE_NO_ACPI_TABLES;
495 goto UnlockAndExit;
496 }
497
498 /*
499 * Save the DSDT pointer for simple access. This is the mapped memory
500 * address. We must take care here because the address of the .Tables
501 * array can change dynamically as tables are loaded at run-time. Note:
502 * .Pointer field is not validated until after call to AcpiTbVerifyTable.
503 */
504 AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
505
506 /*
507 * Optionally copy the entire DSDT to local memory (instead of simply
508 * mapping it.) There are some BIOSs that corrupt or replace the original
509 * DSDT, creating the need for this option. Default is FALSE, do not copy
510 * the DSDT.
511 */
512 if (AcpiGbl_CopyDsdtLocally)
513 {
514 NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
515 if (NewDsdt)
516 {
517 AcpiGbl_DSDT = NewDsdt;
518 }
519 }
520
521 /*
522 * Save the original DSDT header for detection of table corruption
523 * and/or replacement of the DSDT from outside the OS.
524 */
525 ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
526 sizeof (ACPI_TABLE_HEADER));
527
528 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
529
530 /* Load and parse tables */
531
532 Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
533 if (ACPI_FAILURE (Status))
534 {
535 return_ACPI_STATUS (Status);
536 }
537
538 /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
539
540 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
541 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
542 {
543 if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
544 ACPI_SIG_SSDT) &&
545 !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
546 ACPI_SIG_PSDT)) ||
547 ACPI_FAILURE (AcpiTbVerifyTable (
548 &AcpiGbl_RootTableList.Tables[i])))
549 {
550 continue;
551 }
552
553 /* Ignore errors while loading tables, get as many as possible */
554
555 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
556 (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
557 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
558 }
559
560 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
561
562 UnlockAndExit:
563 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
564 return_ACPI_STATUS (Status);
565 }
566
567
568 /*******************************************************************************
569 *
570 * FUNCTION: AcpiLoadTables
571 *
572 * PARAMETERS: None
573 *
574 * RETURN: Status
575 *
576 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
577 *
578 ******************************************************************************/
579
580 ACPI_STATUS
581 AcpiLoadTables (
582 void)
583 {
584 ACPI_STATUS Status;
585
586
587 ACPI_FUNCTION_TRACE (AcpiLoadTables);
588
589
590 /* Load the namespace from the tables */
591
592 Status = AcpiTbLoadNamespace ();
593 if (ACPI_FAILURE (Status))
594 {
595 ACPI_EXCEPTION ((AE_INFO, Status,
596 "While loading namespace from ACPI tables"));
597 }
598
599 return_ACPI_STATUS (Status);
600 }
601
602 ACPI_EXPORT_SYMBOL (AcpiLoadTables)
603
604
605 /*******************************************************************************
606 *
607 * FUNCTION: AcpiInstallTableHandler
608 *
609 * PARAMETERS: Handler - Table event handler
610 * Context - Value passed to the handler on each event
611 *
612 * RETURN: Status
613 *
614 * DESCRIPTION: Install table event handler
615 *
616 ******************************************************************************/
617
618 ACPI_STATUS
619 AcpiInstallTableHandler (
620 ACPI_TABLE_HANDLER Handler,
621 void *Context)
622 {
623 ACPI_STATUS Status;
624
625
626 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
627
628
629 if (!Handler)
630 {
631 return_ACPI_STATUS (AE_BAD_PARAMETER);
632 }
633
634 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
635 if (ACPI_FAILURE (Status))
636 {
637 return_ACPI_STATUS (Status);
638 }
639
640 /* Don't allow more than one handler */
641
642 if (AcpiGbl_TableHandler)
643 {
644 Status = AE_ALREADY_EXISTS;
645 goto Cleanup;
646 }
647
648 /* Install the handler */
649
650 AcpiGbl_TableHandler = Handler;
651 AcpiGbl_TableHandlerContext = Context;
652
653 Cleanup:
654 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
655 return_ACPI_STATUS (Status);
656 }
657
658 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
659
660
661 /*******************************************************************************
662 *
663 * FUNCTION: AcpiRemoveTableHandler
664 *
665 * PARAMETERS: Handler - Table event handler that was installed
666 * previously.
667 *
668 * RETURN: Status
669 *
670 * DESCRIPTION: Remove table event handler
671 *
672 ******************************************************************************/
673
674 ACPI_STATUS
675 AcpiRemoveTableHandler (
676 ACPI_TABLE_HANDLER Handler)
677 {
678 ACPI_STATUS Status;
679
680
681 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
682
683
684 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
685 if (ACPI_FAILURE (Status))
686 {
687 return_ACPI_STATUS (Status);
688 }
689
690 /* Make sure that the installed handler is the same */
691
692 if (!Handler ||
693 Handler != AcpiGbl_TableHandler)
694 {
695 Status = AE_BAD_PARAMETER;
696 goto Cleanup;
697 }
698
699 /* Remove the handler */
700
701 AcpiGbl_TableHandler = NULL;
702
703 Cleanup:
704 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
705 return_ACPI_STATUS (Status);
706 }
707
708 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
709
710