aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acpi/tables
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/acpi/tables')
-rw-r--r--drivers/acpi/tables/Makefile8
-rw-r--r--drivers/acpi/tables/tbconvrt.c564
-rw-r--r--drivers/acpi/tables/tbget.c493
-rw-r--r--drivers/acpi/tables/tbgetall.c313
-rw-r--r--drivers/acpi/tables/tbinstal.c553
-rw-r--r--drivers/acpi/tables/tbrsdt.c324
-rw-r--r--drivers/acpi/tables/tbutils.c240
-rw-r--r--drivers/acpi/tables/tbxface.c448
-rw-r--r--drivers/acpi/tables/tbxfroot.c606
9 files changed, 3549 insertions, 0 deletions
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
new file mode 100644
index 000000000000..aa4c69594d97
--- /dev/null
+++ b/drivers/acpi/tables/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for all Linux ACPI interpreter subdirectories
3#
4
5obj-y := tbconvrt.o tbget.o tbrsdt.o tbxface.o \
6 tbgetall.o tbinstal.o tbutils.o tbxfroot.o
7
8EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
new file mode 100644
index 000000000000..334327c1f66f
--- /dev/null
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -0,0 +1,564 @@
1/******************************************************************************
2 *
3 * Module Name: tbconvrt - ACPI Table conversion utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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#include <linux/module.h>
45
46#include <acpi/acpi.h>
47#include <acpi/actables.h>
48
49
50#define _COMPONENT ACPI_TABLES
51 ACPI_MODULE_NAME ("tbconvrt")
52
53
54u8 acpi_fadt_is_v1;
55EXPORT_SYMBOL(acpi_fadt_is_v1);
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_tb_get_table_count
60 *
61 * PARAMETERS: RSDP - Pointer to the RSDP
62 * RSDT - Pointer to the RSDT/XSDT
63 *
64 * RETURN: The number of tables pointed to by the RSDT or XSDT.
65 *
66 * DESCRIPTION: Calculate the number of tables. Automatically handles either
67 * an RSDT or XSDT.
68 *
69 ******************************************************************************/
70
71u32
72acpi_tb_get_table_count (
73 struct rsdp_descriptor *RSDP,
74 struct acpi_table_header *RSDT)
75{
76 u32 pointer_size;
77
78
79 ACPI_FUNCTION_ENTRY ();
80
81
82 if (RSDP->revision < 2) {
83 pointer_size = sizeof (u32);
84 }
85 else {
86 pointer_size = sizeof (u64);
87 }
88
89 /*
90 * Determine the number of tables pointed to by the RSDT/XSDT.
91 * This is defined by the ACPI Specification to be the number of
92 * pointers contained within the RSDT/XSDT. The size of the pointers
93 * is architecture-dependent.
94 */
95 return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size);
96}
97
98
99/*******************************************************************************
100 *
101 * FUNCTION: acpi_tb_convert_to_xsdt
102 *
103 * PARAMETERS: table_info - Info about the RSDT
104 *
105 * RETURN: Status
106 *
107 * DESCRIPTION: Convert an RSDT to an XSDT (internal common format)
108 *
109 ******************************************************************************/
110
111acpi_status
112acpi_tb_convert_to_xsdt (
113 struct acpi_table_desc *table_info)
114{
115 acpi_size table_size;
116 u32 i;
117 XSDT_DESCRIPTOR *new_table;
118
119
120 ACPI_FUNCTION_ENTRY ();
121
122
123 /* Compute size of the converted XSDT */
124
125 table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) +
126 sizeof (struct acpi_table_header);
127
128 /* Allocate an XSDT */
129
130 new_table = ACPI_MEM_CALLOCATE (table_size);
131 if (!new_table) {
132 return (AE_NO_MEMORY);
133 }
134
135 /* Copy the header and set the length */
136
137 ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
138 new_table->length = (u32) table_size;
139
140 /* Copy the table pointers */
141
142 for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
143 if (acpi_gbl_RSDP->revision < 2) {
144 ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
145 (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]);
146 }
147 else {
148 new_table->table_offset_entry[i] =
149 (ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i];
150 }
151 }
152
153 /* Delete the original table (either mapped or in a buffer) */
154
155 acpi_tb_delete_single_table (table_info);
156
157 /* Point the table descriptor to the new table */
158
159 table_info->pointer = ACPI_CAST_PTR (struct acpi_table_header, new_table);
160 table_info->length = table_size;
161 table_info->allocation = ACPI_MEM_ALLOCATED;
162
163 return (AE_OK);
164}
165
166
167/******************************************************************************
168 *
169 * FUNCTION: acpi_tb_init_generic_address
170 *
171 * PARAMETERS: new_gas_struct - GAS struct to be initialized
172 * register_bit_width - Width of this register
173 * Address - Address of the register
174 *
175 * RETURN: None
176 *
177 * DESCRIPTION: Initialize a GAS structure.
178 *
179 ******************************************************************************/
180
181static void
182acpi_tb_init_generic_address (
183 struct acpi_generic_address *new_gas_struct,
184 u8 register_bit_width,
185 acpi_physical_address address)
186{
187
188 ACPI_STORE_ADDRESS (new_gas_struct->address, address);
189
190 new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
191 new_gas_struct->register_bit_width = register_bit_width;
192 new_gas_struct->register_bit_offset = 0;
193 new_gas_struct->access_width = 0;
194}
195
196
197/*******************************************************************************
198 *
199 * FUNCTION: acpi_tb_convert_fadt1
200 *
201 * PARAMETERS: local_fadt - Pointer to new FADT
202 * original_fadt - Pointer to old FADT
203 *
204 * RETURN: Populates local_fadt
205 *
206 * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
207 *
208 ******************************************************************************/
209
210static void
211acpi_tb_convert_fadt1 (
212 struct fadt_descriptor_rev2 *local_fadt,
213 struct fadt_descriptor_rev1 *original_fadt)
214{
215
216
217 /* ACPI 1.0 FACS */
218 /* The BIOS stored FADT should agree with Revision 1.0 */
219 acpi_fadt_is_v1 = 1;
220
221 /*
222 * Copy the table header and the common part of the tables.
223 *
224 * The 2.0 table is an extension of the 1.0 table, so the entire 1.0
225 * table can be copied first, then expand some fields to 64 bits.
226 */
227 ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1));
228
229 /* Convert table pointers to 64-bit fields */
230
231 ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
232 ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
233
234 /*
235 * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;)
236 */
237
238 /*
239 * This field is set by the OEM to convey the preferred power management
240 * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't
241 * know what kind of 32-bit system this is, we will use "unspecified".
242 */
243 local_fadt->prefer_PM_profile = PM_UNSPECIFIED;
244
245 /*
246 * Processor Performance State Control. This is the value OSPM writes to
247 * the SMI_CMD register to assume processor performance state control
248 * responsibility. There isn't any equivalence in 1.0, but as many 1.x
249 * ACPI tables contain _PCT and _PSS we also keep this value, unless
250 * acpi_strict is set.
251 */
252 if (acpi_strict)
253 local_fadt->pstate_cnt = 0;
254
255 /*
256 * Support for the _CST object and C States change notification.
257 * This data item hasn't any 1.0 equivalence so leave it zero.
258 */
259 local_fadt->cst_cnt = 0;
260
261 /*
262 * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
263 * It primarily adds the FADT reset mechanism.
264 */
265 if ((original_fadt->revision == 2) &&
266 (original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) {
267 /*
268 * Grab the entire generic address struct, plus the 1-byte reset value
269 * that immediately follows.
270 */
271 ACPI_MEMCPY (&local_fadt->reset_register,
272 &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
273 sizeof (struct acpi_generic_address) + 1);
274 }
275 else {
276 /*
277 * Since there isn't any equivalence in 1.0 and since it is highly
278 * likely that a 1.0 system has legacy support.
279 */
280 local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
281 }
282
283 /*
284 * Convert the V1.0 block addresses to V2.0 GAS structures
285 */
286 acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
287 (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
288 acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
289 (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
290 acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
291 (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
292 acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
293 (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
294 acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
295 (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
296 acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
297 (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
298 acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
299 (acpi_physical_address) local_fadt->V1_gpe0_blk);
300 acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
301 (acpi_physical_address) local_fadt->V1_gpe1_blk);
302
303 /* Create separate GAS structs for the PM1 Enable registers */
304
305 acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
306 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
307 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
308 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
309
310 /* PM1B is optional; leave null if not present */
311
312 if (local_fadt->xpm1b_evt_blk.address) {
313 acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
314 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
315 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
316 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
317 }
318}
319
320
321/*******************************************************************************
322 *
323 * FUNCTION: acpi_tb_convert_fadt2
324 *
325 * PARAMETERS: local_fadt - Pointer to new FADT
326 * original_fadt - Pointer to old FADT
327 *
328 * RETURN: Populates local_fadt
329 *
330 * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
331 * Handles optional "X" fields.
332 *
333 ******************************************************************************/
334
335static void
336acpi_tb_convert_fadt2 (
337 struct fadt_descriptor_rev2 *local_fadt,
338 struct fadt_descriptor_rev2 *original_fadt)
339{
340
341 /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
342
343 ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2));
344
345 /*
346 * "X" fields are optional extensions to the original V1.0 fields, so
347 * we must selectively expand V1.0 fields if the corresponding X field
348 * is zero.
349 */
350 if (!(local_fadt->xfirmware_ctrl)) {
351 ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
352 }
353
354 if (!(local_fadt->Xdsdt)) {
355 ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
356 }
357
358 if (!(local_fadt->xpm1a_evt_blk.address)) {
359 acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
360 local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
361 }
362
363 if (!(local_fadt->xpm1b_evt_blk.address)) {
364 acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
365 local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
366 }
367
368 if (!(local_fadt->xpm1a_cnt_blk.address)) {
369 acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
370 local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
371 }
372
373 if (!(local_fadt->xpm1b_cnt_blk.address)) {
374 acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
375 local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
376 }
377
378 if (!(local_fadt->xpm2_cnt_blk.address)) {
379 acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
380 local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
381 }
382
383 if (!(local_fadt->xpm_tmr_blk.address)) {
384 acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
385 local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
386 }
387
388 if (!(local_fadt->xgpe0_blk.address)) {
389 acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
390 0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
391 }
392
393 if (!(local_fadt->xgpe1_blk.address)) {
394 acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
395 0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
396 }
397
398 /* Create separate GAS structs for the PM1 Enable registers */
399
400 acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
401 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
402 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
403 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
404 acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
405
406 /* PM1B is optional; leave null if not present */
407
408 if (local_fadt->xpm1b_evt_blk.address) {
409 acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
410 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
411 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
412 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
413 acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
414 }
415}
416
417
418/*******************************************************************************
419 *
420 * FUNCTION: acpi_tb_convert_table_fadt
421 *
422 * PARAMETERS: None
423 *
424 * RETURN: Status
425 *
426 * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local
427 * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
428 * copied to the local FADT. The ACPI CA software uses this
429 * local FADT. Thus a significant amount of special #ifdef
430 * type codeing is saved.
431 *
432 ******************************************************************************/
433
434acpi_status
435acpi_tb_convert_table_fadt (void)
436{
437 struct fadt_descriptor_rev2 *local_fadt;
438 struct acpi_table_desc *table_desc;
439
440
441 ACPI_FUNCTION_TRACE ("tb_convert_table_fadt");
442
443
444 /*
445 * acpi_gbl_FADT is valid. Validate the FADT length. The table must be
446 * at least as long as the version 1.0 FADT
447 */
448 if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
449 ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length));
450 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
451 }
452
453 /* Allocate buffer for the ACPI 2.0(+) FADT */
454
455 local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
456 if (!local_fadt) {
457 return_ACPI_STATUS (AE_NO_MEMORY);
458 }
459
460 if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
461 if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
462 /* Length is too short to be a V2.0 table */
463
464 ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
465 acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
466
467 acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
468 }
469 else {
470 /* Valid V2.0 table */
471
472 acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT);
473 }
474 }
475 else {
476 /* Valid V1.0 table */
477
478 acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
479 }
480
481 /*
482 * Global FADT pointer will point to the new common V2.0 FADT
483 */
484 acpi_gbl_FADT = local_fadt;
485 acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
486
487 /* Free the original table */
488
489 table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
490 acpi_tb_delete_single_table (table_desc);
491
492 /* Install the new table */
493
494 table_desc->pointer = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT);
495 table_desc->allocation = ACPI_MEM_ALLOCATED;
496 table_desc->length = sizeof (struct fadt_descriptor_rev2);
497
498 /* Dump the entire FADT */
499
500 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
501 "Hex dump of common internal FADT, size %d (%X)\n",
502 acpi_gbl_FADT->length, acpi_gbl_FADT->length));
503 ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
504
505 return_ACPI_STATUS (AE_OK);
506}
507
508
509/*******************************************************************************
510 *
511 * FUNCTION: acpi_tb_convert_table_facs
512 *
513 * PARAMETERS: table_info - Info for currently installed FACS
514 *
515 * RETURN: Status
516 *
517 * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal
518 * table format.
519 *
520 ******************************************************************************/
521
522acpi_status
523acpi_tb_build_common_facs (
524 struct acpi_table_desc *table_info)
525{
526
527 ACPI_FUNCTION_TRACE ("tb_build_common_facs");
528
529
530 /* Absolute minimum length is 24, but the ACPI spec says 64 */
531
532 if (acpi_gbl_FACS->length < 24) {
533 ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length));
534 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
535 }
536
537 if (acpi_gbl_FACS->length < 64) {
538 ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
539 acpi_gbl_FACS->length));
540 }
541
542 /* Copy fields to the new FACS */
543
544 acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock);
545
546 if ((acpi_gbl_RSDP->revision < 2) ||
547 (acpi_gbl_FACS->length < 32) ||
548 (!(acpi_gbl_FACS->xfirmware_waking_vector))) {
549 /* ACPI 1.0 FACS or short table or optional X_ field is zero */
550
551 acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector));
552 acpi_gbl_common_fACS.vector_width = 32;
553 }
554 else {
555 /* ACPI 2.0 FACS with valid X_ field */
556
557 acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector;
558 acpi_gbl_common_fACS.vector_width = 64;
559 }
560
561 return_ACPI_STATUS (AE_OK);
562}
563
564
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
new file mode 100644
index 000000000000..896f3ddda62e
--- /dev/null
+++ b/drivers/acpi/tables/tbget.c
@@ -0,0 +1,493 @@
1/******************************************************************************
2 *
3 * Module Name: tbget - ACPI Table get* routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/actables.h>
47
48
49#define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbget")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_tb_get_table
56 *
57 * PARAMETERS: Address - Address of table to retrieve. Can be
58 * Logical or Physical
59 * table_info - Where table info is returned
60 *
61 * RETURN: None
62 *
63 * DESCRIPTION: Get entire table of unknown size.
64 *
65 ******************************************************************************/
66
67acpi_status
68acpi_tb_get_table (
69 struct acpi_pointer *address,
70 struct acpi_table_desc *table_info)
71{
72 acpi_status status;
73 struct acpi_table_header header;
74
75
76 ACPI_FUNCTION_TRACE ("tb_get_table");
77
78
79 /*
80 * Get the header in order to get signature and table size
81 */
82 status = acpi_tb_get_table_header (address, &header);
83 if (ACPI_FAILURE (status)) {
84 return_ACPI_STATUS (status);
85 }
86
87 /* Get the entire table */
88
89 status = acpi_tb_get_table_body (address, &header, table_info);
90 if (ACPI_FAILURE (status)) {
91 ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
92 header.length, acpi_format_exception (status)));
93 return_ACPI_STATUS (status);
94 }
95
96 return_ACPI_STATUS (AE_OK);
97}
98
99
100/*******************************************************************************
101 *
102 * FUNCTION: acpi_tb_get_table_header
103 *
104 * PARAMETERS: Address - Address of table to retrieve. Can be
105 * Logical or Physical
106 * return_header - Where the table header is returned
107 *
108 * RETURN: Status
109 *
110 * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual
111 * addressing mode. Works with both physical or logical pointers.
112 * Table is either copied or mapped, depending on the pointer
113 * type and mode of the processor.
114 *
115 ******************************************************************************/
116
117acpi_status
118acpi_tb_get_table_header (
119 struct acpi_pointer *address,
120 struct acpi_table_header *return_header)
121{
122 acpi_status status = AE_OK;
123 struct acpi_table_header *header = NULL;
124
125
126 ACPI_FUNCTION_TRACE ("tb_get_table_header");
127
128
129 /*
130 * Flags contains the current processor mode (Virtual or Physical addressing)
131 * The pointer_type is either Logical or Physical
132 */
133 switch (address->pointer_type) {
134 case ACPI_PHYSMODE_PHYSPTR:
135 case ACPI_LOGMODE_LOGPTR:
136
137 /* Pointer matches processor mode, copy the header */
138
139 ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header));
140 break;
141
142
143 case ACPI_LOGMODE_PHYSPTR:
144
145 /* Create a logical address for the physical pointer*/
146
147 status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
148 (void *) &header);
149 if (ACPI_FAILURE (status)) {
150 ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
151 ACPI_FORMAT_UINT64 (address->pointer.physical),
152 sizeof (struct acpi_table_header)));
153 return_ACPI_STATUS (status);
154 }
155
156 /* Copy header and delete mapping */
157
158 ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
159 acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
160 break;
161
162
163 default:
164
165 ACPI_REPORT_ERROR (("Invalid address flags %X\n",
166 address->pointer_type));
167 return_ACPI_STATUS (AE_BAD_PARAMETER);
168 }
169
170 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
171 return_header->signature));
172
173 return_ACPI_STATUS (AE_OK);
174}
175
176
177/*******************************************************************************
178 *
179 * FUNCTION: acpi_tb_get_table_body
180 *
181 * PARAMETERS: Address - Address of table to retrieve. Can be
182 * Logical or Physical
183 * Header - Header of the table to retrieve
184 * table_info - Where the table info is returned
185 *
186 * RETURN: Status
187 *
188 * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
189 * replace the table with a newer version (table override.)
190 * Works in both physical or virtual
191 * addressing mode. Works with both physical or logical pointers.
192 * Table is either copied or mapped, depending on the pointer
193 * type and mode of the processor.
194 *
195 ******************************************************************************/
196
197acpi_status
198acpi_tb_get_table_body (
199 struct acpi_pointer *address,
200 struct acpi_table_header *header,
201 struct acpi_table_desc *table_info)
202{
203 acpi_status status;
204
205
206 ACPI_FUNCTION_TRACE ("tb_get_table_body");
207
208
209 if (!table_info || !address) {
210 return_ACPI_STATUS (AE_BAD_PARAMETER);
211 }
212
213 /*
214 * Attempt table override.
215 */
216 status = acpi_tb_table_override (header, table_info);
217 if (ACPI_SUCCESS (status)) {
218 /* Table was overridden by the host OS */
219
220 return_ACPI_STATUS (status);
221 }
222
223 /* No override, get the original table */
224
225 status = acpi_tb_get_this_table (address, header, table_info);
226 return_ACPI_STATUS (status);
227}
228
229
230/*******************************************************************************
231 *
232 * FUNCTION: acpi_tb_table_override
233 *
234 * PARAMETERS: Header - Pointer to table header
235 * table_info - Return info if table is overridden
236 *
237 * RETURN: None
238 *
239 * DESCRIPTION: Attempts override of current table with a new one if provided
240 * by the host OS.
241 *
242 ******************************************************************************/
243
244acpi_status
245acpi_tb_table_override (
246 struct acpi_table_header *header,
247 struct acpi_table_desc *table_info)
248{
249 struct acpi_table_header *new_table;
250 acpi_status status;
251 struct acpi_pointer address;
252
253
254 ACPI_FUNCTION_TRACE ("tb_table_override");
255
256
257 /*
258 * The OSL will examine the header and decide whether to override this
259 * table. If it decides to override, a table will be returned in new_table,
260 * which we will then copy.
261 */
262 status = acpi_os_table_override (header, &new_table);
263 if (ACPI_FAILURE (status)) {
264 /* Some severe error from the OSL, but we basically ignore it */
265
266 ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
267 acpi_format_exception (status)));
268 return_ACPI_STATUS (status);
269 }
270
271 if (!new_table) {
272 /* No table override */
273
274 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
275 }
276
277 /*
278 * We have a new table to override the old one. Get a copy of
279 * the new one. We know that the new table has a logical pointer.
280 */
281 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
282 address.pointer.logical = new_table;
283
284 status = acpi_tb_get_this_table (&address, new_table, table_info);
285 if (ACPI_FAILURE (status)) {
286 ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
287 acpi_format_exception (status)));
288 return_ACPI_STATUS (status);
289 }
290
291 /* Copy the table info */
292
293 ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
294 table_info->pointer->signature));
295
296 return_ACPI_STATUS (AE_OK);
297}
298
299
300/*******************************************************************************
301 *
302 * FUNCTION: acpi_tb_get_this_table
303 *
304 * PARAMETERS: Address - Address of table to retrieve. Can be
305 * Logical or Physical
306 * Header - Header of the table to retrieve
307 * table_info - Where the table info is returned
308 *
309 * RETURN: Status
310 *
311 * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual
312 * addressing mode. Works with both physical or logical pointers.
313 * Table is either copied or mapped, depending on the pointer
314 * type and mode of the processor.
315 *
316 ******************************************************************************/
317
318acpi_status
319acpi_tb_get_this_table (
320 struct acpi_pointer *address,
321 struct acpi_table_header *header,
322 struct acpi_table_desc *table_info)
323{
324 struct acpi_table_header *full_table = NULL;
325 u8 allocation;
326 acpi_status status = AE_OK;
327
328
329 ACPI_FUNCTION_TRACE ("tb_get_this_table");
330
331
332 /*
333 * Flags contains the current processor mode (Virtual or Physical addressing)
334 * The pointer_type is either Logical or Physical
335 */
336 switch (address->pointer_type) {
337 case ACPI_PHYSMODE_PHYSPTR:
338 case ACPI_LOGMODE_LOGPTR:
339
340 /* Pointer matches processor mode, copy the table to a new buffer */
341
342 full_table = ACPI_MEM_ALLOCATE (header->length);
343 if (!full_table) {
344 ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
345 header->signature, header->length));
346 return_ACPI_STATUS (AE_NO_MEMORY);
347 }
348
349 /* Copy the entire table (including header) to the local buffer */
350
351 ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
352
353 /* Save allocation type */
354
355 allocation = ACPI_MEM_ALLOCATED;
356 break;
357
358
359 case ACPI_LOGMODE_PHYSPTR:
360
361 /*
362 * Just map the table's physical memory
363 * into our address space.
364 */
365 status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
366 (void *) &full_table);
367 if (ACPI_FAILURE (status)) {
368 ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
369 header->signature,
370 ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
371 return (status);
372 }
373
374 /* Save allocation type */
375
376 allocation = ACPI_MEM_MAPPED;
377 break;
378
379
380 default:
381
382 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
383 address->pointer_type));
384 return_ACPI_STATUS (AE_BAD_PARAMETER);
385 }
386
387 /*
388 * Validate checksum for _most_ tables,
389 * even the ones whose signature we don't recognize
390 */
391 if (table_info->type != ACPI_TABLE_FACS) {
392 status = acpi_tb_verify_table_checksum (full_table);
393
394#if (!ACPI_CHECKSUM_ABORT)
395 if (ACPI_FAILURE (status)) {
396 /* Ignore the error if configuration says so */
397
398 status = AE_OK;
399 }
400#endif
401 }
402
403 /* Return values */
404
405 table_info->pointer = full_table;
406 table_info->length = (acpi_size) header->length;
407 table_info->allocation = allocation;
408
409 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
410 "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
411 full_table->signature,
412 ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
413
414 return_ACPI_STATUS (status);
415}
416
417
418/*******************************************************************************
419 *
420 * FUNCTION: acpi_tb_get_table_ptr
421 *
422 * PARAMETERS: table_type - one of the defined table types
423 * Instance - Which table of this type
424 * table_ptr_loc - pointer to location to place the pointer for
425 * return
426 *
427 * RETURN: Status
428 *
429 * DESCRIPTION: This function is called to get the pointer to an ACPI table.
430 *
431 ******************************************************************************/
432
433acpi_status
434acpi_tb_get_table_ptr (
435 acpi_table_type table_type,
436 u32 instance,
437 struct acpi_table_header **table_ptr_loc)
438{
439 struct acpi_table_desc *table_desc;
440 u32 i;
441
442
443 ACPI_FUNCTION_TRACE ("tb_get_table_ptr");
444
445
446 if (!acpi_gbl_DSDT) {
447 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
448 }
449
450 if (table_type > ACPI_TABLE_MAX) {
451 return_ACPI_STATUS (AE_BAD_PARAMETER);
452 }
453
454 /*
455 * For all table types (Single/Multiple), the first
456 * instance is always in the list head.
457 */
458 if (instance == 1) {
459 /* Get the first */
460
461 *table_ptr_loc = NULL;
462 if (acpi_gbl_table_lists[table_type].next) {
463 *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
464 }
465 return_ACPI_STATUS (AE_OK);
466 }
467
468 /*
469 * Check for instance out of range
470 */
471 if (instance > acpi_gbl_table_lists[table_type].count) {
472 return_ACPI_STATUS (AE_NOT_EXIST);
473 }
474
475 /* Walk the list to get the desired table
476 * Since the if (Instance == 1) check above checked for the
477 * first table, setting table_desc equal to the .Next member
478 * is actually pointing to the second table. Therefore, we
479 * need to walk from the 2nd table until we reach the Instance
480 * that the user is looking for and return its table pointer.
481 */
482 table_desc = acpi_gbl_table_lists[table_type].next;
483 for (i = 2; i < instance; i++) {
484 table_desc = table_desc->next;
485 }
486
487 /* We are now pointing to the requested table's descriptor */
488
489 *table_ptr_loc = table_desc->pointer;
490
491 return_ACPI_STATUS (AE_OK);
492}
493
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
new file mode 100644
index 000000000000..adc4270988bc
--- /dev/null
+++ b/drivers/acpi/tables/tbgetall.c
@@ -0,0 +1,313 @@
1/******************************************************************************
2 *
3 * Module Name: tbgetall - Get all required ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/actables.h>
47
48
49#define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbgetall")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_tb_get_primary_table
56 *
57 * PARAMETERS: Address - Physical address of table to retrieve
58 * *table_info - Where the table info is returned
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Maps the physical address of table into a logical address
63 *
64 ******************************************************************************/
65
66acpi_status
67acpi_tb_get_primary_table (
68 struct acpi_pointer *address,
69 struct acpi_table_desc *table_info)
70{
71 acpi_status status;
72 struct acpi_table_header header;
73
74
75 ACPI_FUNCTION_TRACE ("tb_get_primary_table");
76
77
78 /* Ignore a NULL address in the RSDT */
79
80 if (!address->pointer.value) {
81 return_ACPI_STATUS (AE_OK);
82 }
83
84 /*
85 * Get the header in order to get signature and table size
86 */
87 status = acpi_tb_get_table_header (address, &header);
88 if (ACPI_FAILURE (status)) {
89 return_ACPI_STATUS (status);
90 }
91
92 /* Clear the table_info */
93
94 ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc));
95
96 /*
97 * Check the table signature and make sure it is recognized.
98 * Also checks the header checksum
99 */
100 table_info->pointer = &header;
101 status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
102 if (ACPI_FAILURE (status)) {
103 return_ACPI_STATUS (status);
104 }
105
106 /* Get the entire table */
107
108 status = acpi_tb_get_table_body (address, &header, table_info);
109 if (ACPI_FAILURE (status)) {
110 return_ACPI_STATUS (status);
111 }
112
113 /* Install the table */
114
115 status = acpi_tb_install_table (table_info);
116 return_ACPI_STATUS (status);
117}
118
119
120/*******************************************************************************
121 *
122 * FUNCTION: acpi_tb_get_secondary_table
123 *
124 * PARAMETERS: Address - Physical address of table to retrieve
125 * *table_info - Where the table info is returned
126 *
127 * RETURN: Status
128 *
129 * DESCRIPTION: Maps the physical address of table into a logical address
130 *
131 ******************************************************************************/
132
133acpi_status
134acpi_tb_get_secondary_table (
135 struct acpi_pointer *address,
136 acpi_string signature,
137 struct acpi_table_desc *table_info)
138{
139 acpi_status status;
140 struct acpi_table_header header;
141
142
143 ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature);
144
145
146 /* Get the header in order to match the signature */
147
148 status = acpi_tb_get_table_header (address, &header);
149 if (ACPI_FAILURE (status)) {
150 return_ACPI_STATUS (status);
151 }
152
153 /* Signature must match request */
154
155 if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
156 ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
157 signature, header.signature));
158 return_ACPI_STATUS (AE_BAD_SIGNATURE);
159 }
160
161 /*
162 * Check the table signature and make sure it is recognized.
163 * Also checks the header checksum
164 */
165 table_info->pointer = &header;
166 status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
167 if (ACPI_FAILURE (status)) {
168 return_ACPI_STATUS (status);
169 }
170
171 /* Get the entire table */
172
173 status = acpi_tb_get_table_body (address, &header, table_info);
174 if (ACPI_FAILURE (status)) {
175 return_ACPI_STATUS (status);
176 }
177
178 /* Install the table */
179
180 status = acpi_tb_install_table (table_info);
181 return_ACPI_STATUS (status);
182}
183
184
185/*******************************************************************************
186 *
187 * FUNCTION: acpi_tb_get_required_tables
188 *
189 * PARAMETERS: None
190 *
191 * RETURN: Status
192 *
193 * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
194 * already be loaded and validated.
195 *
196 * Get the minimum set of ACPI tables, namely:
197 *
198 * 1) FADT (via RSDT in loop below)
199 * 2) FACS (via FADT)
200 * 3) DSDT (via FADT)
201 *
202 ******************************************************************************/
203
204acpi_status
205acpi_tb_get_required_tables (
206 void)
207{
208 acpi_status status = AE_OK;
209 u32 i;
210 struct acpi_table_desc table_info;
211 struct acpi_pointer address;
212
213
214 ACPI_FUNCTION_TRACE ("tb_get_required_tables");
215
216 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
217 acpi_gbl_rsdt_table_count));
218
219
220 address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
221
222 /*
223 * Loop through all table pointers found in RSDT.
224 * This will NOT include the FACS and DSDT - we must get
225 * them after the loop.
226 *
227 * The only tables we are interested in getting here is the FADT and
228 * any SSDTs.
229 */
230 for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
231 /* Get the table address from the common internal XSDT */
232
233 address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
234
235 /*
236 * Get the tables needed by this subsystem (FADT and any SSDTs).
237 * NOTE: All other tables are completely ignored at this time.
238 */
239 status = acpi_tb_get_primary_table (&address, &table_info);
240 if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
241 ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
242 acpi_format_exception (status),
243 ACPI_FORMAT_UINT64 (address.pointer.value)));
244 }
245 }
246
247 /* We must have a FADT to continue */
248
249 if (!acpi_gbl_FADT) {
250 ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
251 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
252 }
253
254 /*
255 * Convert the FADT to a common format. This allows earlier revisions of the
256 * table to coexist with newer versions, using common access code.
257 */
258 status = acpi_tb_convert_table_fadt ();
259 if (ACPI_FAILURE (status)) {
260 ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
261 return_ACPI_STATUS (status);
262 }
263
264 /*
265 * Get the FACS (Pointed to by the FADT)
266 */
267 address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
268
269 status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
270 if (ACPI_FAILURE (status)) {
271 ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
272 acpi_format_exception (status)));
273 return_ACPI_STATUS (status);
274 }
275
276 /*
277 * Create the common FACS pointer table
278 * (Contains pointers to the original table)
279 */
280 status = acpi_tb_build_common_facs (&table_info);
281 if (ACPI_FAILURE (status)) {
282 return_ACPI_STATUS (status);
283 }
284
285 /*
286 * Get/install the DSDT (Pointed to by the FADT)
287 */
288 address.pointer.value = acpi_gbl_FADT->Xdsdt;
289
290 status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
291 if (ACPI_FAILURE (status)) {
292 ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
293 return_ACPI_STATUS (status);
294 }
295
296 /* Set Integer Width (32/64) based upon DSDT revision */
297
298 acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
299
300 /* Dump the entire DSDT */
301
302 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
303 "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
304 acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
305 ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
306
307 /* Always delete the RSDP mapping, we are done with it */
308
309 acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
310 return_ACPI_STATUS (status);
311}
312
313
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
new file mode 100644
index 000000000000..85d5bb01022c
--- /dev/null
+++ b/drivers/acpi/tables/tbinstal.c
@@ -0,0 +1,553 @@
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/actables.h>
47
48
49#define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbinstal")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_tb_match_signature
56 *
57 * PARAMETERS: Signature - Table signature to match
58 * table_info - Return data
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned"
63 * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
64 *
65 ******************************************************************************/
66
67acpi_status
68acpi_tb_match_signature (
69 char *signature,
70 struct acpi_table_desc *table_info,
71 u8 search_type)
72{
73 acpi_native_uint i;
74
75
76 ACPI_FUNCTION_TRACE ("tb_match_signature");
77
78
79 /*
80 * Search for a signature match among the known table types
81 */
82 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
83 if (!(acpi_gbl_table_data[i].flags & search_type)) {
84 continue;
85 }
86
87 if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
88 acpi_gbl_table_data[i].sig_length)) {
89 /* Found a signature match, return index if requested */
90
91 if (table_info) {
92 table_info->type = (u8) i;
93 }
94
95 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
96 "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
97 (char *) acpi_gbl_table_data[i].signature));
98
99 return_ACPI_STATUS (AE_OK);
100 }
101 }
102
103 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
104 "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
105 (char *) signature));
106
107 return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
108}
109
110
111/*******************************************************************************
112 *
113 * FUNCTION: acpi_tb_install_table
114 *
115 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body
116 *
117 * RETURN: Status
118 *
119 * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must
120 * already be loaded and validated.
121 * Install the table into the global data structs.
122 *
123 ******************************************************************************/
124
125acpi_status
126acpi_tb_install_table (
127 struct acpi_table_desc *table_info)
128{
129 acpi_status status;
130
131 ACPI_FUNCTION_TRACE ("tb_install_table");
132
133
134 /* Lock tables while installing */
135
136 status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
137 if (ACPI_FAILURE (status)) {
138 ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
139 table_info->pointer->signature, acpi_format_exception (status)));
140 return_ACPI_STATUS (status);
141 }
142
143 /* Install the table into the global data structure */
144
145 status = acpi_tb_init_table_descriptor (table_info->type, table_info);
146 if (ACPI_FAILURE (status)) {
147 ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n",
148 table_info->pointer->signature, acpi_format_exception (status)));
149 }
150
151 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
152 acpi_gbl_table_data[table_info->type].name, table_info->pointer));
153
154 (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
155 return_ACPI_STATUS (status);
156}
157
158
159/*******************************************************************************
160 *
161 * FUNCTION: acpi_tb_recognize_table
162 *
163 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: Check a table signature for a match against known table types
168 *
169 * NOTE: All table pointers are validated as follows:
170 * 1) Table pointer must point to valid physical memory
171 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
172 * name
173 * 3) Table must be readable for length specified in the header
174 * 4) Table checksum must be valid (with the exception of the FACS
175 * which has no checksum for some odd reason)
176 *
177 ******************************************************************************/
178
179acpi_status
180acpi_tb_recognize_table (
181 struct acpi_table_desc *table_info,
182 u8 search_type)
183{
184 struct acpi_table_header *table_header;
185 acpi_status status;
186
187
188 ACPI_FUNCTION_TRACE ("tb_recognize_table");
189
190
191 /* Ensure that we have a valid table pointer */
192
193 table_header = (struct acpi_table_header *) table_info->pointer;
194 if (!table_header) {
195 return_ACPI_STATUS (AE_BAD_PARAMETER);
196 }
197
198 /*
199 * We only "recognize" a limited number of ACPI tables -- namely, the
200 * ones that are used by the subsystem (DSDT, FADT, etc.)
201 *
202 * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized.
203 * This can be any one of many valid ACPI tables, it just isn't one of
204 * the tables that is consumed by the core subsystem
205 */
206 status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
207 if (ACPI_FAILURE (status)) {
208 return_ACPI_STATUS (status);
209 }
210
211 status = acpi_tb_validate_table_header (table_header);
212 if (ACPI_FAILURE (status)) {
213 return_ACPI_STATUS (status);
214 }
215
216 /* Return the table type and length via the info struct */
217
218 table_info->length = (acpi_size) table_header->length;
219
220 return_ACPI_STATUS (status);
221}
222
223
224/*******************************************************************************
225 *
226 * FUNCTION: acpi_tb_init_table_descriptor
227 *
228 * PARAMETERS: table_type - The type of the table
229 * table_info - A table info struct
230 *
231 * RETURN: None.
232 *
233 * DESCRIPTION: Install a table into the global data structs.
234 *
235 ******************************************************************************/
236
237acpi_status
238acpi_tb_init_table_descriptor (
239 acpi_table_type table_type,
240 struct acpi_table_desc *table_info)
241{
242 struct acpi_table_list *list_head;
243 struct acpi_table_desc *table_desc;
244
245
246 ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
247
248
249 /* Allocate a descriptor for this table */
250
251 table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
252 if (!table_desc) {
253 return_ACPI_STATUS (AE_NO_MEMORY);
254 }
255
256 /*
257 * Install the table into the global data structure
258 */
259 list_head = &acpi_gbl_table_lists[table_type];
260
261 /*
262 * Two major types of tables: 1) Only one instance is allowed. This
263 * includes most ACPI tables such as the DSDT. 2) Multiple instances of
264 * the table are allowed. This includes SSDT and PSDTs.
265 */
266 if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
267 /*
268 * Only one table allowed, and a table has alread been installed
269 * at this location, so return an error.
270 */
271 if (list_head->next) {
272 ACPI_MEM_FREE (table_desc);
273 return_ACPI_STATUS (AE_ALREADY_EXISTS);
274 }
275
276 table_desc->next = list_head->next;
277 list_head->next = table_desc;
278
279 if (table_desc->next) {
280 table_desc->next->prev = table_desc;
281 }
282
283 list_head->count++;
284 }
285 else {
286 /*
287 * Link the new table in to the list of tables of this type.
288 * Insert at the end of the list, order IS IMPORTANT.
289 *
290 * table_desc->Prev & Next are already NULL from calloc()
291 */
292 list_head->count++;
293
294 if (!list_head->next) {
295 list_head->next = table_desc;
296 }
297 else {
298 table_desc->next = list_head->next;
299
300 while (table_desc->next->next) {
301 table_desc->next = table_desc->next->next;
302 }
303
304 table_desc->next->next = table_desc;
305 table_desc->prev = table_desc->next;
306 table_desc->next = NULL;
307 }
308 }
309
310 /* Finish initialization of the table descriptor */
311
312 table_desc->type = (u8) table_type;
313 table_desc->pointer = table_info->pointer;
314 table_desc->length = table_info->length;
315 table_desc->allocation = table_info->allocation;
316 table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
317 table_desc->aml_length = (u32) (table_desc->length -
318 (u32) sizeof (struct acpi_table_header));
319 table_desc->table_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE);
320 table_desc->loaded_into_namespace = FALSE;
321
322 /*
323 * Set the appropriate global pointer (if there is one) to point to the
324 * newly installed table
325 */
326 if (acpi_gbl_table_data[table_type].global_ptr) {
327 *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
328 }
329
330 /* Return Data */
331
332 table_info->table_id = table_desc->table_id;
333 table_info->installed_desc = table_desc;
334
335 return_ACPI_STATUS (AE_OK);
336}
337
338
339/*******************************************************************************
340 *
341 * FUNCTION: acpi_tb_delete_all_tables
342 *
343 * PARAMETERS: None.
344 *
345 * RETURN: None.
346 *
347 * DESCRIPTION: Delete all internal ACPI tables
348 *
349 ******************************************************************************/
350
351void
352acpi_tb_delete_all_tables (void)
353{
354 acpi_table_type type;
355
356
357 /*
358 * Free memory allocated for ACPI tables
359 * Memory can either be mapped or allocated
360 */
361 for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
362 acpi_tb_delete_tables_by_type (type);
363 }
364}
365
366
367/*******************************************************************************
368 *
369 * FUNCTION: acpi_tb_delete_tables_by_type
370 *
371 * PARAMETERS: Type - The table type to be deleted
372 *
373 * RETURN: None.
374 *
375 * DESCRIPTION: Delete an internal ACPI table
376 * Locks the ACPI table mutex
377 *
378 ******************************************************************************/
379
380void
381acpi_tb_delete_tables_by_type (
382 acpi_table_type type)
383{
384 struct acpi_table_desc *table_desc;
385 u32 count;
386 u32 i;
387
388
389 ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
390
391
392 if (type > ACPI_TABLE_MAX) {
393 return_VOID;
394 }
395
396 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_TABLES))) {
397 return;
398 }
399
400 /* Clear the appropriate "typed" global table pointer */
401
402 switch (type) {
403 case ACPI_TABLE_RSDP:
404 acpi_gbl_RSDP = NULL;
405 break;
406
407 case ACPI_TABLE_DSDT:
408 acpi_gbl_DSDT = NULL;
409 break;
410
411 case ACPI_TABLE_FADT:
412 acpi_gbl_FADT = NULL;
413 break;
414
415 case ACPI_TABLE_FACS:
416 acpi_gbl_FACS = NULL;
417 break;
418
419 case ACPI_TABLE_XSDT:
420 acpi_gbl_XSDT = NULL;
421 break;
422
423 case ACPI_TABLE_SSDT:
424 case ACPI_TABLE_PSDT:
425 default:
426 break;
427 }
428
429 /*
430 * Free the table
431 * 1) Get the head of the list
432 */
433 table_desc = acpi_gbl_table_lists[type].next;
434 count = acpi_gbl_table_lists[type].count;
435
436 /*
437 * 2) Walk the entire list, deleting both the allocated tables
438 * and the table descriptors
439 */
440 for (i = 0; i < count; i++) {
441 table_desc = acpi_tb_uninstall_table (table_desc);
442 }
443
444 (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
445 return_VOID;
446}
447
448
449/*******************************************************************************
450 *
451 * FUNCTION: acpi_tb_delete_single_table
452 *
453 * PARAMETERS: table_info - A table info struct
454 *
455 * RETURN: None.
456 *
457 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where
458 * the table was allocated a buffer or was mapped.
459 *
460 ******************************************************************************/
461
462void
463acpi_tb_delete_single_table (
464 struct acpi_table_desc *table_desc)
465{
466
467 /* Must have a valid table descriptor and pointer */
468
469 if ((!table_desc) ||
470 (!table_desc->pointer)) {
471 return;
472 }
473
474 /* Valid table, determine type of memory allocation */
475
476 switch (table_desc->allocation) {
477 case ACPI_MEM_NOT_ALLOCATED:
478 break;
479
480 case ACPI_MEM_ALLOCATED:
481
482 ACPI_MEM_FREE (table_desc->pointer);
483 break;
484
485 case ACPI_MEM_MAPPED:
486
487 acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
488 break;
489
490 default:
491 break;
492 }
493}
494
495
496/*******************************************************************************
497 *
498 * FUNCTION: acpi_tb_uninstall_table
499 *
500 * PARAMETERS: table_info - A table info struct
501 *
502 * RETURN: Pointer to the next table in the list (of same type)
503 *
504 * DESCRIPTION: Free the memory associated with an internal ACPI table that
505 * is either installed or has never been installed.
506 * Table mutex should be locked.
507 *
508 ******************************************************************************/
509
510struct acpi_table_desc *
511acpi_tb_uninstall_table (
512 struct acpi_table_desc *table_desc)
513{
514 struct acpi_table_desc *next_desc;
515
516
517 ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
518
519
520 if (!table_desc) {
521 return_PTR (NULL);
522 }
523
524 /* Unlink the descriptor from the doubly linked list */
525
526 if (table_desc->prev) {
527 table_desc->prev->next = table_desc->next;
528 }
529 else {
530 /* Is first on list, update list head */
531
532 acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
533 }
534
535 if (table_desc->next) {
536 table_desc->next->prev = table_desc->prev;
537 }
538
539 /* Free the memory allocated for the table itself */
540
541 acpi_tb_delete_single_table (table_desc);
542
543 /* Free the table descriptor */
544
545 next_desc = table_desc->next;
546 ACPI_MEM_FREE (table_desc);
547
548 /* Return pointer to the next descriptor */
549
550 return_PTR (next_desc);
551}
552
553
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
new file mode 100644
index 000000000000..9c6913238d52
--- /dev/null
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -0,0 +1,324 @@
1/******************************************************************************
2 *
3 * Module Name: tbrsdt - ACPI RSDT table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/actables.h>
47
48
49#define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbrsdt")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_tb_verify_rsdp
56 *
57 * PARAMETERS: Address - RSDP (Pointer to RSDT)
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
62 *
63 ******************************************************************************/
64
65acpi_status
66acpi_tb_verify_rsdp (
67 struct acpi_pointer *address)
68{
69 struct acpi_table_desc table_info;
70 acpi_status status;
71 struct rsdp_descriptor *rsdp;
72
73
74 ACPI_FUNCTION_TRACE ("tb_verify_rsdp");
75
76
77 switch (address->pointer_type) {
78 case ACPI_LOGICAL_POINTER:
79
80 rsdp = address->pointer.logical;
81 break;
82
83 case ACPI_PHYSICAL_POINTER:
84 /*
85 * Obtain access to the RSDP structure
86 */
87 status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
88 (void *) &rsdp);
89 if (ACPI_FAILURE (status)) {
90 return_ACPI_STATUS (status);
91 }
92 break;
93
94 default:
95 return_ACPI_STATUS (AE_BAD_PARAMETER);
96 }
97
98 /*
99 * The signature and checksum must both be correct
100 */
101 if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
102 /* Nope, BAD Signature */
103
104 status = AE_BAD_SIGNATURE;
105 goto cleanup;
106 }
107
108 /* Check the standard checksum */
109
110 if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
111 status = AE_BAD_CHECKSUM;
112 goto cleanup;
113 }
114
115 /* Check extended checksum if table version >= 2 */
116
117 if (rsdp->revision >= 2) {
118 if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
119 status = AE_BAD_CHECKSUM;
120 goto cleanup;
121 }
122 }
123
124 /* The RSDP supplied is OK */
125
126 table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp);
127 table_info.length = sizeof (struct rsdp_descriptor);
128 table_info.allocation = ACPI_MEM_MAPPED;
129
130 /* Save the table pointers and allocation info */
131
132 status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
133 if (ACPI_FAILURE (status)) {
134 goto cleanup;
135 }
136
137 /* Save the RSDP in a global for easy access */
138
139 acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer);
140 return_ACPI_STATUS (status);
141
142
143 /* Error exit */
144cleanup:
145
146 if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
147 acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor));
148 }
149 return_ACPI_STATUS (status);
150}
151
152
153/*******************************************************************************
154 *
155 * FUNCTION: acpi_tb_get_rsdt_address
156 *
157 * PARAMETERS: None
158 *
159 * RETURN: RSDT physical address
160 *
161 * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
162 * version of the RSDP
163 *
164 ******************************************************************************/
165
166void
167acpi_tb_get_rsdt_address (
168 struct acpi_pointer *out_address)
169{
170
171 ACPI_FUNCTION_ENTRY ();
172
173
174 out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
175
176 /*
177 * For RSDP revision 0 or 1, we use the RSDT.
178 * For RSDP revision 2 (and above), we use the XSDT
179 */
180 if (acpi_gbl_RSDP->revision < 2) {
181 out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
182 }
183 else {
184 out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address;
185 }
186}
187
188
189/*******************************************************************************
190 *
191 * FUNCTION: acpi_tb_validate_rsdt
192 *
193 * PARAMETERS: table_ptr - Addressable pointer to the RSDT.
194 *
195 * RETURN: Status
196 *
197 * DESCRIPTION: Validate signature for the RSDT or XSDT
198 *
199 ******************************************************************************/
200
201acpi_status
202acpi_tb_validate_rsdt (
203 struct acpi_table_header *table_ptr)
204{
205 int no_match;
206
207
208 ACPI_FUNCTION_NAME ("tb_validate_rsdt");
209
210
211 /*
212 * For RSDP revision 0 or 1, we use the RSDT.
213 * For RSDP revision 2 and above, we use the XSDT
214 */
215 if (acpi_gbl_RSDP->revision < 2) {
216 no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
217 sizeof (RSDT_SIG) -1);
218 }
219 else {
220 no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
221 sizeof (XSDT_SIG) -1);
222 }
223
224 if (no_match) {
225 /* Invalid RSDT or XSDT signature */
226
227 ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
228
229 ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
230
231 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
232 "RSDT/XSDT signature at %X (%p) is invalid\n",
233 acpi_gbl_RSDP->rsdt_physical_address,
234 (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address));
235
236 if (acpi_gbl_RSDP->revision < 2) {
237 ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
238 }
239 else {
240 ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
241 }
242
243 ACPI_DUMP_BUFFER ((char *) table_ptr, 48);
244
245 return (AE_BAD_SIGNATURE);
246 }
247
248 return (AE_OK);
249}
250
251
252/*******************************************************************************
253 *
254 * FUNCTION: acpi_tb_get_table_rsdt
255 *
256 * PARAMETERS: None
257 *
258 * RETURN: Status
259 *
260 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
261 *
262 ******************************************************************************/
263
264acpi_status
265acpi_tb_get_table_rsdt (
266 void)
267{
268 struct acpi_table_desc table_info;
269 acpi_status status;
270 struct acpi_pointer address;
271
272
273 ACPI_FUNCTION_TRACE ("tb_get_table_rsdt");
274
275
276 /* Get the RSDT/XSDT via the RSDP */
277
278 acpi_tb_get_rsdt_address (&address);
279
280 table_info.type = ACPI_TABLE_XSDT;
281 status = acpi_tb_get_table (&address, &table_info);
282 if (ACPI_FAILURE (status)) {
283 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
284 acpi_format_exception (status)));
285 return_ACPI_STATUS (status);
286 }
287
288 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
289 "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
290 acpi_gbl_RSDP,
291 ACPI_FORMAT_UINT64 (address.pointer.value)));
292
293 /* Check the RSDT or XSDT signature */
294
295 status = acpi_tb_validate_rsdt (table_info.pointer);
296 if (ACPI_FAILURE (status)) {
297 return_ACPI_STATUS (status);
298 }
299
300 /* Get the number of tables defined in the RSDT or XSDT */
301
302 acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
303
304 /* Convert and/or copy to an XSDT structure */
305
306 status = acpi_tb_convert_to_xsdt (&table_info);
307 if (ACPI_FAILURE (status)) {
308 return_ACPI_STATUS (status);
309 }
310
311 /* Save the table pointers and allocation info */
312
313 status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
314 if (ACPI_FAILURE (status)) {
315 return_ACPI_STATUS (status);
316 }
317
318 acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer);
319
320 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
321 return_ACPI_STATUS (status);
322}
323
324
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
new file mode 100644
index 000000000000..fede5804c783
--- /dev/null
+++ b/drivers/acpi/tables/tbutils.c
@@ -0,0 +1,240 @@
1/******************************************************************************
2 *
3 * Module Name: tbutils - Table manipulation utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/actables.h>
47
48
49#define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbutils")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_tb_handle_to_object
56 *
57 * PARAMETERS: table_id - Id for which the function is searching
58 * table_desc - Pointer to return the matching table
59 * descriptor.
60 *
61 * RETURN: Search the tables to find one with a matching table_id and
62 * return a pointer to that table descriptor.
63 *
64 ******************************************************************************/
65#ifdef ACPI_FUTURE_USAGE
66acpi_status
67acpi_tb_handle_to_object (
68 u16 table_id,
69 struct acpi_table_desc **return_table_desc)
70{
71 u32 i;
72 struct acpi_table_desc *table_desc;
73
74
75 ACPI_FUNCTION_NAME ("tb_handle_to_object");
76
77
78 for (i = 0; i < ACPI_TABLE_MAX; i++) {
79 table_desc = acpi_gbl_table_lists[i].next;
80 while (table_desc) {
81 if (table_desc->table_id == table_id) {
82 *return_table_desc = table_desc;
83 return (AE_OK);
84 }
85
86 table_desc = table_desc->next;
87 }
88 }
89
90 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
91 return (AE_BAD_PARAMETER);
92}
93#endif /* ACPI_FUTURE_USAGE */
94
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_tb_validate_table_header
99 *
100 * PARAMETERS: table_header - Logical pointer to the table
101 *
102 * RETURN: Status
103 *
104 * DESCRIPTION: Check an ACPI table header for validity
105 *
106 * NOTE: Table pointers are validated as follows:
107 * 1) Table pointer must point to valid physical memory
108 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
109 * name
110 * 3) Table must be readable for length specified in the header
111 * 4) Table checksum must be valid (with the exception of the FACS
112 * which has no checksum because it contains variable fields)
113 *
114 ******************************************************************************/
115
116acpi_status
117acpi_tb_validate_table_header (
118 struct acpi_table_header *table_header)
119{
120 acpi_name signature;
121
122
123 ACPI_FUNCTION_NAME ("tb_validate_table_header");
124
125
126 /* Verify that this is a valid address */
127
128 if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
129 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
130 "Cannot read table header at %p\n", table_header));
131 return (AE_BAD_ADDRESS);
132 }
133
134 /* Ensure that the signature is 4 ASCII characters */
135
136 ACPI_MOVE_32_TO_32 (&signature, table_header->signature);
137 if (!acpi_ut_valid_acpi_name (signature)) {
138 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
139 "Table signature at %p [%p] has invalid characters\n",
140 table_header, &signature));
141
142 ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
143 (char *) &signature));
144 ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
145 return (AE_BAD_SIGNATURE);
146 }
147
148 /* Validate the table length */
149
150 if (table_header->length < sizeof (struct acpi_table_header)) {
151 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
152 "Invalid length in table header %p name %4.4s\n",
153 table_header, (char *) &signature));
154
155 ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
156 (u32) table_header->length));
157 ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
158 return (AE_BAD_HEADER);
159 }
160
161 return (AE_OK);
162}
163
164
165/*******************************************************************************
166 *
167 * FUNCTION: acpi_tb_verify_table_checksum
168 *
169 * PARAMETERS: *table_header - ACPI table to verify
170 *
171 * RETURN: 8 bit checksum of table
172 *
173 * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct
174 * table should have a checksum of 0.
175 *
176 ******************************************************************************/
177
178acpi_status
179acpi_tb_verify_table_checksum (
180 struct acpi_table_header *table_header)
181{
182 u8 checksum;
183 acpi_status status = AE_OK;
184
185
186 ACPI_FUNCTION_TRACE ("tb_verify_table_checksum");
187
188
189 /* Compute the checksum on the table */
190
191 checksum = acpi_tb_checksum (table_header, table_header->length);
192
193 /* Return the appropriate exception */
194
195 if (checksum) {
196 ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
197 table_header->signature, (u32) table_header->checksum, (u32) checksum));
198
199 status = AE_BAD_CHECKSUM;
200 }
201 return_ACPI_STATUS (status);
202}
203
204
205/*******************************************************************************
206 *
207 * FUNCTION: acpi_tb_checksum
208 *
209 * PARAMETERS: Buffer - Buffer to checksum
210 * Length - Size of the buffer
211 *
212 * RETURNS 8 bit checksum of buffer
213 *
214 * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
215 *
216 ******************************************************************************/
217
218u8
219acpi_tb_checksum (
220 void *buffer,
221 u32 length)
222{
223 const u8 *limit;
224 const u8 *rover;
225 u8 sum = 0;
226
227
228 if (buffer && length) {
229 /* Buffer and Length are valid */
230
231 limit = (u8 *) buffer + length;
232
233 for (rover = buffer; rover < limit; rover++) {
234 sum = (u8) (sum + *rover);
235 }
236 }
237 return (sum);
238}
239
240
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
new file mode 100644
index 000000000000..7715043461c4
--- /dev/null
+++ b/drivers/acpi/tables/tbxface.c
@@ -0,0 +1,448 @@
1/******************************************************************************
2 *
3 * Module Name: tbxface - Public interfaces to the ACPI subsystem
4 * ACPI table oriented interfaces
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <linux/module.h>
46
47#include <acpi/acpi.h>
48#include <acpi/acnamesp.h>
49#include <acpi/actables.h>
50
51
52#define _COMPONENT ACPI_TABLES
53 ACPI_MODULE_NAME ("tbxface")
54
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_load_tables
59 *
60 * PARAMETERS: None
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: This function is called to load the ACPI tables from the
65 * provided RSDT
66 *
67 ******************************************************************************/
68
69acpi_status
70acpi_load_tables (void)
71{
72 struct acpi_pointer rsdp_address;
73 acpi_status status;
74
75
76 ACPI_FUNCTION_TRACE ("acpi_load_tables");
77
78
79 /* Get the RSDP */
80
81 status = acpi_os_get_root_pointer (ACPI_LOGICAL_ADDRESSING,
82 &rsdp_address);
83 if (ACPI_FAILURE (status)) {
84 ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n",
85 acpi_format_exception (status)));
86 goto error_exit;
87 }
88
89 /* Map and validate the RSDP */
90
91 acpi_gbl_table_flags = rsdp_address.pointer_type;
92
93 status = acpi_tb_verify_rsdp (&rsdp_address);
94 if (ACPI_FAILURE (status)) {
95 ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n",
96 acpi_format_exception (status)));
97 goto error_exit;
98 }
99
100 /* Get the RSDT via the RSDP */
101
102 status = acpi_tb_get_table_rsdt ();
103 if (ACPI_FAILURE (status)) {
104 ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n",
105 acpi_format_exception (status)));
106 goto error_exit;
107 }
108
109 /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
110
111 status = acpi_tb_get_required_tables ();
112 if (ACPI_FAILURE (status)) {
113 ACPI_REPORT_ERROR (("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
114 acpi_format_exception (status)));
115 goto error_exit;
116 }
117
118 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
119
120
121 /* Load the namespace from the tables */
122
123 status = acpi_ns_load_namespace ();
124 if (ACPI_FAILURE (status)) {
125 ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n",
126 acpi_format_exception (status)));
127 goto error_exit;
128 }
129
130 return_ACPI_STATUS (AE_OK);
131
132
133error_exit:
134 ACPI_REPORT_ERROR (("acpi_load_tables: Could not load tables: %s\n",
135 acpi_format_exception (status)));
136
137 return_ACPI_STATUS (status);
138}
139
140
141#ifdef ACPI_FUTURE_USAGE
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_load_table
146 *
147 * PARAMETERS: table_ptr - pointer to a buffer containing the entire
148 * table to be loaded
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: This function is called to load a table from the caller's
153 * buffer. The buffer must contain an entire ACPI Table including
154 * a valid header. The header fields will be verified, and if it
155 * is determined that the table is invalid, the call will fail.
156 *
157 ******************************************************************************/
158
159acpi_status
160acpi_load_table (
161 struct acpi_table_header *table_ptr)
162{
163 acpi_status status;
164 struct acpi_table_desc table_info;
165 struct acpi_pointer address;
166
167
168 ACPI_FUNCTION_TRACE ("acpi_load_table");
169
170
171 if (!table_ptr) {
172 return_ACPI_STATUS (AE_BAD_PARAMETER);
173 }
174
175 /* Copy the table to a local buffer */
176
177 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
178 address.pointer.logical = table_ptr;
179
180 status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
181 if (ACPI_FAILURE (status)) {
182 return_ACPI_STATUS (status);
183 }
184
185 /* Install the new table into the local data structures */
186
187 status = acpi_tb_install_table (&table_info);
188 if (ACPI_FAILURE (status)) {
189 /* Free table allocated by acpi_tb_get_table_body */
190
191 acpi_tb_delete_single_table (&table_info);
192 return_ACPI_STATUS (status);
193 }
194
195 /* Convert the table to common format if necessary */
196
197 switch (table_info.type) {
198 case ACPI_TABLE_FADT:
199
200 status = acpi_tb_convert_table_fadt ();
201 break;
202
203 case ACPI_TABLE_FACS:
204
205 status = acpi_tb_build_common_facs (&table_info);
206 break;
207
208 default:
209 /* Load table into namespace if it contains executable AML */
210
211 status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
212 break;
213 }
214
215 if (ACPI_FAILURE (status)) {
216 /* Uninstall table and free the buffer */
217
218 (void) acpi_tb_uninstall_table (table_info.installed_desc);
219 }
220
221 return_ACPI_STATUS (status);
222}
223
224
225/*******************************************************************************
226 *
227 * FUNCTION: acpi_unload_table
228 *
229 * PARAMETERS: table_type - Type of table to be unloaded
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: This routine is used to force the unload of a table
234 *
235 ******************************************************************************/
236
237acpi_status
238acpi_unload_table (
239 acpi_table_type table_type)
240{
241 struct acpi_table_desc *table_desc;
242
243
244 ACPI_FUNCTION_TRACE ("acpi_unload_table");
245
246
247 /* Parameter validation */
248
249 if (table_type > ACPI_TABLE_MAX) {
250 return_ACPI_STATUS (AE_BAD_PARAMETER);
251 }
252
253
254 /* Find all tables of the requested type */
255
256 table_desc = acpi_gbl_table_lists[table_type].next;
257 while (table_desc) {
258 /*
259 * Delete all namespace entries owned by this table. Note that these
260 * entries can appear anywhere in the namespace by virtue of the AML
261 * "Scope" operator. Thus, we need to track ownership by an ID, not
262 * simply a position within the hierarchy
263 */
264 acpi_ns_delete_namespace_by_owner (table_desc->table_id);
265
266 table_desc = table_desc->next;
267 }
268
269 /* Delete (or unmap) all tables of this type */
270
271 acpi_tb_delete_tables_by_type (table_type);
272 return_ACPI_STATUS (AE_OK);
273}
274
275
276/*******************************************************************************
277 *
278 * FUNCTION: acpi_get_table_header
279 *
280 * PARAMETERS: table_type - one of the defined table types
281 * Instance - the non zero instance of the table, allows
282 * support for multiple tables of the same type
283 * see acpi_gbl_acpi_table_flag
284 * out_table_header - pointer to the struct acpi_table_header if successful
285 *
286 * DESCRIPTION: This function is called to get an ACPI table header. The caller
287 * supplies an pointer to a data area sufficient to contain an ACPI
288 * struct acpi_table_header structure.
289 *
290 * The header contains a length field that can be used to determine
291 * the size of the buffer needed to contain the entire table. This
292 * function is not valid for the RSD PTR table since it does not
293 * have a standard header and is fixed length.
294 *
295 ******************************************************************************/
296
297acpi_status
298acpi_get_table_header (
299 acpi_table_type table_type,
300 u32 instance,
301 struct acpi_table_header *out_table_header)
302{
303 struct acpi_table_header *tbl_ptr;
304 acpi_status status;
305
306
307 ACPI_FUNCTION_TRACE ("acpi_get_table_header");
308
309
310 if ((instance == 0) ||
311 (table_type == ACPI_TABLE_RSDP) ||
312 (!out_table_header)) {
313 return_ACPI_STATUS (AE_BAD_PARAMETER);
314 }
315
316 /* Check the table type and instance */
317
318 if ((table_type > ACPI_TABLE_MAX) ||
319 (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
320 instance > 1)) {
321 return_ACPI_STATUS (AE_BAD_PARAMETER);
322 }
323
324
325 /* Get a pointer to the entire table */
326
327 status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
328 if (ACPI_FAILURE (status)) {
329 return_ACPI_STATUS (status);
330 }
331
332 /*
333 * The function will return a NULL pointer if the table is not loaded
334 */
335 if (tbl_ptr == NULL) {
336 return_ACPI_STATUS (AE_NOT_EXIST);
337 }
338
339 /*
340 * Copy the header to the caller's buffer
341 */
342 ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
343 sizeof (struct acpi_table_header));
344
345 return_ACPI_STATUS (status);
346}
347
348
349#endif /* ACPI_FUTURE_USAGE */
350
351/*******************************************************************************
352 *
353 * FUNCTION: acpi_get_table
354 *
355 * PARAMETERS: table_type - one of the defined table types
356 * Instance - the non zero instance of the table, allows
357 * support for multiple tables of the same type
358 * see acpi_gbl_acpi_table_flag
359 * ret_buffer - pointer to a structure containing a buffer to
360 * receive the table
361 *
362 * RETURN: Status
363 *
364 * DESCRIPTION: This function is called to get an ACPI table. The caller
365 * supplies an out_buffer large enough to contain the entire ACPI
366 * table. The caller should call the acpi_get_table_header function
367 * first to determine the buffer size needed. Upon completion
368 * the out_buffer->Length field will indicate the number of bytes
369 * copied into the out_buffer->buf_ptr buffer. This table will be
370 * a complete table including the header.
371 *
372 ******************************************************************************/
373
374acpi_status
375acpi_get_table (
376 acpi_table_type table_type,
377 u32 instance,
378 struct acpi_buffer *ret_buffer)
379{
380 struct acpi_table_header *tbl_ptr;
381 acpi_status status;
382 acpi_size table_length;
383
384
385 ACPI_FUNCTION_TRACE ("acpi_get_table");
386
387
388 /* Parameter validation */
389
390 if (instance == 0) {
391 return_ACPI_STATUS (AE_BAD_PARAMETER);
392 }
393
394 status = acpi_ut_validate_buffer (ret_buffer);
395 if (ACPI_FAILURE (status)) {
396 return_ACPI_STATUS (status);
397 }
398
399 /* Check the table type and instance */
400
401 if ((table_type > ACPI_TABLE_MAX) ||
402 (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
403 instance > 1)) {
404 return_ACPI_STATUS (AE_BAD_PARAMETER);
405 }
406
407
408 /* Get a pointer to the entire table */
409
410 status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
411 if (ACPI_FAILURE (status)) {
412 return_ACPI_STATUS (status);
413 }
414
415 /*
416 * acpi_tb_get_table_ptr will return a NULL pointer if the
417 * table is not loaded.
418 */
419 if (tbl_ptr == NULL) {
420 return_ACPI_STATUS (AE_NOT_EXIST);
421 }
422
423 /* Get the table length */
424
425 if (table_type == ACPI_TABLE_RSDP) {
426 /*
427 * RSD PTR is the only "table" without a header
428 */
429 table_length = sizeof (struct rsdp_descriptor);
430 }
431 else {
432 table_length = (acpi_size) tbl_ptr->length;
433 }
434
435 /* Validate/Allocate/Clear caller buffer */
436
437 status = acpi_ut_initialize_buffer (ret_buffer, table_length);
438 if (ACPI_FAILURE (status)) {
439 return_ACPI_STATUS (status);
440 }
441
442 /* Copy the table to the buffer */
443
444 ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length);
445 return_ACPI_STATUS (AE_OK);
446}
447EXPORT_SYMBOL(acpi_get_table);
448
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
new file mode 100644
index 000000000000..6e8072ebbac6
--- /dev/null
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -0,0 +1,606 @@
1/******************************************************************************
2 *
3 * Module Name: tbxfroot - Find the root ACPI table (RSDT)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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#include <linux/module.h>
45
46#include <acpi/acpi.h>
47#include <acpi/actables.h>
48
49
50#define _COMPONENT ACPI_TABLES
51 ACPI_MODULE_NAME ("tbxfroot")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_tb_find_table
57 *
58 * PARAMETERS: Signature - String with ACPI table signature
59 * oem_id - String with the table OEM ID
60 * oem_table_id - String with the OEM Table ID.
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
65 * Signature, OEM ID and OEM Table ID.
66 *
67 ******************************************************************************/
68
69acpi_status
70acpi_tb_find_table (
71 char *signature,
72 char *oem_id,
73 char *oem_table_id,
74 struct acpi_table_header **table_ptr)
75{
76 acpi_status status;
77 struct acpi_table_header *table;
78
79
80 ACPI_FUNCTION_TRACE ("tb_find_table");
81
82
83 /* Validate string lengths */
84
85 if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) ||
86 (ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) ||
87 (ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
88 return_ACPI_STATUS (AE_AML_STRING_LIMIT);
89 }
90
91 if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) {
92 /*
93 * The DSDT pointer is contained in the FADT, not the RSDT.
94 * This code should suffice, because the only code that would perform
95 * a "find" on the DSDT is the data_table_region() AML opcode -- in
96 * which case, the DSDT is guaranteed to be already loaded.
97 * If this becomes insufficient, the FADT will have to be found first.
98 */
99 if (!acpi_gbl_DSDT) {
100 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
101 }
102
103 table = acpi_gbl_DSDT;
104 }
105 else {
106 /* Find the table */
107
108 status = acpi_get_firmware_table (signature, 1,
109 ACPI_LOGICAL_ADDRESSING, &table);
110 if (ACPI_FAILURE (status)) {
111 return_ACPI_STATUS (status);
112 }
113 }
114
115 /* Check oem_id and oem_table_id */
116
117 if ((oem_id[0] && ACPI_STRNCMP (
118 oem_id, table->oem_id, sizeof (table->oem_id))) ||
119 (oem_table_id[0] && ACPI_STRNCMP (
120 oem_table_id, table->oem_table_id, sizeof (table->oem_table_id)))) {
121 return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
122 }
123
124 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature));
125 *table_ptr = table;
126 return_ACPI_STATUS (AE_OK);
127}
128
129
130/*******************************************************************************
131 *
132 * FUNCTION: acpi_get_firmware_table
133 *
134 * PARAMETERS: Signature - Any ACPI table signature
135 * Instance - the non zero instance of the table, allows
136 * support for multiple tables of the same type
137 * Flags - Physical/Virtual support
138 * table_pointer - Where a buffer containing the table is
139 * returned
140 *
141 * RETURN: Status
142 *
143 * DESCRIPTION: This function is called to get an ACPI table. A buffer is
144 * allocated for the table and returned in table_pointer.
145 * This table will be a complete table including the header.
146 *
147 ******************************************************************************/
148
149acpi_status
150acpi_get_firmware_table (
151 acpi_string signature,
152 u32 instance,
153 u32 flags,
154 struct acpi_table_header **table_pointer)
155{
156 acpi_status status;
157 struct acpi_pointer address;
158 struct acpi_table_header *header = NULL;
159 struct acpi_table_desc *table_info = NULL;
160 struct acpi_table_desc *rsdt_info;
161 u32 table_count;
162 u32 i;
163 u32 j;
164
165
166 ACPI_FUNCTION_TRACE ("acpi_get_firmware_table");
167
168
169 /*
170 * Ensure that at least the table manager is initialized. We don't
171 * require that the entire ACPI subsystem is up for this interface.
172 * If we have a buffer, we must have a length too
173 */
174 if ((instance == 0) ||
175 (!signature) ||
176 (!table_pointer)) {
177 return_ACPI_STATUS (AE_BAD_PARAMETER);
178 }
179
180 /* Ensure that we have a RSDP */
181
182 if (!acpi_gbl_RSDP) {
183 /* Get the RSDP */
184
185 status = acpi_os_get_root_pointer (flags, &address);
186 if (ACPI_FAILURE (status)) {
187 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
188 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
189 }
190
191 /* Map and validate the RSDP */
192
193 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
194 status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
195 (void *) &acpi_gbl_RSDP);
196 if (ACPI_FAILURE (status)) {
197 return_ACPI_STATUS (status);
198 }
199 }
200 else {
201 acpi_gbl_RSDP = address.pointer.logical;
202 }
203
204 /* The signature and checksum must both be correct */
205
206 if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
207 /* Nope, BAD Signature */
208
209 return_ACPI_STATUS (AE_BAD_SIGNATURE);
210 }
211
212 if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
213 /* Nope, BAD Checksum */
214
215 return_ACPI_STATUS (AE_BAD_CHECKSUM);
216 }
217 }
218
219 /* Get the RSDT address via the RSDP */
220
221 acpi_tb_get_rsdt_address (&address);
222 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
223 "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
224 acpi_gbl_RSDP,
225 ACPI_FORMAT_UINT64 (address.pointer.value)));
226
227 /* Insert processor_mode flags */
228
229 address.pointer_type |= flags;
230
231 /* Get and validate the RSDT */
232
233 rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
234 if (!rsdt_info) {
235 return_ACPI_STATUS (AE_NO_MEMORY);
236 }
237
238 status = acpi_tb_get_table (&address, rsdt_info);
239 if (ACPI_FAILURE (status)) {
240 goto cleanup;
241 }
242
243 status = acpi_tb_validate_rsdt (rsdt_info->pointer);
244 if (ACPI_FAILURE (status)) {
245 goto cleanup;
246 }
247
248 /* Allocate a scratch table header and table descriptor */
249
250 header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
251 if (!header) {
252 status = AE_NO_MEMORY;
253 goto cleanup;
254 }
255
256 table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
257 if (!table_info) {
258 status = AE_NO_MEMORY;
259 goto cleanup;
260 }
261
262 /* Get the number of table pointers within the RSDT */
263
264 table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
265 address.pointer_type = acpi_gbl_table_flags | flags;
266
267 /*
268 * Search the RSDT/XSDT for the correct instance of the
269 * requested table
270 */
271 for (i = 0, j = 0; i < table_count; i++) {
272 /* Get the next table pointer, handle RSDT vs. XSDT */
273
274 if (acpi_gbl_RSDP->revision < 2) {
275 address.pointer.value = (ACPI_CAST_PTR (
276 RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
277 }
278 else {
279 address.pointer.value = (ACPI_CAST_PTR (
280 XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
281 }
282
283 /* Get the table header */
284
285 status = acpi_tb_get_table_header (&address, header);
286 if (ACPI_FAILURE (status)) {
287 goto cleanup;
288 }
289
290 /* Compare table signatures and table instance */
291
292 if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
293 /* An instance of the table was found */
294
295 j++;
296 if (j >= instance) {
297 /* Found the correct instance, get the entire table */
298
299 status = acpi_tb_get_table_body (&address, header, table_info);
300 if (ACPI_FAILURE (status)) {
301 goto cleanup;
302 }
303
304 *table_pointer = table_info->pointer;
305 goto cleanup;
306 }
307 }
308 }
309
310 /* Did not find the table */
311
312 status = AE_NOT_EXIST;
313
314
315cleanup:
316 acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
317 ACPI_MEM_FREE (rsdt_info);
318
319 if (header) {
320 ACPI_MEM_FREE (header);
321 }
322 if (table_info) {
323 ACPI_MEM_FREE (table_info);
324 }
325 return_ACPI_STATUS (status);
326}
327EXPORT_SYMBOL(acpi_get_firmware_table);
328
329
330/* TBD: Move to a new file */
331
332#if ACPI_MACHINE_WIDTH != 16
333
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_find_root_pointer
337 *
338 * PARAMETERS: **rsdp_address - Where to place the RSDP address
339 * Flags - Logical/Physical addressing
340 *
341 * RETURN: Status, Physical address of the RSDP
342 *
343 * DESCRIPTION: Find the RSDP
344 *
345 ******************************************************************************/
346
347acpi_status
348acpi_find_root_pointer (
349 u32 flags,
350 struct acpi_pointer *rsdp_address)
351{
352 struct acpi_table_desc table_info;
353 acpi_status status;
354
355
356 ACPI_FUNCTION_TRACE ("acpi_find_root_pointer");
357
358
359 /* Get the RSDP */
360
361 status = acpi_tb_find_rsdp (&table_info, flags);
362 if (ACPI_FAILURE (status)) {
363 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
364 "RSDP structure not found, %s Flags=%X\n",
365 acpi_format_exception (status), flags));
366 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
367 }
368
369 rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER;
370 rsdp_address->pointer.physical = table_info.physical_address;
371 return_ACPI_STATUS (AE_OK);
372}
373
374
375/*******************************************************************************
376 *
377 * FUNCTION: acpi_tb_scan_memory_for_rsdp
378 *
379 * PARAMETERS: start_address - Starting pointer for search
380 * Length - Maximum length to search
381 *
382 * RETURN: Pointer to the RSDP if found, otherwise NULL.
383 *
384 * DESCRIPTION: Search a block of memory for the RSDP signature
385 *
386 ******************************************************************************/
387
388u8 *
389acpi_tb_scan_memory_for_rsdp (
390 u8 *start_address,
391 u32 length)
392{
393 u8 *mem_rover;
394 u8 *end_address;
395 u8 checksum;
396
397
398 ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
399
400
401 end_address = start_address + length;
402
403 /* Search from given start address for the requested length */
404
405 for (mem_rover = start_address; mem_rover < end_address;
406 mem_rover += ACPI_RSDP_SCAN_STEP) {
407 /* The signature and checksum must both be correct */
408
409 if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
410 /* No signature match, keep looking */
411
412 continue;
413 }
414
415 /* Signature matches, check the appropriate checksum */
416
417 if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
418 /* ACPI version 1.0 */
419
420 checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
421 }
422 else {
423 /* Post ACPI 1.0, use extended_checksum */
424
425 checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
426 }
427
428 if (checksum == 0) {
429 /* Checksum valid, we have found a valid RSDP */
430
431 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
432 "RSDP located at physical address %p\n", mem_rover));
433 return_PTR (mem_rover);
434 }
435
436 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
437 "Found an RSDP at physical address %p, but it has a bad checksum\n",
438 mem_rover));
439 }
440
441 /* Searched entire block, no RSDP was found */
442
443 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
444 "Searched entire block, no valid RSDP was found.\n"));
445 return_PTR (NULL);
446}
447
448
449/*******************************************************************************
450 *
451 * FUNCTION: acpi_tb_find_rsdp
452 *
453 * PARAMETERS: *table_info - Where the table info is returned
454 * Flags - Current memory mode (logical vs.
455 * physical addressing)
456 *
457 * RETURN: Status, RSDP physical address
458 *
459 * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor
460 * pointer structure. If it is found, set *RSDP to point to it.
461 *
462 * NOTE1: The RSDp must be either in the first 1_k of the Extended
463 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
464 * Only a 32-bit physical address is necessary.
465 *
466 * NOTE2: This function is always available, regardless of the
467 * initialization state of the rest of ACPI.
468 *
469 ******************************************************************************/
470
471acpi_status
472acpi_tb_find_rsdp (
473 struct acpi_table_desc *table_info,
474 u32 flags)
475{
476 u8 *table_ptr;
477 u8 *mem_rover;
478 u32 physical_address;
479 acpi_status status;
480
481
482 ACPI_FUNCTION_TRACE ("tb_find_rsdp");
483
484
485 /*
486 * Scan supports either 1) Logical addressing or 2) Physical addressing
487 */
488 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
489 /*
490 * 1a) Get the location of the EBDA
491 */
492 status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
493 ACPI_EBDA_PTR_LENGTH,
494 (void *) &table_ptr);
495 if (ACPI_FAILURE (status)) {
496 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
497 "Could not map memory at %8.8X for length %X\n",
498 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
499 return_ACPI_STATUS (status);
500 }
501
502 ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
503 physical_address <<= 4; /* Convert segment to physical address */
504 acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
505
506 /* EBDA present? */
507
508 if (physical_address > 0x400) {
509 /*
510 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
511 */
512 status = acpi_os_map_memory ((acpi_physical_address) physical_address,
513 ACPI_EBDA_WINDOW_SIZE,
514 (void *) &table_ptr);
515 if (ACPI_FAILURE (status)) {
516 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
517 "Could not map memory at %8.8X for length %X\n",
518 physical_address, ACPI_EBDA_WINDOW_SIZE));
519 return_ACPI_STATUS (status);
520 }
521
522 mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
523 acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
524
525 if (mem_rover) {
526 /* Found it, return the physical address */
527
528 physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
529
530 table_info->physical_address = (acpi_physical_address) physical_address;
531 return_ACPI_STATUS (AE_OK);
532 }
533 }
534
535 /*
536 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
537 */
538 status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
539 ACPI_HI_RSDP_WINDOW_SIZE,
540 (void *) &table_ptr);
541 if (ACPI_FAILURE (status)) {
542 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
543 "Could not map memory at %8.8X for length %X\n",
544 ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
545 return_ACPI_STATUS (status);
546 }
547
548 mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
549 acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
550
551 if (mem_rover) {
552 /* Found it, return the physical address */
553
554 physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
555
556 table_info->physical_address = (acpi_physical_address) physical_address;
557 return_ACPI_STATUS (AE_OK);
558 }
559 }
560
561 /*
562 * Physical addressing
563 */
564 else {
565 /*
566 * 1a) Get the location of the EBDA
567 */
568 ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
569 physical_address <<= 4; /* Convert segment to physical address */
570
571 /* EBDA present? */
572
573 if (physical_address > 0x400) {
574 /*
575 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
576 */
577 mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
578 ACPI_EBDA_WINDOW_SIZE);
579 if (mem_rover) {
580 /* Found it, return the physical address */
581
582 table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
583 return_ACPI_STATUS (AE_OK);
584 }
585 }
586
587 /*
588 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
589 */
590 mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
591 ACPI_HI_RSDP_WINDOW_SIZE);
592 if (mem_rover) {
593 /* Found it, return the physical address */
594
595 table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
596 return_ACPI_STATUS (AE_OK);
597 }
598 }
599
600 /* RSDP signature was not found */
601
602 return_ACPI_STATUS (AE_NOT_FOUND);
603}
604
605#endif
606