1 | /****************************************************************************** |
2 | * |
3 | * Module Name: tbdata - Table manager data structure functions |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, Intel Corp. |
9 | * All rights reserved. |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions, and the following disclaimer, |
16 | * without modification. |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
18 | * substantially similar to the "NO WARRANTY" disclaimer below |
19 | * ("Disclaimer") and any redistribution must be conditioned upon |
20 | * including a substantially similar Disclaimer requirement for further |
21 | * binary redistribution. |
22 | * 3. Neither the names of the above-listed copyright holders nor the names |
23 | * of any contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. |
25 | * |
26 | * Alternatively, this software may be distributed under the terms of the |
27 | * GNU General Public License ("GPL") version 2 as published by the Free |
28 | * Software Foundation. |
29 | * |
30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ |
43 | |
44 | #include "acpi.h" |
45 | #include "accommon.h" |
46 | #include "acnamesp.h" |
47 | #include "actables.h" |
48 | #include "acevents.h" |
49 | |
50 | #define _COMPONENT ACPI_TABLES |
51 | ACPI_MODULE_NAME ("tbdata" ) |
52 | |
53 | |
54 | /******************************************************************************* |
55 | * |
56 | * FUNCTION: AcpiTbInitTableDescriptor |
57 | * |
58 | * PARAMETERS: TableDesc - Table descriptor |
59 | * Address - Physical address of the table |
60 | * Flags - Allocation flags of the table |
61 | * Table - Pointer to the table |
62 | * |
63 | * RETURN: None |
64 | * |
65 | * DESCRIPTION: Initialize a new table descriptor |
66 | * |
67 | ******************************************************************************/ |
68 | |
69 | void |
70 | AcpiTbInitTableDescriptor ( |
71 | ACPI_TABLE_DESC *TableDesc, |
72 | ACPI_PHYSICAL_ADDRESS Address, |
73 | UINT8 Flags, |
74 | ACPI_TABLE_HEADER *Table) |
75 | { |
76 | |
77 | /* |
78 | * Initialize the table descriptor. Set the pointer to NULL, since the |
79 | * table is not fully mapped at this time. |
80 | */ |
81 | memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); |
82 | TableDesc->Address = Address; |
83 | TableDesc->Length = Table->Length; |
84 | TableDesc->Flags = Flags; |
85 | ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); |
86 | } |
87 | |
88 | |
89 | /******************************************************************************* |
90 | * |
91 | * FUNCTION: AcpiTbAcquireTable |
92 | * |
93 | * PARAMETERS: TableDesc - Table descriptor |
94 | * TablePtr - Where table is returned |
95 | * TableLength - Where table length is returned |
96 | * TableFlags - Where table allocation flags are returned |
97 | * |
98 | * RETURN: Status |
99 | * |
100 | * DESCRIPTION: Acquire an ACPI table. It can be used for tables not |
101 | * maintained in the AcpiGbl_RootTableList. |
102 | * |
103 | ******************************************************************************/ |
104 | |
105 | ACPI_STATUS |
106 | AcpiTbAcquireTable ( |
107 | ACPI_TABLE_DESC *TableDesc, |
108 | ACPI_TABLE_HEADER **TablePtr, |
109 | UINT32 *TableLength, |
110 | UINT8 *TableFlags) |
111 | { |
112 | ACPI_TABLE_HEADER *Table = NULL; |
113 | |
114 | |
115 | switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) |
116 | { |
117 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: |
118 | |
119 | Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); |
120 | break; |
121 | |
122 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: |
123 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: |
124 | |
125 | Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, |
126 | ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); |
127 | break; |
128 | |
129 | default: |
130 | |
131 | break; |
132 | } |
133 | |
134 | /* Table is not valid yet */ |
135 | |
136 | if (!Table) |
137 | { |
138 | return (AE_NO_MEMORY); |
139 | } |
140 | |
141 | /* Fill the return values */ |
142 | |
143 | *TablePtr = Table; |
144 | *TableLength = TableDesc->Length; |
145 | *TableFlags = TableDesc->Flags; |
146 | return (AE_OK); |
147 | } |
148 | |
149 | |
150 | /******************************************************************************* |
151 | * |
152 | * FUNCTION: AcpiTbReleaseTable |
153 | * |
154 | * PARAMETERS: Table - Pointer for the table |
155 | * TableLength - Length for the table |
156 | * TableFlags - Allocation flags for the table |
157 | * |
158 | * RETURN: None |
159 | * |
160 | * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). |
161 | * |
162 | ******************************************************************************/ |
163 | |
164 | void |
165 | AcpiTbReleaseTable ( |
166 | ACPI_TABLE_HEADER *Table, |
167 | UINT32 TableLength, |
168 | UINT8 TableFlags) |
169 | { |
170 | |
171 | switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) |
172 | { |
173 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: |
174 | |
175 | AcpiOsUnmapMemory (Table, TableLength); |
176 | break; |
177 | |
178 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: |
179 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: |
180 | default: |
181 | |
182 | break; |
183 | } |
184 | } |
185 | |
186 | |
187 | /******************************************************************************* |
188 | * |
189 | * FUNCTION: AcpiTbAcquireTempTable |
190 | * |
191 | * PARAMETERS: TableDesc - Table descriptor to be acquired |
192 | * Address - Address of the table |
193 | * Flags - Allocation flags of the table |
194 | * |
195 | * RETURN: Status |
196 | * |
197 | * DESCRIPTION: This function validates the table header to obtain the length |
198 | * of a table and fills the table descriptor to make its state as |
199 | * "INSTALLED". Such a table descriptor is only used for verified |
200 | * installation. |
201 | * |
202 | ******************************************************************************/ |
203 | |
204 | ACPI_STATUS |
205 | AcpiTbAcquireTempTable ( |
206 | ACPI_TABLE_DESC *TableDesc, |
207 | ACPI_PHYSICAL_ADDRESS Address, |
208 | UINT8 Flags) |
209 | { |
210 | ACPI_TABLE_HEADER *; |
211 | |
212 | |
213 | switch (Flags & ACPI_TABLE_ORIGIN_MASK) |
214 | { |
215 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: |
216 | |
217 | /* Get the length of the full table from the header */ |
218 | |
219 | TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); |
220 | if (!TableHeader) |
221 | { |
222 | return (AE_NO_MEMORY); |
223 | } |
224 | |
225 | AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); |
226 | AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); |
227 | return (AE_OK); |
228 | |
229 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: |
230 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: |
231 | |
232 | TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, |
233 | ACPI_PHYSADDR_TO_PTR (Address)); |
234 | if (!TableHeader) |
235 | { |
236 | return (AE_NO_MEMORY); |
237 | } |
238 | |
239 | AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); |
240 | return (AE_OK); |
241 | |
242 | default: |
243 | |
244 | break; |
245 | } |
246 | |
247 | /* Table is not valid yet */ |
248 | |
249 | return (AE_NO_MEMORY); |
250 | } |
251 | |
252 | |
253 | /******************************************************************************* |
254 | * |
255 | * FUNCTION: AcpiTbReleaseTempTable |
256 | * |
257 | * PARAMETERS: TableDesc - Table descriptor to be released |
258 | * |
259 | * RETURN: Status |
260 | * |
261 | * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). |
262 | * |
263 | *****************************************************************************/ |
264 | |
265 | void |
266 | AcpiTbReleaseTempTable ( |
267 | ACPI_TABLE_DESC *TableDesc) |
268 | { |
269 | |
270 | /* |
271 | * Note that the .Address is maintained by the callers of |
272 | * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() |
273 | * where .Address will be freed. |
274 | */ |
275 | AcpiTbInvalidateTable (TableDesc); |
276 | } |
277 | |
278 | |
279 | /****************************************************************************** |
280 | * |
281 | * FUNCTION: AcpiTbValidateTable |
282 | * |
283 | * PARAMETERS: TableDesc - Table descriptor |
284 | * |
285 | * RETURN: Status |
286 | * |
287 | * DESCRIPTION: This function is called to validate the table, the returned |
288 | * table descriptor is in "VALIDATED" state. |
289 | * |
290 | *****************************************************************************/ |
291 | |
292 | ACPI_STATUS |
293 | AcpiTbValidateTable ( |
294 | ACPI_TABLE_DESC *TableDesc) |
295 | { |
296 | ACPI_STATUS Status = AE_OK; |
297 | |
298 | |
299 | ACPI_FUNCTION_TRACE (TbValidateTable); |
300 | |
301 | |
302 | /* Validate the table if necessary */ |
303 | |
304 | if (!TableDesc->Pointer) |
305 | { |
306 | Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, |
307 | &TableDesc->Length, &TableDesc->Flags); |
308 | if (!TableDesc->Pointer) |
309 | { |
310 | Status = AE_NO_MEMORY; |
311 | } |
312 | } |
313 | |
314 | return_ACPI_STATUS (Status); |
315 | } |
316 | |
317 | |
318 | /******************************************************************************* |
319 | * |
320 | * FUNCTION: AcpiTbInvalidateTable |
321 | * |
322 | * PARAMETERS: TableDesc - Table descriptor |
323 | * |
324 | * RETURN: None |
325 | * |
326 | * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of |
327 | * AcpiTbValidateTable(). |
328 | * |
329 | ******************************************************************************/ |
330 | |
331 | void |
332 | AcpiTbInvalidateTable ( |
333 | ACPI_TABLE_DESC *TableDesc) |
334 | { |
335 | |
336 | ACPI_FUNCTION_TRACE (TbInvalidateTable); |
337 | |
338 | |
339 | /* Table must be validated */ |
340 | |
341 | if (!TableDesc->Pointer) |
342 | { |
343 | return_VOID; |
344 | } |
345 | |
346 | AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, |
347 | TableDesc->Flags); |
348 | TableDesc->Pointer = NULL; |
349 | |
350 | return_VOID; |
351 | } |
352 | |
353 | |
354 | /****************************************************************************** |
355 | * |
356 | * FUNCTION: AcpiTbValidateTempTable |
357 | * |
358 | * PARAMETERS: TableDesc - Table descriptor |
359 | * |
360 | * RETURN: Status |
361 | * |
362 | * DESCRIPTION: This function is called to validate the table, the returned |
363 | * table descriptor is in "VALIDATED" state. |
364 | * |
365 | *****************************************************************************/ |
366 | |
367 | ACPI_STATUS |
368 | AcpiTbValidateTempTable ( |
369 | ACPI_TABLE_DESC *TableDesc) |
370 | { |
371 | |
372 | if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum) |
373 | { |
374 | /* |
375 | * Only validates the header of the table. |
376 | * Note that Length contains the size of the mapping after invoking |
377 | * this work around, this value is required by |
378 | * AcpiTbReleaseTempTable(). |
379 | * We can do this because in AcpiInitTableDescriptor(), the Length |
380 | * field of the installed descriptor is filled with the actual |
381 | * table length obtaining from the table header. |
382 | */ |
383 | TableDesc->Length = sizeof (ACPI_TABLE_HEADER); |
384 | } |
385 | |
386 | return (AcpiTbValidateTable (TableDesc)); |
387 | } |
388 | |
389 | |
390 | /****************************************************************************** |
391 | * |
392 | * FUNCTION: AcpiTbVerifyTempTable |
393 | * |
394 | * PARAMETERS: TableDesc - Table descriptor |
395 | * Signature - Table signature to verify |
396 | * |
397 | * RETURN: Status |
398 | * |
399 | * DESCRIPTION: This function is called to validate and verify the table, the |
400 | * returned table descriptor is in "VALIDATED" state. |
401 | * |
402 | *****************************************************************************/ |
403 | |
404 | ACPI_STATUS |
405 | AcpiTbVerifyTempTable ( |
406 | ACPI_TABLE_DESC *TableDesc, |
407 | const char *Signature) |
408 | { |
409 | ACPI_STATUS Status = AE_OK; |
410 | |
411 | |
412 | ACPI_FUNCTION_TRACE (TbVerifyTempTable); |
413 | |
414 | |
415 | /* Validate the table */ |
416 | |
417 | Status = AcpiTbValidateTempTable (TableDesc); |
418 | if (ACPI_FAILURE (Status)) |
419 | { |
420 | return_ACPI_STATUS (AE_NO_MEMORY); |
421 | } |
422 | |
423 | /* If a particular signature is expected (DSDT/FACS), it must match */ |
424 | |
425 | if (Signature && |
426 | !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) |
427 | { |
428 | ACPI_BIOS_ERROR ((AE_INFO, |
429 | "Invalid signature 0x%X for ACPI table, expected [%s]" , |
430 | TableDesc->Signature.Integer, Signature)); |
431 | Status = AE_BAD_SIGNATURE; |
432 | goto InvalidateAndExit; |
433 | } |
434 | |
435 | /* Verify the checksum */ |
436 | |
437 | if (AcpiGbl_VerifyTableChecksum) |
438 | { |
439 | Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); |
440 | if (ACPI_FAILURE (Status)) |
441 | { |
442 | ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, |
443 | "%4.4s 0x%8.8X%8.8X" |
444 | " Attempted table install failed" , |
445 | AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? |
446 | TableDesc->Signature.Ascii : "????" , |
447 | ACPI_FORMAT_UINT64 (TableDesc->Address))); |
448 | |
449 | goto InvalidateAndExit; |
450 | } |
451 | } |
452 | |
453 | return_ACPI_STATUS (AE_OK); |
454 | |
455 | InvalidateAndExit: |
456 | AcpiTbInvalidateTable (TableDesc); |
457 | return_ACPI_STATUS (Status); |
458 | } |
459 | |
460 | |
461 | /******************************************************************************* |
462 | * |
463 | * FUNCTION: AcpiTbResizeRootTableList |
464 | * |
465 | * PARAMETERS: None |
466 | * |
467 | * RETURN: Status |
468 | * |
469 | * DESCRIPTION: Expand the size of global table array |
470 | * |
471 | ******************************************************************************/ |
472 | |
473 | ACPI_STATUS |
474 | AcpiTbResizeRootTableList ( |
475 | void) |
476 | { |
477 | ACPI_TABLE_DESC *Tables; |
478 | UINT32 TableCount; |
479 | |
480 | |
481 | ACPI_FUNCTION_TRACE (TbResizeRootTableList); |
482 | |
483 | |
484 | /* AllowResize flag is a parameter to AcpiInitializeTables */ |
485 | |
486 | if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) |
487 | { |
488 | ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed" )); |
489 | return_ACPI_STATUS (AE_SUPPORT); |
490 | } |
491 | |
492 | /* Increase the Table Array size */ |
493 | |
494 | if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) |
495 | { |
496 | TableCount = AcpiGbl_RootTableList.MaxTableCount; |
497 | } |
498 | else |
499 | { |
500 | TableCount = AcpiGbl_RootTableList.CurrentTableCount; |
501 | } |
502 | |
503 | Tables = ACPI_ALLOCATE_ZEROED ( |
504 | ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * |
505 | sizeof (ACPI_TABLE_DESC)); |
506 | if (!Tables) |
507 | { |
508 | ACPI_ERROR ((AE_INFO, "Could not allocate new root table array" )); |
509 | return_ACPI_STATUS (AE_NO_MEMORY); |
510 | } |
511 | |
512 | /* Copy and free the previous table array */ |
513 | |
514 | if (AcpiGbl_RootTableList.Tables) |
515 | { |
516 | memcpy (Tables, AcpiGbl_RootTableList.Tables, |
517 | (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); |
518 | |
519 | if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) |
520 | { |
521 | ACPI_FREE (AcpiGbl_RootTableList.Tables); |
522 | } |
523 | } |
524 | |
525 | AcpiGbl_RootTableList.Tables = Tables; |
526 | AcpiGbl_RootTableList.MaxTableCount = |
527 | TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; |
528 | AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; |
529 | |
530 | return_ACPI_STATUS (AE_OK); |
531 | } |
532 | |
533 | |
534 | /******************************************************************************* |
535 | * |
536 | * FUNCTION: AcpiTbGetNextTableDescriptor |
537 | * |
538 | * PARAMETERS: TableIndex - Where table index is returned |
539 | * TableDesc - Where table descriptor is returned |
540 | * |
541 | * RETURN: Status and table index/descriptor. |
542 | * |
543 | * DESCRIPTION: Allocate a new ACPI table entry to the global table list |
544 | * |
545 | ******************************************************************************/ |
546 | |
547 | ACPI_STATUS |
548 | AcpiTbGetNextTableDescriptor ( |
549 | UINT32 *TableIndex, |
550 | ACPI_TABLE_DESC **TableDesc) |
551 | { |
552 | ACPI_STATUS Status; |
553 | UINT32 i; |
554 | |
555 | |
556 | /* Ensure that there is room for the table in the Root Table List */ |
557 | |
558 | if (AcpiGbl_RootTableList.CurrentTableCount >= |
559 | AcpiGbl_RootTableList.MaxTableCount) |
560 | { |
561 | Status = AcpiTbResizeRootTableList(); |
562 | if (ACPI_FAILURE (Status)) |
563 | { |
564 | return (Status); |
565 | } |
566 | } |
567 | |
568 | i = AcpiGbl_RootTableList.CurrentTableCount; |
569 | AcpiGbl_RootTableList.CurrentTableCount++; |
570 | |
571 | if (TableIndex) |
572 | { |
573 | *TableIndex = i; |
574 | } |
575 | if (TableDesc) |
576 | { |
577 | *TableDesc = &AcpiGbl_RootTableList.Tables[i]; |
578 | } |
579 | |
580 | return (AE_OK); |
581 | } |
582 | |
583 | |
584 | /******************************************************************************* |
585 | * |
586 | * FUNCTION: AcpiTbTerminate |
587 | * |
588 | * PARAMETERS: None |
589 | * |
590 | * RETURN: None |
591 | * |
592 | * DESCRIPTION: Delete all internal ACPI tables |
593 | * |
594 | ******************************************************************************/ |
595 | |
596 | void |
597 | AcpiTbTerminate ( |
598 | void) |
599 | { |
600 | UINT32 i; |
601 | |
602 | |
603 | ACPI_FUNCTION_TRACE (TbTerminate); |
604 | |
605 | |
606 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
607 | |
608 | /* Delete the individual tables */ |
609 | |
610 | for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) |
611 | { |
612 | AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); |
613 | } |
614 | |
615 | /* |
616 | * Delete the root table array if allocated locally. Array cannot be |
617 | * mapped, so we don't need to check for that flag. |
618 | */ |
619 | if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) |
620 | { |
621 | ACPI_FREE (AcpiGbl_RootTableList.Tables); |
622 | } |
623 | |
624 | AcpiGbl_RootTableList.Tables = NULL; |
625 | AcpiGbl_RootTableList.Flags = 0; |
626 | AcpiGbl_RootTableList.CurrentTableCount = 0; |
627 | |
628 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n" )); |
629 | |
630 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
631 | return_VOID; |
632 | } |
633 | |
634 | |
635 | /******************************************************************************* |
636 | * |
637 | * FUNCTION: AcpiTbDeleteNamespaceByOwner |
638 | * |
639 | * PARAMETERS: TableIndex - Table index |
640 | * |
641 | * RETURN: Status |
642 | * |
643 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. |
644 | * |
645 | ******************************************************************************/ |
646 | |
647 | ACPI_STATUS |
648 | AcpiTbDeleteNamespaceByOwner ( |
649 | UINT32 TableIndex) |
650 | { |
651 | ACPI_OWNER_ID OwnerId; |
652 | ACPI_STATUS Status; |
653 | |
654 | |
655 | ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); |
656 | |
657 | |
658 | Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
659 | if (ACPI_FAILURE (Status)) |
660 | { |
661 | return_ACPI_STATUS (Status); |
662 | } |
663 | |
664 | if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) |
665 | { |
666 | /* The table index does not exist */ |
667 | |
668 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
669 | return_ACPI_STATUS (AE_NOT_EXIST); |
670 | } |
671 | |
672 | /* Get the owner ID for this table, used to delete namespace nodes */ |
673 | |
674 | OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; |
675 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
676 | |
677 | /* |
678 | * Need to acquire the namespace writer lock to prevent interference |
679 | * with any concurrent namespace walks. The interpreter must be |
680 | * released during the deletion since the acquisition of the deletion |
681 | * lock may block, and also since the execution of a namespace walk |
682 | * must be allowed to use the interpreter. |
683 | */ |
684 | Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); |
685 | if (ACPI_FAILURE (Status)) |
686 | { |
687 | return_ACPI_STATUS (Status); |
688 | } |
689 | AcpiNsDeleteNamespaceByOwner (OwnerId); |
690 | AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); |
691 | return_ACPI_STATUS (Status); |
692 | } |
693 | |
694 | |
695 | /******************************************************************************* |
696 | * |
697 | * FUNCTION: AcpiTbAllocateOwnerId |
698 | * |
699 | * PARAMETERS: TableIndex - Table index |
700 | * |
701 | * RETURN: Status |
702 | * |
703 | * DESCRIPTION: Allocates OwnerId in TableDesc |
704 | * |
705 | ******************************************************************************/ |
706 | |
707 | ACPI_STATUS |
708 | AcpiTbAllocateOwnerId ( |
709 | UINT32 TableIndex) |
710 | { |
711 | ACPI_STATUS Status = AE_BAD_PARAMETER; |
712 | |
713 | |
714 | ACPI_FUNCTION_TRACE (TbAllocateOwnerId); |
715 | |
716 | |
717 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
718 | if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) |
719 | { |
720 | Status = AcpiUtAllocateOwnerId ( |
721 | &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); |
722 | } |
723 | |
724 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
725 | return_ACPI_STATUS (Status); |
726 | } |
727 | |
728 | |
729 | /******************************************************************************* |
730 | * |
731 | * FUNCTION: AcpiTbReleaseOwnerId |
732 | * |
733 | * PARAMETERS: TableIndex - Table index |
734 | * |
735 | * RETURN: Status |
736 | * |
737 | * DESCRIPTION: Releases OwnerId in TableDesc |
738 | * |
739 | ******************************************************************************/ |
740 | |
741 | ACPI_STATUS |
742 | AcpiTbReleaseOwnerId ( |
743 | UINT32 TableIndex) |
744 | { |
745 | ACPI_STATUS Status = AE_BAD_PARAMETER; |
746 | |
747 | |
748 | ACPI_FUNCTION_TRACE (TbReleaseOwnerId); |
749 | |
750 | |
751 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
752 | if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) |
753 | { |
754 | AcpiUtReleaseOwnerId ( |
755 | &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); |
756 | Status = AE_OK; |
757 | } |
758 | |
759 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
760 | return_ACPI_STATUS (Status); |
761 | } |
762 | |
763 | |
764 | /******************************************************************************* |
765 | * |
766 | * FUNCTION: AcpiTbGetOwnerId |
767 | * |
768 | * PARAMETERS: TableIndex - Table index |
769 | * OwnerId - Where the table OwnerId is returned |
770 | * |
771 | * RETURN: Status |
772 | * |
773 | * DESCRIPTION: returns OwnerId for the ACPI table |
774 | * |
775 | ******************************************************************************/ |
776 | |
777 | ACPI_STATUS |
778 | AcpiTbGetOwnerId ( |
779 | UINT32 TableIndex, |
780 | ACPI_OWNER_ID *OwnerId) |
781 | { |
782 | ACPI_STATUS Status = AE_BAD_PARAMETER; |
783 | |
784 | |
785 | ACPI_FUNCTION_TRACE (TbGetOwnerId); |
786 | |
787 | |
788 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
789 | if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) |
790 | { |
791 | *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; |
792 | Status = AE_OK; |
793 | } |
794 | |
795 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
796 | return_ACPI_STATUS (Status); |
797 | } |
798 | |
799 | |
800 | /******************************************************************************* |
801 | * |
802 | * FUNCTION: AcpiTbIsTableLoaded |
803 | * |
804 | * PARAMETERS: TableIndex - Index into the root table |
805 | * |
806 | * RETURN: Table Loaded Flag |
807 | * |
808 | ******************************************************************************/ |
809 | |
810 | BOOLEAN |
811 | AcpiTbIsTableLoaded ( |
812 | UINT32 TableIndex) |
813 | { |
814 | BOOLEAN IsLoaded = FALSE; |
815 | |
816 | |
817 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
818 | if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) |
819 | { |
820 | IsLoaded = (BOOLEAN) |
821 | (AcpiGbl_RootTableList.Tables[TableIndex].Flags & |
822 | ACPI_TABLE_IS_LOADED); |
823 | } |
824 | |
825 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
826 | return (IsLoaded); |
827 | } |
828 | |
829 | |
830 | /******************************************************************************* |
831 | * |
832 | * FUNCTION: AcpiTbSetTableLoadedFlag |
833 | * |
834 | * PARAMETERS: TableIndex - Table index |
835 | * IsLoaded - TRUE if table is loaded, FALSE otherwise |
836 | * |
837 | * RETURN: None |
838 | * |
839 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. |
840 | * |
841 | ******************************************************************************/ |
842 | |
843 | void |
844 | AcpiTbSetTableLoadedFlag ( |
845 | UINT32 TableIndex, |
846 | BOOLEAN IsLoaded) |
847 | { |
848 | |
849 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
850 | if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) |
851 | { |
852 | if (IsLoaded) |
853 | { |
854 | AcpiGbl_RootTableList.Tables[TableIndex].Flags |= |
855 | ACPI_TABLE_IS_LOADED; |
856 | } |
857 | else |
858 | { |
859 | AcpiGbl_RootTableList.Tables[TableIndex].Flags &= |
860 | ~ACPI_TABLE_IS_LOADED; |
861 | } |
862 | } |
863 | |
864 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
865 | } |
866 | |
867 | |
868 | /******************************************************************************* |
869 | * |
870 | * FUNCTION: AcpiTbLoadTable |
871 | * |
872 | * PARAMETERS: TableIndex - Table index |
873 | * ParentNode - Where table index is returned |
874 | * |
875 | * RETURN: Status |
876 | * |
877 | * DESCRIPTION: Load an ACPI table |
878 | * |
879 | ******************************************************************************/ |
880 | |
881 | ACPI_STATUS |
882 | AcpiTbLoadTable ( |
883 | UINT32 TableIndex, |
884 | ACPI_NAMESPACE_NODE *ParentNode) |
885 | { |
886 | ACPI_TABLE_HEADER *Table; |
887 | ACPI_STATUS Status; |
888 | ACPI_OWNER_ID OwnerId; |
889 | |
890 | |
891 | ACPI_FUNCTION_TRACE (TbLoadTable); |
892 | |
893 | |
894 | /* |
895 | * Note: Now table is "INSTALLED", it must be validated before |
896 | * using. |
897 | */ |
898 | Status = AcpiGetTableByIndex (TableIndex, &Table); |
899 | if (ACPI_FAILURE (Status)) |
900 | { |
901 | return_ACPI_STATUS (Status); |
902 | } |
903 | |
904 | Status = AcpiNsLoadTable (TableIndex, ParentNode); |
905 | |
906 | /* Execute any module-level code that was found in the table */ |
907 | |
908 | if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) |
909 | { |
910 | AcpiNsExecModuleCodeList (); |
911 | } |
912 | |
913 | /* |
914 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is |
915 | * responsible for discovering any new wake GPEs by running _PRW methods |
916 | * that may have been loaded by this table. |
917 | */ |
918 | Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); |
919 | if (ACPI_SUCCESS (Status)) |
920 | { |
921 | AcpiEvUpdateGpes (OwnerId); |
922 | } |
923 | |
924 | /* Invoke table handler if present */ |
925 | |
926 | if (AcpiGbl_TableHandler) |
927 | { |
928 | (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, |
929 | AcpiGbl_TableHandlerContext); |
930 | } |
931 | |
932 | return_ACPI_STATUS (Status); |
933 | } |
934 | |
935 | |
936 | /******************************************************************************* |
937 | * |
938 | * FUNCTION: AcpiTbInstallAndLoadTable |
939 | * |
940 | * PARAMETERS: Table - Pointer to the table |
941 | * Address - Physical address of the table |
942 | * Flags - Allocation flags of the table |
943 | * TableIndex - Where table index is returned |
944 | * |
945 | * RETURN: Status |
946 | * |
947 | * DESCRIPTION: Install and load an ACPI table |
948 | * |
949 | ******************************************************************************/ |
950 | |
951 | ACPI_STATUS |
952 | AcpiTbInstallAndLoadTable ( |
953 | ACPI_TABLE_HEADER *Table, |
954 | ACPI_PHYSICAL_ADDRESS Address, |
955 | UINT8 Flags, |
956 | BOOLEAN Override, |
957 | UINT32 *TableIndex) |
958 | { |
959 | ACPI_STATUS Status; |
960 | UINT32 i; |
961 | ACPI_OWNER_ID OwnerId; |
962 | |
963 | |
964 | ACPI_FUNCTION_TRACE (AcpiLoadTable); |
965 | |
966 | |
967 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
968 | |
969 | /* Install the table and load it into the namespace */ |
970 | |
971 | Status = AcpiTbInstallStandardTable (Address, Flags, TRUE, |
972 | Override, &i); |
973 | if (ACPI_FAILURE (Status)) |
974 | { |
975 | goto UnlockAndExit; |
976 | } |
977 | |
978 | /* |
979 | * Note: Now table is "INSTALLED", it must be validated before |
980 | * using. |
981 | */ |
982 | Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); |
983 | if (ACPI_FAILURE (Status)) |
984 | { |
985 | goto UnlockAndExit; |
986 | } |
987 | |
988 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
989 | Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); |
990 | |
991 | /* Execute any module-level code that was found in the table */ |
992 | |
993 | if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) |
994 | { |
995 | AcpiNsExecModuleCodeList (); |
996 | } |
997 | |
998 | /* |
999 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is |
1000 | * responsible for discovering any new wake GPEs by running _PRW methods |
1001 | * that may have been loaded by this table. |
1002 | */ |
1003 | Status = AcpiTbGetOwnerId (i, &OwnerId); |
1004 | if (ACPI_SUCCESS (Status)) |
1005 | { |
1006 | AcpiEvUpdateGpes (OwnerId); |
1007 | } |
1008 | |
1009 | /* Invoke table handler if present */ |
1010 | |
1011 | if (AcpiGbl_TableHandler) |
1012 | { |
1013 | (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, |
1014 | AcpiGbl_TableHandlerContext); |
1015 | } |
1016 | (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); |
1017 | |
1018 | UnlockAndExit: |
1019 | *TableIndex = i; |
1020 | (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); |
1021 | return_ACPI_STATUS (Status); |
1022 | } |
1023 | |