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
32 #define _COMPONENT ACPI_TABLES
33 MODULE_NAME ("tbinstal")
36 /*******************************************************************************
38 * FUNCTION: Acpi_tb_install_table
40 * PARAMETERS: Table_ptr - Input buffer pointer, optional
41 * Table_info - Return value from Acpi_tb_get_table
45 * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
46 * already be loaded and validated.
47 * Install the table into the global data structs.
49 ******************************************************************************/
52 acpi_tb_install_table (
53 ACPI_TABLE_HEADER
*table_ptr
,
54 ACPI_TABLE_DESC
*table_info
)
60 * Check the table signature and make sure it is recognized
61 * Also checks the header checksum
64 status
= acpi_tb_recognize_table (table_ptr
, table_info
);
65 if (ACPI_FAILURE (status
)) {
69 /* Lock tables while installing */
71 acpi_cm_acquire_mutex (ACPI_MTX_TABLES
);
73 /* Install the table into the global data structure */
75 status
= acpi_tb_init_table_descriptor (table_info
->type
, table_info
);
77 acpi_cm_release_mutex (ACPI_MTX_TABLES
);
82 /*******************************************************************************
84 * FUNCTION: Acpi_tb_recognize_table
86 * PARAMETERS: Table_ptr - Input buffer pointer, optional
87 * Table_info - Return value from Acpi_tb_get_table
91 * DESCRIPTION: Check a table signature for a match against known table types
93 * NOTE: All table pointers are validated as follows:
94 * 1) Table pointer must point to valid physical memory
95 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
97 * 3) Table must be readable for length specified in the header
98 * 4) Table checksum must be valid (with the exception of the FACS
99 * which has no checksum for some odd reason)
101 ******************************************************************************/
104 acpi_tb_recognize_table (
105 ACPI_TABLE_HEADER
*table_ptr
,
106 ACPI_TABLE_DESC
*table_info
)
108 ACPI_TABLE_HEADER
*table_header
;
110 ACPI_TABLE_TYPE table_type
= 0;
114 /* Ensure that we have a valid table pointer */
116 table_header
= (ACPI_TABLE_HEADER
*) table_info
->pointer
;
118 return (AE_BAD_PARAMETER
);
122 * Search for a signature match among the known table types
123 * Start at index one -> Skip the RSDP
127 for (i
= 1; i
< NUM_ACPI_TABLES
; i
++) {
128 if (!STRNCMP (table_header
->signature
,
129 acpi_gbl_acpi_table_data
[i
].signature
,
130 acpi_gbl_acpi_table_data
[i
].sig_length
)) {
132 * Found a signature match, get the pertinent info from the
133 * Table_data structure
137 status
= acpi_gbl_acpi_table_data
[i
].status
;
143 /* Return the table type and length via the info struct */
145 table_info
->type
= (u8
) table_type
;
146 table_info
->length
= table_header
->length
;
150 * Validate checksum for _most_ tables,
151 * even the ones whose signature we don't recognize
154 if (table_type
!= ACPI_TABLE_FACS
) {
155 /* But don't abort if the checksum is wrong */
156 /* TBD: [Future] make this a configuration option? */
158 acpi_tb_verify_table_checksum (table_header
);
162 * An AE_SUPPORT means that the table was not recognized.
163 * We basically ignore this; just print a debug message
171 /*******************************************************************************
173 * FUNCTION: Acpi_tb_init_table_descriptor
175 * PARAMETERS: Table_type - The type of the table
176 * Table_info - A table info struct
180 * DESCRIPTION: Install a table into the global data structs.
182 ******************************************************************************/
185 acpi_tb_init_table_descriptor (
186 ACPI_TABLE_TYPE table_type
,
187 ACPI_TABLE_DESC
*table_info
)
189 ACPI_TABLE_DESC
*list_head
;
190 ACPI_TABLE_DESC
*table_desc
;
194 * Install the table into the global data structure
197 list_head
= &acpi_gbl_acpi_tables
[table_type
];
198 table_desc
= list_head
;
202 * Two major types of tables: 1) Only one instance is allowed. This
203 * includes most ACPI tables such as the DSDT. 2) Multiple instances of
204 * the table are allowed. This includes SSDT and PSDTs.
207 if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data
[table_type
].flags
)) {
209 * Only one table allowed, and a table has alread been installed
210 * at this location, so return an error.
213 if (list_head
->pointer
) {
217 table_desc
->count
= 1;
223 * Multiple tables allowed for this table type, we must link
224 * the new table in to the list of tables of this type.
227 if (list_head
->pointer
) {
228 table_desc
= acpi_cm_callocate (sizeof (ACPI_TABLE_DESC
));
230 return (AE_NO_MEMORY
);
235 /* Update the original previous */
237 list_head
->prev
->next
= table_desc
;
239 /* Update new entry */
241 table_desc
->prev
= list_head
->prev
;
242 table_desc
->next
= list_head
;
244 /* Update list head */
246 list_head
->prev
= table_desc
;
250 table_desc
->count
= 1;
255 /* Common initialization of the table descriptor */
257 table_desc
->pointer
= table_info
->pointer
;
258 table_desc
->base_pointer
= table_info
->base_pointer
;
259 table_desc
->length
= table_info
->length
;
260 table_desc
->allocation
= table_info
->allocation
;
261 table_desc
->aml_pointer
= (u8
*) (table_desc
->pointer
+ 1),
262 table_desc
->aml_length
= (u32
) (table_desc
->length
-
263 (u32
) sizeof (ACPI_TABLE_HEADER
));
264 table_desc
->table_id
= acpi_cm_allocate_owner_id (OWNER_TYPE_TABLE
);
265 table_desc
->loaded_into_namespace
= FALSE
;
268 * Set the appropriate global pointer (if there is one) to point to the
269 * newly installed table
272 if (acpi_gbl_acpi_table_data
[table_type
].global_ptr
) {
273 *(acpi_gbl_acpi_table_data
[table_type
].global_ptr
) = table_info
->pointer
;
279 table_info
->table_id
= table_desc
->table_id
;
280 table_info
->installed_desc
= table_desc
;
286 /*******************************************************************************
288 * FUNCTION: Acpi_tb_delete_acpi_tables
294 * DESCRIPTION: Delete all internal ACPI tables
296 ******************************************************************************/
299 acpi_tb_delete_acpi_tables (void)
301 ACPI_TABLE_TYPE type
;
305 * Free memory allocated for ACPI tables
306 * Memory can either be mapped or allocated
309 for (type
= 0; type
< NUM_ACPI_TABLES
; type
++) {
310 acpi_tb_delete_acpi_table (type
);
316 /*******************************************************************************
318 * FUNCTION: Acpi_tb_delete_acpi_table
320 * PARAMETERS: Type - The table type to be deleted
324 * DESCRIPTION: Delete an internal ACPI table
325 * Locks the ACPI table mutex
327 ******************************************************************************/
330 acpi_tb_delete_acpi_table (
331 ACPI_TABLE_TYPE type
)
334 if (type
> ACPI_TABLE_MAX
) {
339 acpi_cm_acquire_mutex (ACPI_MTX_TABLES
);
343 acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables
[type
]);
346 /* Clear the appropriate "typed" global table pointer */
349 case ACPI_TABLE_RSDP
:
350 acpi_gbl_RSDP
= NULL
;
353 case ACPI_TABLE_DSDT
:
354 acpi_gbl_DSDT
= NULL
;
357 case ACPI_TABLE_FADT
:
358 acpi_gbl_FADT
= NULL
;
361 case ACPI_TABLE_FACS
:
362 acpi_gbl_FACS
= NULL
;
365 case ACPI_TABLE_XSDT
:
366 acpi_gbl_XSDT
= NULL
;
369 case ACPI_TABLE_SSDT
:
370 case ACPI_TABLE_PSDT
:
375 acpi_cm_release_mutex (ACPI_MTX_TABLES
);
381 /*******************************************************************************
383 * FUNCTION: Acpi_tb_free_acpi_tables_of_type
385 * PARAMETERS: Table_info - A table info struct
389 * DESCRIPTION: Free the memory associated with an internal ACPI table
390 * Table mutex should be locked.
392 ******************************************************************************/
395 acpi_tb_free_acpi_tables_of_type (
396 ACPI_TABLE_DESC
*list_head
)
398 ACPI_TABLE_DESC
*table_desc
;
403 /* Get the head of the list */
405 table_desc
= list_head
;
406 count
= list_head
->count
;
409 * Walk the entire list, deleting both the allocated tables
410 * and the table descriptors
413 for (i
= 0; i
< count
; i
++) {
414 table_desc
= acpi_tb_uninstall_table (table_desc
);
421 /*******************************************************************************
423 * FUNCTION: Acpi_tb_delete_single_table
425 * PARAMETERS: Table_info - A table info struct
429 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where
430 * the table was allocated a buffer or was mapped.
432 ******************************************************************************/
435 acpi_tb_delete_single_table (
436 ACPI_TABLE_DESC
*table_desc
)
443 if (table_desc
->pointer
) {
444 /* Valid table, determine type of memory allocation */
446 switch (table_desc
->allocation
) {
448 case ACPI_MEM_NOT_ALLOCATED
:
452 case ACPI_MEM_ALLOCATED
:
454 acpi_cm_free (table_desc
->base_pointer
);
458 case ACPI_MEM_MAPPED
:
460 acpi_os_unmap_memory (table_desc
->base_pointer
, table_desc
->length
);
467 /*******************************************************************************
469 * FUNCTION: Acpi_tb_uninstall_table
471 * PARAMETERS: Table_info - A table info struct
475 * DESCRIPTION: Free the memory associated with an internal ACPI table that
476 * is either installed or has never been installed.
477 * Table mutex should be locked.
479 ******************************************************************************/
482 acpi_tb_uninstall_table (
483 ACPI_TABLE_DESC
*table_desc
)
485 ACPI_TABLE_DESC
*next_desc
;
493 /* Unlink the descriptor */
495 if (table_desc
->prev
) {
496 table_desc
->prev
->next
= table_desc
->next
;
499 if (table_desc
->next
) {
500 table_desc
->next
->prev
= table_desc
->prev
;
504 /* Free the memory allocated for the table itself */
506 acpi_tb_delete_single_table (table_desc
);
509 /* Free the table descriptor (Don't delete the list head, tho) */
511 if ((table_desc
->prev
) == (table_desc
->next
)) {
515 /* Clear the list head */
517 table_desc
->pointer
= NULL
;
518 table_desc
->length
= 0;
519 table_desc
->count
= 0;
524 /* Free the table descriptor */
526 next_desc
= table_desc
->next
;
527 acpi_cm_free (table_desc
);