Annotation of src/sys/external/bsd/acpica/dist/tables/tbdata.c, Revision 1.10
1.1 christos 1: /******************************************************************************
2: *
3: * Module Name: tbdata - Table manager data structure functions
4: *
5: *****************************************************************************/
6:
7: /*
1.10 ! christos 8: * Copyright (C) 2000 - 2018, Intel Corp.
1.1 christos 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"
1.7 christos 48: #include "acevents.h"
1.1 christos 49:
50: #define _COMPONENT ACPI_TABLES
51: ACPI_MODULE_NAME ("tbdata")
52:
1.9 christos 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:
1.1 christos 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: */
1.4 christos 141: memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
1.1 christos 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:
1.3 christos 185: Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1.5 christos 186: ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
1.1 christos 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:
1.3 christos 292: TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1.5 christos 293: ACPI_PHYSADDR_TO_PTR (Address));
1.1 christos 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,
1.5 christos 367: &TableDesc->Length, &TableDesc->Flags);
1.1 christos 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:
1.9 christos 432: if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
1.1 christos 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:
1.9 christos 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:
1.1 christos 531: /******************************************************************************
532: *
533: * FUNCTION: AcpiTbVerifyTempTable
534: *
535: * PARAMETERS: TableDesc - Table descriptor
536: * Signature - Table signature to verify
1.9 christos 537: * TableIndex - Where the table index is returned
1.1 christos 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.
1.9 christos 543: * Note that 'TableIndex' is required to be set to !NULL to
544: * enable duplication check.
1.1 christos 545: *
546: *****************************************************************************/
547:
548: ACPI_STATUS
549: AcpiTbVerifyTempTable (
550: ACPI_TABLE_DESC *TableDesc,
1.9 christos 551: const char *Signature,
552: UINT32 *TableIndex)
1.1 christos 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:
1.9 christos 580: if (AcpiGbl_EnableTableValidation)
581: {
582: /* Verify the checksum */
1.1 christos 583:
584: Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
585: if (ACPI_FAILURE (Status))
586: {
587: ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
1.3 christos 588: "%4.4s 0x%8.8X%8.8X"
1.1 christos 589: " Attempted table install failed",
1.6 christos 590: AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
1.1 christos 591: TableDesc->Signature.Ascii : "????",
1.3 christos 592: ACPI_FORMAT_UINT64 (TableDesc->Address)));
1.5 christos 593:
1.1 christos 594: goto InvalidateAndExit;
595: }
1.9 christos 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;
1.1 christos 619: }
620:
1.9 christos 621: return_ACPI_STATUS (Status);
1.1 christos 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;
1.9 christos 647: UINT32 CurrentTableCount, MaxTableCount;
648: UINT32 i;
1.1 christos 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:
1.9 christos 673: MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
1.1 christos 674: Tables = ACPI_ALLOCATE_ZEROED (
1.9 christos 675: ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC));
1.1 christos 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:
1.9 christos 684: CurrentTableCount = 0;
1.1 christos 685: if (AcpiGbl_RootTableList.Tables)
686: {
1.9 christos 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: }
1.1 christos 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;
1.9 christos 705: AcpiGbl_RootTableList.MaxTableCount = MaxTableCount;
706: AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount;
1.1 christos 707: AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
708:
709: return_ACPI_STATUS (AE_OK);
710: }
711:
712:
713: /*******************************************************************************
714: *
1.3 christos 715: * FUNCTION: AcpiTbGetNextTableDescriptor
1.1 christos 716: *
717: * PARAMETERS: TableIndex - Where table index is returned
1.3 christos 718: * TableDesc - Where table descriptor is returned
1.1 christos 719: *
1.3 christos 720: * RETURN: Status and table index/descriptor.
1.1 christos 721: *
722: * DESCRIPTION: Allocate a new ACPI table entry to the global table list
723: *
724: ******************************************************************************/
725:
726: ACPI_STATUS
1.3 christos 727: AcpiTbGetNextTableDescriptor (
728: UINT32 *TableIndex,
729: ACPI_TABLE_DESC **TableDesc)
1.1 christos 730: {
731: ACPI_STATUS Status;
1.3 christos 732: UINT32 i;
1.1 christos 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:
1.3 christos 747: i = AcpiGbl_RootTableList.CurrentTableCount;
1.1 christos 748: AcpiGbl_RootTableList.CurrentTableCount++;
1.3 christos 749:
750: if (TableIndex)
751: {
752: *TableIndex = i;
753: }
754: if (TableDesc)
755: {
756: *TableDesc = &AcpiGbl_RootTableList.Tables[i];
757: }
758:
1.1 christos 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: }
1.7 christos 868: AcpiNsDeleteNamespaceByOwner (OwnerId);
1.1 christos 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 (
1.5 christos 900: &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
1.1 christos 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: }
1.7 christos 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:
1.10 ! christos 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 ();
1.7 christos 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:
1.9 christos 1109: /* Invoke table handler */
1.7 christos 1110:
1.9 christos 1111: AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table);
1.7 christos 1112: return_ACPI_STATUS (Status);
1113: }
1114:
1115:
1116: /*******************************************************************************
1117: *
1118: * FUNCTION: AcpiTbInstallAndLoadTable
1119: *
1.8 christos 1120: * PARAMETERS: Address - Physical address of the table
1.7 christos 1121: * Flags - Allocation flags of the table
1.8 christos 1122: * Override - Whether override should be performed
1.7 christos 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:
1.8 christos 1142: ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
1.7 christos 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: {
1.9 christos 1151: goto Exit;
1.7 christos 1152: }
1153:
1.8 christos 1154: Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
1.7 christos 1155:
1.9 christos 1156: Exit:
1.8 christos 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: ******************************************************************************/
1.7 christos 1173:
1.8 christos 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 */
1.7 christos 1186:
1.8 christos 1187: if (!AcpiTbIsTableLoaded (TableIndex))
1.7 christos 1188: {
1.8 christos 1189: return_ACPI_STATUS (AE_NOT_EXIST);
1.7 christos 1190: }
1191:
1.9 christos 1192: /* Invoke table handler */
1.8 christos 1193:
1.9 christos 1194: Status = AcpiGetTableByIndex (TableIndex, &Table);
1195: if (ACPI_SUCCESS (Status))
1.7 christos 1196: {
1.9 christos 1197: AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table);
1.7 christos 1198: }
1199:
1.8 christos 1200: /* Delete the portion of the namespace owned by this table */
1.7 christos 1201:
1.8 christos 1202: Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
1203: if (ACPI_FAILURE (Status))
1.7 christos 1204: {
1.8 christos 1205: return_ACPI_STATUS (Status);
1.7 christos 1206: }
1207:
1.8 christos 1208: (void) AcpiTbReleaseOwnerId (TableIndex);
1209: AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
1.7 christos 1210: return_ACPI_STATUS (Status);
1211: }
1.9 christos 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: }
CVSweb <webmaster@jp.NetBSD.org>