Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/tables/tbdata.c
48406 views
1
/******************************************************************************
2
*
3
* Module Name: tbdata - Table manager data structure functions
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/include/acpi.h>
153
#include <contrib/dev/acpica/include/accommon.h>
154
#include <contrib/dev/acpica/include/acnamesp.h>
155
#include <contrib/dev/acpica/include/actables.h>
156
#include <contrib/dev/acpica/include/acevents.h>
157
158
#define _COMPONENT ACPI_TABLES
159
ACPI_MODULE_NAME ("tbdata")
160
161
/* Local prototypes */
162
163
static ACPI_STATUS
164
AcpiTbCheckDuplication (
165
ACPI_TABLE_DESC *TableDesc,
166
UINT32 *TableIndex);
167
168
static BOOLEAN
169
AcpiTbCompareTables (
170
ACPI_TABLE_DESC *TableDesc,
171
UINT32 TableIndex);
172
173
174
/*******************************************************************************
175
*
176
* FUNCTION: AcpiTbCompareTables
177
*
178
* PARAMETERS: TableDesc - Table 1 descriptor to be compared
179
* TableIndex - Index of table 2 to be compared
180
*
181
* RETURN: TRUE if both tables are identical.
182
*
183
* DESCRIPTION: This function compares a table with another table that has
184
* already been installed in the root table list.
185
*
186
******************************************************************************/
187
188
static BOOLEAN
189
AcpiTbCompareTables (
190
ACPI_TABLE_DESC *TableDesc,
191
UINT32 TableIndex)
192
{
193
ACPI_STATUS Status = AE_OK;
194
BOOLEAN IsIdentical;
195
ACPI_TABLE_HEADER *Table;
196
UINT32 TableLength;
197
UINT8 TableFlags;
198
199
200
Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
201
&Table, &TableLength, &TableFlags);
202
if (ACPI_FAILURE (Status))
203
{
204
return (FALSE);
205
}
206
207
/*
208
* Check for a table match on the entire table length,
209
* not just the header.
210
*/
211
IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
212
memcmp (TableDesc->Pointer, Table, TableLength)) ?
213
FALSE : TRUE);
214
215
/* Release the acquired table */
216
217
AcpiTbReleaseTable (Table, TableLength, TableFlags);
218
return (IsIdentical);
219
}
220
221
222
/*******************************************************************************
223
*
224
* FUNCTION: AcpiTbInitTableDescriptor
225
*
226
* PARAMETERS: TableDesc - Table descriptor
227
* Address - Physical address of the table
228
* Flags - Allocation flags of the table
229
* Table - Pointer to the table
230
*
231
* RETURN: None
232
*
233
* DESCRIPTION: Initialize a new table descriptor
234
*
235
******************************************************************************/
236
237
void
238
AcpiTbInitTableDescriptor (
239
ACPI_TABLE_DESC *TableDesc,
240
ACPI_PHYSICAL_ADDRESS Address,
241
UINT8 Flags,
242
ACPI_TABLE_HEADER *Table)
243
{
244
245
/*
246
* Initialize the table descriptor. Set the pointer to NULL for external
247
* tables, since the table is not fully mapped at this time.
248
*/
249
memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
250
TableDesc->Address = Address;
251
TableDesc->Length = Table->Length;
252
TableDesc->Flags = Flags;
253
ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
254
255
switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
256
{
257
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
258
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
259
260
TableDesc->Pointer = Table;
261
break;
262
263
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
264
default:
265
266
break;
267
}
268
}
269
270
271
/*******************************************************************************
272
*
273
* FUNCTION: AcpiTbAcquireTable
274
*
275
* PARAMETERS: TableDesc - Table descriptor
276
* TablePtr - Where table is returned
277
* TableLength - Where table length is returned
278
* TableFlags - Where table allocation flags are returned
279
*
280
* RETURN: Status
281
*
282
* DESCRIPTION: Acquire an ACPI table. It can be used for tables not
283
* maintained in the AcpiGbl_RootTableList.
284
*
285
******************************************************************************/
286
287
ACPI_STATUS
288
AcpiTbAcquireTable (
289
ACPI_TABLE_DESC *TableDesc,
290
ACPI_TABLE_HEADER **TablePtr,
291
UINT32 *TableLength,
292
UINT8 *TableFlags)
293
{
294
ACPI_TABLE_HEADER *Table = NULL;
295
296
297
switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
298
{
299
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
300
301
Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
302
break;
303
304
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
305
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
306
307
Table = TableDesc->Pointer;
308
break;
309
310
default:
311
312
break;
313
}
314
315
/* Table is not valid yet */
316
317
if (!Table)
318
{
319
return (AE_NO_MEMORY);
320
}
321
322
/* Fill the return values */
323
324
*TablePtr = Table;
325
*TableLength = TableDesc->Length;
326
*TableFlags = TableDesc->Flags;
327
return (AE_OK);
328
}
329
330
331
/*******************************************************************************
332
*
333
* FUNCTION: AcpiTbReleaseTable
334
*
335
* PARAMETERS: Table - Pointer for the table
336
* TableLength - Length for the table
337
* TableFlags - Allocation flags for the table
338
*
339
* RETURN: None
340
*
341
* DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
342
*
343
******************************************************************************/
344
345
void
346
AcpiTbReleaseTable (
347
ACPI_TABLE_HEADER *Table,
348
UINT32 TableLength,
349
UINT8 TableFlags)
350
{
351
352
switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
353
{
354
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
355
356
AcpiOsUnmapMemory (Table, TableLength);
357
break;
358
359
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
360
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
361
default:
362
363
break;
364
}
365
}
366
367
368
/*******************************************************************************
369
*
370
* FUNCTION: AcpiTbAcquireTempTable
371
*
372
* PARAMETERS: TableDesc - Table descriptor to be acquired
373
* Address - Address of the table
374
* Flags - Allocation flags of the table
375
* Table - Pointer to the table (required for virtual
376
* origins, optional for physical)
377
*
378
* RETURN: Status
379
*
380
* DESCRIPTION: This function validates the table header to obtain the length
381
* of a table and fills the table descriptor to make its state as
382
* "INSTALLED". Such a table descriptor is only used for verified
383
* installation.
384
*
385
******************************************************************************/
386
387
ACPI_STATUS
388
AcpiTbAcquireTempTable (
389
ACPI_TABLE_DESC *TableDesc,
390
ACPI_PHYSICAL_ADDRESS Address,
391
UINT8 Flags,
392
ACPI_TABLE_HEADER *Table)
393
{
394
BOOLEAN MappedTable = FALSE;
395
396
397
switch (Flags & ACPI_TABLE_ORIGIN_MASK)
398
{
399
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
400
401
/* Get the length of the full table from the header */
402
403
if (!Table)
404
{
405
Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
406
if (!Table)
407
{
408
return (AE_NO_MEMORY);
409
}
410
411
MappedTable = TRUE;
412
}
413
414
break;
415
416
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
417
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
418
419
if (!Table)
420
{
421
return (AE_BAD_PARAMETER);
422
}
423
424
break;
425
426
default:
427
428
/* Table is not valid yet */
429
430
return (AE_NO_MEMORY);
431
}
432
433
AcpiTbInitTableDescriptor (TableDesc, Address, Flags, Table);
434
if (MappedTable)
435
{
436
AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
437
}
438
439
return (AE_OK);
440
}
441
442
443
/*******************************************************************************
444
*
445
* FUNCTION: AcpiTbReleaseTempTable
446
*
447
* PARAMETERS: TableDesc - Table descriptor to be released
448
*
449
* RETURN: Status
450
*
451
* DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
452
*
453
*****************************************************************************/
454
455
void
456
AcpiTbReleaseTempTable (
457
ACPI_TABLE_DESC *TableDesc)
458
{
459
460
/*
461
* Note that the .Address is maintained by the callers of
462
* AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
463
* where .Address will be freed.
464
*/
465
AcpiTbInvalidateTable (TableDesc);
466
}
467
468
469
/******************************************************************************
470
*
471
* FUNCTION: AcpiTbValidateTable
472
*
473
* PARAMETERS: TableDesc - Table descriptor
474
*
475
* RETURN: Status
476
*
477
* DESCRIPTION: This function is called to validate the table, the returned
478
* table descriptor is in "VALIDATED" state.
479
*
480
*****************************************************************************/
481
482
ACPI_STATUS
483
AcpiTbValidateTable (
484
ACPI_TABLE_DESC *TableDesc)
485
{
486
ACPI_STATUS Status = AE_OK;
487
488
489
ACPI_FUNCTION_TRACE (TbValidateTable);
490
491
492
/* Validate the table if necessary */
493
494
if (!TableDesc->Pointer)
495
{
496
Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
497
&TableDesc->Length, &TableDesc->Flags);
498
if (!TableDesc->Pointer)
499
{
500
Status = AE_NO_MEMORY;
501
}
502
}
503
504
return_ACPI_STATUS (Status);
505
}
506
507
508
/*******************************************************************************
509
*
510
* FUNCTION: AcpiTbInvalidateTable
511
*
512
* PARAMETERS: TableDesc - Table descriptor
513
*
514
* RETURN: None
515
*
516
* DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
517
* AcpiTbValidateTable().
518
*
519
******************************************************************************/
520
521
void
522
AcpiTbInvalidateTable (
523
ACPI_TABLE_DESC *TableDesc)
524
{
525
526
ACPI_FUNCTION_TRACE (TbInvalidateTable);
527
528
529
/* Table must be validated */
530
531
if (!TableDesc->Pointer)
532
{
533
return_VOID;
534
}
535
536
AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
537
TableDesc->Flags);
538
539
switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
540
{
541
case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
542
543
TableDesc->Pointer = NULL;
544
break;
545
546
case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
547
case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
548
default:
549
550
break;
551
}
552
553
return_VOID;
554
}
555
556
557
/******************************************************************************
558
*
559
* FUNCTION: AcpiTbValidateTempTable
560
*
561
* PARAMETERS: TableDesc - Table descriptor
562
*
563
* RETURN: Status
564
*
565
* DESCRIPTION: This function is called to validate the table, the returned
566
* table descriptor is in "VALIDATED" state.
567
*
568
*****************************************************************************/
569
570
ACPI_STATUS
571
AcpiTbValidateTempTable (
572
ACPI_TABLE_DESC *TableDesc)
573
{
574
575
if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
576
{
577
/*
578
* Only validates the header of the table.
579
* Note that Length contains the size of the mapping after invoking
580
* this work around, this value is required by
581
* AcpiTbReleaseTempTable().
582
* We can do this because in AcpiInitTableDescriptor(), the Length
583
* field of the installed descriptor is filled with the actual
584
* table length obtaining from the table header.
585
*/
586
TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
587
}
588
589
return (AcpiTbValidateTable (TableDesc));
590
}
591
592
593
/*******************************************************************************
594
*
595
* FUNCTION: AcpiTbCheckDuplication
596
*
597
* PARAMETERS: TableDesc - Table descriptor
598
* TableIndex - Where the table index is returned
599
*
600
* RETURN: Status
601
*
602
* DESCRIPTION: Avoid installing duplicated tables. However table override and
603
* user aided dynamic table load is allowed, thus comparing the
604
* address of the table is not sufficient, and checking the entire
605
* table content is required.
606
*
607
******************************************************************************/
608
609
static ACPI_STATUS
610
AcpiTbCheckDuplication (
611
ACPI_TABLE_DESC *TableDesc,
612
UINT32 *TableIndex)
613
{
614
UINT32 i;
615
616
617
ACPI_FUNCTION_TRACE (TbCheckDuplication);
618
619
620
/* Check if table is already registered */
621
622
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
623
{
624
/* Do not compare with unverified tables */
625
626
if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED))
627
{
628
continue;
629
}
630
631
/*
632
* Check for a table match on the entire table length,
633
* not just the header.
634
*/
635
if (!AcpiTbCompareTables (TableDesc, i))
636
{
637
continue;
638
}
639
640
/*
641
* Note: the current mechanism does not unregister a table if it is
642
* dynamically unloaded. The related namespace entries are deleted,
643
* but the table remains in the root table list.
644
*
645
* The assumption here is that the number of different tables that
646
* will be loaded is actually small, and there is minimal overhead
647
* in just keeping the table in case it is needed again.
648
*
649
* If this assumption changes in the future (perhaps on large
650
* machines with many table load/unload operations), tables will
651
* need to be unregistered when they are unloaded, and slots in the
652
* root table list should be reused when empty.
653
*/
654
if (AcpiGbl_RootTableList.Tables[i].Flags &
655
ACPI_TABLE_IS_LOADED)
656
{
657
/* Table is still loaded, this is an error */
658
659
return_ACPI_STATUS (AE_ALREADY_EXISTS);
660
}
661
else
662
{
663
*TableIndex = i;
664
return_ACPI_STATUS (AE_CTRL_TERMINATE);
665
}
666
}
667
668
/* Indicate no duplication to the caller */
669
670
return_ACPI_STATUS (AE_OK);
671
}
672
673
674
/******************************************************************************
675
*
676
* FUNCTION: AcpiTbVerifyTempTable
677
*
678
* PARAMETERS: TableDesc - Table descriptor
679
* Signature - Table signature to verify
680
* TableIndex - Where the table index is returned
681
*
682
* RETURN: Status
683
*
684
* DESCRIPTION: This function is called to validate and verify the table, the
685
* returned table descriptor is in "VALIDATED" state.
686
* Note that 'TableIndex' is required to be set to !NULL to
687
* enable duplication check.
688
*
689
*****************************************************************************/
690
691
ACPI_STATUS
692
AcpiTbVerifyTempTable (
693
ACPI_TABLE_DESC *TableDesc,
694
char *Signature,
695
UINT32 *TableIndex)
696
{
697
ACPI_STATUS Status = AE_OK;
698
699
700
ACPI_FUNCTION_TRACE (TbVerifyTempTable);
701
702
703
/* Validate the table */
704
705
Status = AcpiTbValidateTempTable (TableDesc);
706
if (ACPI_FAILURE (Status))
707
{
708
return_ACPI_STATUS (AE_NO_MEMORY);
709
}
710
711
/* If a particular signature is expected (DSDT/FACS), it must match */
712
713
if (Signature &&
714
!ACPI_COMPARE_NAMESEG (&TableDesc->Signature, Signature))
715
{
716
ACPI_BIOS_ERROR ((AE_INFO,
717
"Invalid signature 0x%X for ACPI table, expected [%s]",
718
TableDesc->Signature.Integer, Signature));
719
Status = AE_BAD_SIGNATURE;
720
goto InvalidateAndExit;
721
}
722
723
if (AcpiGbl_EnableTableValidation)
724
{
725
/* Verify the checksum */
726
727
Status = AcpiUtVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
728
if (ACPI_FAILURE (Status))
729
{
730
ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
731
"%4.4s 0x%8.8X%8.8X"
732
" Attempted table install failed",
733
AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
734
TableDesc->Signature.Ascii : "????",
735
ACPI_FORMAT_UINT64 (TableDesc->Address)));
736
737
goto InvalidateAndExit;
738
}
739
740
/* Avoid duplications */
741
742
if (TableIndex)
743
{
744
Status = AcpiTbCheckDuplication (TableDesc, TableIndex);
745
if (ACPI_FAILURE (Status))
746
{
747
if (Status != AE_CTRL_TERMINATE)
748
{
749
ACPI_EXCEPTION ((AE_INFO, Status,
750
"%4.4s 0x%8.8X%8.8X"
751
" Table is already loaded",
752
AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
753
TableDesc->Signature.Ascii : "????",
754
ACPI_FORMAT_UINT64 (TableDesc->Address)));
755
}
756
757
goto InvalidateAndExit;
758
}
759
}
760
761
TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED;
762
}
763
764
return_ACPI_STATUS (Status);
765
766
InvalidateAndExit:
767
AcpiTbInvalidateTable (TableDesc);
768
return_ACPI_STATUS (Status);
769
}
770
771
772
/*******************************************************************************
773
*
774
* FUNCTION: AcpiTbResizeRootTableList
775
*
776
* PARAMETERS: None
777
*
778
* RETURN: Status
779
*
780
* DESCRIPTION: Expand the size of global table array
781
*
782
******************************************************************************/
783
784
ACPI_STATUS
785
AcpiTbResizeRootTableList (
786
void)
787
{
788
ACPI_TABLE_DESC *Tables;
789
UINT32 TableCount;
790
UINT32 CurrentTableCount, MaxTableCount;
791
UINT32 i;
792
793
794
ACPI_FUNCTION_TRACE (TbResizeRootTableList);
795
796
797
/* AllowResize flag is a parameter to AcpiInitializeTables */
798
799
if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
800
{
801
ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
802
return_ACPI_STATUS (AE_SUPPORT);
803
}
804
805
/* Increase the Table Array size */
806
807
if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
808
{
809
TableCount = AcpiGbl_RootTableList.MaxTableCount;
810
}
811
else
812
{
813
TableCount = AcpiGbl_RootTableList.CurrentTableCount;
814
}
815
816
MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
817
Tables = ACPI_ALLOCATE_ZEROED (
818
((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC));
819
if (!Tables)
820
{
821
ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
822
return_ACPI_STATUS (AE_NO_MEMORY);
823
}
824
825
/* Copy and free the previous table array */
826
827
CurrentTableCount = 0;
828
if (AcpiGbl_RootTableList.Tables)
829
{
830
for (i = 0; i < TableCount; i++)
831
{
832
if (AcpiGbl_RootTableList.Tables[i].Address)
833
{
834
memcpy (Tables + CurrentTableCount,
835
AcpiGbl_RootTableList.Tables + i,
836
sizeof (ACPI_TABLE_DESC));
837
CurrentTableCount++;
838
}
839
}
840
841
if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
842
{
843
ACPI_FREE (AcpiGbl_RootTableList.Tables);
844
}
845
}
846
847
AcpiGbl_RootTableList.Tables = Tables;
848
AcpiGbl_RootTableList.MaxTableCount = MaxTableCount;
849
AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount;
850
AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
851
852
return_ACPI_STATUS (AE_OK);
853
}
854
855
856
/*******************************************************************************
857
*
858
* FUNCTION: AcpiTbGetNextTableDescriptor
859
*
860
* PARAMETERS: TableIndex - Where table index is returned
861
* TableDesc - Where table descriptor is returned
862
*
863
* RETURN: Status and table index/descriptor.
864
*
865
* DESCRIPTION: Allocate a new ACPI table entry to the global table list
866
*
867
******************************************************************************/
868
869
ACPI_STATUS
870
AcpiTbGetNextTableDescriptor (
871
UINT32 *TableIndex,
872
ACPI_TABLE_DESC **TableDesc)
873
{
874
ACPI_STATUS Status;
875
UINT32 i;
876
877
878
/* Ensure that there is room for the table in the Root Table List */
879
880
if (AcpiGbl_RootTableList.CurrentTableCount >=
881
AcpiGbl_RootTableList.MaxTableCount)
882
{
883
Status = AcpiTbResizeRootTableList();
884
if (ACPI_FAILURE (Status))
885
{
886
return (Status);
887
}
888
}
889
890
i = AcpiGbl_RootTableList.CurrentTableCount;
891
AcpiGbl_RootTableList.CurrentTableCount++;
892
893
if (TableIndex)
894
{
895
*TableIndex = i;
896
}
897
if (TableDesc)
898
{
899
*TableDesc = &AcpiGbl_RootTableList.Tables[i];
900
}
901
902
return (AE_OK);
903
}
904
905
906
/*******************************************************************************
907
*
908
* FUNCTION: AcpiTbTerminate
909
*
910
* PARAMETERS: None
911
*
912
* RETURN: None
913
*
914
* DESCRIPTION: Delete all internal ACPI tables
915
*
916
******************************************************************************/
917
918
void
919
AcpiTbTerminate (
920
void)
921
{
922
UINT32 i;
923
924
925
ACPI_FUNCTION_TRACE (TbTerminate);
926
927
928
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
929
930
/* Delete the individual tables */
931
932
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
933
{
934
AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
935
}
936
937
/*
938
* Delete the root table array if allocated locally. Array cannot be
939
* mapped, so we don't need to check for that flag.
940
*/
941
if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
942
{
943
ACPI_FREE (AcpiGbl_RootTableList.Tables);
944
}
945
946
AcpiGbl_RootTableList.Tables = NULL;
947
AcpiGbl_RootTableList.Flags = 0;
948
AcpiGbl_RootTableList.CurrentTableCount = 0;
949
950
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
951
952
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
953
return_VOID;
954
}
955
956
957
/*******************************************************************************
958
*
959
* FUNCTION: AcpiTbDeleteNamespaceByOwner
960
*
961
* PARAMETERS: TableIndex - Table index
962
*
963
* RETURN: Status
964
*
965
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
966
*
967
******************************************************************************/
968
969
ACPI_STATUS
970
AcpiTbDeleteNamespaceByOwner (
971
UINT32 TableIndex)
972
{
973
ACPI_OWNER_ID OwnerId;
974
ACPI_STATUS Status;
975
976
977
ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
978
979
980
Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
981
if (ACPI_FAILURE (Status))
982
{
983
return_ACPI_STATUS (Status);
984
}
985
986
if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
987
{
988
/* The table index does not exist */
989
990
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
991
return_ACPI_STATUS (AE_NOT_EXIST);
992
}
993
994
/* Get the owner ID for this table, used to delete namespace nodes */
995
996
OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
997
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
998
999
/*
1000
* Need to acquire the namespace writer lock to prevent interference
1001
* with any concurrent namespace walks. The interpreter must be
1002
* released during the deletion since the acquisition of the deletion
1003
* lock may block, and also since the execution of a namespace walk
1004
* must be allowed to use the interpreter.
1005
*/
1006
Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
1007
if (ACPI_FAILURE (Status))
1008
{
1009
return_ACPI_STATUS (Status);
1010
}
1011
1012
AcpiNsDeleteNamespaceByOwner (OwnerId);
1013
AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
1014
return_ACPI_STATUS (Status);
1015
}
1016
1017
1018
/*******************************************************************************
1019
*
1020
* FUNCTION: AcpiTbAllocateOwnerId
1021
*
1022
* PARAMETERS: TableIndex - Table index
1023
*
1024
* RETURN: Status
1025
*
1026
* DESCRIPTION: Allocates OwnerId in TableDesc
1027
*
1028
******************************************************************************/
1029
1030
ACPI_STATUS
1031
AcpiTbAllocateOwnerId (
1032
UINT32 TableIndex)
1033
{
1034
ACPI_STATUS Status = AE_BAD_PARAMETER;
1035
1036
1037
ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
1038
1039
1040
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1041
if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1042
{
1043
Status = AcpiUtAllocateOwnerId (
1044
&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
1045
}
1046
1047
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1048
return_ACPI_STATUS (Status);
1049
}
1050
1051
1052
/*******************************************************************************
1053
*
1054
* FUNCTION: AcpiTbReleaseOwnerId
1055
*
1056
* PARAMETERS: TableIndex - Table index
1057
*
1058
* RETURN: Status
1059
*
1060
* DESCRIPTION: Releases OwnerId in TableDesc
1061
*
1062
******************************************************************************/
1063
1064
ACPI_STATUS
1065
AcpiTbReleaseOwnerId (
1066
UINT32 TableIndex)
1067
{
1068
ACPI_STATUS Status = AE_BAD_PARAMETER;
1069
1070
1071
ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
1072
1073
1074
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1075
if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1076
{
1077
AcpiUtReleaseOwnerId (
1078
&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
1079
Status = AE_OK;
1080
}
1081
1082
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1083
return_ACPI_STATUS (Status);
1084
}
1085
1086
1087
/*******************************************************************************
1088
*
1089
* FUNCTION: AcpiTbGetOwnerId
1090
*
1091
* PARAMETERS: TableIndex - Table index
1092
* OwnerId - Where the table OwnerId is returned
1093
*
1094
* RETURN: Status
1095
*
1096
* DESCRIPTION: returns OwnerId for the ACPI table
1097
*
1098
******************************************************************************/
1099
1100
ACPI_STATUS
1101
AcpiTbGetOwnerId (
1102
UINT32 TableIndex,
1103
ACPI_OWNER_ID *OwnerId)
1104
{
1105
ACPI_STATUS Status = AE_BAD_PARAMETER;
1106
1107
1108
ACPI_FUNCTION_TRACE (TbGetOwnerId);
1109
1110
1111
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1112
if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1113
{
1114
*OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
1115
Status = AE_OK;
1116
}
1117
1118
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1119
return_ACPI_STATUS (Status);
1120
}
1121
1122
1123
/*******************************************************************************
1124
*
1125
* FUNCTION: AcpiTbIsTableLoaded
1126
*
1127
* PARAMETERS: TableIndex - Index into the root table
1128
*
1129
* RETURN: Table Loaded Flag
1130
*
1131
******************************************************************************/
1132
1133
BOOLEAN
1134
AcpiTbIsTableLoaded (
1135
UINT32 TableIndex)
1136
{
1137
BOOLEAN IsLoaded = FALSE;
1138
1139
1140
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1141
if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1142
{
1143
IsLoaded = (BOOLEAN)
1144
(AcpiGbl_RootTableList.Tables[TableIndex].Flags &
1145
ACPI_TABLE_IS_LOADED);
1146
}
1147
1148
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1149
return (IsLoaded);
1150
}
1151
1152
1153
/*******************************************************************************
1154
*
1155
* FUNCTION: AcpiTbSetTableLoadedFlag
1156
*
1157
* PARAMETERS: TableIndex - Table index
1158
* IsLoaded - TRUE if table is loaded, FALSE otherwise
1159
*
1160
* RETURN: None
1161
*
1162
* DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1163
*
1164
******************************************************************************/
1165
1166
void
1167
AcpiTbSetTableLoadedFlag (
1168
UINT32 TableIndex,
1169
BOOLEAN IsLoaded)
1170
{
1171
1172
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1173
if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1174
{
1175
if (IsLoaded)
1176
{
1177
AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
1178
ACPI_TABLE_IS_LOADED;
1179
}
1180
else
1181
{
1182
AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
1183
~ACPI_TABLE_IS_LOADED;
1184
}
1185
}
1186
1187
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1188
}
1189
1190
1191
/*******************************************************************************
1192
*
1193
* FUNCTION: AcpiTbLoadTable
1194
*
1195
* PARAMETERS: TableIndex - Table index
1196
* ParentNode - Where table index is returned
1197
*
1198
* RETURN: Status
1199
*
1200
* DESCRIPTION: Load an ACPI table
1201
*
1202
******************************************************************************/
1203
1204
ACPI_STATUS
1205
AcpiTbLoadTable (
1206
UINT32 TableIndex,
1207
ACPI_NAMESPACE_NODE *ParentNode)
1208
{
1209
ACPI_TABLE_HEADER *Table;
1210
ACPI_STATUS Status;
1211
ACPI_OWNER_ID OwnerId;
1212
1213
1214
ACPI_FUNCTION_TRACE (TbLoadTable);
1215
1216
1217
/*
1218
* Note: Now table is "INSTALLED", it must be validated before
1219
* using.
1220
*/
1221
Status = AcpiGetTableByIndex (TableIndex, &Table);
1222
if (ACPI_FAILURE (Status))
1223
{
1224
return_ACPI_STATUS (Status);
1225
}
1226
1227
Status = AcpiNsLoadTable (TableIndex, ParentNode);
1228
if (ACPI_FAILURE (Status))
1229
{
1230
return_ACPI_STATUS (Status);
1231
}
1232
1233
/*
1234
* Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1235
* responsible for discovering any new wake GPEs by running _PRW methods
1236
* that may have been loaded by this table.
1237
*/
1238
Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
1239
if (ACPI_SUCCESS (Status))
1240
{
1241
AcpiEvUpdateGpes (OwnerId);
1242
}
1243
1244
/* Invoke table handler */
1245
1246
AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table);
1247
return_ACPI_STATUS (Status);
1248
}
1249
1250
1251
/*******************************************************************************
1252
*
1253
* FUNCTION: AcpiTbInstallAndLoadTable
1254
*
1255
* PARAMETERS: Address - Physical address of the table
1256
* Flags - Allocation flags of the table
1257
* Table - Pointer to the table (required for
1258
* virtual origins, optional for
1259
* physical)
1260
* Override - Whether override should be performed
1261
* TableIndex - Where table index is returned
1262
*
1263
* RETURN: Status
1264
*
1265
* DESCRIPTION: Install and load an ACPI table
1266
*
1267
******************************************************************************/
1268
1269
ACPI_STATUS
1270
AcpiTbInstallAndLoadTable (
1271
ACPI_PHYSICAL_ADDRESS Address,
1272
UINT8 Flags,
1273
ACPI_TABLE_HEADER *Table,
1274
BOOLEAN Override,
1275
UINT32 *TableIndex)
1276
{
1277
ACPI_STATUS Status;
1278
UINT32 i;
1279
1280
1281
ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
1282
1283
1284
/* Install the table and load it into the namespace */
1285
1286
Status = AcpiTbInstallStandardTable (Address, Flags, Table, TRUE,
1287
Override, &i);
1288
if (ACPI_FAILURE (Status))
1289
{
1290
goto Exit;
1291
}
1292
1293
Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
1294
1295
Exit:
1296
*TableIndex = i;
1297
return_ACPI_STATUS (Status);
1298
}
1299
1300
1301
/*******************************************************************************
1302
*
1303
* FUNCTION: AcpiTbUnloadTable
1304
*
1305
* PARAMETERS: TableIndex - Table index
1306
*
1307
* RETURN: Status
1308
*
1309
* DESCRIPTION: Unload an ACPI table
1310
*
1311
******************************************************************************/
1312
1313
ACPI_STATUS
1314
AcpiTbUnloadTable (
1315
UINT32 TableIndex)
1316
{
1317
ACPI_STATUS Status = AE_OK;
1318
ACPI_TABLE_HEADER *Table;
1319
1320
1321
ACPI_FUNCTION_TRACE (TbUnloadTable);
1322
1323
1324
/* Ensure the table is still loaded */
1325
1326
if (!AcpiTbIsTableLoaded (TableIndex))
1327
{
1328
return_ACPI_STATUS (AE_NOT_EXIST);
1329
}
1330
1331
/* Invoke table handler */
1332
1333
Status = AcpiGetTableByIndex (TableIndex, &Table);
1334
if (ACPI_SUCCESS (Status))
1335
{
1336
AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table);
1337
}
1338
1339
/* Delete the portion of the namespace owned by this table */
1340
1341
Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
1342
if (ACPI_FAILURE (Status))
1343
{
1344
return_ACPI_STATUS (Status);
1345
}
1346
1347
(void) AcpiTbReleaseOwnerId (TableIndex);
1348
AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
1349
return_ACPI_STATUS (Status);
1350
}
1351
1352
1353
/*******************************************************************************
1354
*
1355
* FUNCTION: AcpiTbNotifyTable
1356
*
1357
* PARAMETERS: Event - Table event
1358
* Table - Validated table pointer
1359
*
1360
* RETURN: None
1361
*
1362
* DESCRIPTION: Notify a table event to the users.
1363
*
1364
******************************************************************************/
1365
1366
void
1367
AcpiTbNotifyTable (
1368
UINT32 Event,
1369
void *Table)
1370
{
1371
/* Invoke table handler if present */
1372
1373
if (AcpiGbl_TableHandler)
1374
{
1375
(void) AcpiGbl_TableHandler (Event, Table,
1376
AcpiGbl_TableHandlerContext);
1377
}
1378
}
1379
1380