[ACPICA]
[reactos.git] / reactos / 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 - 2017, 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 #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 useable 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 UINT32 i;
188
189
190 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
191
192
193 /*
194 * Only reallocate the root table if the host provided a static buffer
195 * for the table array in the call to AcpiInitializeTables.
196 */
197 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
198 {
199 return_ACPI_STATUS (AE_SUPPORT);
200 }
201
202 /*
203 * Ensure OS early boot logic, which is required by some hosts. If the
204 * table state is reported to be wrong, developers should fix the
205 * issue by invoking AcpiPutTable() for the reported table during the
206 * early stage.
207 */
208 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
209 {
210 if (AcpiGbl_RootTableList.Tables[i].Pointer)
211 {
212 ACPI_ERROR ((AE_INFO,
213 "Table [%4.4s] is not invalidated during early boot stage",
214 AcpiGbl_RootTableList.Tables[i].Signature.Ascii));
215 }
216 }
217
218 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
219
220 Status = AcpiTbResizeRootTableList ();
221 return_ACPI_STATUS (Status);
222 }
223
224 ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
225
226
227 /*******************************************************************************
228 *
229 * FUNCTION: AcpiGetTableHeader
230 *
231 * PARAMETERS: Signature - ACPI signature of needed table
232 * Instance - Which instance (for SSDTs)
233 * OutTableHeader - The pointer to the table header to fill
234 *
235 * RETURN: Status and pointer to mapped table header
236 *
237 * DESCRIPTION: Finds an ACPI table header.
238 *
239 * NOTE: Caller is responsible in unmapping the header with
240 * AcpiOsUnmapMemory
241 *
242 ******************************************************************************/
243
244 ACPI_STATUS
245 AcpiGetTableHeader (
246 char *Signature,
247 UINT32 Instance,
248 ACPI_TABLE_HEADER *OutTableHeader)
249 {
250 UINT32 i;
251 UINT32 j;
252 ACPI_TABLE_HEADER *Header;
253
254
255 /* Parameter validation */
256
257 if (!Signature || !OutTableHeader)
258 {
259 return (AE_BAD_PARAMETER);
260 }
261
262 /* Walk the root table list */
263
264 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
265 {
266 if (!ACPI_COMPARE_NAME (
267 &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
268 {
269 continue;
270 }
271
272 if (++j < Instance)
273 {
274 continue;
275 }
276
277 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
278 {
279 if ((AcpiGbl_RootTableList.Tables[i].Flags &
280 ACPI_TABLE_ORIGIN_MASK) ==
281 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
282 {
283 Header = AcpiOsMapMemory (
284 AcpiGbl_RootTableList.Tables[i].Address,
285 sizeof (ACPI_TABLE_HEADER));
286 if (!Header)
287 {
288 return (AE_NO_MEMORY);
289 }
290
291 memcpy (OutTableHeader, Header, sizeof (ACPI_TABLE_HEADER));
292 AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
293 }
294 else
295 {
296 return (AE_NOT_FOUND);
297 }
298 }
299 else
300 {
301 memcpy (OutTableHeader,
302 AcpiGbl_RootTableList.Tables[i].Pointer,
303 sizeof (ACPI_TABLE_HEADER));
304 }
305
306 return (AE_OK);
307 }
308
309 return (AE_NOT_FOUND);
310 }
311
312 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
313
314
315 /*******************************************************************************
316 *
317 * FUNCTION: AcpiGetTable
318 *
319 * PARAMETERS: Signature - ACPI signature of needed table
320 * Instance - Which instance (for SSDTs)
321 * OutTable - Where the pointer to the table is returned
322 *
323 * RETURN: Status and pointer to the requested table
324 *
325 * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
326 * RSDT/XSDT.
327 * Note that an early stage AcpiGetTable() call must be paired
328 * with an early stage AcpiPutTable() call. otherwise the table
329 * pointer mapped by the early stage mapping implementation may be
330 * erroneously unmapped by the late stage unmapping implementation
331 * in an AcpiPutTable() invoked during the late stage.
332 *
333 ******************************************************************************/
334
335 ACPI_STATUS
336 AcpiGetTable (
337 char *Signature,
338 UINT32 Instance,
339 ACPI_TABLE_HEADER **OutTable)
340 {
341 UINT32 i;
342 UINT32 j;
343 ACPI_STATUS Status = AE_NOT_FOUND;
344 ACPI_TABLE_DESC *TableDesc;
345
346
347 /* Parameter validation */
348
349 if (!Signature || !OutTable)
350 {
351 return (AE_BAD_PARAMETER);
352 }
353
354 /*
355 * Note that the following line is required by some OSPMs, they only
356 * check if the returned table is NULL instead of the returned status
357 * to determined if this function is succeeded.
358 */
359 *OutTable = NULL;
360
361 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
362
363 /* Walk the root table list */
364
365 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
366 {
367 TableDesc = &AcpiGbl_RootTableList.Tables[i];
368
369 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
370 {
371 continue;
372 }
373
374 if (++j < Instance)
375 {
376 continue;
377 }
378
379 Status = AcpiTbGetTable (TableDesc, OutTable);
380 break;
381 }
382
383 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
384 return (Status);
385 }
386
387 ACPI_EXPORT_SYMBOL (AcpiGetTable)
388
389
390 /*******************************************************************************
391 *
392 * FUNCTION: AcpiPutTable
393 *
394 * PARAMETERS: Table - The pointer to the table
395 *
396 * RETURN: None
397 *
398 * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones.
399 * Note that it is not safe if this function was invoked after an
400 * uninstallation happened to the original table descriptor.
401 * Currently there is no OSPMs' requirement to handle such
402 * situations.
403 *
404 ******************************************************************************/
405
406 void
407 AcpiPutTable (
408 ACPI_TABLE_HEADER *Table)
409 {
410 UINT32 i;
411 ACPI_TABLE_DESC *TableDesc;
412
413
414 ACPI_FUNCTION_TRACE (AcpiPutTable);
415
416
417 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
418
419 /* Walk the root table list */
420
421 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
422 {
423 TableDesc = &AcpiGbl_RootTableList.Tables[i];
424
425 if (TableDesc->Pointer != Table)
426 {
427 continue;
428 }
429
430 AcpiTbPutTable (TableDesc);
431 break;
432 }
433
434 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
435 return_VOID;
436 }
437
438 ACPI_EXPORT_SYMBOL (AcpiPutTable)
439
440
441 /*******************************************************************************
442 *
443 * FUNCTION: AcpiGetTableByIndex
444 *
445 * PARAMETERS: TableIndex - Table index
446 * OutTable - Where the pointer to the table is returned
447 *
448 * RETURN: Status and pointer to the requested table
449 *
450 * DESCRIPTION: Obtain a table by an index into the global table list. Used
451 * internally also.
452 *
453 ******************************************************************************/
454
455 ACPI_STATUS
456 AcpiGetTableByIndex (
457 UINT32 TableIndex,
458 ACPI_TABLE_HEADER **OutTable)
459 {
460 ACPI_STATUS Status;
461
462
463 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
464
465
466 /* Parameter validation */
467
468 if (!OutTable)
469 {
470 return_ACPI_STATUS (AE_BAD_PARAMETER);
471 }
472
473 /*
474 * Note that the following line is required by some OSPMs, they only
475 * check if the returned table is NULL instead of the returned status
476 * to determined if this function is succeeded.
477 */
478 *OutTable = NULL;
479
480 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
481
482 /* Validate index */
483
484 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
485 {
486 Status = AE_BAD_PARAMETER;
487 goto UnlockAndExit;
488 }
489
490 Status = AcpiTbGetTable (
491 &AcpiGbl_RootTableList.Tables[TableIndex], OutTable);
492
493 UnlockAndExit:
494 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
495 return_ACPI_STATUS (Status);
496 }
497
498 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
499
500
501 /*******************************************************************************
502 *
503 * FUNCTION: AcpiInstallTableHandler
504 *
505 * PARAMETERS: Handler - Table event handler
506 * Context - Value passed to the handler on each event
507 *
508 * RETURN: Status
509 *
510 * DESCRIPTION: Install a global table event handler.
511 *
512 ******************************************************************************/
513
514 ACPI_STATUS
515 AcpiInstallTableHandler (
516 ACPI_TABLE_HANDLER Handler,
517 void *Context)
518 {
519 ACPI_STATUS Status;
520
521
522 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
523
524
525 if (!Handler)
526 {
527 return_ACPI_STATUS (AE_BAD_PARAMETER);
528 }
529
530 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
531 if (ACPI_FAILURE (Status))
532 {
533 return_ACPI_STATUS (Status);
534 }
535
536 /* Don't allow more than one handler */
537
538 if (AcpiGbl_TableHandler)
539 {
540 Status = AE_ALREADY_EXISTS;
541 goto Cleanup;
542 }
543
544 /* Install the handler */
545
546 AcpiGbl_TableHandler = Handler;
547 AcpiGbl_TableHandlerContext = Context;
548
549 Cleanup:
550 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
551 return_ACPI_STATUS (Status);
552 }
553
554 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
555
556
557 /*******************************************************************************
558 *
559 * FUNCTION: AcpiRemoveTableHandler
560 *
561 * PARAMETERS: Handler - Table event handler that was installed
562 * previously.
563 *
564 * RETURN: Status
565 *
566 * DESCRIPTION: Remove a table event handler
567 *
568 ******************************************************************************/
569
570 ACPI_STATUS
571 AcpiRemoveTableHandler (
572 ACPI_TABLE_HANDLER Handler)
573 {
574 ACPI_STATUS Status;
575
576
577 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
578
579
580 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
581 if (ACPI_FAILURE (Status))
582 {
583 return_ACPI_STATUS (Status);
584 }
585
586 /* Make sure that the installed handler is the same */
587
588 if (!Handler ||
589 Handler != AcpiGbl_TableHandler)
590 {
591 Status = AE_BAD_PARAMETER;
592 goto Cleanup;
593 }
594
595 /* Remove the handler */
596
597 AcpiGbl_TableHandler = NULL;
598
599 Cleanup:
600 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
601 return_ACPI_STATUS (Status);
602 }
603
604 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)