Deleted Added
full compact
tbinstal.c (233250) tbinstal.c (238381)
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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
45#define __TBINSTAL_C__
46
47#include <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/actables.h>
51
52
53#define _COMPONENT ACPI_TABLES
54 ACPI_MODULE_NAME ("tbinstal")
55
56
57/******************************************************************************
58 *
59 * FUNCTION: AcpiTbVerifyTable
60 *
61 * PARAMETERS: TableDesc - table
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: this function is called to verify and map table
66 *
67 *****************************************************************************/
68
69ACPI_STATUS
70AcpiTbVerifyTable (
71 ACPI_TABLE_DESC *TableDesc)
72{
73 ACPI_STATUS Status = AE_OK;
74
75
76 ACPI_FUNCTION_TRACE (TbVerifyTable);
77
78
79 /* Map the table if necessary */
80
81 if (!TableDesc->Pointer)
82 {
83 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
84 ACPI_TABLE_ORIGIN_MAPPED)
85 {
86 TableDesc->Pointer = AcpiOsMapMemory (
87 TableDesc->Address, TableDesc->Length);
88 }
89
90 if (!TableDesc->Pointer)
91 {
92 return_ACPI_STATUS (AE_NO_MEMORY);
93 }
94 }
95
96 /* FACS is the odd table, has no standard ACPI header and no checksum */
97
98 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
99 {
100 /* Always calculate checksum, ignore bad checksum if requested */
101
102 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
103 }
104
105 return_ACPI_STATUS (Status);
106}
107
108
109/*******************************************************************************
110 *
111 * FUNCTION: AcpiTbAddTable
112 *
113 * PARAMETERS: TableDesc - Table descriptor
114 * TableIndex - Where the table index is returned
115 *
116 * RETURN: Status
117 *
118 * DESCRIPTION: This function is called to add an ACPI table. It is used to
119 * dynamically load tables via the Load and LoadTable AML
120 * operators.
121 *
122 ******************************************************************************/
123
124ACPI_STATUS
125AcpiTbAddTable (
126 ACPI_TABLE_DESC *TableDesc,
127 UINT32 *TableIndex)
128{
129 UINT32 i;
130 ACPI_STATUS Status = AE_OK;
131
132
133 ACPI_FUNCTION_TRACE (TbAddTable);
134
135
136 if (!TableDesc->Pointer)
137 {
138 Status = AcpiTbVerifyTable (TableDesc);
139 if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
140 {
141 return_ACPI_STATUS (Status);
142 }
143 }
144
145 /*
146 * Validate the incoming table signature.
147 *
148 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
149 * 2) We added support for OEMx tables, signature "OEM".
150 * 3) Valid tables were encountered with a null signature, so we just
151 * gave up on validating the signature, (05/2008).
152 * 4) We encountered non-AML tables such as the MADT, which caused
153 * interpreter errors and kernel faults. So now, we once again allow
154 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
155 */
156 if ((TableDesc->Pointer->Signature[0] != 0x00) &&
157 (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
158 (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
159 {
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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
45#define __TBINSTAL_C__
46
47#include <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/actables.h>
51
52
53#define _COMPONENT ACPI_TABLES
54 ACPI_MODULE_NAME ("tbinstal")
55
56
57/******************************************************************************
58 *
59 * FUNCTION: AcpiTbVerifyTable
60 *
61 * PARAMETERS: TableDesc - table
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: this function is called to verify and map table
66 *
67 *****************************************************************************/
68
69ACPI_STATUS
70AcpiTbVerifyTable (
71 ACPI_TABLE_DESC *TableDesc)
72{
73 ACPI_STATUS Status = AE_OK;
74
75
76 ACPI_FUNCTION_TRACE (TbVerifyTable);
77
78
79 /* Map the table if necessary */
80
81 if (!TableDesc->Pointer)
82 {
83 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
84 ACPI_TABLE_ORIGIN_MAPPED)
85 {
86 TableDesc->Pointer = AcpiOsMapMemory (
87 TableDesc->Address, TableDesc->Length);
88 }
89
90 if (!TableDesc->Pointer)
91 {
92 return_ACPI_STATUS (AE_NO_MEMORY);
93 }
94 }
95
96 /* FACS is the odd table, has no standard ACPI header and no checksum */
97
98 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
99 {
100 /* Always calculate checksum, ignore bad checksum if requested */
101
102 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
103 }
104
105 return_ACPI_STATUS (Status);
106}
107
108
109/*******************************************************************************
110 *
111 * FUNCTION: AcpiTbAddTable
112 *
113 * PARAMETERS: TableDesc - Table descriptor
114 * TableIndex - Where the table index is returned
115 *
116 * RETURN: Status
117 *
118 * DESCRIPTION: This function is called to add an ACPI table. It is used to
119 * dynamically load tables via the Load and LoadTable AML
120 * operators.
121 *
122 ******************************************************************************/
123
124ACPI_STATUS
125AcpiTbAddTable (
126 ACPI_TABLE_DESC *TableDesc,
127 UINT32 *TableIndex)
128{
129 UINT32 i;
130 ACPI_STATUS Status = AE_OK;
131
132
133 ACPI_FUNCTION_TRACE (TbAddTable);
134
135
136 if (!TableDesc->Pointer)
137 {
138 Status = AcpiTbVerifyTable (TableDesc);
139 if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
140 {
141 return_ACPI_STATUS (Status);
142 }
143 }
144
145 /*
146 * Validate the incoming table signature.
147 *
148 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
149 * 2) We added support for OEMx tables, signature "OEM".
150 * 3) Valid tables were encountered with a null signature, so we just
151 * gave up on validating the signature, (05/2008).
152 * 4) We encountered non-AML tables such as the MADT, which caused
153 * interpreter errors and kernel faults. So now, we once again allow
154 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
155 */
156 if ((TableDesc->Pointer->Signature[0] != 0x00) &&
157 (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
158 (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
159 {
160 ACPI_ERROR ((AE_INFO,
161 "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
160 ACPI_BIOS_ERROR ((AE_INFO,
161 "Table has invalid signature [%4.4s] (0x%8.8X), "
162 "must be SSDT or OEMx",
162 AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
163 TableDesc->Pointer->Signature : "????",
164 *(UINT32 *) TableDesc->Pointer->Signature));
165
166 return_ACPI_STATUS (AE_BAD_SIGNATURE);
167 }
168
169 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
170
171 /* Check if table is already registered */
172
173 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
174 {
175 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
176 {
177 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
178 if (ACPI_FAILURE (Status) ||
179 !AcpiGbl_RootTableList.Tables[i].Pointer)
180 {
181 continue;
182 }
183 }
184
185 /*
186 * Check for a table match on the entire table length,
187 * not just the header.
188 */
189 if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
190 {
191 continue;
192 }
193
194 if (ACPI_MEMCMP (TableDesc->Pointer,
195 AcpiGbl_RootTableList.Tables[i].Pointer,
196 AcpiGbl_RootTableList.Tables[i].Length))
197 {
198 continue;
199 }
200
201 /*
202 * Note: the current mechanism does not unregister a table if it is
203 * dynamically unloaded. The related namespace entries are deleted,
204 * but the table remains in the root table list.
205 *
206 * The assumption here is that the number of different tables that
207 * will be loaded is actually small, and there is minimal overhead
208 * in just keeping the table in case it is needed again.
209 *
210 * If this assumption changes in the future (perhaps on large
211 * machines with many table load/unload operations), tables will
212 * need to be unregistered when they are unloaded, and slots in the
213 * root table list should be reused when empty.
214 */
215
216 /*
217 * Table is already registered.
218 * We can delete the table that was passed as a parameter.
219 */
220 AcpiTbDeleteTable (TableDesc);
221 *TableIndex = i;
222
223 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
224 {
225 /* Table is still loaded, this is an error */
226
227 Status = AE_ALREADY_EXISTS;
228 goto Release;
229 }
230 else
231 {
232 /* Table was unloaded, allow it to be reloaded */
233
234 TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
235 TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
236 Status = AE_OK;
237 goto PrintHeader;
238 }
239 }
240
241 /*
242 * ACPI Table Override:
243 * Allow the host to override dynamically loaded tables.
244 * NOTE: the table is fully mapped at this point, and the mapping will
245 * be deleted by TbTableOverride if the table is actually overridden.
246 */
247 (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
248
249 /* Add the table to the global root table list */
250
251 Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
252 TableDesc->Length, TableDesc->Flags, TableIndex);
253 if (ACPI_FAILURE (Status))
254 {
255 goto Release;
256 }
257
258PrintHeader:
259 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
260
261Release:
262 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
263 return_ACPI_STATUS (Status);
264}
265
266
267/*******************************************************************************
268 *
269 * FUNCTION: AcpiTbTableOverride
270 *
271 * PARAMETERS: TableHeader - Header for the original table
272 * TableDesc - Table descriptor initialized for the
273 * original table. May or may not be mapped.
274 *
275 * RETURN: Pointer to the entire new table. NULL if table not overridden.
276 * If overridden, installs the new table within the input table
277 * descriptor.
278 *
279 * DESCRIPTION: Attempt table override by calling the OSL override functions.
280 * Note: If the table is overridden, then the entire new table
281 * is mapped and returned by this function.
282 *
283 ******************************************************************************/
284
285ACPI_TABLE_HEADER *
286AcpiTbTableOverride (
287 ACPI_TABLE_HEADER *TableHeader,
288 ACPI_TABLE_DESC *TableDesc)
289{
290 ACPI_STATUS Status;
291 ACPI_TABLE_HEADER *NewTable = NULL;
292 ACPI_PHYSICAL_ADDRESS NewAddress = 0;
293 UINT32 NewTableLength = 0;
294 UINT8 NewFlags;
295 char *OverrideType;
296
297
298 /* (1) Attempt logical override (returns a logical address) */
299
300 Status = AcpiOsTableOverride (TableHeader, &NewTable);
301 if (ACPI_SUCCESS (Status) && NewTable)
302 {
303 NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
304 NewTableLength = NewTable->Length;
305 NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
306 OverrideType = "Logical";
307 goto FinishOverride;
308 }
309
310 /* (2) Attempt physical override (returns a physical address) */
311
312 Status = AcpiOsPhysicalTableOverride (TableHeader,
313 &NewAddress, &NewTableLength);
314 if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
315 {
316 /* Map the entire new table */
317
318 NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
319 if (!NewTable)
320 {
321 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
322 "%4.4s %p Attempted physical table override failed",
323 TableHeader->Signature,
324 ACPI_CAST_PTR (void, TableDesc->Address)));
325 return (NULL);
326 }
327
328 OverrideType = "Physical";
329 NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
330 goto FinishOverride;
331 }
332
333 return (NULL); /* There was no override */
334
335
336FinishOverride:
337
338 ACPI_INFO ((AE_INFO,
339 "%4.4s %p %s table override, new table: %p",
340 TableHeader->Signature,
341 ACPI_CAST_PTR (void, TableDesc->Address),
342 OverrideType, NewTable));
343
344 /* We can now unmap/delete the original table (if fully mapped) */
345
346 AcpiTbDeleteTable (TableDesc);
347
348 /* Setup descriptor for the new table */
349
350 TableDesc->Address = NewAddress;
351 TableDesc->Pointer = NewTable;
352 TableDesc->Length = NewTableLength;
353 TableDesc->Flags = NewFlags;
354
355 return (NewTable);
356}
357
358
359/*******************************************************************************
360 *
361 * FUNCTION: AcpiTbResizeRootTableList
362 *
363 * PARAMETERS: None
364 *
365 * RETURN: Status
366 *
367 * DESCRIPTION: Expand the size of global table array
368 *
369 ******************************************************************************/
370
371ACPI_STATUS
372AcpiTbResizeRootTableList (
373 void)
374{
375 ACPI_TABLE_DESC *Tables;
376
377
378 ACPI_FUNCTION_TRACE (TbResizeRootTableList);
379
380
381 /* AllowResize flag is a parameter to AcpiInitializeTables */
382
383 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
384 {
385 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
386 return_ACPI_STATUS (AE_SUPPORT);
387 }
388
389 /* Increase the Table Array size */
390
391 Tables = ACPI_ALLOCATE_ZEROED (
392 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
393 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
394 sizeof (ACPI_TABLE_DESC));
395 if (!Tables)
396 {
397 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
398 return_ACPI_STATUS (AE_NO_MEMORY);
399 }
400
401 /* Copy and free the previous table array */
402
403 if (AcpiGbl_RootTableList.Tables)
404 {
405 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
406 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
407
408 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
409 {
410 ACPI_FREE (AcpiGbl_RootTableList.Tables);
411 }
412 }
413
414 AcpiGbl_RootTableList.Tables = Tables;
415 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
416 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
417
418 return_ACPI_STATUS (AE_OK);
419}
420
421
422/*******************************************************************************
423 *
424 * FUNCTION: AcpiTbStoreTable
425 *
426 * PARAMETERS: Address - Table address
427 * Table - Table header
428 * Length - Table length
429 * Flags - flags
430 *
431 * RETURN: Status and table index.
432 *
433 * DESCRIPTION: Add an ACPI table to the global table list
434 *
435 ******************************************************************************/
436
437ACPI_STATUS
438AcpiTbStoreTable (
439 ACPI_PHYSICAL_ADDRESS Address,
440 ACPI_TABLE_HEADER *Table,
441 UINT32 Length,
442 UINT8 Flags,
443 UINT32 *TableIndex)
444{
445 ACPI_STATUS Status;
446 ACPI_TABLE_DESC *NewTable;
447
448
449 /* Ensure that there is room for the table in the Root Table List */
450
451 if (AcpiGbl_RootTableList.CurrentTableCount >=
452 AcpiGbl_RootTableList.MaxTableCount)
453 {
454 Status = AcpiTbResizeRootTableList();
455 if (ACPI_FAILURE (Status))
456 {
457 return (Status);
458 }
459 }
460
461 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
462
463 /* Initialize added table */
464
465 NewTable->Address = Address;
466 NewTable->Pointer = Table;
467 NewTable->Length = Length;
468 NewTable->OwnerId = 0;
469 NewTable->Flags = Flags;
470
471 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
472
473 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
474 AcpiGbl_RootTableList.CurrentTableCount++;
475 return (AE_OK);
476}
477
478
479/*******************************************************************************
480 *
481 * FUNCTION: AcpiTbDeleteTable
482 *
483 * PARAMETERS: TableIndex - Table index
484 *
485 * RETURN: None
486 *
487 * DESCRIPTION: Delete one internal ACPI table
488 *
489 ******************************************************************************/
490
491void
492AcpiTbDeleteTable (
493 ACPI_TABLE_DESC *TableDesc)
494{
495
496 /* Table must be mapped or allocated */
497
498 if (!TableDesc->Pointer)
499 {
500 return;
501 }
502
503 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
504 {
505 case ACPI_TABLE_ORIGIN_MAPPED:
506 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
507 break;
508
509 case ACPI_TABLE_ORIGIN_ALLOCATED:
510 ACPI_FREE (TableDesc->Pointer);
511 break;
512
513 /* Not mapped or allocated, there is nothing we can do */
514
515 default:
516 return;
517 }
518
519 TableDesc->Pointer = NULL;
520}
521
522
523/*******************************************************************************
524 *
525 * FUNCTION: AcpiTbTerminate
526 *
527 * PARAMETERS: None
528 *
529 * RETURN: None
530 *
531 * DESCRIPTION: Delete all internal ACPI tables
532 *
533 ******************************************************************************/
534
535void
536AcpiTbTerminate (
537 void)
538{
539 UINT32 i;
540
541
542 ACPI_FUNCTION_TRACE (TbTerminate);
543
544
545 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
546
547 /* Delete the individual tables */
548
549 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
550 {
551 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
552 }
553
554 /*
555 * Delete the root table array if allocated locally. Array cannot be
556 * mapped, so we don't need to check for that flag.
557 */
558 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
559 {
560 ACPI_FREE (AcpiGbl_RootTableList.Tables);
561 }
562
563 AcpiGbl_RootTableList.Tables = NULL;
564 AcpiGbl_RootTableList.Flags = 0;
565 AcpiGbl_RootTableList.CurrentTableCount = 0;
566
567 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
568 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
569}
570
571
572/*******************************************************************************
573 *
574 * FUNCTION: AcpiTbDeleteNamespaceByOwner
575 *
576 * PARAMETERS: TableIndex - Table index
577 *
578 * RETURN: Status
579 *
580 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
581 *
582 ******************************************************************************/
583
584ACPI_STATUS
585AcpiTbDeleteNamespaceByOwner (
586 UINT32 TableIndex)
587{
588 ACPI_OWNER_ID OwnerId;
589 ACPI_STATUS Status;
590
591
592 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
593
594
595 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
596 if (ACPI_FAILURE (Status))
597 {
598 return_ACPI_STATUS (Status);
599 }
600
601 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
602 {
603 /* The table index does not exist */
604
605 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
606 return_ACPI_STATUS (AE_NOT_EXIST);
607 }
608
609 /* Get the owner ID for this table, used to delete namespace nodes */
610
611 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
612 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
613
614 /*
615 * Need to acquire the namespace writer lock to prevent interference
616 * with any concurrent namespace walks. The interpreter must be
617 * released during the deletion since the acquisition of the deletion
618 * lock may block, and also since the execution of a namespace walk
619 * must be allowed to use the interpreter.
620 */
621 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
622 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
623
624 AcpiNsDeleteNamespaceByOwner (OwnerId);
625 if (ACPI_FAILURE (Status))
626 {
627 return_ACPI_STATUS (Status);
628 }
629
630 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
631
632 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
633 return_ACPI_STATUS (Status);
634}
635
636
637/*******************************************************************************
638 *
639 * FUNCTION: AcpiTbAllocateOwnerId
640 *
641 * PARAMETERS: TableIndex - Table index
642 *
643 * RETURN: Status
644 *
645 * DESCRIPTION: Allocates OwnerId in TableDesc
646 *
647 ******************************************************************************/
648
649ACPI_STATUS
650AcpiTbAllocateOwnerId (
651 UINT32 TableIndex)
652{
653 ACPI_STATUS Status = AE_BAD_PARAMETER;
654
655
656 ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
657
658
659 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
660 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
661 {
662 Status = AcpiUtAllocateOwnerId
663 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
664 }
665
666 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
667 return_ACPI_STATUS (Status);
668}
669
670
671/*******************************************************************************
672 *
673 * FUNCTION: AcpiTbReleaseOwnerId
674 *
675 * PARAMETERS: TableIndex - Table index
676 *
677 * RETURN: Status
678 *
679 * DESCRIPTION: Releases OwnerId in TableDesc
680 *
681 ******************************************************************************/
682
683ACPI_STATUS
684AcpiTbReleaseOwnerId (
685 UINT32 TableIndex)
686{
687 ACPI_STATUS Status = AE_BAD_PARAMETER;
688
689
690 ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
691
692
693 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
694 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
695 {
696 AcpiUtReleaseOwnerId (
697 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
698 Status = AE_OK;
699 }
700
701 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
702 return_ACPI_STATUS (Status);
703}
704
705
706/*******************************************************************************
707 *
708 * FUNCTION: AcpiTbGetOwnerId
709 *
710 * PARAMETERS: TableIndex - Table index
711 * OwnerId - Where the table OwnerId is returned
712 *
713 * RETURN: Status
714 *
715 * DESCRIPTION: returns OwnerId for the ACPI table
716 *
717 ******************************************************************************/
718
719ACPI_STATUS
720AcpiTbGetOwnerId (
721 UINT32 TableIndex,
722 ACPI_OWNER_ID *OwnerId)
723{
724 ACPI_STATUS Status = AE_BAD_PARAMETER;
725
726
727 ACPI_FUNCTION_TRACE (TbGetOwnerId);
728
729
730 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
731 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
732 {
733 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
734 Status = AE_OK;
735 }
736
737 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
738 return_ACPI_STATUS (Status);
739}
740
741
742/*******************************************************************************
743 *
744 * FUNCTION: AcpiTbIsTableLoaded
745 *
746 * PARAMETERS: TableIndex - Table index
747 *
748 * RETURN: Table Loaded Flag
749 *
750 ******************************************************************************/
751
752BOOLEAN
753AcpiTbIsTableLoaded (
754 UINT32 TableIndex)
755{
756 BOOLEAN IsLoaded = FALSE;
757
758
759 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
760 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
761 {
762 IsLoaded = (BOOLEAN)
763 (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
764 ACPI_TABLE_IS_LOADED);
765 }
766
767 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
768 return (IsLoaded);
769}
770
771
772/*******************************************************************************
773 *
774 * FUNCTION: AcpiTbSetTableLoadedFlag
775 *
776 * PARAMETERS: TableIndex - Table index
777 * IsLoaded - TRUE if table is loaded, FALSE otherwise
778 *
779 * RETURN: None
780 *
781 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
782 *
783 ******************************************************************************/
784
785void
786AcpiTbSetTableLoadedFlag (
787 UINT32 TableIndex,
788 BOOLEAN IsLoaded)
789{
790
791 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
792 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
793 {
794 if (IsLoaded)
795 {
796 AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
797 ACPI_TABLE_IS_LOADED;
798 }
799 else
800 {
801 AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
802 ~ACPI_TABLE_IS_LOADED;
803 }
804 }
805
806 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
807}
808
163 AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
164 TableDesc->Pointer->Signature : "????",
165 *(UINT32 *) TableDesc->Pointer->Signature));
166
167 return_ACPI_STATUS (AE_BAD_SIGNATURE);
168 }
169
170 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
171
172 /* Check if table is already registered */
173
174 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
175 {
176 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
177 {
178 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
179 if (ACPI_FAILURE (Status) ||
180 !AcpiGbl_RootTableList.Tables[i].Pointer)
181 {
182 continue;
183 }
184 }
185
186 /*
187 * Check for a table match on the entire table length,
188 * not just the header.
189 */
190 if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
191 {
192 continue;
193 }
194
195 if (ACPI_MEMCMP (TableDesc->Pointer,
196 AcpiGbl_RootTableList.Tables[i].Pointer,
197 AcpiGbl_RootTableList.Tables[i].Length))
198 {
199 continue;
200 }
201
202 /*
203 * Note: the current mechanism does not unregister a table if it is
204 * dynamically unloaded. The related namespace entries are deleted,
205 * but the table remains in the root table list.
206 *
207 * The assumption here is that the number of different tables that
208 * will be loaded is actually small, and there is minimal overhead
209 * in just keeping the table in case it is needed again.
210 *
211 * If this assumption changes in the future (perhaps on large
212 * machines with many table load/unload operations), tables will
213 * need to be unregistered when they are unloaded, and slots in the
214 * root table list should be reused when empty.
215 */
216
217 /*
218 * Table is already registered.
219 * We can delete the table that was passed as a parameter.
220 */
221 AcpiTbDeleteTable (TableDesc);
222 *TableIndex = i;
223
224 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
225 {
226 /* Table is still loaded, this is an error */
227
228 Status = AE_ALREADY_EXISTS;
229 goto Release;
230 }
231 else
232 {
233 /* Table was unloaded, allow it to be reloaded */
234
235 TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
236 TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
237 Status = AE_OK;
238 goto PrintHeader;
239 }
240 }
241
242 /*
243 * ACPI Table Override:
244 * Allow the host to override dynamically loaded tables.
245 * NOTE: the table is fully mapped at this point, and the mapping will
246 * be deleted by TbTableOverride if the table is actually overridden.
247 */
248 (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
249
250 /* Add the table to the global root table list */
251
252 Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
253 TableDesc->Length, TableDesc->Flags, TableIndex);
254 if (ACPI_FAILURE (Status))
255 {
256 goto Release;
257 }
258
259PrintHeader:
260 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
261
262Release:
263 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
264 return_ACPI_STATUS (Status);
265}
266
267
268/*******************************************************************************
269 *
270 * FUNCTION: AcpiTbTableOverride
271 *
272 * PARAMETERS: TableHeader - Header for the original table
273 * TableDesc - Table descriptor initialized for the
274 * original table. May or may not be mapped.
275 *
276 * RETURN: Pointer to the entire new table. NULL if table not overridden.
277 * If overridden, installs the new table within the input table
278 * descriptor.
279 *
280 * DESCRIPTION: Attempt table override by calling the OSL override functions.
281 * Note: If the table is overridden, then the entire new table
282 * is mapped and returned by this function.
283 *
284 ******************************************************************************/
285
286ACPI_TABLE_HEADER *
287AcpiTbTableOverride (
288 ACPI_TABLE_HEADER *TableHeader,
289 ACPI_TABLE_DESC *TableDesc)
290{
291 ACPI_STATUS Status;
292 ACPI_TABLE_HEADER *NewTable = NULL;
293 ACPI_PHYSICAL_ADDRESS NewAddress = 0;
294 UINT32 NewTableLength = 0;
295 UINT8 NewFlags;
296 char *OverrideType;
297
298
299 /* (1) Attempt logical override (returns a logical address) */
300
301 Status = AcpiOsTableOverride (TableHeader, &NewTable);
302 if (ACPI_SUCCESS (Status) && NewTable)
303 {
304 NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
305 NewTableLength = NewTable->Length;
306 NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
307 OverrideType = "Logical";
308 goto FinishOverride;
309 }
310
311 /* (2) Attempt physical override (returns a physical address) */
312
313 Status = AcpiOsPhysicalTableOverride (TableHeader,
314 &NewAddress, &NewTableLength);
315 if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
316 {
317 /* Map the entire new table */
318
319 NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
320 if (!NewTable)
321 {
322 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
323 "%4.4s %p Attempted physical table override failed",
324 TableHeader->Signature,
325 ACPI_CAST_PTR (void, TableDesc->Address)));
326 return (NULL);
327 }
328
329 OverrideType = "Physical";
330 NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
331 goto FinishOverride;
332 }
333
334 return (NULL); /* There was no override */
335
336
337FinishOverride:
338
339 ACPI_INFO ((AE_INFO,
340 "%4.4s %p %s table override, new table: %p",
341 TableHeader->Signature,
342 ACPI_CAST_PTR (void, TableDesc->Address),
343 OverrideType, NewTable));
344
345 /* We can now unmap/delete the original table (if fully mapped) */
346
347 AcpiTbDeleteTable (TableDesc);
348
349 /* Setup descriptor for the new table */
350
351 TableDesc->Address = NewAddress;
352 TableDesc->Pointer = NewTable;
353 TableDesc->Length = NewTableLength;
354 TableDesc->Flags = NewFlags;
355
356 return (NewTable);
357}
358
359
360/*******************************************************************************
361 *
362 * FUNCTION: AcpiTbResizeRootTableList
363 *
364 * PARAMETERS: None
365 *
366 * RETURN: Status
367 *
368 * DESCRIPTION: Expand the size of global table array
369 *
370 ******************************************************************************/
371
372ACPI_STATUS
373AcpiTbResizeRootTableList (
374 void)
375{
376 ACPI_TABLE_DESC *Tables;
377
378
379 ACPI_FUNCTION_TRACE (TbResizeRootTableList);
380
381
382 /* AllowResize flag is a parameter to AcpiInitializeTables */
383
384 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
385 {
386 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
387 return_ACPI_STATUS (AE_SUPPORT);
388 }
389
390 /* Increase the Table Array size */
391
392 Tables = ACPI_ALLOCATE_ZEROED (
393 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
394 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
395 sizeof (ACPI_TABLE_DESC));
396 if (!Tables)
397 {
398 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
399 return_ACPI_STATUS (AE_NO_MEMORY);
400 }
401
402 /* Copy and free the previous table array */
403
404 if (AcpiGbl_RootTableList.Tables)
405 {
406 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
407 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
408
409 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
410 {
411 ACPI_FREE (AcpiGbl_RootTableList.Tables);
412 }
413 }
414
415 AcpiGbl_RootTableList.Tables = Tables;
416 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
417 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
418
419 return_ACPI_STATUS (AE_OK);
420}
421
422
423/*******************************************************************************
424 *
425 * FUNCTION: AcpiTbStoreTable
426 *
427 * PARAMETERS: Address - Table address
428 * Table - Table header
429 * Length - Table length
430 * Flags - flags
431 *
432 * RETURN: Status and table index.
433 *
434 * DESCRIPTION: Add an ACPI table to the global table list
435 *
436 ******************************************************************************/
437
438ACPI_STATUS
439AcpiTbStoreTable (
440 ACPI_PHYSICAL_ADDRESS Address,
441 ACPI_TABLE_HEADER *Table,
442 UINT32 Length,
443 UINT8 Flags,
444 UINT32 *TableIndex)
445{
446 ACPI_STATUS Status;
447 ACPI_TABLE_DESC *NewTable;
448
449
450 /* Ensure that there is room for the table in the Root Table List */
451
452 if (AcpiGbl_RootTableList.CurrentTableCount >=
453 AcpiGbl_RootTableList.MaxTableCount)
454 {
455 Status = AcpiTbResizeRootTableList();
456 if (ACPI_FAILURE (Status))
457 {
458 return (Status);
459 }
460 }
461
462 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
463
464 /* Initialize added table */
465
466 NewTable->Address = Address;
467 NewTable->Pointer = Table;
468 NewTable->Length = Length;
469 NewTable->OwnerId = 0;
470 NewTable->Flags = Flags;
471
472 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
473
474 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
475 AcpiGbl_RootTableList.CurrentTableCount++;
476 return (AE_OK);
477}
478
479
480/*******************************************************************************
481 *
482 * FUNCTION: AcpiTbDeleteTable
483 *
484 * PARAMETERS: TableIndex - Table index
485 *
486 * RETURN: None
487 *
488 * DESCRIPTION: Delete one internal ACPI table
489 *
490 ******************************************************************************/
491
492void
493AcpiTbDeleteTable (
494 ACPI_TABLE_DESC *TableDesc)
495{
496
497 /* Table must be mapped or allocated */
498
499 if (!TableDesc->Pointer)
500 {
501 return;
502 }
503
504 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
505 {
506 case ACPI_TABLE_ORIGIN_MAPPED:
507 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
508 break;
509
510 case ACPI_TABLE_ORIGIN_ALLOCATED:
511 ACPI_FREE (TableDesc->Pointer);
512 break;
513
514 /* Not mapped or allocated, there is nothing we can do */
515
516 default:
517 return;
518 }
519
520 TableDesc->Pointer = NULL;
521}
522
523
524/*******************************************************************************
525 *
526 * FUNCTION: AcpiTbTerminate
527 *
528 * PARAMETERS: None
529 *
530 * RETURN: None
531 *
532 * DESCRIPTION: Delete all internal ACPI tables
533 *
534 ******************************************************************************/
535
536void
537AcpiTbTerminate (
538 void)
539{
540 UINT32 i;
541
542
543 ACPI_FUNCTION_TRACE (TbTerminate);
544
545
546 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
547
548 /* Delete the individual tables */
549
550 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
551 {
552 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
553 }
554
555 /*
556 * Delete the root table array if allocated locally. Array cannot be
557 * mapped, so we don't need to check for that flag.
558 */
559 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
560 {
561 ACPI_FREE (AcpiGbl_RootTableList.Tables);
562 }
563
564 AcpiGbl_RootTableList.Tables = NULL;
565 AcpiGbl_RootTableList.Flags = 0;
566 AcpiGbl_RootTableList.CurrentTableCount = 0;
567
568 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
569 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
570}
571
572
573/*******************************************************************************
574 *
575 * FUNCTION: AcpiTbDeleteNamespaceByOwner
576 *
577 * PARAMETERS: TableIndex - Table index
578 *
579 * RETURN: Status
580 *
581 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
582 *
583 ******************************************************************************/
584
585ACPI_STATUS
586AcpiTbDeleteNamespaceByOwner (
587 UINT32 TableIndex)
588{
589 ACPI_OWNER_ID OwnerId;
590 ACPI_STATUS Status;
591
592
593 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
594
595
596 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
597 if (ACPI_FAILURE (Status))
598 {
599 return_ACPI_STATUS (Status);
600 }
601
602 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
603 {
604 /* The table index does not exist */
605
606 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
607 return_ACPI_STATUS (AE_NOT_EXIST);
608 }
609
610 /* Get the owner ID for this table, used to delete namespace nodes */
611
612 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
613 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
614
615 /*
616 * Need to acquire the namespace writer lock to prevent interference
617 * with any concurrent namespace walks. The interpreter must be
618 * released during the deletion since the acquisition of the deletion
619 * lock may block, and also since the execution of a namespace walk
620 * must be allowed to use the interpreter.
621 */
622 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
623 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
624
625 AcpiNsDeleteNamespaceByOwner (OwnerId);
626 if (ACPI_FAILURE (Status))
627 {
628 return_ACPI_STATUS (Status);
629 }
630
631 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
632
633 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
634 return_ACPI_STATUS (Status);
635}
636
637
638/*******************************************************************************
639 *
640 * FUNCTION: AcpiTbAllocateOwnerId
641 *
642 * PARAMETERS: TableIndex - Table index
643 *
644 * RETURN: Status
645 *
646 * DESCRIPTION: Allocates OwnerId in TableDesc
647 *
648 ******************************************************************************/
649
650ACPI_STATUS
651AcpiTbAllocateOwnerId (
652 UINT32 TableIndex)
653{
654 ACPI_STATUS Status = AE_BAD_PARAMETER;
655
656
657 ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
658
659
660 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
661 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
662 {
663 Status = AcpiUtAllocateOwnerId
664 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
665 }
666
667 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
668 return_ACPI_STATUS (Status);
669}
670
671
672/*******************************************************************************
673 *
674 * FUNCTION: AcpiTbReleaseOwnerId
675 *
676 * PARAMETERS: TableIndex - Table index
677 *
678 * RETURN: Status
679 *
680 * DESCRIPTION: Releases OwnerId in TableDesc
681 *
682 ******************************************************************************/
683
684ACPI_STATUS
685AcpiTbReleaseOwnerId (
686 UINT32 TableIndex)
687{
688 ACPI_STATUS Status = AE_BAD_PARAMETER;
689
690
691 ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
692
693
694 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
695 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
696 {
697 AcpiUtReleaseOwnerId (
698 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
699 Status = AE_OK;
700 }
701
702 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
703 return_ACPI_STATUS (Status);
704}
705
706
707/*******************************************************************************
708 *
709 * FUNCTION: AcpiTbGetOwnerId
710 *
711 * PARAMETERS: TableIndex - Table index
712 * OwnerId - Where the table OwnerId is returned
713 *
714 * RETURN: Status
715 *
716 * DESCRIPTION: returns OwnerId for the ACPI table
717 *
718 ******************************************************************************/
719
720ACPI_STATUS
721AcpiTbGetOwnerId (
722 UINT32 TableIndex,
723 ACPI_OWNER_ID *OwnerId)
724{
725 ACPI_STATUS Status = AE_BAD_PARAMETER;
726
727
728 ACPI_FUNCTION_TRACE (TbGetOwnerId);
729
730
731 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
732 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
733 {
734 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
735 Status = AE_OK;
736 }
737
738 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
739 return_ACPI_STATUS (Status);
740}
741
742
743/*******************************************************************************
744 *
745 * FUNCTION: AcpiTbIsTableLoaded
746 *
747 * PARAMETERS: TableIndex - Table index
748 *
749 * RETURN: Table Loaded Flag
750 *
751 ******************************************************************************/
752
753BOOLEAN
754AcpiTbIsTableLoaded (
755 UINT32 TableIndex)
756{
757 BOOLEAN IsLoaded = FALSE;
758
759
760 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
761 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
762 {
763 IsLoaded = (BOOLEAN)
764 (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
765 ACPI_TABLE_IS_LOADED);
766 }
767
768 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
769 return (IsLoaded);
770}
771
772
773/*******************************************************************************
774 *
775 * FUNCTION: AcpiTbSetTableLoadedFlag
776 *
777 * PARAMETERS: TableIndex - Table index
778 * IsLoaded - TRUE if table is loaded, FALSE otherwise
779 *
780 * RETURN: None
781 *
782 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
783 *
784 ******************************************************************************/
785
786void
787AcpiTbSetTableLoadedFlag (
788 UINT32 TableIndex,
789 BOOLEAN IsLoaded)
790{
791
792 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
793 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
794 {
795 if (IsLoaded)
796 {
797 AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
798 ACPI_TABLE_IS_LOADED;
799 }
800 else
801 {
802 AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
803 ~ACPI_TABLE_IS_LOADED;
804 }
805 }
806
807 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
808}
809