Merge trunk HEAD (46152)
[reactos.git] / drivers / bus / acpi / tables / tbinstal.c
1 /******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 * $Revision: 1.1 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
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.
15 *
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.
20 *
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
24 */
25
26
27 #include <acpi.h>
28
29 #define _COMPONENT ACPI_TABLES
30 MODULE_NAME ("tbinstal")
31
32
33 /*******************************************************************************
34 *
35 * FUNCTION: Acpi_tb_install_table
36 *
37 * PARAMETERS: Table_ptr - Input buffer pointer, optional
38 * Table_info - Return value from Acpi_tb_get_table
39 *
40 * RETURN: Status
41 *
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.
45 *
46 ******************************************************************************/
47
48 ACPI_STATUS
49 acpi_tb_install_table (
50 ACPI_TABLE_HEADER *table_ptr,
51 ACPI_TABLE_DESC *table_info)
52 {
53 ACPI_STATUS status;
54
55
56 /*
57 * Check the table signature and make sure it is recognized
58 * Also checks the header checksum
59 */
60
61 status = acpi_tb_recognize_table (table_ptr, table_info);
62 if (ACPI_FAILURE (status)) {
63 return (status);
64 }
65
66 /* Lock tables while installing */
67
68 acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
69
70 /* Install the table into the global data structure */
71
72 status = acpi_tb_init_table_descriptor (table_info->type, table_info);
73
74 acpi_cm_release_mutex (ACPI_MTX_TABLES);
75 return (status);
76 }
77
78
79 /*******************************************************************************
80 *
81 * FUNCTION: Acpi_tb_recognize_table
82 *
83 * PARAMETERS: Table_ptr - Input buffer pointer, optional
84 * Table_info - Return value from Acpi_tb_get_table
85 *
86 * RETURN: Status
87 *
88 * DESCRIPTION: Check a table signature for a match against known table types
89 *
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
93 * name
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)
97 *
98 ******************************************************************************/
99
100 ACPI_STATUS
101 acpi_tb_recognize_table (
102 ACPI_TABLE_HEADER *table_ptr,
103 ACPI_TABLE_DESC *table_info)
104 {
105 ACPI_TABLE_HEADER *table_header;
106 ACPI_STATUS status;
107 ACPI_TABLE_TYPE table_type = 0;
108 u32 i;
109
110
111 /* Ensure that we have a valid table pointer */
112
113 table_header = (ACPI_TABLE_HEADER *) table_info->pointer;
114 if (!table_header) {
115 return (AE_BAD_PARAMETER);
116 }
117
118 /*
119 * Search for a signature match among the known table types
120 * Start at index one -> Skip the RSDP
121 */
122
123 status = AE_SUPPORT;
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)) {
128 /*
129 * Found a signature match, get the pertinent info from the
130 * Table_data structure
131 */
132
133 table_type = i;
134 status = acpi_gbl_acpi_table_data[i].status;
135
136 break;
137 }
138 }
139
140 /* Return the table type and length via the info struct */
141
142 table_info->type = (u8) table_type;
143 table_info->length = table_header->length;
144
145
146 /*
147 * Validate checksum for _most_ tables,
148 * even the ones whose signature we don't recognize
149 */
150
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? */
154
155 acpi_tb_verify_table_checksum (table_header);
156 }
157
158 /*
159 * An AE_SUPPORT means that the table was not recognized.
160 * We basically ignore this; just print a debug message
161 */
162
163
164 return (status);
165 }
166
167
168 /*******************************************************************************
169 *
170 * FUNCTION: Acpi_tb_init_table_descriptor
171 *
172 * PARAMETERS: Table_type - The type of the table
173 * Table_info - A table info struct
174 *
175 * RETURN: None.
176 *
177 * DESCRIPTION: Install a table into the global data structs.
178 *
179 ******************************************************************************/
180
181 ACPI_STATUS
182 acpi_tb_init_table_descriptor (
183 ACPI_TABLE_TYPE table_type,
184 ACPI_TABLE_DESC *table_info)
185 {
186 ACPI_TABLE_DESC *list_head;
187 ACPI_TABLE_DESC *table_desc;
188
189
190 /*
191 * Install the table into the global data structure
192 */
193
194 list_head = &acpi_gbl_acpi_tables[table_type];
195 table_desc = list_head;
196
197
198 /*
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.
202 */
203
204 if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
205 /*
206 * Only one table allowed, and a table has alread been installed
207 * at this location, so return an error.
208 */
209
210 if (list_head->pointer) {
211 return (AE_EXIST);
212 }
213
214 table_desc->count = 1;
215 }
216
217
218 else {
219 /*
220 * Multiple tables allowed for this table type, we must link
221 * the new table in to the list of tables of this type.
222 */
223
224 if (list_head->pointer) {
225 table_desc = acpi_cm_callocate (sizeof (ACPI_TABLE_DESC));
226 if (!table_desc) {
227 return (AE_NO_MEMORY);
228 }
229
230 list_head->count++;
231
232 /* Update the original previous */
233
234 list_head->prev->next = table_desc;
235
236 /* Update new entry */
237
238 table_desc->prev = list_head->prev;
239 table_desc->next = list_head;
240
241 /* Update list head */
242
243 list_head->prev = table_desc;
244 }
245
246 else {
247 table_desc->count = 1;
248 }
249 }
250
251
252 /* Common initialization of the table descriptor */
253
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;
263
264 /*
265 * Set the appropriate global pointer (if there is one) to point to the
266 * newly installed table
267 */
268
269 if (acpi_gbl_acpi_table_data[table_type].global_ptr) {
270 *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer;
271 }
272
273
274 /* Return Data */
275
276 table_info->table_id = table_desc->table_id;
277 table_info->installed_desc = table_desc;
278
279 return (AE_OK);
280 }
281
282
283 /*******************************************************************************
284 *
285 * FUNCTION: Acpi_tb_delete_acpi_tables
286 *
287 * PARAMETERS: None.
288 *
289 * RETURN: None.
290 *
291 * DESCRIPTION: Delete all internal ACPI tables
292 *
293 ******************************************************************************/
294
295 void
296 acpi_tb_delete_acpi_tables (void)
297 {
298 ACPI_TABLE_TYPE type;
299
300
301 /*
302 * Free memory allocated for ACPI tables
303 * Memory can either be mapped or allocated
304 */
305
306 for (type = 0; type < NUM_ACPI_TABLES; type++) {
307 acpi_tb_delete_acpi_table (type);
308 }
309
310 }
311
312
313 /*******************************************************************************
314 *
315 * FUNCTION: Acpi_tb_delete_acpi_table
316 *
317 * PARAMETERS: Type - The table type to be deleted
318 *
319 * RETURN: None.
320 *
321 * DESCRIPTION: Delete an internal ACPI table
322 * Locks the ACPI table mutex
323 *
324 ******************************************************************************/
325
326 void
327 acpi_tb_delete_acpi_table (
328 ACPI_TABLE_TYPE type)
329 {
330
331 if (type > ACPI_TABLE_MAX) {
332 return;
333 }
334
335
336 acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
337
338 /* Free the table */
339
340 acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]);
341
342
343 /* Clear the appropriate "typed" global table pointer */
344
345 switch (type) {
346 case ACPI_TABLE_RSDP:
347 acpi_gbl_RSDP = NULL;
348 break;
349
350 case ACPI_TABLE_DSDT:
351 acpi_gbl_DSDT = NULL;
352 break;
353
354 case ACPI_TABLE_FADT:
355 acpi_gbl_FADT = NULL;
356 break;
357
358 case ACPI_TABLE_FACS:
359 acpi_gbl_FACS = NULL;
360 break;
361
362 case ACPI_TABLE_XSDT:
363 acpi_gbl_XSDT = NULL;
364 break;
365
366 case ACPI_TABLE_SSDT:
367 case ACPI_TABLE_PSDT:
368 default:
369 break;
370 }
371
372 acpi_cm_release_mutex (ACPI_MTX_TABLES);
373
374 return;
375 }
376
377
378 /*******************************************************************************
379 *
380 * FUNCTION: Acpi_tb_free_acpi_tables_of_type
381 *
382 * PARAMETERS: Table_info - A table info struct
383 *
384 * RETURN: None.
385 *
386 * DESCRIPTION: Free the memory associated with an internal ACPI table
387 * Table mutex should be locked.
388 *
389 ******************************************************************************/
390
391 void
392 acpi_tb_free_acpi_tables_of_type (
393 ACPI_TABLE_DESC *list_head)
394 {
395 ACPI_TABLE_DESC *table_desc;
396 u32 count;
397 u32 i;
398
399
400 /* Get the head of the list */
401
402 table_desc = list_head;
403 count = list_head->count;
404
405 /*
406 * Walk the entire list, deleting both the allocated tables
407 * and the table descriptors
408 */
409
410 for (i = 0; i < count; i++) {
411 table_desc = acpi_tb_uninstall_table (table_desc);
412 }
413
414 return;
415 }
416
417
418 /*******************************************************************************
419 *
420 * FUNCTION: Acpi_tb_delete_single_table
421 *
422 * PARAMETERS: Table_info - A table info struct
423 *
424 * RETURN: None.
425 *
426 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where
427 * the table was allocated a buffer or was mapped.
428 *
429 ******************************************************************************/
430
431 void
432 acpi_tb_delete_single_table (
433 ACPI_TABLE_DESC *table_desc)
434 {
435
436 if (!table_desc) {
437 return;
438 }
439
440 if (table_desc->pointer) {
441 /* Valid table, determine type of memory allocation */
442
443 switch (table_desc->allocation) {
444
445 case ACPI_MEM_NOT_ALLOCATED:
446 break;
447
448
449 case ACPI_MEM_ALLOCATED:
450
451 acpi_cm_free (table_desc->base_pointer);
452 break;
453
454
455 case ACPI_MEM_MAPPED:
456
457 acpi_os_unmap_memory (table_desc->base_pointer, table_desc->length);
458 break;
459 }
460 }
461 }
462
463
464 /*******************************************************************************
465 *
466 * FUNCTION: Acpi_tb_uninstall_table
467 *
468 * PARAMETERS: Table_info - A table info struct
469 *
470 * RETURN: None.
471 *
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.
475 *
476 ******************************************************************************/
477
478 ACPI_TABLE_DESC *
479 acpi_tb_uninstall_table (
480 ACPI_TABLE_DESC *table_desc)
481 {
482 ACPI_TABLE_DESC *next_desc;
483
484
485 if (!table_desc) {
486 return (NULL);
487 }
488
489
490 /* Unlink the descriptor */
491
492 if (table_desc->prev) {
493 table_desc->prev->next = table_desc->next;
494 }
495
496 if (table_desc->next) {
497 table_desc->next->prev = table_desc->prev;
498 }
499
500
501 /* Free the memory allocated for the table itself */
502
503 acpi_tb_delete_single_table (table_desc);
504
505
506 /* Free the table descriptor (Don't delete the list head, tho) */
507
508 if ((table_desc->prev) == (table_desc->next)) {
509
510 next_desc = NULL;
511
512 /* Clear the list head */
513
514 table_desc->pointer = NULL;
515 table_desc->length = 0;
516 table_desc->count = 0;
517
518 }
519
520 else {
521 /* Free the table descriptor */
522
523 next_desc = table_desc->next;
524 acpi_cm_free (table_desc);
525 }
526
527
528 return (next_desc);
529 }
530
531