[ACPICA] Update to version 20180531. CORE-15222
[reactos.git] / drivers / bus / acpi / acpica / tables / tbdata.c
1 /******************************************************************************
2 *
3 * Module Name: tbdata - Table manager data structure functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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 /* Local prototypes */
54
55 static ACPI_STATUS
56 AcpiTbCheckDuplication (
57 ACPI_TABLE_DESC *TableDesc,
58 UINT32 *TableIndex);
59
60 static BOOLEAN
61 AcpiTbCompareTables (
62 ACPI_TABLE_DESC *TableDesc,
63 UINT32 TableIndex);
64
65
66 /*******************************************************************************
67 *
68 * FUNCTION: AcpiTbCompareTables
69 *
70 * PARAMETERS: TableDesc - Table 1 descriptor to be compared
71 * TableIndex - Index of table 2 to be compared
72 *
73 * RETURN: TRUE if both tables are identical.
74 *
75 * DESCRIPTION: This function compares a table with another table that has
76 * already been installed in the root table list.
77 *
78 ******************************************************************************/
79
80 static BOOLEAN
81 AcpiTbCompareTables (
82 ACPI_TABLE_DESC *TableDesc,
83 UINT32 TableIndex)
84 {
85 ACPI_STATUS Status = AE_OK;
86 BOOLEAN IsIdentical;
87 ACPI_TABLE_HEADER *Table;
88 UINT32 TableLength;
89 UINT8 TableFlags;
90
91
92 Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
93 &Table, &TableLength, &TableFlags);
94 if (ACPI_FAILURE (Status))
95 {
96 return (FALSE);
97 }
98
99 /*
100 * Check for a table match on the entire table length,
101 * not just the header.
102 */
103 IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
104 memcmp (TableDesc->Pointer, Table, TableLength)) ?
105 FALSE : TRUE);
106
107 /* Release the acquired table */
108
109 AcpiTbReleaseTable (Table, TableLength, TableFlags);
110 return (IsIdentical);
111 }
112
113
114 /*******************************************************************************
115 *
116 * FUNCTION: AcpiTbInitTableDescriptor
117 *
118 * PARAMETERS: TableDesc - Table descriptor
119 * Address - Physical address of the table
120 * Flags - Allocation flags of the table
121 * Table - Pointer to the table
122 *
123 * RETURN: None
124 *
125 * DESCRIPTION: Initialize a new table descriptor
126 *
127 ******************************************************************************/
128
129 void
130 AcpiTbInitTableDescriptor (
131 ACPI_TABLE_DESC *TableDesc,
132 ACPI_PHYSICAL_ADDRESS Address,
133 UINT8 Flags,
134 ACPI_TABLE_HEADER *Table)
135 {
136
137 /*
138 * Initialize the table descriptor. Set the pointer to NULL, since the
139 * table is not fully mapped at this time.
140 */
141 memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
142 TableDesc->Address = Address;
143 TableDesc->Length = Table->Length;
144 TableDesc->Flags = Flags;
145 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
146 }
147
148
149 /*******************************************************************************
150 *
151 * FUNCTION: AcpiTbAcquireTable
152 *
153 * PARAMETERS: TableDesc - Table descriptor
154 * TablePtr - Where table is returned
155 * TableLength - Where table length is returned
156 * TableFlags - Where table allocation flags are returned
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
161 * maintained in the AcpiGbl_RootTableList.
162 *
163 ******************************************************************************/
164
165 ACPI_STATUS
166 AcpiTbAcquireTable (
167 ACPI_TABLE_DESC *TableDesc,
168 ACPI_TABLE_HEADER **TablePtr,
169 UINT32 *TableLength,
170 UINT8 *TableFlags)
171 {
172 ACPI_TABLE_HEADER *Table = NULL;
173
174
175 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
176 {
177 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
178
179 Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
180 break;
181
182 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
183 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
184
185 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
186 ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
187 break;
188
189 default:
190
191 break;
192 }
193
194 /* Table is not valid yet */
195
196 if (!Table)
197 {
198 return (AE_NO_MEMORY);
199 }
200
201 /* Fill the return values */
202
203 *TablePtr = Table;
204 *TableLength = TableDesc->Length;
205 *TableFlags = TableDesc->Flags;
206 return (AE_OK);
207 }
208
209
210 /*******************************************************************************
211 *
212 * FUNCTION: AcpiTbReleaseTable
213 *
214 * PARAMETERS: Table - Pointer for the table
215 * TableLength - Length for the table
216 * TableFlags - Allocation flags for the table
217 *
218 * RETURN: None
219 *
220 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
221 *
222 ******************************************************************************/
223
224 void
225 AcpiTbReleaseTable (
226 ACPI_TABLE_HEADER *Table,
227 UINT32 TableLength,
228 UINT8 TableFlags)
229 {
230
231 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
232 {
233 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
234
235 AcpiOsUnmapMemory (Table, TableLength);
236 break;
237
238 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
239 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
240 default:
241
242 break;
243 }
244 }
245
246
247 /*******************************************************************************
248 *
249 * FUNCTION: AcpiTbAcquireTempTable
250 *
251 * PARAMETERS: TableDesc - Table descriptor to be acquired
252 * Address - Address of the table
253 * Flags - Allocation flags of the table
254 *
255 * RETURN: Status
256 *
257 * DESCRIPTION: This function validates the table header to obtain the length
258 * of a table and fills the table descriptor to make its state as
259 * "INSTALLED". Such a table descriptor is only used for verified
260 * installation.
261 *
262 ******************************************************************************/
263
264 ACPI_STATUS
265 AcpiTbAcquireTempTable (
266 ACPI_TABLE_DESC *TableDesc,
267 ACPI_PHYSICAL_ADDRESS Address,
268 UINT8 Flags)
269 {
270 ACPI_TABLE_HEADER *TableHeader;
271
272
273 switch (Flags & ACPI_TABLE_ORIGIN_MASK)
274 {
275 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
276
277 /* Get the length of the full table from the header */
278
279 TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
280 if (!TableHeader)
281 {
282 return (AE_NO_MEMORY);
283 }
284
285 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
286 AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
287 return (AE_OK);
288
289 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
290 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
291
292 TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
293 ACPI_PHYSADDR_TO_PTR (Address));
294 if (!TableHeader)
295 {
296 return (AE_NO_MEMORY);
297 }
298
299 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
300 return (AE_OK);
301
302 default:
303
304 break;
305 }
306
307 /* Table is not valid yet */
308
309 return (AE_NO_MEMORY);
310 }
311
312
313 /*******************************************************************************
314 *
315 * FUNCTION: AcpiTbReleaseTempTable
316 *
317 * PARAMETERS: TableDesc - Table descriptor to be released
318 *
319 * RETURN: Status
320 *
321 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
322 *
323 *****************************************************************************/
324
325 void
326 AcpiTbReleaseTempTable (
327 ACPI_TABLE_DESC *TableDesc)
328 {
329
330 /*
331 * Note that the .Address is maintained by the callers of
332 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
333 * where .Address will be freed.
334 */
335 AcpiTbInvalidateTable (TableDesc);
336 }
337
338
339 /******************************************************************************
340 *
341 * FUNCTION: AcpiTbValidateTable
342 *
343 * PARAMETERS: TableDesc - Table descriptor
344 *
345 * RETURN: Status
346 *
347 * DESCRIPTION: This function is called to validate the table, the returned
348 * table descriptor is in "VALIDATED" state.
349 *
350 *****************************************************************************/
351
352 ACPI_STATUS
353 AcpiTbValidateTable (
354 ACPI_TABLE_DESC *TableDesc)
355 {
356 ACPI_STATUS Status = AE_OK;
357
358
359 ACPI_FUNCTION_TRACE (TbValidateTable);
360
361
362 /* Validate the table if necessary */
363
364 if (!TableDesc->Pointer)
365 {
366 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
367 &TableDesc->Length, &TableDesc->Flags);
368 if (!TableDesc->Pointer)
369 {
370 Status = AE_NO_MEMORY;
371 }
372 }
373
374 return_ACPI_STATUS (Status);
375 }
376
377
378 /*******************************************************************************
379 *
380 * FUNCTION: AcpiTbInvalidateTable
381 *
382 * PARAMETERS: TableDesc - Table descriptor
383 *
384 * RETURN: None
385 *
386 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
387 * AcpiTbValidateTable().
388 *
389 ******************************************************************************/
390
391 void
392 AcpiTbInvalidateTable (
393 ACPI_TABLE_DESC *TableDesc)
394 {
395
396 ACPI_FUNCTION_TRACE (TbInvalidateTable);
397
398
399 /* Table must be validated */
400
401 if (!TableDesc->Pointer)
402 {
403 return_VOID;
404 }
405
406 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
407 TableDesc->Flags);
408 TableDesc->Pointer = NULL;
409
410 return_VOID;
411 }
412
413
414 /******************************************************************************
415 *
416 * FUNCTION: AcpiTbValidateTempTable
417 *
418 * PARAMETERS: TableDesc - Table descriptor
419 *
420 * RETURN: Status
421 *
422 * DESCRIPTION: This function is called to validate the table, the returned
423 * table descriptor is in "VALIDATED" state.
424 *
425 *****************************************************************************/
426
427 ACPI_STATUS
428 AcpiTbValidateTempTable (
429 ACPI_TABLE_DESC *TableDesc)
430 {
431
432 if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
433 {
434 /*
435 * Only validates the header of the table.
436 * Note that Length contains the size of the mapping after invoking
437 * this work around, this value is required by
438 * AcpiTbReleaseTempTable().
439 * We can do this because in AcpiInitTableDescriptor(), the Length
440 * field of the installed descriptor is filled with the actual
441 * table length obtaining from the table header.
442 */
443 TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
444 }
445
446 return (AcpiTbValidateTable (TableDesc));
447 }
448
449
450 /*******************************************************************************
451 *
452 * FUNCTION: AcpiTbCheckDuplication
453 *
454 * PARAMETERS: TableDesc - Table descriptor
455 * TableIndex - Where the table index is returned
456 *
457 * RETURN: Status
458 *
459 * DESCRIPTION: Avoid installing duplicated tables. However table override and
460 * user aided dynamic table load is allowed, thus comparing the
461 * address of the table is not sufficient, and checking the entire
462 * table content is required.
463 *
464 ******************************************************************************/
465
466 static ACPI_STATUS
467 AcpiTbCheckDuplication (
468 ACPI_TABLE_DESC *TableDesc,
469 UINT32 *TableIndex)
470 {
471 UINT32 i;
472
473
474 ACPI_FUNCTION_TRACE (TbCheckDuplication);
475
476
477 /* Check if table is already registered */
478
479 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
480 {
481 /* Do not compare with unverified tables */
482
483 if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED))
484 {
485 continue;
486 }
487
488 /*
489 * Check for a table match on the entire table length,
490 * not just the header.
491 */
492 if (!AcpiTbCompareTables (TableDesc, i))
493 {
494 continue;
495 }
496
497 /*
498 * Note: the current mechanism does not unregister a table if it is
499 * dynamically unloaded. The related namespace entries are deleted,
500 * but the table remains in the root table list.
501 *
502 * The assumption here is that the number of different tables that
503 * will be loaded is actually small, and there is minimal overhead
504 * in just keeping the table in case it is needed again.
505 *
506 * If this assumption changes in the future (perhaps on large
507 * machines with many table load/unload operations), tables will
508 * need to be unregistered when they are unloaded, and slots in the
509 * root table list should be reused when empty.
510 */
511 if (AcpiGbl_RootTableList.Tables[i].Flags &
512 ACPI_TABLE_IS_LOADED)
513 {
514 /* Table is still loaded, this is an error */
515
516 return_ACPI_STATUS (AE_ALREADY_EXISTS);
517 }
518 else
519 {
520 *TableIndex = i;
521 return_ACPI_STATUS (AE_CTRL_TERMINATE);
522 }
523 }
524
525 /* Indicate no duplication to the caller */
526
527 return_ACPI_STATUS (AE_OK);
528 }
529
530
531 /******************************************************************************
532 *
533 * FUNCTION: AcpiTbVerifyTempTable
534 *
535 * PARAMETERS: TableDesc - Table descriptor
536 * Signature - Table signature to verify
537 * TableIndex - Where the table index is returned
538 *
539 * RETURN: Status
540 *
541 * DESCRIPTION: This function is called to validate and verify the table, the
542 * returned table descriptor is in "VALIDATED" state.
543 * Note that 'TableIndex' is required to be set to !NULL to
544 * enable duplication check.
545 *
546 *****************************************************************************/
547
548 ACPI_STATUS
549 AcpiTbVerifyTempTable (
550 ACPI_TABLE_DESC *TableDesc,
551 char *Signature,
552 UINT32 *TableIndex)
553 {
554 ACPI_STATUS Status = AE_OK;
555
556
557 ACPI_FUNCTION_TRACE (TbVerifyTempTable);
558
559
560 /* Validate the table */
561
562 Status = AcpiTbValidateTempTable (TableDesc);
563 if (ACPI_FAILURE (Status))
564 {
565 return_ACPI_STATUS (AE_NO_MEMORY);
566 }
567
568 /* If a particular signature is expected (DSDT/FACS), it must match */
569
570 if (Signature &&
571 !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
572 {
573 ACPI_BIOS_ERROR ((AE_INFO,
574 "Invalid signature 0x%X for ACPI table, expected [%s]",
575 TableDesc->Signature.Integer, Signature));
576 Status = AE_BAD_SIGNATURE;
577 goto InvalidateAndExit;
578 }
579
580 if (AcpiGbl_EnableTableValidation)
581 {
582 /* Verify the checksum */
583
584 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
585 if (ACPI_FAILURE (Status))
586 {
587 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
588 "%4.4s 0x%8.8X%8.8X"
589 " Attempted table install failed",
590 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
591 TableDesc->Signature.Ascii : "????",
592 ACPI_FORMAT_UINT64 (TableDesc->Address)));
593
594 goto InvalidateAndExit;
595 }
596
597 /* Avoid duplications */
598
599 if (TableIndex)
600 {
601 Status = AcpiTbCheckDuplication (TableDesc, TableIndex);
602 if (ACPI_FAILURE (Status))
603 {
604 if (Status != AE_CTRL_TERMINATE)
605 {
606 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
607 "%4.4s 0x%8.8X%8.8X"
608 " Table is duplicated",
609 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
610 TableDesc->Signature.Ascii : "????",
611 ACPI_FORMAT_UINT64 (TableDesc->Address)));
612 }
613
614 goto InvalidateAndExit;
615 }
616 }
617
618 TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED;
619 }
620
621 return_ACPI_STATUS (Status);
622
623 InvalidateAndExit:
624 AcpiTbInvalidateTable (TableDesc);
625 return_ACPI_STATUS (Status);
626 }
627
628
629 /*******************************************************************************
630 *
631 * FUNCTION: AcpiTbResizeRootTableList
632 *
633 * PARAMETERS: None
634 *
635 * RETURN: Status
636 *
637 * DESCRIPTION: Expand the size of global table array
638 *
639 ******************************************************************************/
640
641 ACPI_STATUS
642 AcpiTbResizeRootTableList (
643 void)
644 {
645 ACPI_TABLE_DESC *Tables;
646 UINT32 TableCount;
647 UINT32 CurrentTableCount, MaxTableCount;
648 UINT32 i;
649
650
651 ACPI_FUNCTION_TRACE (TbResizeRootTableList);
652
653
654 /* AllowResize flag is a parameter to AcpiInitializeTables */
655
656 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
657 {
658 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
659 return_ACPI_STATUS (AE_SUPPORT);
660 }
661
662 /* Increase the Table Array size */
663
664 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
665 {
666 TableCount = AcpiGbl_RootTableList.MaxTableCount;
667 }
668 else
669 {
670 TableCount = AcpiGbl_RootTableList.CurrentTableCount;
671 }
672
673 MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
674 Tables = ACPI_ALLOCATE_ZEROED (
675 ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC));
676 if (!Tables)
677 {
678 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
679 return_ACPI_STATUS (AE_NO_MEMORY);
680 }
681
682 /* Copy and free the previous table array */
683
684 CurrentTableCount = 0;
685 if (AcpiGbl_RootTableList.Tables)
686 {
687 for (i = 0; i < TableCount; i++)
688 {
689 if (AcpiGbl_RootTableList.Tables[i].Address)
690 {
691 memcpy (Tables + CurrentTableCount,
692 AcpiGbl_RootTableList.Tables + i,
693 sizeof (ACPI_TABLE_DESC));
694 CurrentTableCount++;
695 }
696 }
697
698 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
699 {
700 ACPI_FREE (AcpiGbl_RootTableList.Tables);
701 }
702 }
703
704 AcpiGbl_RootTableList.Tables = Tables;
705 AcpiGbl_RootTableList.MaxTableCount = MaxTableCount;
706 AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount;
707 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
708
709 return_ACPI_STATUS (AE_OK);
710 }
711
712
713 /*******************************************************************************
714 *
715 * FUNCTION: AcpiTbGetNextTableDescriptor
716 *
717 * PARAMETERS: TableIndex - Where table index is returned
718 * TableDesc - Where table descriptor is returned
719 *
720 * RETURN: Status and table index/descriptor.
721 *
722 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
723 *
724 ******************************************************************************/
725
726 ACPI_STATUS
727 AcpiTbGetNextTableDescriptor (
728 UINT32 *TableIndex,
729 ACPI_TABLE_DESC **TableDesc)
730 {
731 ACPI_STATUS Status;
732 UINT32 i;
733
734
735 /* Ensure that there is room for the table in the Root Table List */
736
737 if (AcpiGbl_RootTableList.CurrentTableCount >=
738 AcpiGbl_RootTableList.MaxTableCount)
739 {
740 Status = AcpiTbResizeRootTableList();
741 if (ACPI_FAILURE (Status))
742 {
743 return (Status);
744 }
745 }
746
747 i = AcpiGbl_RootTableList.CurrentTableCount;
748 AcpiGbl_RootTableList.CurrentTableCount++;
749
750 if (TableIndex)
751 {
752 *TableIndex = i;
753 }
754 if (TableDesc)
755 {
756 *TableDesc = &AcpiGbl_RootTableList.Tables[i];
757 }
758
759 return (AE_OK);
760 }
761
762
763 /*******************************************************************************
764 *
765 * FUNCTION: AcpiTbTerminate
766 *
767 * PARAMETERS: None
768 *
769 * RETURN: None
770 *
771 * DESCRIPTION: Delete all internal ACPI tables
772 *
773 ******************************************************************************/
774
775 void
776 AcpiTbTerminate (
777 void)
778 {
779 UINT32 i;
780
781
782 ACPI_FUNCTION_TRACE (TbTerminate);
783
784
785 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
786
787 /* Delete the individual tables */
788
789 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
790 {
791 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
792 }
793
794 /*
795 * Delete the root table array if allocated locally. Array cannot be
796 * mapped, so we don't need to check for that flag.
797 */
798 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
799 {
800 ACPI_FREE (AcpiGbl_RootTableList.Tables);
801 }
802
803 AcpiGbl_RootTableList.Tables = NULL;
804 AcpiGbl_RootTableList.Flags = 0;
805 AcpiGbl_RootTableList.CurrentTableCount = 0;
806
807 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
808
809 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
810 return_VOID;
811 }
812
813
814 /*******************************************************************************
815 *
816 * FUNCTION: AcpiTbDeleteNamespaceByOwner
817 *
818 * PARAMETERS: TableIndex - Table index
819 *
820 * RETURN: Status
821 *
822 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
823 *
824 ******************************************************************************/
825
826 ACPI_STATUS
827 AcpiTbDeleteNamespaceByOwner (
828 UINT32 TableIndex)
829 {
830 ACPI_OWNER_ID OwnerId;
831 ACPI_STATUS Status;
832
833
834 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
835
836
837 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
838 if (ACPI_FAILURE (Status))
839 {
840 return_ACPI_STATUS (Status);
841 }
842
843 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
844 {
845 /* The table index does not exist */
846
847 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
848 return_ACPI_STATUS (AE_NOT_EXIST);
849 }
850
851 /* Get the owner ID for this table, used to delete namespace nodes */
852
853 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
854 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
855
856 /*
857 * Need to acquire the namespace writer lock to prevent interference
858 * with any concurrent namespace walks. The interpreter must be
859 * released during the deletion since the acquisition of the deletion
860 * lock may block, and also since the execution of a namespace walk
861 * must be allowed to use the interpreter.
862 */
863 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
864 if (ACPI_FAILURE (Status))
865 {
866 return_ACPI_STATUS (Status);
867 }
868 AcpiNsDeleteNamespaceByOwner (OwnerId);
869 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
870 return_ACPI_STATUS (Status);
871 }
872
873
874 /*******************************************************************************
875 *
876 * FUNCTION: AcpiTbAllocateOwnerId
877 *
878 * PARAMETERS: TableIndex - Table index
879 *
880 * RETURN: Status
881 *
882 * DESCRIPTION: Allocates OwnerId in TableDesc
883 *
884 ******************************************************************************/
885
886 ACPI_STATUS
887 AcpiTbAllocateOwnerId (
888 UINT32 TableIndex)
889 {
890 ACPI_STATUS Status = AE_BAD_PARAMETER;
891
892
893 ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
894
895
896 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
897 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
898 {
899 Status = AcpiUtAllocateOwnerId (
900 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
901 }
902
903 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
904 return_ACPI_STATUS (Status);
905 }
906
907
908 /*******************************************************************************
909 *
910 * FUNCTION: AcpiTbReleaseOwnerId
911 *
912 * PARAMETERS: TableIndex - Table index
913 *
914 * RETURN: Status
915 *
916 * DESCRIPTION: Releases OwnerId in TableDesc
917 *
918 ******************************************************************************/
919
920 ACPI_STATUS
921 AcpiTbReleaseOwnerId (
922 UINT32 TableIndex)
923 {
924 ACPI_STATUS Status = AE_BAD_PARAMETER;
925
926
927 ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
928
929
930 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
931 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
932 {
933 AcpiUtReleaseOwnerId (
934 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
935 Status = AE_OK;
936 }
937
938 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
939 return_ACPI_STATUS (Status);
940 }
941
942
943 /*******************************************************************************
944 *
945 * FUNCTION: AcpiTbGetOwnerId
946 *
947 * PARAMETERS: TableIndex - Table index
948 * OwnerId - Where the table OwnerId is returned
949 *
950 * RETURN: Status
951 *
952 * DESCRIPTION: returns OwnerId for the ACPI table
953 *
954 ******************************************************************************/
955
956 ACPI_STATUS
957 AcpiTbGetOwnerId (
958 UINT32 TableIndex,
959 ACPI_OWNER_ID *OwnerId)
960 {
961 ACPI_STATUS Status = AE_BAD_PARAMETER;
962
963
964 ACPI_FUNCTION_TRACE (TbGetOwnerId);
965
966
967 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
968 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
969 {
970 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
971 Status = AE_OK;
972 }
973
974 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
975 return_ACPI_STATUS (Status);
976 }
977
978
979 /*******************************************************************************
980 *
981 * FUNCTION: AcpiTbIsTableLoaded
982 *
983 * PARAMETERS: TableIndex - Index into the root table
984 *
985 * RETURN: Table Loaded Flag
986 *
987 ******************************************************************************/
988
989 BOOLEAN
990 AcpiTbIsTableLoaded (
991 UINT32 TableIndex)
992 {
993 BOOLEAN IsLoaded = FALSE;
994
995
996 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
997 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
998 {
999 IsLoaded = (BOOLEAN)
1000 (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
1001 ACPI_TABLE_IS_LOADED);
1002 }
1003
1004 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1005 return (IsLoaded);
1006 }
1007
1008
1009 /*******************************************************************************
1010 *
1011 * FUNCTION: AcpiTbSetTableLoadedFlag
1012 *
1013 * PARAMETERS: TableIndex - Table index
1014 * IsLoaded - TRUE if table is loaded, FALSE otherwise
1015 *
1016 * RETURN: None
1017 *
1018 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1019 *
1020 ******************************************************************************/
1021
1022 void
1023 AcpiTbSetTableLoadedFlag (
1024 UINT32 TableIndex,
1025 BOOLEAN IsLoaded)
1026 {
1027
1028 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1029 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1030 {
1031 if (IsLoaded)
1032 {
1033 AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
1034 ACPI_TABLE_IS_LOADED;
1035 }
1036 else
1037 {
1038 AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
1039 ~ACPI_TABLE_IS_LOADED;
1040 }
1041 }
1042
1043 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1044 }
1045
1046
1047 /*******************************************************************************
1048 *
1049 * FUNCTION: AcpiTbLoadTable
1050 *
1051 * PARAMETERS: TableIndex - Table index
1052 * ParentNode - Where table index is returned
1053 *
1054 * RETURN: Status
1055 *
1056 * DESCRIPTION: Load an ACPI table
1057 *
1058 ******************************************************************************/
1059
1060 ACPI_STATUS
1061 AcpiTbLoadTable (
1062 UINT32 TableIndex,
1063 ACPI_NAMESPACE_NODE *ParentNode)
1064 {
1065 ACPI_TABLE_HEADER *Table;
1066 ACPI_STATUS Status;
1067 ACPI_OWNER_ID OwnerId;
1068
1069
1070 ACPI_FUNCTION_TRACE (TbLoadTable);
1071
1072
1073 /*
1074 * Note: Now table is "INSTALLED", it must be validated before
1075 * using.
1076 */
1077 Status = AcpiGetTableByIndex (TableIndex, &Table);
1078 if (ACPI_FAILURE (Status))
1079 {
1080 return_ACPI_STATUS (Status);
1081 }
1082
1083 Status = AcpiNsLoadTable (TableIndex, ParentNode);
1084
1085 /*
1086 * This case handles the legacy option that groups all module-level
1087 * code blocks together and defers execution until all of the tables
1088 * are loaded. Execute all of these blocks at this time.
1089 * Execute any module-level code that was detected during the table
1090 * load phase.
1091 *
1092 * Note: this option is deprecated and will be eliminated in the
1093 * future. Use of this option can cause problems with AML code that
1094 * depends upon in-order immediate execution of module-level code.
1095 */
1096 AcpiNsExecModuleCodeList ();
1097
1098 /*
1099 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1100 * responsible for discovering any new wake GPEs by running _PRW methods
1101 * that may have been loaded by this table.
1102 */
1103 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
1104 if (ACPI_SUCCESS (Status))
1105 {
1106 AcpiEvUpdateGpes (OwnerId);
1107 }
1108
1109 /* Invoke table handler */
1110
1111 AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table);
1112 return_ACPI_STATUS (Status);
1113 }
1114
1115
1116 /*******************************************************************************
1117 *
1118 * FUNCTION: AcpiTbInstallAndLoadTable
1119 *
1120 * PARAMETERS: Address - Physical address of the table
1121 * Flags - Allocation flags of the table
1122 * Override - Whether override should be performed
1123 * TableIndex - Where table index is returned
1124 *
1125 * RETURN: Status
1126 *
1127 * DESCRIPTION: Install and load an ACPI table
1128 *
1129 ******************************************************************************/
1130
1131 ACPI_STATUS
1132 AcpiTbInstallAndLoadTable (
1133 ACPI_PHYSICAL_ADDRESS Address,
1134 UINT8 Flags,
1135 BOOLEAN Override,
1136 UINT32 *TableIndex)
1137 {
1138 ACPI_STATUS Status;
1139 UINT32 i;
1140
1141
1142 ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
1143
1144
1145 /* Install the table and load it into the namespace */
1146
1147 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
1148 Override, &i);
1149 if (ACPI_FAILURE (Status))
1150 {
1151 goto Exit;
1152 }
1153
1154 Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
1155
1156 Exit:
1157 *TableIndex = i;
1158 return_ACPI_STATUS (Status);
1159 }
1160
1161
1162 /*******************************************************************************
1163 *
1164 * FUNCTION: AcpiTbUnloadTable
1165 *
1166 * PARAMETERS: TableIndex - Table index
1167 *
1168 * RETURN: Status
1169 *
1170 * DESCRIPTION: Unload an ACPI table
1171 *
1172 ******************************************************************************/
1173
1174 ACPI_STATUS
1175 AcpiTbUnloadTable (
1176 UINT32 TableIndex)
1177 {
1178 ACPI_STATUS Status = AE_OK;
1179 ACPI_TABLE_HEADER *Table;
1180
1181
1182 ACPI_FUNCTION_TRACE (TbUnloadTable);
1183
1184
1185 /* Ensure the table is still loaded */
1186
1187 if (!AcpiTbIsTableLoaded (TableIndex))
1188 {
1189 return_ACPI_STATUS (AE_NOT_EXIST);
1190 }
1191
1192 /* Invoke table handler */
1193
1194 Status = AcpiGetTableByIndex (TableIndex, &Table);
1195 if (ACPI_SUCCESS (Status))
1196 {
1197 AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table);
1198 }
1199
1200 /* Delete the portion of the namespace owned by this table */
1201
1202 Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
1203 if (ACPI_FAILURE (Status))
1204 {
1205 return_ACPI_STATUS (Status);
1206 }
1207
1208 (void) AcpiTbReleaseOwnerId (TableIndex);
1209 AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
1210 return_ACPI_STATUS (Status);
1211 }
1212
1213
1214 /*******************************************************************************
1215 *
1216 * FUNCTION: AcpiTbNotifyTable
1217 *
1218 * PARAMETERS: Event - Table event
1219 * Table - Validated table pointer
1220 *
1221 * RETURN: None
1222 *
1223 * DESCRIPTION: Notify a table event to the users.
1224 *
1225 ******************************************************************************/
1226
1227 void
1228 AcpiTbNotifyTable (
1229 UINT32 Event,
1230 void *Table)
1231 {
1232 /* Invoke table handler if present */
1233
1234 if (AcpiGbl_TableHandler)
1235 {
1236 (void) AcpiGbl_TableHandler (Event, Table,
1237 AcpiGbl_TableHandlerContext);
1238 }
1239 }