- Update to new ACPI driver by Samuel Serapion (and fixes by me)
[reactos.git] / reactos / drivers / bus / acpi / acpica / tables / tbget.c
1 /******************************************************************************
2 *
3 * Module Name: tbget - ACPI Table get* routines
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 ("tbget")
31
32 #define RSDP_CHECKSUM_LENGTH 20
33
34 /*******************************************************************************
35 *
36 * FUNCTION: Acpi_tb_get_table_ptr
37 *
38 * PARAMETERS: Table_type - one of the defined table types
39 * Instance - Which table of this type
40 * Table_ptr_loc - pointer to location to place the pointer for
41 * return
42 *
43 * RETURN: Status
44 *
45 * DESCRIPTION: This function is called to get the pointer to an ACPI table.
46 *
47 ******************************************************************************/
48
49 ACPI_STATUS
50 acpi_tb_get_table_ptr (
51 ACPI_TABLE_TYPE table_type,
52 u32 instance,
53 ACPI_TABLE_HEADER **table_ptr_loc)
54 {
55 ACPI_TABLE_DESC *table_desc;
56 u32 i;
57
58
59 if (!acpi_gbl_DSDT) {
60 return (AE_NO_ACPI_TABLES);
61 }
62
63 if (table_type > ACPI_TABLE_MAX) {
64 return (AE_BAD_PARAMETER);
65 }
66
67
68 /*
69 * For all table types (Single/Multiple), the first
70 * instance is always in the list head.
71 */
72
73 if (instance == 1) {
74 /*
75 * Just pluck the pointer out of the global table!
76 * Will be null if no table is present
77 */
78
79 *table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
80 return (AE_OK);
81 }
82
83
84 /*
85 * Check for instance out of range
86 */
87 if (instance > acpi_gbl_acpi_tables[table_type].count) {
88 return (AE_NOT_EXIST);
89 }
90
91 /* Walk the list to get the desired table
92 * Since the if (Instance == 1) check above checked for the
93 * first table, setting Table_desc equal to the .Next member
94 * is actually pointing to the second table. Therefore, we
95 * need to walk from the 2nd table until we reach the Instance
96 * that the user is looking for and return its table pointer.
97 */
98 table_desc = acpi_gbl_acpi_tables[table_type].next;
99 for (i = 2; i < instance; i++) {
100 table_desc = table_desc->next;
101 }
102
103 /* We are now pointing to the requested table's descriptor */
104
105 *table_ptr_loc = table_desc->pointer;
106
107 return (AE_OK);
108 }
109
110
111 /*******************************************************************************
112 *
113 * FUNCTION: Acpi_tb_get_table
114 *
115 * PARAMETERS: Physical_address - Physical address of table to retrieve
116 * *Buffer_ptr - If Buffer_ptr is valid, read data from
117 * buffer rather than searching memory
118 * *Table_info - Where the table info is returned
119 *
120 * RETURN: Status
121 *
122 * DESCRIPTION: Maps the physical address of table into a logical address
123 *
124 ******************************************************************************/
125
126 ACPI_STATUS
127 acpi_tb_get_table (
128 ACPI_PHYSICAL_ADDRESS physical_address,
129 ACPI_TABLE_HEADER *buffer_ptr,
130 ACPI_TABLE_DESC *table_info)
131 {
132 ACPI_TABLE_HEADER *table_header = NULL;
133 ACPI_TABLE_HEADER *full_table = NULL;
134 u32 size;
135 u8 allocation;
136 ACPI_STATUS status = AE_OK;
137
138
139 if (!table_info) {
140 return (AE_BAD_PARAMETER);
141 }
142
143
144 if (buffer_ptr) {
145 /*
146 * Getting data from a buffer, not BIOS tables
147 */
148
149 table_header = buffer_ptr;
150 status = acpi_tb_validate_table_header (table_header);
151 if (ACPI_FAILURE (status)) {
152 /* Table failed verification, map all errors to BAD_DATA */
153
154 return (AE_BAD_DATA);
155 }
156
157 /* Allocate buffer for the entire table */
158
159 full_table = acpi_cm_allocate (table_header->length);
160 if (!full_table) {
161 return (AE_NO_MEMORY);
162 }
163
164 /* Copy the entire table (including header) to the local buffer */
165
166 size = table_header->length;
167 MEMCPY (full_table, buffer_ptr, size);
168
169 /* Save allocation type */
170
171 allocation = ACPI_MEM_ALLOCATED;
172 }
173
174
175 /*
176 * Not reading from a buffer, just map the table's physical memory
177 * into our address space.
178 */
179 else {
180 size = SIZE_IN_HEADER;
181
182 status = acpi_tb_map_acpi_table (physical_address, &size,
183 (void **) &full_table);
184 if (ACPI_FAILURE (status)) {
185 return (status);
186 }
187
188 /* Save allocation type */
189
190 allocation = ACPI_MEM_MAPPED;
191 }
192
193
194 /* Return values */
195
196 table_info->pointer = full_table;
197 table_info->length = size;
198 table_info->allocation = allocation;
199 table_info->base_pointer = full_table;
200
201 return (status);
202 }
203
204
205 /*******************************************************************************
206 *
207 * FUNCTION: Acpi_tb_get_all_tables
208 *
209 * PARAMETERS: Number_of_tables - Number of tables to get
210 * Table_ptr - Input buffer pointer, optional
211 *
212 * RETURN: Status
213 *
214 * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
215 * already be loaded and validated.
216 *
217 ******************************************************************************/
218
219 ACPI_STATUS
220 acpi_tb_get_all_tables (
221 u32 number_of_tables,
222 ACPI_TABLE_HEADER *table_ptr)
223 {
224 ACPI_STATUS status = AE_OK;
225 u32 index;
226 ACPI_TABLE_DESC table_info;
227
228
229 /*
230 * Loop through all table pointers found in RSDT.
231 * This will NOT include the FACS and DSDT - we must get
232 * them after the loop
233 */
234
235 for (index = 0; index < number_of_tables; index++) {
236 /* Clear the Table_info each time */
237
238 MEMSET (&table_info, 0, sizeof (ACPI_TABLE_DESC));
239
240 /* Get the table via the XSDT */
241
242 status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS)
243 ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]),
244 table_ptr, &table_info);
245
246 /* Ignore a table that failed verification */
247
248 if (status == AE_BAD_DATA) {
249 continue;
250 }
251
252 /* However, abort on serious errors */
253
254 if (ACPI_FAILURE (status)) {
255 return (status);
256 }
257
258 /* Recognize and install the table */
259
260 status = acpi_tb_install_table (table_ptr, &table_info);
261 if (ACPI_FAILURE (status)) {
262 /*
263 * Unrecognized or unsupported table, delete it and ignore the
264 * error. Just get as many tables as we can, later we will
265 * determine if there are enough tables to continue.
266 */
267
268 acpi_tb_uninstall_table (&table_info);
269 }
270 }
271
272
273 /*
274 * Convert the FADT to a common format. This allows earlier revisions of the
275 * table to coexist with newer versions, using common access code.
276 */
277 status = acpi_tb_convert_table_fadt ();
278 if (ACPI_FAILURE (status)) {
279 return (status);
280 }
281
282
283 /*
284 * Get the minimum set of ACPI tables, namely:
285 *
286 * 1) FADT (via RSDT in loop above)
287 * 2) FACS
288 * 3) DSDT
289 *
290 */
291
292
293 /*
294 * Get the FACS (must have the FADT first, from loop above)
295 * Acpi_tb_get_table_facs will fail if FADT pointer is not valid
296 */
297
298 status = acpi_tb_get_table_facs (table_ptr, &table_info);
299 if (ACPI_FAILURE (status)) {
300 return (status);
301 }
302
303
304 /* Install the FACS */
305
306 status = acpi_tb_install_table (table_ptr, &table_info);
307 if (ACPI_FAILURE (status)) {
308 return (status);
309 }
310
311 /*
312 * Create the common FACS pointer table
313 * (Contains pointers to the original table)
314 */
315
316 status = acpi_tb_build_common_facs (&table_info);
317 if (ACPI_FAILURE (status)) {
318 return (status);
319 }
320
321
322 /*
323 * Get the DSDT (We know that the FADT is valid now)
324 */
325
326 status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt),
327 table_ptr, &table_info);
328 if (ACPI_FAILURE (status)) {
329 return (status);
330 }
331
332 /* Install the DSDT */
333
334 status = acpi_tb_install_table (table_ptr, &table_info);
335 if (ACPI_FAILURE (status)) {
336 return (status);
337 }
338
339 /* Dump the DSDT Header */
340
341 /* Dump the entire DSDT */
342
343 /*
344 * Initialize the capabilities flags.
345 * Assumes that platform supports ACPI_MODE since we have tables!
346 */
347 acpi_gbl_system_flags |= acpi_hw_get_mode_capabilities ();
348
349
350 /* Always delete the RSDP mapping, we are done with it */
351
352 acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
353
354 return (status);
355 }
356
357
358 /*******************************************************************************
359 *
360 * FUNCTION: Acpi_tb_verify_rsdp
361 *
362 * PARAMETERS: Number_of_tables - Where the table count is placed
363 *
364 * RETURN: Status
365 *
366 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
367 *
368 ******************************************************************************/
369
370 ACPI_STATUS
371 acpi_tb_verify_rsdp (
372 ACPI_PHYSICAL_ADDRESS rsdp_physical_address)
373 {
374 ACPI_TABLE_DESC table_info;
375 ACPI_STATUS status;
376 u8 *table_ptr;
377
378
379 /*
380 * Obtain access to the RSDP structure
381 */
382 status = acpi_os_map_memory (rsdp_physical_address,
383 sizeof (RSDP_DESCRIPTOR),
384 (void **) &table_ptr);
385 if (ACPI_FAILURE (status)) {
386 return (status);
387 }
388
389 /*
390 * The signature and checksum must both be correct
391 */
392 if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
393 /* Nope, BAD Signature */
394
395 status = AE_BAD_SIGNATURE;
396 goto cleanup;
397 }
398
399 if (acpi_tb_checksum (table_ptr, RSDP_CHECKSUM_LENGTH) != 0) {
400 /* Nope, BAD Checksum */
401
402 status = AE_BAD_CHECKSUM;
403 goto cleanup;
404 }
405
406 /* TBD: Check extended checksum if table version >= 2 */
407
408 /* The RSDP supplied is OK */
409
410 table_info.pointer = (ACPI_TABLE_HEADER *) table_ptr;
411 table_info.length = sizeof (RSDP_DESCRIPTOR);
412 table_info.allocation = ACPI_MEM_MAPPED;
413 table_info.base_pointer = table_ptr;
414
415 /* Save the table pointers and allocation info */
416
417 status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
418 if (ACPI_FAILURE (status)) {
419 goto cleanup;
420 }
421
422
423 /* Save the RSDP in a global for easy access */
424
425 acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer;
426 return (status);
427
428
429 /* Error exit */
430 cleanup:
431
432 acpi_os_unmap_memory (table_ptr, sizeof (RSDP_DESCRIPTOR));
433 return (status);
434 }
435
436
437 /*******************************************************************************
438 *
439 * FUNCTION: Acpi_tb_get_table_rsdt
440 *
441 * PARAMETERS: Number_of_tables - Where the table count is placed
442 *
443 * RETURN: Status
444 *
445 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
446 *
447 ******************************************************************************/
448
449 ACPI_STATUS
450 acpi_tb_get_table_rsdt (
451 u32 *number_of_tables)
452 {
453 ACPI_TABLE_DESC table_info;
454 ACPI_STATUS status = AE_OK;
455 ACPI_PHYSICAL_ADDRESS physical_address;
456 u32 signature_length;
457 char *table_signature;
458
459
460 /*
461 * Get the RSDT from the RSDP
462 */
463
464 /*
465 * For RSDP revision 0 or 1, we use the RSDT.
466 * For RSDP revision 2 (and above), we use the XSDT
467 */
468 if (acpi_gbl_RSDP->revision < 2) {
469 #ifdef _IA64
470 /* 0.71 RSDP has 64bit Rsdt address field */
471 physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address;
472 #else
473 physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->rsdt_physical_address;
474 #endif
475 table_signature = RSDT_SIG;
476 signature_length = sizeof (RSDT_SIG) -1;
477 }
478 else {
479 physical_address = (ACPI_PHYSICAL_ADDRESS)
480 ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
481 table_signature = XSDT_SIG;
482 signature_length = sizeof (XSDT_SIG) -1;
483 }
484
485
486 /* Get the RSDT/XSDT */
487
488 status = acpi_tb_get_table (physical_address, NULL, &table_info);
489 if (ACPI_FAILURE (status)) {
490 return (status);
491 }
492
493
494 /* Check the RSDT or XSDT signature */
495
496 if (STRNCMP ((char *) table_info.pointer, table_signature,
497 signature_length)) {
498 /* Invalid RSDT or XSDT signature */
499
500 REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n",
501 table_signature));
502
503 return (AE_NO_ACPI_TABLES);
504 }
505
506
507 /* Valid RSDT signature, verify the checksum */
508
509 status = acpi_tb_verify_table_checksum (table_info.pointer);
510
511
512 /* Convert and/or copy to an XSDT structure */
513
514 status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables);
515 if (ACPI_FAILURE (status)) {
516 return (status);
517 }
518
519 /* Save the table pointers and allocation info */
520
521 status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
522 if (ACPI_FAILURE (status)) {
523 return (status);
524 }
525
526 acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer;
527
528 return (status);
529 }
530
531
532 /******************************************************************************
533 *
534 * FUNCTION: Acpi_tb_get_table_facs
535 *
536 * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from
537 * buffer rather than searching memory
538 * *Table_info - Where the table info is returned
539 *
540 * RETURN: Status
541 *
542 * DESCRIPTION: Returns a pointer to the FACS as defined in FADT. This
543 * function assumes the global variable FADT has been
544 * correctly initialized. The value of FADT->Firmware_ctrl
545 * into a far pointer which is returned.
546 *
547 *****************************************************************************/
548
549 ACPI_STATUS
550 acpi_tb_get_table_facs (
551 ACPI_TABLE_HEADER *buffer_ptr,
552 ACPI_TABLE_DESC *table_info)
553 {
554 void *table_ptr = NULL;
555 u32 size;
556 u8 allocation;
557 ACPI_STATUS status = AE_OK;
558
559
560 /* Must have a valid FADT pointer */
561
562 if (!acpi_gbl_FADT) {
563 return (AE_NO_ACPI_TABLES);
564 }
565
566 size = sizeof (FACS_DESCRIPTOR);
567 if (buffer_ptr) {
568 /*
569 * Getting table from a file -- allocate a buffer and
570 * read the table.
571 */
572 table_ptr = acpi_cm_allocate (size);
573 if(!table_ptr) {
574 return (AE_NO_MEMORY);
575 }
576
577 MEMCPY (table_ptr, buffer_ptr, size);
578
579 /* Save allocation type */
580
581 allocation = ACPI_MEM_ALLOCATED;
582 }
583
584 else {
585 /* Just map the physical memory to our address space */
586
587 status = acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl),
588 &size, &table_ptr);
589 if (ACPI_FAILURE(status)) {
590 return (status);
591 }
592
593 /* Save allocation type */
594
595 allocation = ACPI_MEM_MAPPED;
596 }
597
598
599 /* Return values */
600
601 table_info->pointer = table_ptr;
602 table_info->length = size;
603 table_info->allocation = allocation;
604 table_info->base_pointer = table_ptr;
605
606 return (status);
607 }
608