1/******************************************************************************
2 *
3 * Module Name: tbdata - Table manager data structure functions
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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#include "acpi.h"
45#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h"
48#include "acevents.h"
49
50#define _COMPONENT ACPI_TABLES
51 ACPI_MODULE_NAME ("tbdata")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: AcpiTbInitTableDescriptor
57 *
58 * PARAMETERS: TableDesc - Table descriptor
59 * Address - Physical address of the table
60 * Flags - Allocation flags of the table
61 * Table - Pointer to the table
62 *
63 * RETURN: None
64 *
65 * DESCRIPTION: Initialize a new table descriptor
66 *
67 ******************************************************************************/
68
69void
70AcpiTbInitTableDescriptor (
71 ACPI_TABLE_DESC *TableDesc,
72 ACPI_PHYSICAL_ADDRESS Address,
73 UINT8 Flags,
74 ACPI_TABLE_HEADER *Table)
75{
76
77 /*
78 * Initialize the table descriptor. Set the pointer to NULL, since the
79 * table is not fully mapped at this time.
80 */
81 memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
82 TableDesc->Address = Address;
83 TableDesc->Length = Table->Length;
84 TableDesc->Flags = Flags;
85 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
86}
87
88
89/*******************************************************************************
90 *
91 * FUNCTION: AcpiTbAcquireTable
92 *
93 * PARAMETERS: TableDesc - Table descriptor
94 * TablePtr - Where table is returned
95 * TableLength - Where table length is returned
96 * TableFlags - Where table allocation flags are returned
97 *
98 * RETURN: Status
99 *
100 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
101 * maintained in the AcpiGbl_RootTableList.
102 *
103 ******************************************************************************/
104
105ACPI_STATUS
106AcpiTbAcquireTable (
107 ACPI_TABLE_DESC *TableDesc,
108 ACPI_TABLE_HEADER **TablePtr,
109 UINT32 *TableLength,
110 UINT8 *TableFlags)
111{
112 ACPI_TABLE_HEADER *Table = NULL;
113
114
115 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
116 {
117 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
118
119 Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
120 break;
121
122 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
123 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
124
125 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
126 ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
127 break;
128
129 default:
130
131 break;
132 }
133
134 /* Table is not valid yet */
135
136 if (!Table)
137 {
138 return (AE_NO_MEMORY);
139 }
140
141 /* Fill the return values */
142
143 *TablePtr = Table;
144 *TableLength = TableDesc->Length;
145 *TableFlags = TableDesc->Flags;
146 return (AE_OK);
147}
148
149
150/*******************************************************************************
151 *
152 * FUNCTION: AcpiTbReleaseTable
153 *
154 * PARAMETERS: Table - Pointer for the table
155 * TableLength - Length for the table
156 * TableFlags - Allocation flags for the table
157 *
158 * RETURN: None
159 *
160 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
161 *
162 ******************************************************************************/
163
164void
165AcpiTbReleaseTable (
166 ACPI_TABLE_HEADER *Table,
167 UINT32 TableLength,
168 UINT8 TableFlags)
169{
170
171 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
172 {
173 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
174
175 AcpiOsUnmapMemory (Table, TableLength);
176 break;
177
178 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
179 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
180 default:
181
182 break;
183 }
184}
185
186
187/*******************************************************************************
188 *
189 * FUNCTION: AcpiTbAcquireTempTable
190 *
191 * PARAMETERS: TableDesc - Table descriptor to be acquired
192 * Address - Address of the table
193 * Flags - Allocation flags of the table
194 *
195 * RETURN: Status
196 *
197 * DESCRIPTION: This function validates the table header to obtain the length
198 * of a table and fills the table descriptor to make its state as
199 * "INSTALLED". Such a table descriptor is only used for verified
200 * installation.
201 *
202 ******************************************************************************/
203
204ACPI_STATUS
205AcpiTbAcquireTempTable (
206 ACPI_TABLE_DESC *TableDesc,
207 ACPI_PHYSICAL_ADDRESS Address,
208 UINT8 Flags)
209{
210 ACPI_TABLE_HEADER *TableHeader;
211
212
213 switch (Flags & ACPI_TABLE_ORIGIN_MASK)
214 {
215 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
216
217 /* Get the length of the full table from the header */
218
219 TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
220 if (!TableHeader)
221 {
222 return (AE_NO_MEMORY);
223 }
224
225 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
226 AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
227 return (AE_OK);
228
229 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
230 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
231
232 TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
233 ACPI_PHYSADDR_TO_PTR (Address));
234 if (!TableHeader)
235 {
236 return (AE_NO_MEMORY);
237 }
238
239 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
240 return (AE_OK);
241
242 default:
243
244 break;
245 }
246
247 /* Table is not valid yet */
248
249 return (AE_NO_MEMORY);
250}
251
252
253/*******************************************************************************
254 *
255 * FUNCTION: AcpiTbReleaseTempTable
256 *
257 * PARAMETERS: TableDesc - Table descriptor to be released
258 *
259 * RETURN: Status
260 *
261 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
262 *
263 *****************************************************************************/
264
265void
266AcpiTbReleaseTempTable (
267 ACPI_TABLE_DESC *TableDesc)
268{
269
270 /*
271 * Note that the .Address is maintained by the callers of
272 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
273 * where .Address will be freed.
274 */
275 AcpiTbInvalidateTable (TableDesc);
276}
277
278
279/******************************************************************************
280 *
281 * FUNCTION: AcpiTbValidateTable
282 *
283 * PARAMETERS: TableDesc - Table descriptor
284 *
285 * RETURN: Status
286 *
287 * DESCRIPTION: This function is called to validate the table, the returned
288 * table descriptor is in "VALIDATED" state.
289 *
290 *****************************************************************************/
291
292ACPI_STATUS
293AcpiTbValidateTable (
294 ACPI_TABLE_DESC *TableDesc)
295{
296 ACPI_STATUS Status = AE_OK;
297
298
299 ACPI_FUNCTION_TRACE (TbValidateTable);
300
301
302 /* Validate the table if necessary */
303
304 if (!TableDesc->Pointer)
305 {
306 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
307 &TableDesc->Length, &TableDesc->Flags);
308 if (!TableDesc->Pointer)
309 {
310 Status = AE_NO_MEMORY;
311 }
312 }
313
314 return_ACPI_STATUS (Status);
315}
316
317
318/*******************************************************************************
319 *
320 * FUNCTION: AcpiTbInvalidateTable
321 *
322 * PARAMETERS: TableDesc - Table descriptor
323 *
324 * RETURN: None
325 *
326 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
327 * AcpiTbValidateTable().
328 *
329 ******************************************************************************/
330
331void
332AcpiTbInvalidateTable (
333 ACPI_TABLE_DESC *TableDesc)
334{
335
336 ACPI_FUNCTION_TRACE (TbInvalidateTable);
337
338
339 /* Table must be validated */
340
341 if (!TableDesc->Pointer)
342 {
343 return_VOID;
344 }
345
346 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
347 TableDesc->Flags);
348 TableDesc->Pointer = NULL;
349
350 return_VOID;
351}
352
353
354/******************************************************************************
355 *
356 * FUNCTION: AcpiTbValidateTempTable
357 *
358 * PARAMETERS: TableDesc - Table descriptor
359 *
360 * RETURN: Status
361 *
362 * DESCRIPTION: This function is called to validate the table, the returned
363 * table descriptor is in "VALIDATED" state.
364 *
365 *****************************************************************************/
366
367ACPI_STATUS
368AcpiTbValidateTempTable (
369 ACPI_TABLE_DESC *TableDesc)
370{
371
372 if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
373 {
374 /*
375 * Only validates the header of the table.
376 * Note that Length contains the size of the mapping after invoking
377 * this work around, this value is required by
378 * AcpiTbReleaseTempTable().
379 * We can do this because in AcpiInitTableDescriptor(), the Length
380 * field of the installed descriptor is filled with the actual
381 * table length obtaining from the table header.
382 */
383 TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
384 }
385
386 return (AcpiTbValidateTable (TableDesc));
387}
388
389
390/******************************************************************************
391 *
392 * FUNCTION: AcpiTbVerifyTempTable
393 *
394 * PARAMETERS: TableDesc - Table descriptor
395 * Signature - Table signature to verify
396 *
397 * RETURN: Status
398 *
399 * DESCRIPTION: This function is called to validate and verify the table, the
400 * returned table descriptor is in "VALIDATED" state.
401 *
402 *****************************************************************************/
403
404ACPI_STATUS
405AcpiTbVerifyTempTable (
406 ACPI_TABLE_DESC *TableDesc,
407 const char *Signature)
408{
409 ACPI_STATUS Status = AE_OK;
410
411
412 ACPI_FUNCTION_TRACE (TbVerifyTempTable);
413
414
415 /* Validate the table */
416
417 Status = AcpiTbValidateTempTable (TableDesc);
418 if (ACPI_FAILURE (Status))
419 {
420 return_ACPI_STATUS (AE_NO_MEMORY);
421 }
422
423 /* If a particular signature is expected (DSDT/FACS), it must match */
424
425 if (Signature &&
426 !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
427 {
428 ACPI_BIOS_ERROR ((AE_INFO,
429 "Invalid signature 0x%X for ACPI table, expected [%s]",
430 TableDesc->Signature.Integer, Signature));
431 Status = AE_BAD_SIGNATURE;
432 goto InvalidateAndExit;
433 }
434
435 /* Verify the checksum */
436
437 if (AcpiGbl_VerifyTableChecksum)
438 {
439 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
440 if (ACPI_FAILURE (Status))
441 {
442 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
443 "%4.4s 0x%8.8X%8.8X"
444 " Attempted table install failed",
445 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
446 TableDesc->Signature.Ascii : "????",
447 ACPI_FORMAT_UINT64 (TableDesc->Address)));
448
449 goto InvalidateAndExit;
450 }
451 }
452
453 return_ACPI_STATUS (AE_OK);
454
455InvalidateAndExit:
456 AcpiTbInvalidateTable (TableDesc);
457 return_ACPI_STATUS (Status);
458}
459
460
461/*******************************************************************************
462 *
463 * FUNCTION: AcpiTbResizeRootTableList
464 *
465 * PARAMETERS: None
466 *
467 * RETURN: Status
468 *
469 * DESCRIPTION: Expand the size of global table array
470 *
471 ******************************************************************************/
472
473ACPI_STATUS
474AcpiTbResizeRootTableList (
475 void)
476{
477 ACPI_TABLE_DESC *Tables;
478 UINT32 TableCount;
479
480
481 ACPI_FUNCTION_TRACE (TbResizeRootTableList);
482
483
484 /* AllowResize flag is a parameter to AcpiInitializeTables */
485
486 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
487 {
488 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
489 return_ACPI_STATUS (AE_SUPPORT);
490 }
491
492 /* Increase the Table Array size */
493
494 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
495 {
496 TableCount = AcpiGbl_RootTableList.MaxTableCount;
497 }
498 else
499 {
500 TableCount = AcpiGbl_RootTableList.CurrentTableCount;
501 }
502
503 Tables = ACPI_ALLOCATE_ZEROED (
504 ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
505 sizeof (ACPI_TABLE_DESC));
506 if (!Tables)
507 {
508 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
509 return_ACPI_STATUS (AE_NO_MEMORY);
510 }
511
512 /* Copy and free the previous table array */
513
514 if (AcpiGbl_RootTableList.Tables)
515 {
516 memcpy (Tables, AcpiGbl_RootTableList.Tables,
517 (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
518
519 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
520 {
521 ACPI_FREE (AcpiGbl_RootTableList.Tables);
522 }
523 }
524
525 AcpiGbl_RootTableList.Tables = Tables;
526 AcpiGbl_RootTableList.MaxTableCount =
527 TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
528 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
529
530 return_ACPI_STATUS (AE_OK);
531}
532
533
534/*******************************************************************************
535 *
536 * FUNCTION: AcpiTbGetNextTableDescriptor
537 *
538 * PARAMETERS: TableIndex - Where table index is returned
539 * TableDesc - Where table descriptor is returned
540 *
541 * RETURN: Status and table index/descriptor.
542 *
543 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
544 *
545 ******************************************************************************/
546
547ACPI_STATUS
548AcpiTbGetNextTableDescriptor (
549 UINT32 *TableIndex,
550 ACPI_TABLE_DESC **TableDesc)
551{
552 ACPI_STATUS Status;
553 UINT32 i;
554
555
556 /* Ensure that there is room for the table in the Root Table List */
557
558 if (AcpiGbl_RootTableList.CurrentTableCount >=
559 AcpiGbl_RootTableList.MaxTableCount)
560 {
561 Status = AcpiTbResizeRootTableList();
562 if (ACPI_FAILURE (Status))
563 {
564 return (Status);
565 }
566 }
567
568 i = AcpiGbl_RootTableList.CurrentTableCount;
569 AcpiGbl_RootTableList.CurrentTableCount++;
570
571 if (TableIndex)
572 {
573 *TableIndex = i;
574 }
575 if (TableDesc)
576 {
577 *TableDesc = &AcpiGbl_RootTableList.Tables[i];
578 }
579
580 return (AE_OK);
581}
582
583
584/*******************************************************************************
585 *
586 * FUNCTION: AcpiTbTerminate
587 *
588 * PARAMETERS: None
589 *
590 * RETURN: None
591 *
592 * DESCRIPTION: Delete all internal ACPI tables
593 *
594 ******************************************************************************/
595
596void
597AcpiTbTerminate (
598 void)
599{
600 UINT32 i;
601
602
603 ACPI_FUNCTION_TRACE (TbTerminate);
604
605
606 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
607
608 /* Delete the individual tables */
609
610 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
611 {
612 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
613 }
614
615 /*
616 * Delete the root table array if allocated locally. Array cannot be
617 * mapped, so we don't need to check for that flag.
618 */
619 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
620 {
621 ACPI_FREE (AcpiGbl_RootTableList.Tables);
622 }
623
624 AcpiGbl_RootTableList.Tables = NULL;
625 AcpiGbl_RootTableList.Flags = 0;
626 AcpiGbl_RootTableList.CurrentTableCount = 0;
627
628 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
629
630 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
631 return_VOID;
632}
633
634
635/*******************************************************************************
636 *
637 * FUNCTION: AcpiTbDeleteNamespaceByOwner
638 *
639 * PARAMETERS: TableIndex - Table index
640 *
641 * RETURN: Status
642 *
643 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
644 *
645 ******************************************************************************/
646
647ACPI_STATUS
648AcpiTbDeleteNamespaceByOwner (
649 UINT32 TableIndex)
650{
651 ACPI_OWNER_ID OwnerId;
652 ACPI_STATUS Status;
653
654
655 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
656
657
658 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
659 if (ACPI_FAILURE (Status))
660 {
661 return_ACPI_STATUS (Status);
662 }
663
664 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
665 {
666 /* The table index does not exist */
667
668 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
669 return_ACPI_STATUS (AE_NOT_EXIST);
670 }
671
672 /* Get the owner ID for this table, used to delete namespace nodes */
673
674 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
675 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
676
677 /*
678 * Need to acquire the namespace writer lock to prevent interference
679 * with any concurrent namespace walks. The interpreter must be
680 * released during the deletion since the acquisition of the deletion
681 * lock may block, and also since the execution of a namespace walk
682 * must be allowed to use the interpreter.
683 */
684 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
685 if (ACPI_FAILURE (Status))
686 {
687 return_ACPI_STATUS (Status);
688 }
689 AcpiNsDeleteNamespaceByOwner (OwnerId);
690 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
691 return_ACPI_STATUS (Status);
692}
693
694
695/*******************************************************************************
696 *
697 * FUNCTION: AcpiTbAllocateOwnerId
698 *
699 * PARAMETERS: TableIndex - Table index
700 *
701 * RETURN: Status
702 *
703 * DESCRIPTION: Allocates OwnerId in TableDesc
704 *
705 ******************************************************************************/
706
707ACPI_STATUS
708AcpiTbAllocateOwnerId (
709 UINT32 TableIndex)
710{
711 ACPI_STATUS Status = AE_BAD_PARAMETER;
712
713
714 ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
715
716
717 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
718 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
719 {
720 Status = AcpiUtAllocateOwnerId (
721 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
722 }
723
724 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
725 return_ACPI_STATUS (Status);
726}
727
728
729/*******************************************************************************
730 *
731 * FUNCTION: AcpiTbReleaseOwnerId
732 *
733 * PARAMETERS: TableIndex - Table index
734 *
735 * RETURN: Status
736 *
737 * DESCRIPTION: Releases OwnerId in TableDesc
738 *
739 ******************************************************************************/
740
741ACPI_STATUS
742AcpiTbReleaseOwnerId (
743 UINT32 TableIndex)
744{
745 ACPI_STATUS Status = AE_BAD_PARAMETER;
746
747
748 ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
749
750
751 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
752 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
753 {
754 AcpiUtReleaseOwnerId (
755 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
756 Status = AE_OK;
757 }
758
759 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
760 return_ACPI_STATUS (Status);
761}
762
763
764/*******************************************************************************
765 *
766 * FUNCTION: AcpiTbGetOwnerId
767 *
768 * PARAMETERS: TableIndex - Table index
769 * OwnerId - Where the table OwnerId is returned
770 *
771 * RETURN: Status
772 *
773 * DESCRIPTION: returns OwnerId for the ACPI table
774 *
775 ******************************************************************************/
776
777ACPI_STATUS
778AcpiTbGetOwnerId (
779 UINT32 TableIndex,
780 ACPI_OWNER_ID *OwnerId)
781{
782 ACPI_STATUS Status = AE_BAD_PARAMETER;
783
784
785 ACPI_FUNCTION_TRACE (TbGetOwnerId);
786
787
788 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
789 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
790 {
791 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
792 Status = AE_OK;
793 }
794
795 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
796 return_ACPI_STATUS (Status);
797}
798
799
800/*******************************************************************************
801 *
802 * FUNCTION: AcpiTbIsTableLoaded
803 *
804 * PARAMETERS: TableIndex - Index into the root table
805 *
806 * RETURN: Table Loaded Flag
807 *
808 ******************************************************************************/
809
810BOOLEAN
811AcpiTbIsTableLoaded (
812 UINT32 TableIndex)
813{
814 BOOLEAN IsLoaded = FALSE;
815
816
817 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
818 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
819 {
820 IsLoaded = (BOOLEAN)
821 (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
822 ACPI_TABLE_IS_LOADED);
823 }
824
825 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
826 return (IsLoaded);
827}
828
829
830/*******************************************************************************
831 *
832 * FUNCTION: AcpiTbSetTableLoadedFlag
833 *
834 * PARAMETERS: TableIndex - Table index
835 * IsLoaded - TRUE if table is loaded, FALSE otherwise
836 *
837 * RETURN: None
838 *
839 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
840 *
841 ******************************************************************************/
842
843void
844AcpiTbSetTableLoadedFlag (
845 UINT32 TableIndex,
846 BOOLEAN IsLoaded)
847{
848
849 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
850 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
851 {
852 if (IsLoaded)
853 {
854 AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
855 ACPI_TABLE_IS_LOADED;
856 }
857 else
858 {
859 AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
860 ~ACPI_TABLE_IS_LOADED;
861 }
862 }
863
864 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
865}
866
867
868/*******************************************************************************
869 *
870 * FUNCTION: AcpiTbLoadTable
871 *
872 * PARAMETERS: TableIndex - Table index
873 * ParentNode - Where table index is returned
874 *
875 * RETURN: Status
876 *
877 * DESCRIPTION: Load an ACPI table
878 *
879 ******************************************************************************/
880
881ACPI_STATUS
882AcpiTbLoadTable (
883 UINT32 TableIndex,
884 ACPI_NAMESPACE_NODE *ParentNode)
885{
886 ACPI_TABLE_HEADER *Table;
887 ACPI_STATUS Status;
888 ACPI_OWNER_ID OwnerId;
889
890
891 ACPI_FUNCTION_TRACE (TbLoadTable);
892
893
894 /*
895 * Note: Now table is "INSTALLED", it must be validated before
896 * using.
897 */
898 Status = AcpiGetTableByIndex (TableIndex, &Table);
899 if (ACPI_FAILURE (Status))
900 {
901 return_ACPI_STATUS (Status);
902 }
903
904 Status = AcpiNsLoadTable (TableIndex, ParentNode);
905
906 /* Execute any module-level code that was found in the table */
907
908 if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
909 {
910 AcpiNsExecModuleCodeList ();
911 }
912
913 /*
914 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
915 * responsible for discovering any new wake GPEs by running _PRW methods
916 * that may have been loaded by this table.
917 */
918 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
919 if (ACPI_SUCCESS (Status))
920 {
921 AcpiEvUpdateGpes (OwnerId);
922 }
923
924 /* Invoke table handler if present */
925
926 if (AcpiGbl_TableHandler)
927 {
928 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
929 AcpiGbl_TableHandlerContext);
930 }
931
932 return_ACPI_STATUS (Status);
933}
934
935
936/*******************************************************************************
937 *
938 * FUNCTION: AcpiTbInstallAndLoadTable
939 *
940 * PARAMETERS: Table - Pointer to the table
941 * Address - Physical address of the table
942 * Flags - Allocation flags of the table
943 * TableIndex - Where table index is returned
944 *
945 * RETURN: Status
946 *
947 * DESCRIPTION: Install and load an ACPI table
948 *
949 ******************************************************************************/
950
951ACPI_STATUS
952AcpiTbInstallAndLoadTable (
953 ACPI_TABLE_HEADER *Table,
954 ACPI_PHYSICAL_ADDRESS Address,
955 UINT8 Flags,
956 BOOLEAN Override,
957 UINT32 *TableIndex)
958{
959 ACPI_STATUS Status;
960 UINT32 i;
961 ACPI_OWNER_ID OwnerId;
962
963
964 ACPI_FUNCTION_TRACE (AcpiLoadTable);
965
966
967 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
968
969 /* Install the table and load it into the namespace */
970
971 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
972 Override, &i);
973 if (ACPI_FAILURE (Status))
974 {
975 goto UnlockAndExit;
976 }
977
978 /*
979 * Note: Now table is "INSTALLED", it must be validated before
980 * using.
981 */
982 Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
983 if (ACPI_FAILURE (Status))
984 {
985 goto UnlockAndExit;
986 }
987
988 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
989 Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
990
991 /* Execute any module-level code that was found in the table */
992
993 if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
994 {
995 AcpiNsExecModuleCodeList ();
996 }
997
998 /*
999 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1000 * responsible for discovering any new wake GPEs by running _PRW methods
1001 * that may have been loaded by this table.
1002 */
1003 Status = AcpiTbGetOwnerId (i, &OwnerId);
1004 if (ACPI_SUCCESS (Status))
1005 {
1006 AcpiEvUpdateGpes (OwnerId);
1007 }
1008
1009 /* Invoke table handler if present */
1010
1011 if (AcpiGbl_TableHandler)
1012 {
1013 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
1014 AcpiGbl_TableHandlerContext);
1015 }
1016 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1017
1018UnlockAndExit:
1019 *TableIndex = i;
1020 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1021 return_ACPI_STATUS (Status);
1022}
1023