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