tbxface.c revision 1.5 1 /******************************************************************************
2 *
3 * Module Name: tbxface - ACPI table-oriented external interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, 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 __TBXFACE_C__
45 #define EXPORT_ACPI_INTERFACES
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "actables.h"
50
51 #define _COMPONENT ACPI_TABLES
52 ACPI_MODULE_NAME ("tbxface")
53
54
55 /*******************************************************************************
56 *
57 * FUNCTION: AcpiAllocateRootTable
58 *
59 * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of
60 * ACPI_TABLE_DESC structures
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
65 * AcpiInitializeTables.
66 *
67 ******************************************************************************/
68
69 ACPI_STATUS
70 AcpiAllocateRootTable (
71 UINT32 InitialTableCount)
72 {
73
74 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
75 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
76
77 return (AcpiTbResizeRootTableList ());
78 }
79
80
81 /*******************************************************************************
82 *
83 * FUNCTION: AcpiInitializeTables
84 *
85 * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated
86 * ACPI_TABLE_DESC structures. If NULL, the
87 * array is dynamically allocated.
88 * InitialTableCount - Size of InitialTableArray, in number of
89 * ACPI_TABLE_DESC structures
90 * AllowResize - Flag to tell Table Manager if resize of
91 * pre-allocated array is allowed. Ignored
92 * if InitialTableArray is NULL.
93 *
94 * RETURN: Status
95 *
96 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
97 *
98 * NOTE: Allows static allocation of the initial table array in order
99 * to avoid the use of dynamic memory in confined environments
100 * such as the kernel boot sequence where it may not be available.
101 *
102 * If the host OS memory managers are initialized, use NULL for
103 * InitialTableArray, and the table will be dynamically allocated.
104 *
105 ******************************************************************************/
106
107 ACPI_STATUS
108 AcpiInitializeTables (
109 ACPI_TABLE_DESC *InitialTableArray,
110 UINT32 InitialTableCount,
111 BOOLEAN AllowResize)
112 {
113 ACPI_PHYSICAL_ADDRESS RsdpAddress;
114 ACPI_STATUS Status;
115
116
117 ACPI_FUNCTION_TRACE (AcpiInitializeTables);
118
119
120 /*
121 * Setup the Root Table Array and allocate the table array
122 * if requested
123 */
124 if (!InitialTableArray)
125 {
126 Status = AcpiAllocateRootTable (InitialTableCount);
127 if (ACPI_FAILURE (Status))
128 {
129 return_ACPI_STATUS (Status);
130 }
131 }
132 else
133 {
134 /* Root Table Array has been statically allocated by the host */
135
136 ACPI_MEMSET (InitialTableArray, 0,
137 (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
138
139 AcpiGbl_RootTableList.Tables = InitialTableArray;
140 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
141 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
142 if (AllowResize)
143 {
144 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
145 }
146 }
147
148 /* Get the address of the RSDP */
149
150 RsdpAddress = AcpiOsGetRootPointer ();
151 if (!RsdpAddress)
152 {
153 return_ACPI_STATUS (AE_NOT_FOUND);
154 }
155
156 /*
157 * Get the root table (RSDT or XSDT) and extract all entries to the local
158 * Root Table Array. This array contains the information of the RSDT/XSDT
159 * in a common, more useable format.
160 */
161 Status = AcpiTbParseRootTable (RsdpAddress);
162 return_ACPI_STATUS (Status);
163 }
164
165 ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeTables)
166
167
168 /*******************************************************************************
169 *
170 * FUNCTION: AcpiReallocateRootTable
171 *
172 * PARAMETERS: None
173 *
174 * RETURN: Status
175 *
176 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
177 * root list from the previously provided scratch area. Should
178 * be called once dynamic memory allocation is available in the
179 * kernel.
180 *
181 ******************************************************************************/
182
183 ACPI_STATUS
184 AcpiReallocateRootTable (
185 void)
186 {
187 ACPI_STATUS Status;
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 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
203
204 Status = AcpiTbResizeRootTableList ();
205 return_ACPI_STATUS (Status);
206 }
207
208 ACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
209
210
211 /*******************************************************************************
212 *
213 * FUNCTION: AcpiGetTableHeader
214 *
215 * PARAMETERS: Signature - ACPI signature of needed table
216 * Instance - Which instance (for SSDTs)
217 * OutTableHeader - The pointer to the table header to fill
218 *
219 * RETURN: Status and pointer to mapped table header
220 *
221 * DESCRIPTION: Finds an ACPI table header.
222 *
223 ******************************************************************************/
224
225 ACPI_STATUS
226 AcpiGetTableHeader (
227 ACPI_CONST_STRING Signature,
228 UINT32 Instance,
229 ACPI_TABLE_HEADER *OutTableHeader)
230 {
231 UINT32 i;
232 UINT32 j;
233 ACPI_TABLE_HEADER *Header;
234 ACPI_STRING USignature = __UNCONST(Signature);
235
236 /* Parameter validation */
237
238 if (!Signature || !OutTableHeader)
239 {
240 return (AE_BAD_PARAMETER);
241 }
242
243 /* Walk the root table list */
244
245 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
246 {
247 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
248 USignature))
249 {
250 continue;
251 }
252
253 if (++j < Instance)
254 {
255 continue;
256 }
257
258 if (!AcpiGbl_RootTableList.Tables[i].Pointer)
259 {
260 if ((AcpiGbl_RootTableList.Tables[i].Flags &
261 ACPI_TABLE_ORIGIN_MASK) ==
262 ACPI_TABLE_ORIGIN_MAPPED)
263 {
264 Header = AcpiOsMapMemory (
265 AcpiGbl_RootTableList.Tables[i].Address,
266 sizeof (ACPI_TABLE_HEADER));
267 if (!Header)
268 {
269 return (AE_NO_MEMORY);
270 }
271
272 ACPI_MEMCPY (OutTableHeader, Header,
273 sizeof (ACPI_TABLE_HEADER));
274 AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
275 }
276 else
277 {
278 return (AE_NOT_FOUND);
279 }
280 }
281 else
282 {
283 ACPI_MEMCPY (OutTableHeader,
284 AcpiGbl_RootTableList.Tables[i].Pointer,
285 sizeof (ACPI_TABLE_HEADER));
286 }
287
288 return (AE_OK);
289 }
290
291 return (AE_NOT_FOUND);
292 }
293
294 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
295
296
297 /*******************************************************************************
298 *
299 * FUNCTION: AcpiGetTable
300 *
301 * PARAMETERS: Signature - ACPI signature of needed table
302 * Instance - Which instance (for SSDTs)
303 * OutTable - Where the pointer to the table is returned
304 *
305 * RETURN: Status and pointer to the requested table
306 *
307 * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
308 * RSDT/XSDT.
309 *
310 ******************************************************************************/
311
312 ACPI_STATUS
313 AcpiGetTable (
314 ACPI_CONST_STRING Signature,
315 UINT32 Instance,
316 ACPI_TABLE_HEADER **OutTable)
317 {
318 UINT32 i;
319 UINT32 j;
320 ACPI_STATUS Status;
321 ACPI_STRING USignature = __UNCONST(Signature);
322
323 /* Parameter validation */
324
325 if (!Signature || !OutTable)
326 {
327 return (AE_BAD_PARAMETER);
328 }
329
330 /* Walk the root table list */
331
332 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
333 {
334 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
335 USignature))
336 {
337 continue;
338 }
339
340 if (++j < Instance)
341 {
342 continue;
343 }
344
345 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
346 if (ACPI_SUCCESS (Status))
347 {
348 *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
349 }
350
351 return (Status);
352 }
353
354 return (AE_NOT_FOUND);
355 }
356
357 ACPI_EXPORT_SYMBOL (AcpiGetTable)
358
359
360 /*******************************************************************************
361 *
362 * FUNCTION: AcpiGetTableByIndex
363 *
364 * PARAMETERS: TableIndex - Table index
365 * Table - Where the pointer to the table is returned
366 *
367 * RETURN: Status and pointer to the requested table
368 *
369 * DESCRIPTION: Obtain a table by an index into the global table list. Used
370 * internally also.
371 *
372 ******************************************************************************/
373
374 ACPI_STATUS
375 AcpiGetTableByIndex (
376 UINT32 TableIndex,
377 ACPI_TABLE_HEADER **Table)
378 {
379 ACPI_STATUS Status;
380
381
382 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
383
384
385 /* Parameter validation */
386
387 if (!Table)
388 {
389 return_ACPI_STATUS (AE_BAD_PARAMETER);
390 }
391
392 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
393
394 /* Validate index */
395
396 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
397 {
398 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
399 return_ACPI_STATUS (AE_BAD_PARAMETER);
400 }
401
402 if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
403 {
404 /* Table is not mapped, map it */
405
406 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
407 if (ACPI_FAILURE (Status))
408 {
409 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
410 return_ACPI_STATUS (Status);
411 }
412 }
413
414 *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
415 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
416 return_ACPI_STATUS (AE_OK);
417 }
418
419 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
420
421
422 /*******************************************************************************
423 *
424 * FUNCTION: AcpiInstallTableHandler
425 *
426 * PARAMETERS: Handler - Table event handler
427 * Context - Value passed to the handler on each event
428 *
429 * RETURN: Status
430 *
431 * DESCRIPTION: Install a global table event handler.
432 *
433 ******************************************************************************/
434
435 ACPI_STATUS
436 AcpiInstallTableHandler (
437 ACPI_TABLE_HANDLER Handler,
438 void *Context)
439 {
440 ACPI_STATUS Status;
441
442
443 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
444
445
446 if (!Handler)
447 {
448 return_ACPI_STATUS (AE_BAD_PARAMETER);
449 }
450
451 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
452 if (ACPI_FAILURE (Status))
453 {
454 return_ACPI_STATUS (Status);
455 }
456
457 /* Don't allow more than one handler */
458
459 if (AcpiGbl_TableHandler)
460 {
461 Status = AE_ALREADY_EXISTS;
462 goto Cleanup;
463 }
464
465 /* Install the handler */
466
467 AcpiGbl_TableHandler = Handler;
468 AcpiGbl_TableHandlerContext = Context;
469
470 Cleanup:
471 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
472 return_ACPI_STATUS (Status);
473 }
474
475 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
476
477
478 /*******************************************************************************
479 *
480 * FUNCTION: AcpiRemoveTableHandler
481 *
482 * PARAMETERS: Handler - Table event handler that was installed
483 * previously.
484 *
485 * RETURN: Status
486 *
487 * DESCRIPTION: Remove a table event handler
488 *
489 ******************************************************************************/
490
491 ACPI_STATUS
492 AcpiRemoveTableHandler (
493 ACPI_TABLE_HANDLER Handler)
494 {
495 ACPI_STATUS Status;
496
497
498 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
499
500
501 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
502 if (ACPI_FAILURE (Status))
503 {
504 return_ACPI_STATUS (Status);
505 }
506
507 /* Make sure that the installed handler is the same */
508
509 if (!Handler ||
510 Handler != AcpiGbl_TableHandler)
511 {
512 Status = AE_BAD_PARAMETER;
513 goto Cleanup;
514 }
515
516 /* Remove the handler */
517
518 AcpiGbl_TableHandler = NULL;
519
520 Cleanup:
521 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
522 return_ACPI_STATUS (Status);
523 }
524
525 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
526