[BROWSEUI] SHExplorerParseCmdLine: Fix parsing of /root (#6752)
[reactos.git] / drivers / bus / acpi / acpica / tables / tbxface.c
1 /******************************************************************************
2 *
3 * Module Name: tbxface - ACPI table-oriented external interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 #define EXPORT_ACPI_INTERFACES
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "actables.h"
49
50 #define _COMPONENT ACPI_TABLES
51 ACPI_MODULE_NAME ("tbxface")
52
53
54 /*******************************************************************************
55 *
56 * FUNCTION: AcpiAllocateRootTable
57 *
58 * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of
59 * ACPI_TABLE_DESC structures
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
64 * AcpiInitializeTables.
65 *
66 ******************************************************************************/
67
68 ACPI_STATUS
69 AcpiAllocateRootTable (
70 UINT32 InitialTableCount)
71 {
72
73 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
74 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
75
76 return (AcpiTbResizeRootTableList ());
77 }
78
79
80 /*******************************************************************************
81 *
82 * FUNCTION: AcpiInitializeTables
83 *
84 * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated
85 * ACPI_TABLE_DESC structures. If NULL, the
86 * array is dynamically allocated.
87 * InitialTableCount - Size of InitialTableArray, in number of
88 * ACPI_TABLE_DESC structures
89 * AllowResize - Flag to tell Table Manager if resize of
90 * pre-allocated array is allowed. Ignored
91 * if InitialTableArray is NULL.
92 *
93 * RETURN: Status
94 *
95 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
96 *
97 * NOTE: Allows static allocation of the initial table array in order
98 * to avoid the use of dynamic memory in confined environments
99 * such as the kernel boot sequence where it may not be available.
100 *
101 * If the host OS memory managers are initialized, use NULL for
102 * InitialTableArray, and the table will be dynamically allocated.
103 *
104 ******************************************************************************/
105
106 ACPI_STATUS ACPI_INIT_FUNCTION
107 AcpiInitializeTables (
108 ACPI_TABLE_DESC *InitialTableArray,
109 UINT32 InitialTableCount,
110 BOOLEAN AllowResize)
111 {
112 ACPI_PHYSICAL_ADDRESS RsdpAddress;
113 ACPI_STATUS Status;
114
115
116 ACPI_FUNCTION_TRACE (AcpiInitializeTables);
117
118
119 /*
120 * Setup the Root Table Array and allocate the table array
121 * if requested
122 */
123 if (!InitialTableArray)
124 {
125 Status = AcpiAllocateRootTable (InitialTableCount);
126 if (ACPI_FAILURE (Status))
127 {
128 return_ACPI_STATUS (Status);
129 }
130 }
131 else
132 {
133 /* Root Table Array has been statically allocated by the host */
134
135 memset (InitialTableArray, 0,
136 (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
137
138 AcpiGbl_RootTableList.Tables = InitialTableArray;
139 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
140 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
141 if (AllowResize)
142 {
143 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
144 }
145 }
146
147 /* Get the address of the RSDP */
148
149 RsdpAddress = AcpiOsGetRootPointer ();
150 if (!RsdpAddress)
151 {
152 return_ACPI_STATUS (AE_NOT_FOUND);
153 }
154
155 /*
156 * Get the root table (RSDT or XSDT) and extract all entries to the local
157 * Root Table Array. This array contains the information of the RSDT/XSDT
158 * in a common, more usable format.
159 */
160 Status = AcpiTbParseRootTable (RsdpAddress);
161 return_ACPI_STATUS (Status);
162 }
163
164 ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeTables)
165
166
167 /*******************************************************************************
168 *
169 * FUNCTION: AcpiReallocateRootTable
170 *
171 * PARAMETERS: None
172 *
173 * RETURN: Status
174 *
175 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
176 * root list from the previously provided scratch area. Should
177 * be called once dynamic memory allocation is available in the
178 * kernel.
179 *
180 ******************************************************************************/
181
182 ACPI_STATUS ACPI_INIT_FUNCTION
183 AcpiReallocateRootTable (
184 void)
185 {
186 ACPI_STATUS Status;
187 ACPI_TABLE_DESC *TableDesc;
188 UINT32 i, j;
189
190
191 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
192
193
194 /*
195 * If there are tables unverified, it is required to reallocate the
196 * root table list to clean up invalid table entries. Otherwise only
197 * reallocate the root table list if the host provided a static buffer
198 * for the table array in the call to AcpiInitializeTables().
199 */
200 if ((AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) &&
201 AcpiGbl_EnableTableValidation)
202 {
203 return_ACPI_STATUS (AE_SUPPORT);
204 }
205
206 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
207
208 /*
209 * Ensure OS early boot logic, which is required by some hosts. If the
210 * table state is reported to be wrong, developers should fix the
211 * issue by invoking AcpiPutTable() for the reported table during the
212 * early stage.
213 */
214 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
215 {
216 TableDesc = &AcpiGbl_RootTableList.Tables[i];
217 if (TableDesc->Pointer)
218 {
219 ACPI_ERROR ((AE_INFO,
220 "Table [%4.4s] is not invalidated during early boot stage",
221 TableDesc->Signature.Ascii));
222 }
223 }
224
225 if (!AcpiGbl_EnableTableValidation)
226 {
227 /*
228 * Now it's safe to do full table validation. We can do deferred
229 * table initialization here once the flag is set.
230 */
231 AcpiGbl_EnableTableValidation = TRUE;
232 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
233 {
234 TableDesc = &AcpiGbl_RootTableList.Tables[i];
235 if (!(TableDesc->Flags & ACPI_TABLE_IS_VERIFIED))
236 {
237 Status = AcpiTbVerifyTempTable (TableDesc, NULL, &j);
238 if (ACPI_FAILURE (Status))
239 {
240 AcpiTbUninstallTable (TableDesc);
241 }
242 }
243 }
244 }
245
246 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
247 Status = AcpiTbResizeRootTableList ();
248 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
249
250 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
251 return_ACPI_STATUS (Status);
252 }
253
254 ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
255
256
257 /*******************************************************************************
258 *
259 * FUNCTION: AcpiGetTableHeader
260 *
261 * PARAMETERS: Signature - ACPI signature of needed table
262 * Instance - Which instance (for SSDTs)
263 * OutTableHeader - The pointer to the where the table header
264 * is returned
265 *
266 * RETURN: Status and a copy of the table header
267 *
268 * DESCRIPTION: Finds and returns an ACPI table header. Caller provides the
269 * memory where a copy of the header is to be returned
270 * (fixed length).
271 *
272 ******************************************************************************/
273
274 ACPI_STATUS
275 AcpiGetTableHeader (
276 char *Signature,
277 UINT32 Instance,
278 ACPI_TABLE_HEADER *OutTableHeader)
279 {
280 UINT32 i;
281 UINT32 j;
282 ACPI_TABLE_HEADER *Header;
283
284
285 /* Parameter validation */
286
287 if (!Signature || !OutTableHeader)
288 {
289 return (AE_BAD_PARAMETER);
290 }
291
292 /* Walk the root table list */
293
294 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
295 {
296 if (!ACPI_COMPARE_NAMESEG (
297 &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
298 {
299 continue;
300 }
301
302 if (++j < Instance)
303 {
304 continue;
305 }
306
307 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
308 {
309 if ((AcpiGbl_RootTableList.Tables[i].Flags &
310 ACPI_TABLE_ORIGIN_MASK) ==
311 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
312 {
313 Header = AcpiOsMapMemory (
314 AcpiGbl_RootTableList.Tables[i].Address,
315 sizeof (ACPI_TABLE_HEADER));
316 if (!Header)
317 {
318 return (AE_NO_MEMORY);
319 }
320
321 memcpy (OutTableHeader, Header, sizeof (ACPI_TABLE_HEADER));
322 AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
323 }
324 else
325 {
326 return (AE_NOT_FOUND);
327 }
328 }
329 else
330 {
331 memcpy (OutTableHeader,
332 AcpiGbl_RootTableList.Tables[i].Pointer,
333 sizeof (ACPI_TABLE_HEADER));
334 }
335
336 return (AE_OK);
337 }
338
339 return (AE_NOT_FOUND);
340 }
341
342 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
343
344
345 /*******************************************************************************
346 *
347 * FUNCTION: AcpiGetTable
348 *
349 * PARAMETERS: Signature - ACPI signature of needed table
350 * Instance - Which instance (for SSDTs)
351 * OutTable - Where the pointer to the table is returned
352 *
353 * RETURN: Status and pointer to the requested table
354 *
355 * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
356 * RSDT/XSDT.
357 * Note that an early stage AcpiGetTable() call must be paired
358 * with an early stage AcpiPutTable() call. otherwise the table
359 * pointer mapped by the early stage mapping implementation may be
360 * erroneously unmapped by the late stage unmapping implementation
361 * in an AcpiPutTable() invoked during the late stage.
362 *
363 ******************************************************************************/
364
365 ACPI_STATUS
366 AcpiGetTable (
367 char *Signature,
368 UINT32 Instance,
369 ACPI_TABLE_HEADER **OutTable)
370 {
371 UINT32 i;
372 UINT32 j;
373 ACPI_STATUS Status = AE_NOT_FOUND;
374 ACPI_TABLE_DESC *TableDesc;
375
376
377 /* Parameter validation */
378
379 if (!Signature || !OutTable)
380 {
381 return (AE_BAD_PARAMETER);
382 }
383
384 /*
385 * Note that the following line is required by some OSPMs, they only
386 * check if the returned table is NULL instead of the returned status
387 * to determined if this function is succeeded.
388 */
389 *OutTable = NULL;
390
391 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
392
393 /* Walk the root table list */
394
395 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
396 {
397 TableDesc = &AcpiGbl_RootTableList.Tables[i];
398
399 if (!ACPI_COMPARE_NAMESEG (&TableDesc->Signature, Signature))
400 {
401 continue;
402 }
403
404 if (++j < Instance)
405 {
406 continue;
407 }
408
409 Status = AcpiTbGetTable (TableDesc, OutTable);
410 break;
411 }
412
413 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
414 return (Status);
415 }
416
417 ACPI_EXPORT_SYMBOL (AcpiGetTable)
418
419
420 /*******************************************************************************
421 *
422 * FUNCTION: AcpiPutTable
423 *
424 * PARAMETERS: Table - The pointer to the table
425 *
426 * RETURN: None
427 *
428 * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones.
429 * Note that it is not safe if this function was invoked after an
430 * uninstallation happened to the original table descriptor.
431 * Currently there is no OSPMs' requirement to handle such
432 * situations.
433 *
434 ******************************************************************************/
435
436 void
437 AcpiPutTable (
438 ACPI_TABLE_HEADER *Table)
439 {
440 UINT32 i;
441 ACPI_TABLE_DESC *TableDesc;
442
443
444 ACPI_FUNCTION_TRACE (AcpiPutTable);
445
446
447 if (!Table)
448 {
449 return_VOID;
450 }
451
452 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
453
454 /* Walk the root table list */
455
456 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
457 {
458 TableDesc = &AcpiGbl_RootTableList.Tables[i];
459
460 if (TableDesc->Pointer != Table)
461 {
462 continue;
463 }
464
465 AcpiTbPutTable (TableDesc);
466 break;
467 }
468
469 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
470 return_VOID;
471 }
472
473 ACPI_EXPORT_SYMBOL (AcpiPutTable)
474
475
476 /*******************************************************************************
477 *
478 * FUNCTION: AcpiGetTableByIndex
479 *
480 * PARAMETERS: TableIndex - Table index
481 * OutTable - Where the pointer to the table is returned
482 *
483 * RETURN: Status and pointer to the requested table
484 *
485 * DESCRIPTION: Obtain a table by an index into the global table list. Used
486 * internally also.
487 *
488 ******************************************************************************/
489
490 ACPI_STATUS
491 AcpiGetTableByIndex (
492 UINT32 TableIndex,
493 ACPI_TABLE_HEADER **OutTable)
494 {
495 ACPI_STATUS Status;
496
497
498 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
499
500
501 /* Parameter validation */
502
503 if (!OutTable)
504 {
505 return_ACPI_STATUS (AE_BAD_PARAMETER);
506 }
507
508 /*
509 * Note that the following line is required by some OSPMs, they only
510 * check if the returned table is NULL instead of the returned status
511 * to determined if this function is succeeded.
512 */
513 *OutTable = NULL;
514
515 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
516
517 /* Validate index */
518
519 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
520 {
521 Status = AE_BAD_PARAMETER;
522 goto UnlockAndExit;
523 }
524
525 Status = AcpiTbGetTable (
526 &AcpiGbl_RootTableList.Tables[TableIndex], OutTable);
527
528 UnlockAndExit:
529 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
530 return_ACPI_STATUS (Status);
531 }
532
533 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
534
535
536 /*******************************************************************************
537 *
538 * FUNCTION: AcpiInstallTableHandler
539 *
540 * PARAMETERS: Handler - Table event handler
541 * Context - Value passed to the handler on each event
542 *
543 * RETURN: Status
544 *
545 * DESCRIPTION: Install a global table event handler.
546 *
547 ******************************************************************************/
548
549 ACPI_STATUS
550 AcpiInstallTableHandler (
551 ACPI_TABLE_HANDLER Handler,
552 void *Context)
553 {
554 ACPI_STATUS Status;
555
556
557 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
558
559
560 if (!Handler)
561 {
562 return_ACPI_STATUS (AE_BAD_PARAMETER);
563 }
564
565 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
566 if (ACPI_FAILURE (Status))
567 {
568 return_ACPI_STATUS (Status);
569 }
570
571 /* Don't allow more than one handler */
572
573 if (AcpiGbl_TableHandler)
574 {
575 Status = AE_ALREADY_EXISTS;
576 goto Cleanup;
577 }
578
579 /* Install the handler */
580
581 AcpiGbl_TableHandler = Handler;
582 AcpiGbl_TableHandlerContext = Context;
583
584 Cleanup:
585 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
586 return_ACPI_STATUS (Status);
587 }
588
589 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
590
591
592 /*******************************************************************************
593 *
594 * FUNCTION: AcpiRemoveTableHandler
595 *
596 * PARAMETERS: Handler - Table event handler that was installed
597 * previously.
598 *
599 * RETURN: Status
600 *
601 * DESCRIPTION: Remove a table event handler
602 *
603 ******************************************************************************/
604
605 ACPI_STATUS
606 AcpiRemoveTableHandler (
607 ACPI_TABLE_HANDLER Handler)
608 {
609 ACPI_STATUS Status;
610
611
612 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
613
614
615 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
616 if (ACPI_FAILURE (Status))
617 {
618 return_ACPI_STATUS (Status);
619 }
620
621 /* Make sure that the installed handler is the same */
622
623 if (!Handler ||
624 Handler != AcpiGbl_TableHandler)
625 {
626 Status = AE_BAD_PARAMETER;
627 goto Cleanup;
628 }
629
630 /* Remove the handler */
631
632 AcpiGbl_TableHandler = NULL;
633
634 Cleanup:
635 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
636 return_ACPI_STATUS (Status);
637 }
638
639 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)