tbxface.c revision 1.8 1 /******************************************************************************
2 *
3 * Module Name: tbxface - ACPI table-oriented external interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2015, 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
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
183 AcpiReallocateRootTable (
184 void)
185 {
186 ACPI_STATUS Status;
187
188
189 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
190
191
192 /*
193 * Only reallocate the root table if the host provided a static buffer
194 * for the table array in the call to AcpiInitializeTables.
195 */
196 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
197 {
198 return_ACPI_STATUS (AE_SUPPORT);
199 }
200
201 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
202
203 Status = AcpiTbResizeRootTableList ();
204 return_ACPI_STATUS (Status);
205 }
206
207 ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
208
209
210 /*******************************************************************************
211 *
212 * FUNCTION: AcpiGetTableHeader
213 *
214 * PARAMETERS: Signature - ACPI signature of needed table
215 * Instance - Which instance (for SSDTs)
216 * OutTableHeader - The pointer to the table header to fill
217 *
218 * RETURN: Status and pointer to mapped table header
219 *
220 * DESCRIPTION: Finds an ACPI table header.
221 *
222 ******************************************************************************/
223
224 ACPI_STATUS
225 AcpiGetTableHeader (
226 ACPI_CONST_STRING Signature,
227 UINT32 Instance,
228 ACPI_TABLE_HEADER *OutTableHeader)
229 {
230 UINT32 i;
231 UINT32 j;
232 ACPI_TABLE_HEADER *Header;
233 ACPI_STRING USignature = __UNCONST(Signature);
234
235 /* Parameter validation */
236
237 if (!Signature || !OutTableHeader)
238 {
239 return (AE_BAD_PARAMETER);
240 }
241
242 /* Walk the root table list */
243
244 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
245 {
246 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
247 USignature))
248 {
249 continue;
250 }
251
252 if (++j < Instance)
253 {
254 continue;
255 }
256
257 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
258 {
259 if ((AcpiGbl_RootTableList.Tables[i].Flags &
260 ACPI_TABLE_ORIGIN_MASK) ==
261 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
262 {
263 Header = AcpiOsMapMemory (
264 AcpiGbl_RootTableList.Tables[i].Address,
265 sizeof (ACPI_TABLE_HEADER));
266 if (!Header)
267 {
268 return (AE_NO_MEMORY);
269 }
270
271 memcpy (OutTableHeader, Header,
272 sizeof (ACPI_TABLE_HEADER));
273 AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
274 }
275 else
276 {
277 return (AE_NOT_FOUND);
278 }
279 }
280 else
281 {
282 memcpy (OutTableHeader,
283 AcpiGbl_RootTableList.Tables[i].Pointer,
284 sizeof (ACPI_TABLE_HEADER));
285 }
286
287 return (AE_OK);
288 }
289
290 return (AE_NOT_FOUND);
291 }
292
293 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
294
295
296 /*******************************************************************************
297 *
298 * FUNCTION: AcpiGetTable
299 *
300 * PARAMETERS: Signature - ACPI signature of needed table
301 * Instance - Which instance (for SSDTs)
302 * OutTable - Where the pointer to the table is returned
303 *
304 * RETURN: Status and pointer to the requested table
305 *
306 * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
307 * RSDT/XSDT.
308 *
309 ******************************************************************************/
310
311 ACPI_STATUS
312 AcpiGetTable (
313 ACPI_CONST_STRING Signature,
314 UINT32 Instance,
315 ACPI_TABLE_HEADER **OutTable)
316 {
317 UINT32 i;
318 UINT32 j;
319 ACPI_STATUS Status;
320 ACPI_STRING USignature = __UNCONST(Signature);
321
322 /* Parameter validation */
323
324 if (!Signature || !OutTable)
325 {
326 return (AE_BAD_PARAMETER);
327 }
328
329 /* Walk the root table list */
330
331 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
332 {
333 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
334 USignature))
335 {
336 continue;
337 }
338
339 if (++j < Instance)
340 {
341 continue;
342 }
343
344 Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
345 if (ACPI_SUCCESS (Status))
346 {
347 *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
348 }
349
350 return (Status);
351 }
352
353 return (AE_NOT_FOUND);
354 }
355
356 ACPI_EXPORT_SYMBOL (AcpiGetTable)
357
358
359 /*******************************************************************************
360 *
361 * FUNCTION: AcpiGetTableByIndex
362 *
363 * PARAMETERS: TableIndex - Table index
364 * Table - Where the pointer to the table is returned
365 *
366 * RETURN: Status and pointer to the requested table
367 *
368 * DESCRIPTION: Obtain a table by an index into the global table list. Used
369 * internally also.
370 *
371 ******************************************************************************/
372
373 ACPI_STATUS
374 AcpiGetTableByIndex (
375 UINT32 TableIndex,
376 ACPI_TABLE_HEADER **Table)
377 {
378 ACPI_STATUS Status;
379
380
381 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
382
383
384 /* Parameter validation */
385
386 if (!Table)
387 {
388 return_ACPI_STATUS (AE_BAD_PARAMETER);
389 }
390
391 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
392
393 /* Validate index */
394
395 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
396 {
397 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
398 return_ACPI_STATUS (AE_BAD_PARAMETER);
399 }
400
401 if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
402 {
403 /* Table is not mapped, map it */
404
405 Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
406 if (ACPI_FAILURE (Status))
407 {
408 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
409 return_ACPI_STATUS (Status);
410 }
411 }
412
413 *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
414 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
415 return_ACPI_STATUS (AE_OK);
416 }
417
418 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
419
420
421 /*******************************************************************************
422 *
423 * FUNCTION: AcpiInstallTableHandler
424 *
425 * PARAMETERS: Handler - Table event handler
426 * Context - Value passed to the handler on each event
427 *
428 * RETURN: Status
429 *
430 * DESCRIPTION: Install a global table event handler.
431 *
432 ******************************************************************************/
433
434 ACPI_STATUS
435 AcpiInstallTableHandler (
436 ACPI_TABLE_HANDLER Handler,
437 void *Context)
438 {
439 ACPI_STATUS Status;
440
441
442 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
443
444
445 if (!Handler)
446 {
447 return_ACPI_STATUS (AE_BAD_PARAMETER);
448 }
449
450 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
451 if (ACPI_FAILURE (Status))
452 {
453 return_ACPI_STATUS (Status);
454 }
455
456 /* Don't allow more than one handler */
457
458 if (AcpiGbl_TableHandler)
459 {
460 Status = AE_ALREADY_EXISTS;
461 goto Cleanup;
462 }
463
464 /* Install the handler */
465
466 AcpiGbl_TableHandler = Handler;
467 AcpiGbl_TableHandlerContext = Context;
468
469 Cleanup:
470 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
471 return_ACPI_STATUS (Status);
472 }
473
474 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
475
476
477 /*******************************************************************************
478 *
479 * FUNCTION: AcpiRemoveTableHandler
480 *
481 * PARAMETERS: Handler - Table event handler that was installed
482 * previously.
483 *
484 * RETURN: Status
485 *
486 * DESCRIPTION: Remove a table event handler
487 *
488 ******************************************************************************/
489
490 ACPI_STATUS
491 AcpiRemoveTableHandler (
492 ACPI_TABLE_HANDLER Handler)
493 {
494 ACPI_STATUS Status;
495
496
497 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
498
499
500 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
501 if (ACPI_FAILURE (Status))
502 {
503 return_ACPI_STATUS (Status);
504 }
505
506 /* Make sure that the installed handler is the same */
507
508 if (!Handler ||
509 Handler != AcpiGbl_TableHandler)
510 {
511 Status = AE_BAD_PARAMETER;
512 goto Cleanup;
513 }
514
515 /* Remove the handler */
516
517 AcpiGbl_TableHandler = NULL;
518
519 Cleanup:
520 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
521 return_ACPI_STATUS (Status);
522 }
523
524 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
525