1 /******************************************************************************
3 * Module Name: tbinstal - ACPI table installation and removal
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define _COMPONENT ACPI_TABLES
30 MODULE_NAME ("tbinstal")
33 /*******************************************************************************
35 * FUNCTION: Acpi_tb_install_table
37 * PARAMETERS: Table_ptr - Input buffer pointer, optional
38 * Table_info - Return value from Acpi_tb_get_table
42 * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
43 * already be loaded and validated.
44 * Install the table into the global data structs.
46 ******************************************************************************/
49 acpi_tb_install_table (
50 ACPI_TABLE_HEADER
*table_ptr
,
51 ACPI_TABLE_DESC
*table_info
)
57 * Check the table signature and make sure it is recognized
58 * Also checks the header checksum
61 status
= acpi_tb_recognize_table (table_ptr
, table_info
);
62 if (ACPI_FAILURE (status
)) {
66 /* Lock tables while installing */
68 acpi_cm_acquire_mutex (ACPI_MTX_TABLES
);
70 /* Install the table into the global data structure */
72 status
= acpi_tb_init_table_descriptor (table_info
->type
, table_info
);
74 acpi_cm_release_mutex (ACPI_MTX_TABLES
);
79 /*******************************************************************************
81 * FUNCTION: Acpi_tb_recognize_table
83 * PARAMETERS: Table_ptr - Input buffer pointer, optional
84 * Table_info - Return value from Acpi_tb_get_table
88 * DESCRIPTION: Check a table signature for a match against known table types
90 * NOTE: All table pointers are validated as follows:
91 * 1) Table pointer must point to valid physical memory
92 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
94 * 3) Table must be readable for length specified in the header
95 * 4) Table checksum must be valid (with the exception of the FACS
96 * which has no checksum for some odd reason)
98 ******************************************************************************/
101 acpi_tb_recognize_table (
102 ACPI_TABLE_HEADER
*table_ptr
,
103 ACPI_TABLE_DESC
*table_info
)
105 ACPI_TABLE_HEADER
*table_header
;
107 ACPI_TABLE_TYPE table_type
= 0;
111 /* Ensure that we have a valid table pointer */
113 table_header
= (ACPI_TABLE_HEADER
*) table_info
->pointer
;
115 return (AE_BAD_PARAMETER
);
119 * Search for a signature match among the known table types
120 * Start at index one -> Skip the RSDP
124 for (i
= 1; i
< NUM_ACPI_TABLES
; i
++) {
125 if (!STRNCMP (table_header
->signature
,
126 acpi_gbl_acpi_table_data
[i
].signature
,
127 acpi_gbl_acpi_table_data
[i
].sig_length
)) {
129 * Found a signature match, get the pertinent info from the
130 * Table_data structure
134 status
= acpi_gbl_acpi_table_data
[i
].status
;
140 /* Return the table type and length via the info struct */
142 table_info
->type
= (u8
) table_type
;
143 table_info
->length
= table_header
->length
;
147 * Validate checksum for _most_ tables,
148 * even the ones whose signature we don't recognize
151 if (table_type
!= ACPI_TABLE_FACS
) {
152 /* But don't abort if the checksum is wrong */
153 /* TBD: [Future] make this a configuration option? */
155 acpi_tb_verify_table_checksum (table_header
);
159 * An AE_SUPPORT means that the table was not recognized.
160 * We basically ignore this; just print a debug message
168 /*******************************************************************************
170 * FUNCTION: Acpi_tb_init_table_descriptor
172 * PARAMETERS: Table_type - The type of the table
173 * Table_info - A table info struct
177 * DESCRIPTION: Install a table into the global data structs.
179 ******************************************************************************/
182 acpi_tb_init_table_descriptor (
183 ACPI_TABLE_TYPE table_type
,
184 ACPI_TABLE_DESC
*table_info
)
186 ACPI_TABLE_DESC
*list_head
;
187 ACPI_TABLE_DESC
*table_desc
;
191 * Install the table into the global data structure
194 list_head
= &acpi_gbl_acpi_tables
[table_type
];
195 table_desc
= list_head
;
199 * Two major types of tables: 1) Only one instance is allowed. This
200 * includes most ACPI tables such as the DSDT. 2) Multiple instances of
201 * the table are allowed. This includes SSDT and PSDTs.
204 if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data
[table_type
].flags
)) {
206 * Only one table allowed, and a table has alread been installed
207 * at this location, so return an error.
210 if (list_head
->pointer
) {
214 table_desc
->count
= 1;
220 * Multiple tables allowed for this table type, we must link
221 * the new table in to the list of tables of this type.
224 if (list_head
->pointer
) {
225 table_desc
= acpi_cm_callocate (sizeof (ACPI_TABLE_DESC
));
227 return (AE_NO_MEMORY
);
232 /* Update the original previous */
234 list_head
->prev
->next
= table_desc
;
236 /* Update new entry */
238 table_desc
->prev
= list_head
->prev
;
239 table_desc
->next
= list_head
;
241 /* Update list head */
243 list_head
->prev
= table_desc
;
247 table_desc
->count
= 1;
252 /* Common initialization of the table descriptor */
254 table_desc
->pointer
= table_info
->pointer
;
255 table_desc
->base_pointer
= table_info
->base_pointer
;
256 table_desc
->length
= table_info
->length
;
257 table_desc
->allocation
= table_info
->allocation
;
258 table_desc
->aml_pointer
= (u8
*) (table_desc
->pointer
+ 1),
259 table_desc
->aml_length
= (u32
) (table_desc
->length
-
260 (u32
) sizeof (ACPI_TABLE_HEADER
));
261 table_desc
->table_id
= acpi_cm_allocate_owner_id (OWNER_TYPE_TABLE
);
262 table_desc
->loaded_into_namespace
= FALSE
;
265 * Set the appropriate global pointer (if there is one) to point to the
266 * newly installed table
269 if (acpi_gbl_acpi_table_data
[table_type
].global_ptr
) {
270 *(acpi_gbl_acpi_table_data
[table_type
].global_ptr
) = table_info
->pointer
;
276 table_info
->table_id
= table_desc
->table_id
;
277 table_info
->installed_desc
= table_desc
;
283 /*******************************************************************************
285 * FUNCTION: Acpi_tb_delete_acpi_tables
291 * DESCRIPTION: Delete all internal ACPI tables
293 ******************************************************************************/
296 acpi_tb_delete_acpi_tables (void)
298 ACPI_TABLE_TYPE type
;
302 * Free memory allocated for ACPI tables
303 * Memory can either be mapped or allocated
306 for (type
= 0; type
< NUM_ACPI_TABLES
; type
++) {
307 acpi_tb_delete_acpi_table (type
);
313 /*******************************************************************************
315 * FUNCTION: Acpi_tb_delete_acpi_table
317 * PARAMETERS: Type - The table type to be deleted
321 * DESCRIPTION: Delete an internal ACPI table
322 * Locks the ACPI table mutex
324 ******************************************************************************/
327 acpi_tb_delete_acpi_table (
328 ACPI_TABLE_TYPE type
)
331 if (type
> ACPI_TABLE_MAX
) {
336 acpi_cm_acquire_mutex (ACPI_MTX_TABLES
);
340 acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables
[type
]);
343 /* Clear the appropriate "typed" global table pointer */
346 case ACPI_TABLE_RSDP
:
347 acpi_gbl_RSDP
= NULL
;
350 case ACPI_TABLE_DSDT
:
351 acpi_gbl_DSDT
= NULL
;
354 case ACPI_TABLE_FADT
:
355 acpi_gbl_FADT
= NULL
;
358 case ACPI_TABLE_FACS
:
359 acpi_gbl_FACS
= NULL
;
362 case ACPI_TABLE_XSDT
:
363 acpi_gbl_XSDT
= NULL
;
366 case ACPI_TABLE_SSDT
:
367 case ACPI_TABLE_PSDT
:
372 acpi_cm_release_mutex (ACPI_MTX_TABLES
);
378 /*******************************************************************************
380 * FUNCTION: Acpi_tb_free_acpi_tables_of_type
382 * PARAMETERS: Table_info - A table info struct
386 * DESCRIPTION: Free the memory associated with an internal ACPI table
387 * Table mutex should be locked.
389 ******************************************************************************/
392 acpi_tb_free_acpi_tables_of_type (
393 ACPI_TABLE_DESC
*list_head
)
395 ACPI_TABLE_DESC
*table_desc
;
400 /* Get the head of the list */
402 table_desc
= list_head
;
403 count
= list_head
->count
;
406 * Walk the entire list, deleting both the allocated tables
407 * and the table descriptors
410 for (i
= 0; i
< count
; i
++) {
411 table_desc
= acpi_tb_uninstall_table (table_desc
);
418 /*******************************************************************************
420 * FUNCTION: Acpi_tb_delete_single_table
422 * PARAMETERS: Table_info - A table info struct
426 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where
427 * the table was allocated a buffer or was mapped.
429 ******************************************************************************/
432 acpi_tb_delete_single_table (
433 ACPI_TABLE_DESC
*table_desc
)
440 if (table_desc
->pointer
) {
441 /* Valid table, determine type of memory allocation */
443 switch (table_desc
->allocation
) {
445 case ACPI_MEM_NOT_ALLOCATED
:
449 case ACPI_MEM_ALLOCATED
:
451 acpi_cm_free (table_desc
->base_pointer
);
455 case ACPI_MEM_MAPPED
:
457 acpi_os_unmap_memory (table_desc
->base_pointer
, table_desc
->length
);
464 /*******************************************************************************
466 * FUNCTION: Acpi_tb_uninstall_table
468 * PARAMETERS: Table_info - A table info struct
472 * DESCRIPTION: Free the memory associated with an internal ACPI table that
473 * is either installed or has never been installed.
474 * Table mutex should be locked.
476 ******************************************************************************/
479 acpi_tb_uninstall_table (
480 ACPI_TABLE_DESC
*table_desc
)
482 ACPI_TABLE_DESC
*next_desc
;
490 /* Unlink the descriptor */
492 if (table_desc
->prev
) {
493 table_desc
->prev
->next
= table_desc
->next
;
496 if (table_desc
->next
) {
497 table_desc
->next
->prev
= table_desc
->prev
;
501 /* Free the memory allocated for the table itself */
503 acpi_tb_delete_single_table (table_desc
);
506 /* Free the table descriptor (Don't delete the list head, tho) */
508 if ((table_desc
->prev
) == (table_desc
->next
)) {
512 /* Clear the list head */
514 table_desc
->pointer
= NULL
;
515 table_desc
->length
= 0;
516 table_desc
->count
= 0;
521 /* Free the table descriptor */
523 next_desc
= table_desc
->next
;
524 acpi_cm_free (table_desc
);