[ACPICA]
[reactos.git] / reactos / 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 - 2017, 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
69 void
70 AcpiTbInitTableDescriptor (
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
105 ACPI_STATUS
106 AcpiTbAcquireTable (
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
164 void
165 AcpiTbReleaseTable (
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
204 ACPI_STATUS
205 AcpiTbAcquireTempTable (
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
265 void
266 AcpiTbReleaseTempTable (
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
292 ACPI_STATUS
293 AcpiTbValidateTable (
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
331 void
332 AcpiTbInvalidateTable (
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
367 ACPI_STATUS
368 AcpiTbValidateTempTable (
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
404 ACPI_STATUS
405 AcpiTbVerifyTempTable (
406 ACPI_TABLE_DESC *TableDesc,
407 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
455 InvalidateAndExit:
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
473 ACPI_STATUS
474 AcpiTbResizeRootTableList (
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
547 ACPI_STATUS
548 AcpiTbGetNextTableDescriptor (
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
596 void
597 AcpiTbTerminate (
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
647 ACPI_STATUS
648 AcpiTbDeleteNamespaceByOwner (
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
707 ACPI_STATUS
708 AcpiTbAllocateOwnerId (
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
741 ACPI_STATUS
742 AcpiTbReleaseOwnerId (
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
777 ACPI_STATUS
778 AcpiTbGetOwnerId (
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
810 BOOLEAN
811 AcpiTbIsTableLoaded (
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
843 void
844 AcpiTbSetTableLoadedFlag (
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
881 ACPI_STATUS
882 AcpiTbLoadTable (
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: Address - Physical address of the table
941 * Flags - Allocation flags of the table
942 * Override - Whether override should be performed
943 * TableIndex - Where table index is returned
944 *
945 * RETURN: Status
946 *
947 * DESCRIPTION: Install and load an ACPI table
948 *
949 ******************************************************************************/
950
951 ACPI_STATUS
952 AcpiTbInstallAndLoadTable (
953 ACPI_PHYSICAL_ADDRESS Address,
954 UINT8 Flags,
955 BOOLEAN Override,
956 UINT32 *TableIndex)
957 {
958 ACPI_STATUS Status;
959 UINT32 i;
960
961
962 ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
963
964
965 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
966
967 /* Install the table and load it into the namespace */
968
969 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
970 Override, &i);
971 if (ACPI_FAILURE (Status))
972 {
973 goto UnlockAndExit;
974 }
975
976 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
977 Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
978 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
979
980 UnlockAndExit:
981 *TableIndex = i;
982 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
983 return_ACPI_STATUS (Status);
984 }
985
986
987 /*******************************************************************************
988 *
989 * FUNCTION: AcpiTbUnloadTable
990 *
991 * PARAMETERS: TableIndex - Table index
992 *
993 * RETURN: Status
994 *
995 * DESCRIPTION: Unload an ACPI table
996 *
997 ******************************************************************************/
998
999 ACPI_STATUS
1000 AcpiTbUnloadTable (
1001 UINT32 TableIndex)
1002 {
1003 ACPI_STATUS Status = AE_OK;
1004 ACPI_TABLE_HEADER *Table;
1005
1006
1007 ACPI_FUNCTION_TRACE (TbUnloadTable);
1008
1009
1010 /* Ensure the table is still loaded */
1011
1012 if (!AcpiTbIsTableLoaded (TableIndex))
1013 {
1014 return_ACPI_STATUS (AE_NOT_EXIST);
1015 }
1016
1017 /* Invoke table handler if present */
1018
1019 if (AcpiGbl_TableHandler)
1020 {
1021 Status = AcpiGetTableByIndex (TableIndex, &Table);
1022 if (ACPI_SUCCESS (Status))
1023 {
1024 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
1025 AcpiGbl_TableHandlerContext);
1026 }
1027 }
1028
1029 /* Delete the portion of the namespace owned by this table */
1030
1031 Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
1032 if (ACPI_FAILURE (Status))
1033 {
1034 return_ACPI_STATUS (Status);
1035 }
1036
1037 (void) AcpiTbReleaseOwnerId (TableIndex);
1038 AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
1039 return_ACPI_STATUS (Status);
1040 }