diff options
Diffstat (limited to 'drivers/acpi/tables')
-rw-r--r-- | drivers/acpi/tables/tbconvrt.c | 622 | ||||
-rw-r--r-- | drivers/acpi/tables/tbfind.c | 126 | ||||
-rw-r--r-- | drivers/acpi/tables/tbget.c | 471 | ||||
-rw-r--r-- | drivers/acpi/tables/tbgetall.c | 311 | ||||
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 650 | ||||
-rw-r--r-- | drivers/acpi/tables/tbrsdt.c | 307 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 600 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 620 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 550 |
9 files changed, 1290 insertions, 2967 deletions
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c deleted file mode 100644 index d697fcb35d52..000000000000 --- a/drivers/acpi/tables/tbconvrt.c +++ /dev/null | |||
@@ -1,622 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbconvrt - ACPI Table conversion utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, 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 <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbconvrt") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static void | ||
52 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
53 | u8 register_bit_width, | ||
54 | acpi_physical_address address); | ||
55 | |||
56 | static void | ||
57 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
58 | struct fadt_descriptor_rev1 *original_fadt); | ||
59 | |||
60 | static void | ||
61 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
62 | struct fadt_descriptor *original_fadt); | ||
63 | |||
64 | u8 acpi_fadt_is_v1; | ||
65 | ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) | ||
66 | |||
67 | /******************************************************************************* | ||
68 | * | ||
69 | * FUNCTION: acpi_tb_get_table_count | ||
70 | * | ||
71 | * PARAMETERS: RSDP - Pointer to the RSDP | ||
72 | * RSDT - Pointer to the RSDT/XSDT | ||
73 | * | ||
74 | * RETURN: The number of tables pointed to by the RSDT or XSDT. | ||
75 | * | ||
76 | * DESCRIPTION: Calculate the number of tables. Automatically handles either | ||
77 | * an RSDT or XSDT. | ||
78 | * | ||
79 | ******************************************************************************/ | ||
80 | |||
81 | u32 | ||
82 | acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, | ||
83 | struct acpi_table_header *RSDT) | ||
84 | { | ||
85 | u32 pointer_size; | ||
86 | |||
87 | ACPI_FUNCTION_ENTRY(); | ||
88 | |||
89 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
90 | |||
91 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
92 | pointer_size = sizeof(u32); | ||
93 | } else { | ||
94 | pointer_size = sizeof(u64); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Determine the number of tables pointed to by the RSDT/XSDT. | ||
99 | * This is defined by the ACPI Specification to be the number of | ||
100 | * pointers contained within the RSDT/XSDT. The size of the pointers | ||
101 | * is architecture-dependent. | ||
102 | */ | ||
103 | return ((RSDT->length - | ||
104 | sizeof(struct acpi_table_header)) / pointer_size); | ||
105 | } | ||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_tb_convert_to_xsdt | ||
110 | * | ||
111 | * PARAMETERS: table_info - Info about the RSDT | ||
112 | * | ||
113 | * RETURN: Status | ||
114 | * | ||
115 | * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) | ||
116 | * | ||
117 | ******************************************************************************/ | ||
118 | |||
119 | acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) | ||
120 | { | ||
121 | acpi_size table_size; | ||
122 | u32 i; | ||
123 | struct xsdt_descriptor *new_table; | ||
124 | |||
125 | ACPI_FUNCTION_ENTRY(); | ||
126 | |||
127 | /* Compute size of the converted XSDT */ | ||
128 | |||
129 | table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) + | ||
130 | sizeof(struct acpi_table_header); | ||
131 | |||
132 | /* Allocate an XSDT */ | ||
133 | |||
134 | new_table = ACPI_ALLOCATE_ZEROED(table_size); | ||
135 | if (!new_table) { | ||
136 | return (AE_NO_MEMORY); | ||
137 | } | ||
138 | |||
139 | /* Copy the header and set the length */ | ||
140 | |||
141 | ACPI_MEMCPY(new_table, table_info->pointer, | ||
142 | sizeof(struct acpi_table_header)); | ||
143 | new_table->length = (u32) table_size; | ||
144 | |||
145 | /* Copy the table pointers */ | ||
146 | |||
147 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
148 | |||
149 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
150 | |||
151 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
152 | ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], | ||
153 | (ACPI_CAST_PTR | ||
154 | (struct rsdt_descriptor, | ||
155 | table_info->pointer))-> | ||
156 | table_offset_entry[i]); | ||
157 | } else { | ||
158 | new_table->table_offset_entry[i] = | ||
159 | (ACPI_CAST_PTR(struct xsdt_descriptor, | ||
160 | table_info->pointer))-> | ||
161 | table_offset_entry[i]; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* Delete the original table (either mapped or in a buffer) */ | ||
166 | |||
167 | acpi_tb_delete_single_table(table_info); | ||
168 | |||
169 | /* Point the table descriptor to the new table */ | ||
170 | |||
171 | table_info->pointer = | ||
172 | ACPI_CAST_PTR(struct acpi_table_header, new_table); | ||
173 | table_info->length = table_size; | ||
174 | table_info->allocation = ACPI_MEM_ALLOCATED; | ||
175 | |||
176 | return (AE_OK); | ||
177 | } | ||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * FUNCTION: acpi_tb_init_generic_address | ||
182 | * | ||
183 | * PARAMETERS: new_gas_struct - GAS struct to be initialized | ||
184 | * register_bit_width - Width of this register | ||
185 | * Address - Address of the register | ||
186 | * | ||
187 | * RETURN: None | ||
188 | * | ||
189 | * DESCRIPTION: Initialize a GAS structure. | ||
190 | * | ||
191 | ******************************************************************************/ | ||
192 | |||
193 | static void | ||
194 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
195 | u8 register_bit_width, | ||
196 | acpi_physical_address address) | ||
197 | { | ||
198 | |||
199 | ACPI_STORE_ADDRESS(new_gas_struct->address, address); | ||
200 | |||
201 | new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
202 | new_gas_struct->register_bit_width = register_bit_width; | ||
203 | new_gas_struct->register_bit_offset = 0; | ||
204 | new_gas_struct->access_width = 0; | ||
205 | } | ||
206 | |||
207 | /******************************************************************************* | ||
208 | * | ||
209 | * FUNCTION: acpi_tb_convert_fadt1 | ||
210 | * | ||
211 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
212 | * original_fadt - Pointer to old FADT | ||
213 | * | ||
214 | * RETURN: None, populates local_fadt | ||
215 | * | ||
216 | * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format | ||
217 | * | ||
218 | ******************************************************************************/ | ||
219 | |||
220 | static void | ||
221 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
222 | struct fadt_descriptor_rev1 *original_fadt) | ||
223 | { | ||
224 | |||
225 | /* ACPI 1.0 FACS */ | ||
226 | /* The BIOS stored FADT should agree with Revision 1.0 */ | ||
227 | acpi_fadt_is_v1 = 1; | ||
228 | |||
229 | /* | ||
230 | * Copy the table header and the common part of the tables. | ||
231 | * | ||
232 | * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 | ||
233 | * table can be copied first, then expand some fields to 64 bits. | ||
234 | */ | ||
235 | ACPI_MEMCPY(local_fadt, original_fadt, | ||
236 | sizeof(struct fadt_descriptor_rev1)); | ||
237 | |||
238 | /* Convert table pointers to 64-bit fields */ | ||
239 | |||
240 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
241 | local_fadt->V1_firmware_ctrl); | ||
242 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
243 | |||
244 | /* | ||
245 | * System Interrupt Model isn't used in ACPI 2.0 | ||
246 | * (local_fadt->Reserved1 = 0;) | ||
247 | */ | ||
248 | |||
249 | /* | ||
250 | * This field is set by the OEM to convey the preferred power management | ||
251 | * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't | ||
252 | * know what kind of 32-bit system this is, we will use "unspecified". | ||
253 | */ | ||
254 | local_fadt->prefer_PM_profile = PM_UNSPECIFIED; | ||
255 | |||
256 | /* | ||
257 | * Processor Performance State Control. This is the value OSPM writes to | ||
258 | * the SMI_CMD register to assume processor performance state control | ||
259 | * responsibility. There isn't any equivalence in 1.0, but as many 1.x | ||
260 | * ACPI tables contain _PCT and _PSS we also keep this value, unless | ||
261 | * acpi_strict is set. | ||
262 | */ | ||
263 | if (acpi_strict) | ||
264 | local_fadt->pstate_cnt = 0; | ||
265 | |||
266 | /* | ||
267 | * Support for the _CST object and C States change notification. | ||
268 | * This data item hasn't any 1.0 equivalence so leave it zero. | ||
269 | */ | ||
270 | local_fadt->cst_cnt = 0; | ||
271 | |||
272 | /* | ||
273 | * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. | ||
274 | * It primarily adds the FADT reset mechanism. | ||
275 | */ | ||
276 | if ((original_fadt->revision == 2) && | ||
277 | (original_fadt->length == | ||
278 | sizeof(struct fadt_descriptor_rev2_minus))) { | ||
279 | /* | ||
280 | * Grab the entire generic address struct, plus the 1-byte reset value | ||
281 | * that immediately follows. | ||
282 | */ | ||
283 | ACPI_MEMCPY(&local_fadt->reset_register, | ||
284 | &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus, | ||
285 | original_fadt))->reset_register, | ||
286 | sizeof(struct acpi_generic_address) + 1); | ||
287 | } else { | ||
288 | /* | ||
289 | * Since there isn't any equivalence in 1.0 and since it is highly | ||
290 | * likely that a 1.0 system has legacy support. | ||
291 | */ | ||
292 | local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Convert the V1.0 block addresses to V2.0 GAS structures | ||
297 | */ | ||
298 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
299 | local_fadt->pm1_evt_len, | ||
300 | (acpi_physical_address) local_fadt-> | ||
301 | V1_pm1a_evt_blk); | ||
302 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
303 | local_fadt->pm1_evt_len, | ||
304 | (acpi_physical_address) local_fadt-> | ||
305 | V1_pm1b_evt_blk); | ||
306 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
307 | local_fadt->pm1_cnt_len, | ||
308 | (acpi_physical_address) local_fadt-> | ||
309 | V1_pm1a_cnt_blk); | ||
310 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
311 | local_fadt->pm1_cnt_len, | ||
312 | (acpi_physical_address) local_fadt-> | ||
313 | V1_pm1b_cnt_blk); | ||
314 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
315 | local_fadt->pm2_cnt_len, | ||
316 | (acpi_physical_address) local_fadt-> | ||
317 | V1_pm2_cnt_blk); | ||
318 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
319 | local_fadt->pm_tm_len, | ||
320 | (acpi_physical_address) local_fadt-> | ||
321 | V1_pm_tmr_blk); | ||
322 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0, | ||
323 | (acpi_physical_address) local_fadt-> | ||
324 | V1_gpe0_blk); | ||
325 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0, | ||
326 | (acpi_physical_address) local_fadt-> | ||
327 | V1_gpe1_blk); | ||
328 | |||
329 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
330 | |||
331 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
332 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
333 | pm1_evt_len), | ||
334 | (acpi_physical_address) | ||
335 | (local_fadt->xpm1a_evt_blk.address + | ||
336 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
337 | |||
338 | /* PM1B is optional; leave null if not present */ | ||
339 | |||
340 | if (local_fadt->xpm1b_evt_blk.address) { | ||
341 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
342 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
343 | pm1_evt_len), | ||
344 | (acpi_physical_address) | ||
345 | (local_fadt->xpm1b_evt_blk. | ||
346 | address + | ||
347 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
348 | pm1_evt_len))); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /******************************************************************************* | ||
353 | * | ||
354 | * FUNCTION: acpi_tb_convert_fadt2 | ||
355 | * | ||
356 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
357 | * original_fadt - Pointer to old FADT | ||
358 | * | ||
359 | * RETURN: None, populates local_fadt | ||
360 | * | ||
361 | * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. | ||
362 | * Handles optional "X" fields. | ||
363 | * | ||
364 | ******************************************************************************/ | ||
365 | |||
366 | static void | ||
367 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
368 | struct fadt_descriptor *original_fadt) | ||
369 | { | ||
370 | |||
371 | /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ | ||
372 | |||
373 | ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); | ||
374 | |||
375 | /* | ||
376 | * "X" fields are optional extensions to the original V1.0 fields, so | ||
377 | * we must selectively expand V1.0 fields if the corresponding X field | ||
378 | * is zero. | ||
379 | */ | ||
380 | if (!(local_fadt->xfirmware_ctrl)) { | ||
381 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
382 | local_fadt->V1_firmware_ctrl); | ||
383 | } | ||
384 | |||
385 | if (!(local_fadt->Xdsdt)) { | ||
386 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
387 | } | ||
388 | |||
389 | if (!(local_fadt->xpm1a_evt_blk.address)) { | ||
390 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
391 | local_fadt->pm1_evt_len, | ||
392 | (acpi_physical_address) | ||
393 | local_fadt->V1_pm1a_evt_blk); | ||
394 | } | ||
395 | |||
396 | if (!(local_fadt->xpm1b_evt_blk.address)) { | ||
397 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
398 | local_fadt->pm1_evt_len, | ||
399 | (acpi_physical_address) | ||
400 | local_fadt->V1_pm1b_evt_blk); | ||
401 | } | ||
402 | |||
403 | if (!(local_fadt->xpm1a_cnt_blk.address)) { | ||
404 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
405 | local_fadt->pm1_cnt_len, | ||
406 | (acpi_physical_address) | ||
407 | local_fadt->V1_pm1a_cnt_blk); | ||
408 | } | ||
409 | |||
410 | if (!(local_fadt->xpm1b_cnt_blk.address)) { | ||
411 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
412 | local_fadt->pm1_cnt_len, | ||
413 | (acpi_physical_address) | ||
414 | local_fadt->V1_pm1b_cnt_blk); | ||
415 | } | ||
416 | |||
417 | if (!(local_fadt->xpm2_cnt_blk.address)) { | ||
418 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
419 | local_fadt->pm2_cnt_len, | ||
420 | (acpi_physical_address) | ||
421 | local_fadt->V1_pm2_cnt_blk); | ||
422 | } | ||
423 | |||
424 | if (!(local_fadt->xpm_tmr_blk.address)) { | ||
425 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
426 | local_fadt->pm_tm_len, | ||
427 | (acpi_physical_address) | ||
428 | local_fadt->V1_pm_tmr_blk); | ||
429 | } | ||
430 | |||
431 | if (!(local_fadt->xgpe0_blk.address)) { | ||
432 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, | ||
433 | 0, | ||
434 | (acpi_physical_address) | ||
435 | local_fadt->V1_gpe0_blk); | ||
436 | } | ||
437 | |||
438 | if (!(local_fadt->xgpe1_blk.address)) { | ||
439 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, | ||
440 | 0, | ||
441 | (acpi_physical_address) | ||
442 | local_fadt->V1_gpe1_blk); | ||
443 | } | ||
444 | |||
445 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
446 | |||
447 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
448 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
449 | pm1_evt_len), | ||
450 | (acpi_physical_address) | ||
451 | (local_fadt->xpm1a_evt_blk.address + | ||
452 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
453 | |||
454 | acpi_gbl_xpm1a_enable.address_space_id = | ||
455 | local_fadt->xpm1a_evt_blk.address_space_id; | ||
456 | |||
457 | /* PM1B is optional; leave null if not present */ | ||
458 | |||
459 | if (local_fadt->xpm1b_evt_blk.address) { | ||
460 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
461 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
462 | pm1_evt_len), | ||
463 | (acpi_physical_address) | ||
464 | (local_fadt->xpm1b_evt_blk. | ||
465 | address + | ||
466 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
467 | pm1_evt_len))); | ||
468 | |||
469 | acpi_gbl_xpm1b_enable.address_space_id = | ||
470 | local_fadt->xpm1b_evt_blk.address_space_id; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /******************************************************************************* | ||
475 | * | ||
476 | * FUNCTION: acpi_tb_convert_table_fadt | ||
477 | * | ||
478 | * PARAMETERS: None | ||
479 | * | ||
480 | * RETURN: Status | ||
481 | * | ||
482 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local | ||
483 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | ||
484 | * copied to the local FADT. The ACPI CA software uses this | ||
485 | * local FADT. Thus a significant amount of special #ifdef | ||
486 | * type codeing is saved. | ||
487 | * | ||
488 | ******************************************************************************/ | ||
489 | |||
490 | acpi_status acpi_tb_convert_table_fadt(void) | ||
491 | { | ||
492 | struct fadt_descriptor *local_fadt; | ||
493 | struct acpi_table_desc *table_desc; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_convert_table_fadt); | ||
496 | |||
497 | /* | ||
498 | * acpi_gbl_FADT is valid. Validate the FADT length. The table must be | ||
499 | * at least as long as the version 1.0 FADT | ||
500 | */ | ||
501 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { | ||
502 | ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", | ||
503 | acpi_gbl_FADT->length)); | ||
504 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
505 | } | ||
506 | |||
507 | /* Allocate buffer for the ACPI 2.0(+) FADT */ | ||
508 | |||
509 | local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); | ||
510 | if (!local_fadt) { | ||
511 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
512 | } | ||
513 | |||
514 | if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { | ||
515 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { | ||
516 | |||
517 | /* Length is too short to be a V2.0 table */ | ||
518 | |||
519 | ACPI_WARNING((AE_INFO, | ||
520 | "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", | ||
521 | acpi_gbl_FADT->length, | ||
522 | acpi_gbl_FADT->revision)); | ||
523 | |||
524 | acpi_tb_convert_fadt1(local_fadt, | ||
525 | (void *)acpi_gbl_FADT); | ||
526 | } else { | ||
527 | /* Valid V2.0 table */ | ||
528 | |||
529 | acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT); | ||
530 | } | ||
531 | } else { | ||
532 | /* Valid V1.0 table */ | ||
533 | |||
534 | acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); | ||
535 | } | ||
536 | |||
537 | /* Global FADT pointer will point to the new common V2.0 FADT */ | ||
538 | |||
539 | acpi_gbl_FADT = local_fadt; | ||
540 | acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); | ||
541 | |||
542 | /* Free the original table */ | ||
543 | |||
544 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; | ||
545 | acpi_tb_delete_single_table(table_desc); | ||
546 | |||
547 | /* Install the new table */ | ||
548 | |||
549 | table_desc->pointer = | ||
550 | ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); | ||
551 | table_desc->allocation = ACPI_MEM_ALLOCATED; | ||
552 | table_desc->length = sizeof(struct fadt_descriptor); | ||
553 | |||
554 | /* Dump the entire FADT */ | ||
555 | |||
556 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
557 | "Hex dump of common internal FADT, size %d (%X)\n", | ||
558 | acpi_gbl_FADT->length, acpi_gbl_FADT->length)); | ||
559 | |||
560 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), | ||
561 | acpi_gbl_FADT->length); | ||
562 | |||
563 | return_ACPI_STATUS(AE_OK); | ||
564 | } | ||
565 | |||
566 | /******************************************************************************* | ||
567 | * | ||
568 | * FUNCTION: acpi_tb_build_common_facs | ||
569 | * | ||
570 | * PARAMETERS: table_info - Info for currently installed FACS | ||
571 | * | ||
572 | * RETURN: Status | ||
573 | * | ||
574 | * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal | ||
575 | * table format. | ||
576 | * | ||
577 | ******************************************************************************/ | ||
578 | |||
579 | acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) | ||
580 | { | ||
581 | |||
582 | ACPI_FUNCTION_TRACE(tb_build_common_facs); | ||
583 | |||
584 | /* Absolute minimum length is 24, but the ACPI spec says 64 */ | ||
585 | |||
586 | if (acpi_gbl_FACS->length < 24) { | ||
587 | ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", | ||
588 | acpi_gbl_FACS->length)); | ||
589 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
590 | } | ||
591 | |||
592 | if (acpi_gbl_FACS->length < 64) { | ||
593 | ACPI_WARNING((AE_INFO, | ||
594 | "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", | ||
595 | acpi_gbl_FACS->length)); | ||
596 | } | ||
597 | |||
598 | /* Copy fields to the new FACS */ | ||
599 | |||
600 | acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); | ||
601 | |||
602 | if ((acpi_gbl_RSDP->revision < 2) || | ||
603 | (acpi_gbl_FACS->length < 32) || | ||
604 | (!(acpi_gbl_FACS->xfirmware_waking_vector))) { | ||
605 | |||
606 | /* ACPI 1.0 FACS or short table or optional X_ field is zero */ | ||
607 | |||
608 | acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, | ||
609 | & | ||
610 | (acpi_gbl_FACS-> | ||
611 | firmware_waking_vector)); | ||
612 | acpi_gbl_common_fACS.vector_width = 32; | ||
613 | } else { | ||
614 | /* ACPI 2.0 FACS with valid X_ field */ | ||
615 | |||
616 | acpi_gbl_common_fACS.firmware_waking_vector = | ||
617 | &acpi_gbl_FACS->xfirmware_waking_vector; | ||
618 | acpi_gbl_common_fACS.vector_width = 64; | ||
619 | } | ||
620 | |||
621 | return_ACPI_STATUS(AE_OK); | ||
622 | } | ||
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c new file mode 100644 index 000000000000..769213c74c16 --- /dev/null +++ b/drivers/acpi/tables/tbfind.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbfind - find table | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, 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 <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbfind") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_find_table | ||
53 | * | ||
54 | * PARAMETERS: Signature - String with ACPI table signature | ||
55 | * oem_id - String with the table OEM ID | ||
56 | * oem_table_id - String with the OEM Table ID | ||
57 | * table_index - Where the table index is returned | ||
58 | * | ||
59 | * RETURN: Status and table index | ||
60 | * | ||
61 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | ||
62 | * Signature, OEM ID and OEM Table ID. Returns an index that can | ||
63 | * be used to get the table header or entire table. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_tb_find_table(char *signature, | ||
68 | char *oem_id, | ||
69 | char *oem_table_id, acpi_native_uint * table_index) | ||
70 | { | ||
71 | acpi_native_uint i; | ||
72 | acpi_status status; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
75 | |||
76 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
77 | if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), | ||
78 | signature, ACPI_NAME_SIZE)) { | ||
79 | |||
80 | /* Not the requested table */ | ||
81 | |||
82 | continue; | ||
83 | } | ||
84 | |||
85 | /* Table with matching signature has been found */ | ||
86 | |||
87 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
88 | |||
89 | /* Table is not currently mapped, map it */ | ||
90 | |||
91 | status = | ||
92 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
93 | tables[i]); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | return_ACPI_STATUS(status); | ||
96 | } | ||
97 | |||
98 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
99 | continue; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Check for table match on all IDs */ | ||
104 | |||
105 | if (!ACPI_MEMCMP | ||
106 | (acpi_gbl_root_table_list.tables[i].pointer->signature, | ||
107 | signature, ACPI_NAME_SIZE) && (!oem_id[0] | ||
108 | || | ||
109 | !ACPI_MEMCMP | ||
110 | (acpi_gbl_root_table_list. | ||
111 | tables[i].pointer->oem_id, | ||
112 | oem_id, ACPI_OEM_ID_SIZE)) | ||
113 | && (!oem_table_id[0] | ||
114 | || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. | ||
115 | pointer->oem_table_id, oem_table_id, | ||
116 | ACPI_OEM_TABLE_ID_SIZE))) { | ||
117 | *table_index = i; | ||
118 | |||
119 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
120 | "Found table [%4.4s]\n", signature)); | ||
121 | return_ACPI_STATUS(AE_OK); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
126 | } | ||
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c deleted file mode 100644 index 11e2d4454e05..000000000000 --- a/drivers/acpi/tables/tbget.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbget - ACPI Table get* routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, 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 <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbget") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_header *header, | ||
54 | struct acpi_table_desc *table_info); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_tb_table_override(struct acpi_table_header *header, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
65 | * Logical or Physical | ||
66 | * table_info - Where table info is returned | ||
67 | * | ||
68 | * RETURN: None | ||
69 | * | ||
70 | * DESCRIPTION: Get entire table of unknown size. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status | ||
75 | acpi_tb_get_table(struct acpi_pointer *address, | ||
76 | struct acpi_table_desc *table_info) | ||
77 | { | ||
78 | acpi_status status; | ||
79 | struct acpi_table_header header; | ||
80 | |||
81 | ACPI_FUNCTION_TRACE(tb_get_table); | ||
82 | |||
83 | /* Get the header in order to get signature and table size */ | ||
84 | |||
85 | status = acpi_tb_get_table_header(address, &header); | ||
86 | if (ACPI_FAILURE(status)) { | ||
87 | return_ACPI_STATUS(status); | ||
88 | } | ||
89 | |||
90 | /* Get the entire table */ | ||
91 | |||
92 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
93 | if (ACPI_FAILURE(status)) { | ||
94 | ACPI_EXCEPTION((AE_INFO, status, | ||
95 | "Could not get ACPI table (size %X)", | ||
96 | header.length)); | ||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | return_ACPI_STATUS(AE_OK); | ||
101 | } | ||
102 | |||
103 | /******************************************************************************* | ||
104 | * | ||
105 | * FUNCTION: acpi_tb_get_table_header | ||
106 | * | ||
107 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
108 | * Logical or Physical | ||
109 | * return_header - Where the table header is returned | ||
110 | * | ||
111 | * RETURN: Status | ||
112 | * | ||
113 | * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual | ||
114 | * addressing mode. Works with both physical or logical pointers. | ||
115 | * Table is either copied or mapped, depending on the pointer | ||
116 | * type and mode of the processor. | ||
117 | * | ||
118 | ******************************************************************************/ | ||
119 | |||
120 | acpi_status | ||
121 | acpi_tb_get_table_header(struct acpi_pointer *address, | ||
122 | struct acpi_table_header *return_header) | ||
123 | { | ||
124 | acpi_status status = AE_OK; | ||
125 | struct acpi_table_header *header = NULL; | ||
126 | |||
127 | ACPI_FUNCTION_TRACE(tb_get_table_header); | ||
128 | |||
129 | /* | ||
130 | * Flags contains the current processor mode (Virtual or Physical | ||
131 | * addressing) 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, | ||
140 | sizeof(struct acpi_table_header)); | ||
141 | break; | ||
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, | ||
148 | sizeof(struct acpi_table_header), | ||
149 | (void *)&header); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | ACPI_ERROR((AE_INFO, | ||
152 | "Could not map memory at %8.8X%8.8X for table header", | ||
153 | ACPI_FORMAT_UINT64(address->pointer. | ||
154 | physical))); | ||
155 | return_ACPI_STATUS(status); | ||
156 | } | ||
157 | |||
158 | /* Copy header and delete mapping */ | ||
159 | |||
160 | ACPI_MEMCPY(return_header, header, | ||
161 | sizeof(struct acpi_table_header)); | ||
162 | acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); | ||
163 | break; | ||
164 | |||
165 | default: | ||
166 | |||
167 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
168 | address->pointer_type)); | ||
169 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
170 | } | ||
171 | |||
172 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", | ||
173 | return_header->signature)); | ||
174 | |||
175 | return_ACPI_STATUS(AE_OK); | ||
176 | } | ||
177 | |||
178 | /******************************************************************************* | ||
179 | * | ||
180 | * FUNCTION: acpi_tb_get_table_body | ||
181 | * | ||
182 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
183 | * Logical or Physical | ||
184 | * Header - Header of the table to retrieve | ||
185 | * table_info - Where the table info is returned | ||
186 | * | ||
187 | * RETURN: Status | ||
188 | * | ||
189 | * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to | ||
190 | * replace the table with a newer version (table override.) | ||
191 | * Works in both physical or virtual | ||
192 | * addressing mode. Works with both physical or logical pointers. | ||
193 | * Table is either copied or mapped, depending on the pointer | ||
194 | * type and mode of the processor. | ||
195 | * | ||
196 | ******************************************************************************/ | ||
197 | |||
198 | acpi_status | ||
199 | acpi_tb_get_table_body(struct acpi_pointer *address, | ||
200 | struct acpi_table_header *header, | ||
201 | struct acpi_table_desc *table_info) | ||
202 | { | ||
203 | acpi_status status; | ||
204 | |||
205 | ACPI_FUNCTION_TRACE(tb_get_table_body); | ||
206 | |||
207 | if (!table_info || !address) { | ||
208 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
209 | } | ||
210 | |||
211 | /* Attempt table override. */ | ||
212 | |||
213 | status = acpi_tb_table_override(header, table_info); | ||
214 | if (ACPI_SUCCESS(status)) { | ||
215 | |||
216 | /* Table was overridden by the host OS */ | ||
217 | |||
218 | return_ACPI_STATUS(status); | ||
219 | } | ||
220 | |||
221 | /* No override, get the original table */ | ||
222 | |||
223 | status = acpi_tb_get_this_table(address, header, table_info); | ||
224 | return_ACPI_STATUS(status); | ||
225 | } | ||
226 | |||
227 | /******************************************************************************* | ||
228 | * | ||
229 | * FUNCTION: acpi_tb_table_override | ||
230 | * | ||
231 | * PARAMETERS: Header - Pointer to table header | ||
232 | * table_info - Return info if table is overridden | ||
233 | * | ||
234 | * RETURN: None | ||
235 | * | ||
236 | * DESCRIPTION: Attempts override of current table with a new one if provided | ||
237 | * by the host OS. | ||
238 | * | ||
239 | ******************************************************************************/ | ||
240 | |||
241 | static acpi_status | ||
242 | acpi_tb_table_override(struct acpi_table_header *header, | ||
243 | struct acpi_table_desc *table_info) | ||
244 | { | ||
245 | struct acpi_table_header *new_table; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_table_override); | ||
250 | |||
251 | /* | ||
252 | * The OSL will examine the header and decide whether to override this | ||
253 | * table. If it decides to override, a table will be returned in new_table, | ||
254 | * which we will then copy. | ||
255 | */ | ||
256 | status = acpi_os_table_override(header, &new_table); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | |||
259 | /* Some severe error from the OSL, but we basically ignore it */ | ||
260 | |||
261 | ACPI_EXCEPTION((AE_INFO, status, | ||
262 | "Could not override ACPI table")); | ||
263 | return_ACPI_STATUS(status); | ||
264 | } | ||
265 | |||
266 | if (!new_table) { | ||
267 | |||
268 | /* No table override */ | ||
269 | |||
270 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * We have a new table to override the old one. Get a copy of | ||
275 | * the new one. We know that the new table has a logical pointer. | ||
276 | */ | ||
277 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | ||
278 | address.pointer.logical = new_table; | ||
279 | |||
280 | status = acpi_tb_get_this_table(&address, new_table, table_info); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); | ||
283 | return_ACPI_STATUS(status); | ||
284 | } | ||
285 | |||
286 | /* Copy the table info */ | ||
287 | |||
288 | ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", | ||
289 | table_info->pointer->signature)); | ||
290 | |||
291 | return_ACPI_STATUS(AE_OK); | ||
292 | } | ||
293 | |||
294 | /******************************************************************************* | ||
295 | * | ||
296 | * FUNCTION: acpi_tb_get_this_table | ||
297 | * | ||
298 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
299 | * Logical or Physical | ||
300 | * Header - Header of the table to retrieve | ||
301 | * table_info - Where the table info is returned | ||
302 | * | ||
303 | * RETURN: Status | ||
304 | * | ||
305 | * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual | ||
306 | * addressing mode. Works with both physical or logical pointers. | ||
307 | * Table is either copied or mapped, depending on the pointer | ||
308 | * type and mode of the processor. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | |||
312 | static acpi_status | ||
313 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
314 | struct acpi_table_header *header, | ||
315 | struct acpi_table_desc *table_info) | ||
316 | { | ||
317 | struct acpi_table_header *full_table = NULL; | ||
318 | u8 allocation; | ||
319 | acpi_status status = AE_OK; | ||
320 | |||
321 | ACPI_FUNCTION_TRACE(tb_get_this_table); | ||
322 | |||
323 | /* Validate minimum length */ | ||
324 | |||
325 | if (header->length < sizeof(struct acpi_table_header)) { | ||
326 | ACPI_ERROR((AE_INFO, | ||
327 | "Table length (%X) is smaller than minimum (%zX)", | ||
328 | header->length, sizeof(struct acpi_table_header))); | ||
329 | |||
330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Flags contains the current processor mode (Virtual or Physical | ||
335 | * addressing) The pointer_type is either Logical or Physical | ||
336 | */ | ||
337 | switch (address->pointer_type) { | ||
338 | case ACPI_PHYSMODE_PHYSPTR: | ||
339 | case ACPI_LOGMODE_LOGPTR: | ||
340 | |||
341 | /* Pointer matches processor mode, copy the table to a new buffer */ | ||
342 | |||
343 | full_table = ACPI_ALLOCATE(header->length); | ||
344 | if (!full_table) { | ||
345 | ACPI_ERROR((AE_INFO, | ||
346 | "Could not allocate table memory for [%4.4s] length %X", | ||
347 | header->signature, header->length)); | ||
348 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
349 | } | ||
350 | |||
351 | /* Copy the entire table (including header) to the local buffer */ | ||
352 | |||
353 | ACPI_MEMCPY(full_table, address->pointer.logical, | ||
354 | header->length); | ||
355 | |||
356 | /* Save allocation type */ | ||
357 | |||
358 | allocation = ACPI_MEM_ALLOCATED; | ||
359 | break; | ||
360 | |||
361 | case ACPI_LOGMODE_PHYSPTR: | ||
362 | |||
363 | /* | ||
364 | * Just map the table's physical memory | ||
365 | * into our address space. | ||
366 | */ | ||
367 | status = acpi_os_map_memory(address->pointer.physical, | ||
368 | (acpi_size) header->length, | ||
369 | ACPI_CAST_PTR(void, &full_table)); | ||
370 | if (ACPI_FAILURE(status)) { | ||
371 | ACPI_ERROR((AE_INFO, | ||
372 | "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", | ||
373 | header->signature, | ||
374 | ACPI_FORMAT_UINT64(address->pointer. | ||
375 | physical), | ||
376 | header->length)); | ||
377 | return (status); | ||
378 | } | ||
379 | |||
380 | /* Save allocation type */ | ||
381 | |||
382 | allocation = ACPI_MEM_MAPPED; | ||
383 | break; | ||
384 | |||
385 | default: | ||
386 | |||
387 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
388 | address->pointer_type)); | ||
389 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Validate checksum for _most_ tables, | ||
394 | * even the ones whose signature we don't recognize | ||
395 | */ | ||
396 | if (table_info->type != ACPI_TABLE_ID_FACS) { | ||
397 | status = acpi_tb_verify_table_checksum(full_table); | ||
398 | |||
399 | #if (!ACPI_CHECKSUM_ABORT) | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | |||
402 | /* Ignore the error if configuration says so */ | ||
403 | |||
404 | status = AE_OK; | ||
405 | } | ||
406 | #endif | ||
407 | } | ||
408 | |||
409 | /* Return values */ | ||
410 | |||
411 | table_info->pointer = full_table; | ||
412 | table_info->length = (acpi_size) header->length; | ||
413 | table_info->allocation = allocation; | ||
414 | |||
415 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
416 | "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", | ||
417 | full_table->signature, | ||
418 | ACPI_FORMAT_UINT64(address->pointer.physical), | ||
419 | full_table)); | ||
420 | |||
421 | return_ACPI_STATUS(status); | ||
422 | } | ||
423 | |||
424 | /******************************************************************************* | ||
425 | * | ||
426 | * FUNCTION: acpi_tb_get_table_ptr | ||
427 | * | ||
428 | * PARAMETERS: table_type - one of the defined table types | ||
429 | * Instance - Which table of this type | ||
430 | * return_table - pointer to location to place the pointer for | ||
431 | * return | ||
432 | * | ||
433 | * RETURN: Status | ||
434 | * | ||
435 | * DESCRIPTION: This function is called to get the pointer to an ACPI table. | ||
436 | * | ||
437 | ******************************************************************************/ | ||
438 | |||
439 | acpi_status | ||
440 | acpi_tb_get_table_ptr(acpi_table_type table_type, | ||
441 | u32 instance, struct acpi_table_header **return_table) | ||
442 | { | ||
443 | struct acpi_table_desc *table_desc; | ||
444 | u32 i; | ||
445 | |||
446 | ACPI_FUNCTION_TRACE(tb_get_table_ptr); | ||
447 | |||
448 | if (table_type > ACPI_TABLE_ID_MAX) { | ||
449 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
450 | } | ||
451 | |||
452 | /* Check for instance out of range of the current table count */ | ||
453 | |||
454 | if (instance > acpi_gbl_table_lists[table_type].count) { | ||
455 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
456 | } | ||
457 | |||
458 | /* | ||
459 | * Walk the list to get the desired table | ||
460 | * Note: Instance is one-based | ||
461 | */ | ||
462 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
463 | for (i = 1; i < instance; i++) { | ||
464 | table_desc = table_desc->next; | ||
465 | } | ||
466 | |||
467 | /* We are now pointing to the requested table's descriptor */ | ||
468 | |||
469 | *return_table = table_desc->pointer; | ||
470 | return_ACPI_STATUS(AE_OK); | ||
471 | } | ||
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c deleted file mode 100644 index ad982112e4c6..000000000000 --- a/drivers/acpi/tables/tbgetall.c +++ /dev/null | |||
@@ -1,311 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbgetall - Get all required ACPI tables | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, 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 <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbgetall") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_desc *table_info); | ||
54 | |||
55 | static acpi_status | ||
56 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
57 | acpi_string signature, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_primary_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Physical address of table to retrieve | ||
65 | * *table_info - Where the table info is returned | ||
66 | * | ||
67 | * RETURN: Status | ||
68 | * | ||
69 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | static acpi_status | ||
74 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
75 | struct acpi_table_desc *table_info) | ||
76 | { | ||
77 | acpi_status status; | ||
78 | struct acpi_table_header header; | ||
79 | |||
80 | ACPI_FUNCTION_TRACE(tb_get_primary_table); | ||
81 | |||
82 | /* Ignore a NULL address in the RSDT */ | ||
83 | |||
84 | if (!address->pointer.value) { | ||
85 | return_ACPI_STATUS(AE_OK); | ||
86 | } | ||
87 | |||
88 | /* Get the header in order to get signature and table size */ | ||
89 | |||
90 | status = acpi_tb_get_table_header(address, &header); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* Clear the table_info */ | ||
96 | |||
97 | ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc)); | ||
98 | |||
99 | /* | ||
100 | * Check the table signature and make sure it is recognized. | ||
101 | * Also checks the header checksum | ||
102 | */ | ||
103 | table_info->pointer = &header; | ||
104 | status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY); | ||
105 | if (ACPI_FAILURE(status)) { | ||
106 | return_ACPI_STATUS(status); | ||
107 | } | ||
108 | |||
109 | /* Get the entire table */ | ||
110 | |||
111 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | return_ACPI_STATUS(status); | ||
114 | } | ||
115 | |||
116 | /* Install the table */ | ||
117 | |||
118 | status = acpi_tb_install_table(table_info); | ||
119 | return_ACPI_STATUS(status); | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_tb_get_secondary_table | ||
125 | * | ||
126 | * PARAMETERS: Address - Physical address of table to retrieve | ||
127 | * *table_info - Where the table info is returned | ||
128 | * | ||
129 | * RETURN: Status | ||
130 | * | ||
131 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
132 | * | ||
133 | ******************************************************************************/ | ||
134 | |||
135 | static acpi_status | ||
136 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
137 | acpi_string signature, | ||
138 | struct acpi_table_desc *table_info) | ||
139 | { | ||
140 | acpi_status status; | ||
141 | struct acpi_table_header header; | ||
142 | |||
143 | ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); | ||
144 | |||
145 | /* Get the header in order to match the signature */ | ||
146 | |||
147 | status = acpi_tb_get_table_header(address, &header); | ||
148 | if (ACPI_FAILURE(status)) { | ||
149 | return_ACPI_STATUS(status); | ||
150 | } | ||
151 | |||
152 | /* Signature must match request */ | ||
153 | |||
154 | if (!ACPI_COMPARE_NAME(header.signature, signature)) { | ||
155 | ACPI_ERROR((AE_INFO, | ||
156 | "Incorrect table signature - wanted [%s] found [%4.4s]", | ||
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 | * FUNCTION: acpi_tb_get_required_tables | ||
187 | * | ||
188 | * PARAMETERS: None | ||
189 | * | ||
190 | * RETURN: Status | ||
191 | * | ||
192 | * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must | ||
193 | * already be loaded and validated. | ||
194 | * | ||
195 | * Get the minimum set of ACPI tables, namely: | ||
196 | * | ||
197 | * 1) FADT (via RSDT in loop below) | ||
198 | * 2) FACS (via FADT) | ||
199 | * 3) DSDT (via FADT) | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | |||
203 | acpi_status acpi_tb_get_required_tables(void) | ||
204 | { | ||
205 | acpi_status status = AE_OK; | ||
206 | u32 i; | ||
207 | struct acpi_table_desc table_info; | ||
208 | struct acpi_pointer address; | ||
209 | |||
210 | ACPI_FUNCTION_TRACE(tb_get_required_tables); | ||
211 | |||
212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", | ||
213 | acpi_gbl_rsdt_table_count)); | ||
214 | |||
215 | address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
216 | |||
217 | /* | ||
218 | * Loop through all table pointers found in RSDT. | ||
219 | * This will NOT include the FACS and DSDT - we must get | ||
220 | * them after the loop. | ||
221 | * | ||
222 | * The only tables we are interested in getting here is the FADT and | ||
223 | * any SSDTs. | ||
224 | */ | ||
225 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
226 | |||
227 | /* Get the table address from the common internal XSDT */ | ||
228 | |||
229 | address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; | ||
230 | |||
231 | /* | ||
232 | * Get the tables needed by this subsystem (FADT and any SSDTs). | ||
233 | * NOTE: All other tables are completely ignored at this time. | ||
234 | */ | ||
235 | status = acpi_tb_get_primary_table(&address, &table_info); | ||
236 | if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { | ||
237 | ACPI_WARNING((AE_INFO, | ||
238 | "%s, while getting table at %8.8X%8.8X", | ||
239 | acpi_format_exception(status), | ||
240 | ACPI_FORMAT_UINT64(address.pointer. | ||
241 | value))); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* We must have a FADT to continue */ | ||
246 | |||
247 | if (!acpi_gbl_FADT) { | ||
248 | ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); | ||
249 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Convert the FADT to a common format. This allows earlier revisions of | ||
254 | * the table to coexist with newer versions, using common access code. | ||
255 | */ | ||
256 | status = acpi_tb_convert_table_fadt(); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_ERROR((AE_INFO, | ||
259 | "Could not convert FADT to internal common format")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Get the FACS (Pointed to by the FADT) */ | ||
264 | |||
265 | address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; | ||
266 | |||
267 | status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); | ||
268 | if (ACPI_FAILURE(status)) { | ||
269 | ACPI_EXCEPTION((AE_INFO, status, | ||
270 | "Could not get/install the FACS")); | ||
271 | return_ACPI_STATUS(status); | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Create the common FACS pointer table | ||
276 | * (Contains pointers to the original table) | ||
277 | */ | ||
278 | status = acpi_tb_build_common_facs(&table_info); | ||
279 | if (ACPI_FAILURE(status)) { | ||
280 | return_ACPI_STATUS(status); | ||
281 | } | ||
282 | |||
283 | /* Get/install the DSDT (Pointed to by the FADT) */ | ||
284 | |||
285 | address.pointer.value = acpi_gbl_FADT->Xdsdt; | ||
286 | |||
287 | status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); | ||
290 | return_ACPI_STATUS(status); | ||
291 | } | ||
292 | |||
293 | /* Set Integer Width (32/64) based upon DSDT revision */ | ||
294 | |||
295 | acpi_ut_set_integer_width(acpi_gbl_DSDT->revision); | ||
296 | |||
297 | /* Dump the entire DSDT */ | ||
298 | |||
299 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
300 | "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", | ||
301 | acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, | ||
302 | acpi_gbl_integer_bit_width)); | ||
303 | |||
304 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), | ||
305 | 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_ID_RSDP); | ||
310 | return_ACPI_STATUS(status); | ||
311 | } | ||
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 1668a232fb67..9076ca0913b7 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -42,510 +42,494 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | ||
45 | #include <acpi/actables.h> | 46 | #include <acpi/actables.h> |
46 | 47 | ||
47 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
48 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
49 | 50 | ||
50 | /* Local prototypes */ | 51 | /****************************************************************************** |
51 | static acpi_status | ||
52 | acpi_tb_match_signature(char *signature, | ||
53 | struct acpi_table_desc *table_info, u8 search_type); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | 52 | * |
57 | * FUNCTION: acpi_tb_match_signature | 53 | * FUNCTION: acpi_tb_verify_table |
58 | * | 54 | * |
59 | * PARAMETERS: Signature - Table signature to match | 55 | * PARAMETERS: table_desc - table |
60 | * table_info - Return data | ||
61 | * search_type - Table type to match (primary/secondary) | ||
62 | * | 56 | * |
63 | * RETURN: Status | 57 | * RETURN: Status |
64 | * | 58 | * |
65 | * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" | 59 | * DESCRIPTION: this function is called to verify and map table |
66 | * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. | ||
67 | * | 60 | * |
68 | ******************************************************************************/ | 61 | *****************************************************************************/ |
69 | 62 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |
70 | static acpi_status | ||
71 | acpi_tb_match_signature(char *signature, | ||
72 | struct acpi_table_desc *table_info, u8 search_type) | ||
73 | { | 63 | { |
74 | acpi_native_uint i; | 64 | u8 checksum; |
75 | 65 | ||
76 | ACPI_FUNCTION_TRACE(tb_match_signature); | 66 | ACPI_FUNCTION_TRACE(tb_verify_table); |
77 | 67 | ||
78 | /* Search for a signature match among the known table types */ | 68 | /* Map the table if necessary */ |
79 | 69 | ||
80 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | 70 | if (!table_desc->pointer) { |
81 | if (!(acpi_gbl_table_data[i].flags & search_type)) { | 71 | table_desc->pointer = |
82 | continue; | 72 | acpi_tb_map(table_desc->address, table_desc->length, |
73 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); | ||
74 | if (!table_desc->pointer) { | ||
75 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
83 | } | 76 | } |
77 | } | ||
84 | 78 | ||
85 | if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, | 79 | /* FACS is the odd table, has no standard ACPI header and no checksum */ |
86 | acpi_gbl_table_data[i].sig_length)) { | ||
87 | 80 | ||
88 | /* Found a signature match, return index if requested */ | 81 | if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) { |
82 | return_ACPI_STATUS(AE_OK); | ||
83 | } | ||
89 | 84 | ||
90 | if (table_info) { | 85 | /* Always calculate checksum, ignore bad checksum if requested */ |
91 | table_info->type = (u8) i; | ||
92 | } | ||
93 | 86 | ||
94 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 87 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(void, table_desc->pointer), |
95 | "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", | 88 | table_desc->length); |
96 | (char *)acpi_gbl_table_data[i]. | ||
97 | signature)); | ||
98 | 89 | ||
99 | return_ACPI_STATUS(AE_OK); | 90 | #if (ACPI_CHECKSUM_ABORT) |
100 | } | ||
101 | } | ||
102 | 91 | ||
103 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 92 | if (checksum) { |
104 | "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", | 93 | return_ACPI_STATUS(AE_BAD_CHECKSUM); |
105 | (char *)signature)); | 94 | } |
95 | #endif | ||
106 | 96 | ||
107 | return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); | 97 | return_ACPI_STATUS(AE_OK); |
108 | } | 98 | } |
109 | 99 | ||
110 | /******************************************************************************* | 100 | /******************************************************************************* |
111 | * | 101 | * |
112 | * FUNCTION: acpi_tb_install_table | 102 | * FUNCTION: acpi_tb_add_table |
113 | * | 103 | * |
114 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 104 | * PARAMETERS: Table - Pointer to the table header |
105 | * table_index - Where the table index is returned | ||
115 | * | 106 | * |
116 | * RETURN: Status | 107 | * RETURN: Status |
117 | * | 108 | * |
118 | * DESCRIPTION: Install the table into the global data structures. | 109 | * DESCRIPTION: This function is called to add the ACPI table |
119 | * | 110 | * |
120 | ******************************************************************************/ | 111 | ******************************************************************************/ |
121 | 112 | ||
122 | acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) | 113 | acpi_status |
114 | acpi_tb_add_table(struct acpi_table_header *table, | ||
115 | acpi_native_uint * table_index) | ||
123 | { | 116 | { |
124 | acpi_status status; | 117 | acpi_native_uint i; |
118 | acpi_native_uint length; | ||
119 | acpi_status status = AE_OK; | ||
125 | 120 | ||
126 | ACPI_FUNCTION_TRACE(tb_install_table); | 121 | ACPI_FUNCTION_TRACE(tb_add_table); |
127 | 122 | ||
128 | /* Lock tables while installing */ | 123 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
129 | 124 | ||
130 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 125 | /* Check if table is already registered */ |
131 | if (ACPI_FAILURE(status)) { | 126 | |
132 | ACPI_EXCEPTION((AE_INFO, status, | 127 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
133 | "Could not acquire table mutex")); | 128 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
134 | return_ACPI_STATUS(status); | 129 | status = |
130 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
131 | tables[i]); | ||
132 | if (ACPI_FAILURE(status) | ||
133 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
134 | continue; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | length = ACPI_MIN(table->length, | ||
139 | acpi_gbl_root_table_list.tables[i].pointer-> | ||
140 | length); | ||
141 | if (ACPI_MEMCMP | ||
142 | (table, acpi_gbl_root_table_list.tables[i].pointer, | ||
143 | length)) { | ||
144 | continue; | ||
145 | } | ||
146 | |||
147 | /* Table is already registered */ | ||
148 | |||
149 | ACPI_FREE(table); | ||
150 | *table_index = i; | ||
151 | goto release; | ||
135 | } | 152 | } |
136 | 153 | ||
137 | /* | 154 | /* |
138 | * Ignore a table that is already installed. For example, some BIOS | 155 | * Add the table to the global table list |
139 | * ASL code will repeatedly attempt to load the same SSDT. | ||
140 | */ | 156 | */ |
141 | status = acpi_tb_is_table_installed(table_info); | 157 | status = acpi_tb_store_table(ACPI_TO_INTEGER(table), |
158 | table, table->length, | ||
159 | ACPI_TABLE_ORIGIN_ALLOCATED, table_index); | ||
142 | if (ACPI_FAILURE(status)) { | 160 | if (ACPI_FAILURE(status)) { |
143 | goto unlock_and_exit; | 161 | goto release; |
144 | } | 162 | } |
145 | 163 | ||
146 | /* Install the table into the global data structure */ | 164 | acpi_tb_print_table_header(0, table); |
147 | 165 | ||
148 | status = acpi_tb_init_table_descriptor(table_info->type, table_info); | 166 | release: |
149 | if (ACPI_FAILURE(status)) { | ||
150 | ACPI_EXCEPTION((AE_INFO, status, | ||
151 | "Could not install table [%4.4s]", | ||
152 | table_info->pointer->signature)); | ||
153 | } | ||
154 | |||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", | ||
156 | acpi_gbl_table_data[table_info->type].name, | ||
157 | table_info->pointer)); | ||
158 | |||
159 | unlock_and_exit: | ||
160 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 167 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
161 | return_ACPI_STATUS(status); | 168 | return_ACPI_STATUS(status); |
162 | } | 169 | } |
163 | 170 | ||
164 | /******************************************************************************* | 171 | /******************************************************************************* |
165 | * | 172 | * |
166 | * FUNCTION: acpi_tb_recognize_table | 173 | * FUNCTION: acpi_tb_resize_root_table_list |
167 | * | 174 | * |
168 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 175 | * PARAMETERS: None |
169 | * search_type - Table type to match (primary/secondary) | ||
170 | * | 176 | * |
171 | * RETURN: Status | 177 | * RETURN: Status |
172 | * | 178 | * |
173 | * DESCRIPTION: Check a table signature for a match against known table types | 179 | * DESCRIPTION: Expand the size of global table array |
174 | * | ||
175 | * NOTE: All table pointers are validated as follows: | ||
176 | * 1) Table pointer must point to valid physical memory | ||
177 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
178 | * name | ||
179 | * 3) Table must be readable for length specified in the header | ||
180 | * 4) Table checksum must be valid (with the exception of the FACS | ||
181 | * which has no checksum for some odd reason) | ||
182 | * | 180 | * |
183 | ******************************************************************************/ | 181 | ******************************************************************************/ |
184 | 182 | ||
185 | acpi_status | 183 | acpi_status acpi_tb_resize_root_table_list(void) |
186 | acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) | ||
187 | { | 184 | { |
188 | struct acpi_table_header *table_header; | 185 | struct acpi_table_desc *tables; |
189 | acpi_status status; | ||
190 | 186 | ||
191 | ACPI_FUNCTION_TRACE(tb_recognize_table); | 187 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); |
192 | 188 | ||
193 | /* Ensure that we have a valid table pointer */ | 189 | /* allow_resize flag is a parameter to acpi_initialize_tables */ |
194 | 190 | ||
195 | table_header = (struct acpi_table_header *)table_info->pointer; | 191 | if (!(acpi_gbl_root_table_list.flags & ACPI_TABLE_FLAGS_ALLOW_RESIZE)) { |
196 | if (!table_header) { | 192 | ACPI_ERROR((AE_INFO, |
197 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 193 | "Resize of Root Table Array is not allowed")); |
194 | return_ACPI_STATUS(AE_SUPPORT); | ||
198 | } | 195 | } |
199 | 196 | ||
200 | /* | 197 | /* Increase the Table Array size */ |
201 | * We only "recognize" a limited number of ACPI tables -- namely, the | 198 | |
202 | * ones that are used by the subsystem (DSDT, FADT, etc.) | 199 | tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + |
203 | * | 200 | ACPI_ROOT_TABLE_SIZE_INCREMENT) |
204 | * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. | 201 | * sizeof(struct acpi_table_desc)); |
205 | * This can be any one of many valid ACPI tables, it just isn't one of | 202 | if (!tables) { |
206 | * the tables that is consumed by the core subsystem | 203 | ACPI_ERROR((AE_INFO, |
207 | */ | 204 | "Could not allocate new root table array")); |
208 | status = acpi_tb_match_signature(table_header->signature, | 205 | return_ACPI_STATUS(AE_NO_MEMORY); |
209 | table_info, search_type); | ||
210 | if (ACPI_FAILURE(status)) { | ||
211 | return_ACPI_STATUS(status); | ||
212 | } | 206 | } |
213 | 207 | ||
214 | status = acpi_tb_validate_table_header(table_header); | 208 | /* Copy and free the previous table array */ |
215 | if (ACPI_FAILURE(status)) { | 209 | |
216 | return_ACPI_STATUS(status); | 210 | if (acpi_gbl_root_table_list.tables) { |
211 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
212 | acpi_gbl_root_table_list.size * | ||
213 | sizeof(struct acpi_table_desc)); | ||
214 | |||
215 | if (acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK == | ||
216 | ACPI_TABLE_ORIGIN_ALLOCATED) { | ||
217 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
218 | } | ||
217 | } | 219 | } |
218 | 220 | ||
219 | /* Return the table type and length via the info struct */ | 221 | acpi_gbl_root_table_list.tables = tables; |
222 | acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
223 | acpi_gbl_root_table_list.flags = (u8) (ACPI_TABLE_ORIGIN_ALLOCATED | | ||
224 | (acpi_gbl_root_table_list. | ||
225 | flags & | ||
226 | ~ACPI_TABLE_ORIGIN_MASK)); | ||
220 | 227 | ||
221 | table_info->length = (acpi_size) table_header->length; | 228 | return_ACPI_STATUS(AE_OK); |
222 | return_ACPI_STATUS(status); | ||
223 | } | 229 | } |
224 | 230 | ||
225 | /******************************************************************************* | 231 | /******************************************************************************* |
226 | * | 232 | * |
227 | * FUNCTION: acpi_tb_init_table_descriptor | 233 | * FUNCTION: acpi_tb_store_table |
228 | * | 234 | * |
229 | * PARAMETERS: table_type - The type of the table | 235 | * PARAMETERS: Address - Table address |
230 | * table_info - A table info struct | 236 | * Table - Table header |
237 | * Length - Table length | ||
238 | * Flags - flags | ||
231 | * | 239 | * |
232 | * RETURN: None. | 240 | * RETURN: Status and table index. |
233 | * | 241 | * |
234 | * DESCRIPTION: Install a table into the global data structs. | 242 | * DESCRIPTION: Add an ACPI table to the global table list |
235 | * | 243 | * |
236 | ******************************************************************************/ | 244 | ******************************************************************************/ |
237 | 245 | ||
238 | acpi_status | 246 | acpi_status |
239 | acpi_tb_init_table_descriptor(acpi_table_type table_type, | 247 | acpi_tb_store_table(acpi_physical_address address, |
240 | struct acpi_table_desc *table_info) | 248 | struct acpi_table_header *table, |
249 | u32 length, u8 flags, acpi_native_uint * table_index) | ||
241 | { | 250 | { |
242 | struct acpi_table_list *list_head; | 251 | acpi_status status = AE_OK; |
243 | struct acpi_table_desc *table_desc; | ||
244 | acpi_status status; | ||
245 | |||
246 | ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); | ||
247 | |||
248 | /* Allocate a descriptor for this table */ | ||
249 | 252 | ||
250 | table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | 253 | /* Ensure that there is room for the table in the Root Table List */ |
251 | if (!table_desc) { | ||
252 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
253 | } | ||
254 | |||
255 | /* Get a new owner ID for the table */ | ||
256 | 254 | ||
257 | status = acpi_ut_allocate_owner_id(&table_desc->owner_id); | 255 | if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { |
258 | if (ACPI_FAILURE(status)) { | 256 | status = acpi_tb_resize_root_table_list(); |
259 | goto error_exit1; | 257 | if (ACPI_FAILURE(status)) { |
258 | return (status); | ||
259 | } | ||
260 | } | 260 | } |
261 | 261 | ||
262 | /* Install the table into the global data structure */ | 262 | /* Initialize added table */ |
263 | 263 | ||
264 | list_head = &acpi_gbl_table_lists[table_type]; | 264 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. |
265 | address = address; | ||
266 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
267 | pointer = table; | ||
268 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = | ||
269 | length; | ||
270 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
271 | owner_id = 0; | ||
272 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = | ||
273 | flags; | ||
274 | |||
275 | ACPI_MOVE_32_TO_32(& | ||
276 | (acpi_gbl_root_table_list. | ||
277 | tables[acpi_gbl_root_table_list.count].signature), | ||
278 | table->signature); | ||
279 | |||
280 | *table_index = acpi_gbl_root_table_list.count; | ||
281 | acpi_gbl_root_table_list.count++; | ||
282 | return (status); | ||
283 | } | ||
265 | 284 | ||
266 | /* | 285 | /******************************************************************************* |
267 | * Two major types of tables: 1) Only one instance is allowed. This | 286 | * |
268 | * includes most ACPI tables such as the DSDT. 2) Multiple instances of | 287 | * FUNCTION: acpi_tb_delete_table |
269 | * the table are allowed. This includes SSDT and PSDTs. | 288 | * |
270 | */ | 289 | * PARAMETERS: table_index - Table index |
271 | if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { | 290 | * |
272 | /* | 291 | * RETURN: None |
273 | * Only one table allowed, and a table has alread been installed | 292 | * |
274 | * at this location, so return an error. | 293 | * DESCRIPTION: Delete one internal ACPI table |
275 | */ | 294 | * |
276 | if (list_head->next) { | 295 | ******************************************************************************/ |
277 | status = AE_ALREADY_EXISTS; | ||
278 | goto error_exit2; | ||
279 | } | ||
280 | 296 | ||
281 | table_desc->next = list_head->next; | 297 | void acpi_tb_delete_table(acpi_native_uint table_index) |
282 | list_head->next = table_desc; | 298 | { |
299 | struct acpi_table_desc *table_desc; | ||
283 | 300 | ||
284 | if (table_desc->next) { | 301 | /* table_index assumed valid */ |
285 | table_desc->next->prev = table_desc; | ||
286 | } | ||
287 | 302 | ||
288 | list_head->count++; | 303 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; |
289 | } else { | ||
290 | /* | ||
291 | * Link the new table in to the list of tables of this type. | ||
292 | * Insert at the end of the list, order IS IMPORTANT. | ||
293 | * | ||
294 | * table_desc->Prev & Next are already NULL from calloc() | ||
295 | */ | ||
296 | list_head->count++; | ||
297 | |||
298 | if (!list_head->next) { | ||
299 | list_head->next = table_desc; | ||
300 | } else { | ||
301 | table_desc->next = list_head->next; | ||
302 | 304 | ||
303 | while (table_desc->next->next) { | 305 | /* Table must be mapped or allocated */ |
304 | table_desc->next = table_desc->next->next; | ||
305 | } | ||
306 | 306 | ||
307 | table_desc->next->next = table_desc; | 307 | if (!table_desc->pointer) { |
308 | table_desc->prev = table_desc->next; | 308 | return; |
309 | table_desc->next = NULL; | ||
310 | } | ||
311 | } | 309 | } |
312 | 310 | ||
313 | /* Finish initialization of the table descriptor */ | 311 | if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) { |
314 | 312 | acpi_tb_unmap(table_desc->pointer, table_desc->length, | |
315 | table_desc->loaded_into_namespace = FALSE; | 313 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); |
316 | table_desc->type = (u8) table_type; | 314 | } else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) { |
317 | table_desc->pointer = table_info->pointer; | 315 | ACPI_FREE(table_desc->pointer); |
318 | table_desc->length = table_info->length; | ||
319 | table_desc->allocation = table_info->allocation; | ||
320 | table_desc->aml_start = (u8 *) (table_desc->pointer + 1), | ||
321 | table_desc->aml_length = (u32) | ||
322 | (table_desc->length - (u32) sizeof(struct acpi_table_header)); | ||
323 | |||
324 | /* | ||
325 | * Set the appropriate global pointer (if there is one) to point to the | ||
326 | * newly installed table | ||
327 | */ | ||
328 | if (acpi_gbl_table_data[table_type].global_ptr) { | ||
329 | *(acpi_gbl_table_data[table_type].global_ptr) = | ||
330 | table_info->pointer; | ||
331 | } | 316 | } |
332 | 317 | ||
333 | /* Return Data */ | 318 | table_desc->pointer = NULL; |
334 | |||
335 | table_info->owner_id = table_desc->owner_id; | ||
336 | table_info->installed_desc = table_desc; | ||
337 | return_ACPI_STATUS(AE_OK); | ||
338 | |||
339 | /* Error exit with cleanup */ | ||
340 | |||
341 | error_exit2: | ||
342 | |||
343 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
344 | |||
345 | error_exit1: | ||
346 | |||
347 | ACPI_FREE(table_desc); | ||
348 | return_ACPI_STATUS(status); | ||
349 | } | 319 | } |
350 | 320 | ||
351 | /******************************************************************************* | 321 | /******************************************************************************* |
352 | * | 322 | * |
353 | * FUNCTION: acpi_tb_delete_all_tables | 323 | * FUNCTION: acpi_tb_terminate |
354 | * | 324 | * |
355 | * PARAMETERS: None. | 325 | * PARAMETERS: None |
356 | * | 326 | * |
357 | * RETURN: None. | 327 | * RETURN: None |
358 | * | 328 | * |
359 | * DESCRIPTION: Delete all internal ACPI tables | 329 | * DESCRIPTION: Delete all internal ACPI tables |
360 | * | 330 | * |
361 | ******************************************************************************/ | 331 | ******************************************************************************/ |
362 | 332 | ||
363 | void acpi_tb_delete_all_tables(void) | 333 | void acpi_tb_terminate(void) |
364 | { | 334 | { |
365 | acpi_table_type type; | 335 | acpi_native_uint i; |
336 | |||
337 | ACPI_FUNCTION_TRACE(tb_terminate); | ||
338 | |||
339 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
340 | |||
341 | /* Delete the individual tables */ | ||
342 | |||
343 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
344 | acpi_tb_delete_table(i); | ||
345 | } | ||
366 | 346 | ||
367 | /* | 347 | /* |
368 | * Free memory allocated for ACPI tables | 348 | * Delete the root table array if allocated locally. Array cannot be |
369 | * Memory can either be mapped or allocated | 349 | * mapped, so we don't need to check for that flag. |
370 | */ | 350 | */ |
371 | for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { | 351 | if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) == |
372 | acpi_tb_delete_tables_by_type(type); | 352 | ACPI_TABLE_ORIGIN_ALLOCATED) { |
353 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
373 | } | 354 | } |
355 | |||
356 | acpi_gbl_root_table_list.tables = NULL; | ||
357 | acpi_gbl_root_table_list.flags = 0; | ||
358 | acpi_gbl_root_table_list.count = 0; | ||
359 | |||
360 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
361 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
374 | } | 362 | } |
375 | 363 | ||
376 | /******************************************************************************* | 364 | /******************************************************************************* |
377 | * | 365 | * |
378 | * FUNCTION: acpi_tb_delete_tables_by_type | 366 | * FUNCTION: acpi_tb_delete_namespace_by_owner |
379 | * | 367 | * |
380 | * PARAMETERS: Type - The table type to be deleted | 368 | * PARAMETERS: table_index - Table index |
381 | * | 369 | * |
382 | * RETURN: None. | 370 | * RETURN: None |
383 | * | 371 | * |
384 | * DESCRIPTION: Delete an internal ACPI table | 372 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. |
385 | * Locks the ACPI table mutex | ||
386 | * | 373 | * |
387 | ******************************************************************************/ | 374 | ******************************************************************************/ |
388 | 375 | ||
389 | void acpi_tb_delete_tables_by_type(acpi_table_type type) | 376 | void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) |
390 | { | 377 | { |
391 | struct acpi_table_desc *table_desc; | 378 | acpi_owner_id owner_id; |
392 | u32 count; | ||
393 | u32 i; | ||
394 | |||
395 | ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); | ||
396 | |||
397 | if (type > ACPI_TABLE_ID_MAX) { | ||
398 | return_VOID; | ||
399 | } | ||
400 | 379 | ||
401 | if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { | 380 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
381 | if (table_index < acpi_gbl_root_table_list.count) { | ||
382 | owner_id = | ||
383 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
384 | } else { | ||
385 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
402 | return; | 386 | return; |
403 | } | 387 | } |
404 | 388 | ||
405 | /* Clear the appropriate "typed" global table pointer */ | 389 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
406 | 390 | acpi_ns_delete_namespace_by_owner(owner_id); | |
407 | switch (type) { | 391 | } |
408 | case ACPI_TABLE_ID_RSDP: | ||
409 | acpi_gbl_RSDP = NULL; | ||
410 | break; | ||
411 | |||
412 | case ACPI_TABLE_ID_DSDT: | ||
413 | acpi_gbl_DSDT = NULL; | ||
414 | break; | ||
415 | |||
416 | case ACPI_TABLE_ID_FADT: | ||
417 | acpi_gbl_FADT = NULL; | ||
418 | break; | ||
419 | |||
420 | case ACPI_TABLE_ID_FACS: | ||
421 | acpi_gbl_FACS = NULL; | ||
422 | break; | ||
423 | 392 | ||
424 | case ACPI_TABLE_ID_XSDT: | 393 | /******************************************************************************* |
425 | acpi_gbl_XSDT = NULL; | 394 | * |
426 | break; | 395 | * FUNCTION: acpi_tb_allocate_owner_id |
396 | * | ||
397 | * PARAMETERS: table_index - Table index | ||
398 | * | ||
399 | * RETURN: Status | ||
400 | * | ||
401 | * DESCRIPTION: Allocates owner_id in table_desc | ||
402 | * | ||
403 | ******************************************************************************/ | ||
427 | 404 | ||
428 | case ACPI_TABLE_ID_SSDT: | 405 | acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) |
429 | case ACPI_TABLE_ID_PSDT: | 406 | { |
430 | default: | 407 | acpi_status status = AE_BAD_PARAMETER; |
431 | break; | ||
432 | } | ||
433 | 408 | ||
434 | /* | 409 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); |
435 | * Free the table | ||
436 | * 1) Get the head of the list | ||
437 | */ | ||
438 | table_desc = acpi_gbl_table_lists[type].next; | ||
439 | count = acpi_gbl_table_lists[type].count; | ||
440 | 410 | ||
441 | /* | 411 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
442 | * 2) Walk the entire list, deleting both the allocated tables | 412 | if (table_index < acpi_gbl_root_table_list.count) { |
443 | * and the table descriptors | 413 | status = acpi_ut_allocate_owner_id |
444 | */ | 414 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); |
445 | for (i = 0; i < count; i++) { | ||
446 | table_desc = acpi_tb_uninstall_table(table_desc); | ||
447 | } | 415 | } |
448 | 416 | ||
449 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 417 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
450 | return_VOID; | 418 | return_ACPI_STATUS(status); |
451 | } | 419 | } |
452 | 420 | ||
453 | /******************************************************************************* | 421 | /******************************************************************************* |
454 | * | 422 | * |
455 | * FUNCTION: acpi_tb_delete_single_table | 423 | * FUNCTION: acpi_tb_release_owner_id |
456 | * | 424 | * |
457 | * PARAMETERS: table_info - A table info struct | 425 | * PARAMETERS: table_index - Table index |
458 | * | 426 | * |
459 | * RETURN: None. | 427 | * RETURN: Status |
460 | * | 428 | * |
461 | * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where | 429 | * DESCRIPTION: Releases owner_id in table_desc |
462 | * the table was allocated a buffer or was mapped. | ||
463 | * | 430 | * |
464 | ******************************************************************************/ | 431 | ******************************************************************************/ |
465 | 432 | ||
466 | void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) | 433 | acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) |
467 | { | 434 | { |
435 | acpi_status status = AE_BAD_PARAMETER; | ||
468 | 436 | ||
469 | /* Must have a valid table descriptor and pointer */ | 437 | ACPI_FUNCTION_TRACE(tb_release_owner_id); |
470 | 438 | ||
471 | if ((!table_desc) || (!table_desc->pointer)) { | 439 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
472 | return; | 440 | if (table_index < acpi_gbl_root_table_list.count) { |
441 | acpi_ut_release_owner_id(& | ||
442 | (acpi_gbl_root_table_list. | ||
443 | tables[table_index].owner_id)); | ||
444 | status = AE_OK; | ||
473 | } | 445 | } |
474 | 446 | ||
475 | /* Valid table, determine type of memory allocation */ | 447 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
476 | 448 | return_ACPI_STATUS(status); | |
477 | switch (table_desc->allocation) { | ||
478 | case ACPI_MEM_NOT_ALLOCATED: | ||
479 | break; | ||
480 | |||
481 | case ACPI_MEM_ALLOCATED: | ||
482 | |||
483 | ACPI_FREE(table_desc->pointer); | ||
484 | break; | ||
485 | |||
486 | case ACPI_MEM_MAPPED: | ||
487 | |||
488 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
489 | break; | ||
490 | |||
491 | default: | ||
492 | break; | ||
493 | } | ||
494 | } | 449 | } |
495 | 450 | ||
496 | /******************************************************************************* | 451 | /******************************************************************************* |
497 | * | 452 | * |
498 | * FUNCTION: acpi_tb_uninstall_table | 453 | * FUNCTION: acpi_tb_get_owner_id |
499 | * | 454 | * |
500 | * PARAMETERS: table_info - A table info struct | 455 | * PARAMETERS: table_index - Table index |
456 | * owner_id - Where the table owner_id is returned | ||
501 | * | 457 | * |
502 | * RETURN: Pointer to the next table in the list (of same type) | 458 | * RETURN: Status |
503 | * | 459 | * |
504 | * DESCRIPTION: Free the memory associated with an internal ACPI table that | 460 | * DESCRIPTION: returns owner_id for the ACPI table |
505 | * is either installed or has never been installed. | ||
506 | * Table mutex should be locked. | ||
507 | * | 461 | * |
508 | ******************************************************************************/ | 462 | ******************************************************************************/ |
509 | 463 | ||
510 | struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc | 464 | acpi_status |
511 | *table_desc) | 465 | acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) |
512 | { | 466 | { |
513 | struct acpi_table_desc *next_desc; | 467 | acpi_status status = AE_BAD_PARAMETER; |
514 | 468 | ||
515 | ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); | 469 | ACPI_FUNCTION_TRACE(tb_get_owner_id); |
516 | 470 | ||
517 | if (!table_desc) { | 471 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
518 | return_PTR(NULL); | 472 | if (table_index < acpi_gbl_root_table_list.count) { |
473 | *owner_id = | ||
474 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
475 | status = AE_OK; | ||
519 | } | 476 | } |
520 | 477 | ||
521 | /* Unlink the descriptor from the doubly linked list */ | 478 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
479 | return_ACPI_STATUS(status); | ||
480 | } | ||
522 | 481 | ||
523 | if (table_desc->prev) { | 482 | /******************************************************************************* |
524 | table_desc->prev->next = table_desc->next; | 483 | * |
525 | } else { | 484 | * FUNCTION: acpi_tb_is_table_loaded |
526 | /* Is first on list, update list head */ | 485 | * |
486 | * PARAMETERS: table_index - Table index | ||
487 | * | ||
488 | * RETURN: Table Loaded Flag | ||
489 | * | ||
490 | ******************************************************************************/ | ||
527 | 491 | ||
528 | acpi_gbl_table_lists[table_desc->type].next = table_desc->next; | 492 | u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) |
529 | } | 493 | { |
494 | u8 is_loaded = FALSE; | ||
530 | 495 | ||
531 | if (table_desc->next) { | 496 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
532 | table_desc->next->prev = table_desc->prev; | 497 | if (table_index < acpi_gbl_root_table_list.count) { |
498 | is_loaded = (u8) | ||
499 | (acpi_gbl_root_table_list.tables[table_index]. | ||
500 | flags & ACPI_TABLE_FLAGS_LOADED); | ||
533 | } | 501 | } |
534 | 502 | ||
535 | /* Free the memory allocated for the table itself */ | 503 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
536 | 504 | return (is_loaded); | |
537 | acpi_tb_delete_single_table(table_desc); | 505 | } |
538 | |||
539 | /* Free the owner ID associated with this table */ | ||
540 | |||
541 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
542 | 506 | ||
543 | /* Free the table descriptor */ | 507 | /******************************************************************************* |
508 | * | ||
509 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
510 | * | ||
511 | * PARAMETERS: table_index - Table index | ||
512 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
513 | * | ||
514 | * RETURN: None | ||
515 | * | ||
516 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
517 | * | ||
518 | ******************************************************************************/ | ||
544 | 519 | ||
545 | next_desc = table_desc->next; | 520 | void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) |
546 | ACPI_FREE(table_desc); | 521 | { |
547 | 522 | ||
548 | /* Return pointer to the next descriptor */ | 523 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
524 | if (table_index < acpi_gbl_root_table_list.count) { | ||
525 | if (is_loaded) { | ||
526 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
527 | ACPI_TABLE_FLAGS_LOADED; | ||
528 | } else { | ||
529 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
530 | ~ACPI_TABLE_FLAGS_LOADED; | ||
531 | } | ||
532 | } | ||
549 | 533 | ||
550 | return_PTR(next_desc); | 534 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
551 | } | 535 | } |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c deleted file mode 100644 index 86a5fca9b739..000000000000 --- a/drivers/acpi/tables/tbrsdt.c +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbrsdt - ACPI RSDT table utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, 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 <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbrsdt") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_verify_rsdp | ||
53 | * | ||
54 | * PARAMETERS: Address - RSDP (Pointer to RSDT) | ||
55 | * | ||
56 | * RETURN: Status | ||
57 | * | ||
58 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
59 | * | ||
60 | ******************************************************************************/ | ||
61 | acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) | ||
62 | { | ||
63 | struct acpi_table_desc table_info; | ||
64 | acpi_status status; | ||
65 | struct rsdp_descriptor *rsdp; | ||
66 | |||
67 | ACPI_FUNCTION_TRACE(tb_verify_rsdp); | ||
68 | |||
69 | switch (address->pointer_type) { | ||
70 | case ACPI_LOGICAL_POINTER: | ||
71 | |||
72 | rsdp = address->pointer.logical; | ||
73 | break; | ||
74 | |||
75 | case ACPI_PHYSICAL_POINTER: | ||
76 | /* | ||
77 | * Obtain access to the RSDP structure | ||
78 | */ | ||
79 | status = acpi_os_map_memory(address->pointer.physical, | ||
80 | sizeof(struct rsdp_descriptor), | ||
81 | ACPI_CAST_PTR(void, &rsdp)); | ||
82 | if (ACPI_FAILURE(status)) { | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | default: | ||
88 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
89 | } | ||
90 | |||
91 | /* Verify RSDP signature and checksum */ | ||
92 | |||
93 | status = acpi_tb_validate_rsdp(rsdp); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | goto cleanup; | ||
96 | } | ||
97 | |||
98 | /* RSDP is ok. Init the table info */ | ||
99 | |||
100 | table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); | ||
101 | table_info.length = sizeof(struct rsdp_descriptor); | ||
102 | |||
103 | if (address->pointer_type == ACPI_PHYSICAL_POINTER) { | ||
104 | table_info.allocation = ACPI_MEM_MAPPED; | ||
105 | } else { | ||
106 | table_info.allocation = ACPI_MEM_NOT_ALLOCATED; | ||
107 | } | ||
108 | |||
109 | /* Save the table pointers and allocation info */ | ||
110 | |||
111 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | goto cleanup; | ||
114 | } | ||
115 | |||
116 | /* Save the RSDP in a global for easy access */ | ||
117 | |||
118 | acpi_gbl_RSDP = | ||
119 | ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); | ||
120 | return_ACPI_STATUS(status); | ||
121 | |||
122 | /* Error exit */ | ||
123 | cleanup: | ||
124 | |||
125 | if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { | ||
126 | acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); | ||
127 | } | ||
128 | return_ACPI_STATUS(status); | ||
129 | } | ||
130 | |||
131 | /******************************************************************************* | ||
132 | * | ||
133 | * FUNCTION: acpi_tb_get_rsdt_address | ||
134 | * | ||
135 | * PARAMETERS: out_address - Where the address is returned | ||
136 | * | ||
137 | * RETURN: None, Address | ||
138 | * | ||
139 | * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the | ||
140 | * version of the RSDP and whether the XSDT pointer is valid | ||
141 | * | ||
142 | ******************************************************************************/ | ||
143 | |||
144 | void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) | ||
145 | { | ||
146 | |||
147 | ACPI_FUNCTION_ENTRY(); | ||
148 | |||
149 | out_address->pointer_type = | ||
150 | acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
151 | |||
152 | /* Use XSDT if it is present */ | ||
153 | |||
154 | if ((acpi_gbl_RSDP->revision >= 2) && | ||
155 | acpi_gbl_RSDP->xsdt_physical_address) { | ||
156 | out_address->pointer.value = | ||
157 | acpi_gbl_RSDP->xsdt_physical_address; | ||
158 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; | ||
159 | } else { | ||
160 | /* No XSDT, use the RSDT */ | ||
161 | |||
162 | out_address->pointer.value = | ||
163 | acpi_gbl_RSDP->rsdt_physical_address; | ||
164 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /******************************************************************************* | ||
169 | * | ||
170 | * FUNCTION: acpi_tb_validate_rsdt | ||
171 | * | ||
172 | * PARAMETERS: table_ptr - Addressable pointer to the RSDT. | ||
173 | * | ||
174 | * RETURN: Status | ||
175 | * | ||
176 | * DESCRIPTION: Validate signature for the RSDT or XSDT | ||
177 | * | ||
178 | ******************************************************************************/ | ||
179 | |||
180 | acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | ||
181 | { | ||
182 | char *signature; | ||
183 | |||
184 | ACPI_FUNCTION_ENTRY(); | ||
185 | |||
186 | /* Validate minimum length */ | ||
187 | |||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "RSDT/XSDT length (%X) is smaller than minimum (%zX)", | ||
191 | table_ptr->length, | ||
192 | sizeof(struct acpi_table_header))); | ||
193 | |||
194 | return (AE_INVALID_TABLE_LENGTH); | ||
195 | } | ||
196 | |||
197 | /* Search for appropriate signature, RSDT or XSDT */ | ||
198 | |||
199 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
200 | signature = RSDT_SIG; | ||
201 | } else { | ||
202 | signature = XSDT_SIG; | ||
203 | } | ||
204 | |||
205 | if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { | ||
206 | |||
207 | /* Invalid RSDT or XSDT signature */ | ||
208 | |||
209 | ACPI_ERROR((AE_INFO, | ||
210 | "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); | ||
211 | |||
212 | ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); | ||
213 | |||
214 | ACPI_ERROR((AE_INFO, | ||
215 | "RSDT/XSDT signature at %X is invalid", | ||
216 | acpi_gbl_RSDP->rsdt_physical_address)); | ||
217 | |||
218 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
219 | ACPI_ERROR((AE_INFO, "Looking for RSDT")); | ||
220 | } else { | ||
221 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); | ||
222 | } | ||
223 | |||
224 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); | ||
225 | return (AE_BAD_SIGNATURE); | ||
226 | } | ||
227 | |||
228 | return (AE_OK); | ||
229 | } | ||
230 | |||
231 | /******************************************************************************* | ||
232 | * | ||
233 | * FUNCTION: acpi_tb_get_table_rsdt | ||
234 | * | ||
235 | * PARAMETERS: None | ||
236 | * | ||
237 | * RETURN: Status | ||
238 | * | ||
239 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | |||
243 | acpi_status acpi_tb_get_table_rsdt(void) | ||
244 | { | ||
245 | struct acpi_table_desc table_info; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_get_table_rsdt); | ||
250 | |||
251 | /* Get the RSDT/XSDT via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | |||
255 | table_info.type = ACPI_TABLE_ID_XSDT; | ||
256 | status = acpi_tb_get_table(&address, &table_info); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_EXCEPTION((AE_INFO, status, | ||
259 | "Could not get the RSDT/XSDT")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
264 | "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", | ||
265 | acpi_gbl_RSDP, | ||
266 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
267 | |||
268 | /* Check the RSDT or XSDT signature */ | ||
269 | |||
270 | status = acpi_tb_validate_rsdt(table_info.pointer); | ||
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto error_cleanup; | ||
273 | } | ||
274 | |||
275 | /* Get the number of tables defined in the RSDT or XSDT */ | ||
276 | |||
277 | acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP, | ||
278 | table_info.pointer); | ||
279 | |||
280 | /* Convert and/or copy to an XSDT structure */ | ||
281 | |||
282 | status = acpi_tb_convert_to_xsdt(&table_info); | ||
283 | if (ACPI_FAILURE(status)) { | ||
284 | goto error_cleanup; | ||
285 | } | ||
286 | |||
287 | /* Save the table pointers and allocation info */ | ||
288 | |||
289 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); | ||
290 | if (ACPI_FAILURE(status)) { | ||
291 | goto error_cleanup; | ||
292 | } | ||
293 | |||
294 | acpi_gbl_XSDT = | ||
295 | ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); | ||
296 | |||
297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); | ||
298 | return_ACPI_STATUS(status); | ||
299 | |||
300 | error_cleanup: | ||
301 | |||
302 | /* Free table allocated by acpi_tb_get_table */ | ||
303 | |||
304 | acpi_tb_delete_single_table(&table_info); | ||
305 | |||
306 | return_ACPI_STATUS(status); | ||
307 | } | ||
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 209a401801e3..3620ac5f8681 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: tbutils - Table manipulation utilities | 3 | * Module Name: tbutils - table utilities |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
@@ -48,295 +48,507 @@ | |||
48 | ACPI_MODULE_NAME("tbutils") | 48 | ACPI_MODULE_NAME("tbutils") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 51 | static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags); |
52 | acpi_status | 52 | |
53 | acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); | 53 | static void inline |
54 | #endif | 54 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, |
55 | u8 bit_width, acpi_physical_address address); | ||
55 | 56 | ||
56 | /******************************************************************************* | 57 | /******************************************************************************* |
57 | * | 58 | * |
58 | * FUNCTION: acpi_tb_is_table_installed | 59 | * FUNCTION: acpi_tb_print_table_header |
59 | * | 60 | * |
60 | * PARAMETERS: new_table_desc - Descriptor for new table being installed | 61 | * PARAMETERS: Address - Table physical address |
62 | * Header - Table header | ||
61 | * | 63 | * |
62 | * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed | 64 | * RETURN: None |
63 | * | 65 | * |
64 | * DESCRIPTION: Determine if an ACPI table is already installed | 66 | * DESCRIPTION: Print an ACPI table header |
65 | * | ||
66 | * MUTEX: Table data structures should be locked | ||
67 | * | 67 | * |
68 | ******************************************************************************/ | 68 | ******************************************************************************/ |
69 | 69 | ||
70 | acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) | 70 | void |
71 | acpi_tb_print_table_header(acpi_physical_address address, | ||
72 | struct acpi_table_header *header) | ||
71 | { | 73 | { |
72 | struct acpi_table_desc *table_desc; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_is_table_installed); | ||
75 | |||
76 | /* Get the list descriptor and first table descriptor */ | ||
77 | |||
78 | table_desc = acpi_gbl_table_lists[new_table_desc->type].next; | ||
79 | |||
80 | /* Examine all installed tables of this type */ | ||
81 | |||
82 | while (table_desc) { | ||
83 | /* | ||
84 | * If the table lengths match, perform a full bytewise compare. This | ||
85 | * means that we will allow tables with duplicate oem_table_id(s), as | ||
86 | * long as the tables are different in some way. | ||
87 | * | ||
88 | * Checking if the table has been loaded into the namespace means that | ||
89 | * we don't check for duplicate tables during the initial installation | ||
90 | * of tables within the RSDT/XSDT. | ||
91 | */ | ||
92 | if ((table_desc->loaded_into_namespace) && | ||
93 | (table_desc->pointer->length == | ||
94 | new_table_desc->pointer->length) | ||
95 | && | ||
96 | (!ACPI_MEMCMP | ||
97 | (table_desc->pointer, new_table_desc->pointer, | ||
98 | new_table_desc->pointer->length))) { | ||
99 | |||
100 | /* Match: this table is already installed */ | ||
101 | |||
102 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
103 | "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", | ||
104 | new_table_desc->pointer->signature, | ||
105 | new_table_desc->pointer->revision, | ||
106 | new_table_desc->pointer-> | ||
107 | oem_table_id)); | ||
108 | |||
109 | new_table_desc->owner_id = table_desc->owner_id; | ||
110 | new_table_desc->installed_desc = table_desc; | ||
111 | |||
112 | return_ACPI_STATUS(AE_ALREADY_EXISTS); | ||
113 | } | ||
114 | |||
115 | /* Get next table on the list */ | ||
116 | 74 | ||
117 | table_desc = table_desc->next; | 75 | ACPI_INFO((AE_INFO, |
118 | } | 76 | "%4.4s @ 0x%p Length 0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)", |
119 | 77 | header->signature, ACPI_CAST_PTR(void, address), | |
120 | return_ACPI_STATUS(AE_OK); | 78 | header->length, header->revision, header->oem_id, |
79 | header->oem_table_id, header->oem_revision, | ||
80 | header->asl_compiler_id, header->asl_compiler_revision)); | ||
121 | } | 81 | } |
122 | 82 | ||
123 | /******************************************************************************* | 83 | /******************************************************************************* |
124 | * | 84 | * |
125 | * FUNCTION: acpi_tb_validate_table_header | 85 | * FUNCTION: acpi_tb_init_generic_address |
126 | * | ||
127 | * PARAMETERS: table_header - Logical pointer to the table | ||
128 | * | 86 | * |
129 | * RETURN: Status | 87 | * PARAMETERS: new_gas_struct - GAS struct to be initialized |
88 | * bit_width - Width of this register | ||
89 | * Address - Address of the register | ||
130 | * | 90 | * |
131 | * DESCRIPTION: Check an ACPI table header for validity | 91 | * RETURN: None |
132 | * | 92 | * |
133 | * NOTE: Table pointers are validated as follows: | 93 | * DESCRIPTION: Initialize a GAS structure. |
134 | * 1) Table pointer must point to valid physical memory | ||
135 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
136 | * name | ||
137 | * 3) Table must be readable for length specified in the header | ||
138 | * 4) Table checksum must be valid (with the exception of the FACS | ||
139 | * which has no checksum because it contains variable fields) | ||
140 | * | 94 | * |
141 | ******************************************************************************/ | 95 | ******************************************************************************/ |
142 | 96 | ||
143 | acpi_status | 97 | static void inline |
144 | acpi_tb_validate_table_header(struct acpi_table_header *table_header) | 98 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, |
99 | u8 bit_width, acpi_physical_address address) | ||
145 | { | 100 | { |
146 | acpi_name signature; | ||
147 | |||
148 | ACPI_FUNCTION_ENTRY(); | ||
149 | |||
150 | /* Verify that this is a valid address */ | ||
151 | |||
152 | if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { | ||
153 | ACPI_ERROR((AE_INFO, | ||
154 | "Cannot read table header at %p", table_header)); | ||
155 | |||
156 | return (AE_BAD_ADDRESS); | ||
157 | } | ||
158 | |||
159 | /* Ensure that the signature is 4 ASCII characters */ | ||
160 | |||
161 | ACPI_MOVE_32_TO_32(&signature, table_header->signature); | ||
162 | if (!acpi_ut_valid_acpi_name(signature)) { | ||
163 | ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", | ||
164 | signature)); | ||
165 | 101 | ||
166 | ACPI_DUMP_BUFFER(table_header, | 102 | ACPI_STORE_ADDRESS(new_gas_struct->address, address); |
167 | sizeof(struct acpi_table_header)); | 103 | new_gas_struct->space_id = ACPI_ADR_SPACE_SYSTEM_IO; |
168 | return (AE_BAD_SIGNATURE); | 104 | new_gas_struct->bit_width = bit_width; |
169 | } | 105 | new_gas_struct->bit_offset = 0; |
170 | 106 | new_gas_struct->access_width = 0; | |
171 | /* Validate the table length */ | ||
172 | |||
173 | if (table_header->length < sizeof(struct acpi_table_header)) { | ||
174 | ACPI_ERROR((AE_INFO, | ||
175 | "Invalid length 0x%X in table with signature %4.4s", | ||
176 | (u32) table_header->length, | ||
177 | ACPI_CAST_PTR(char, &signature))); | ||
178 | |||
179 | ACPI_DUMP_BUFFER(table_header, | ||
180 | sizeof(struct acpi_table_header)); | ||
181 | return (AE_BAD_HEADER); | ||
182 | } | ||
183 | |||
184 | return (AE_OK); | ||
185 | } | 107 | } |
186 | 108 | ||
187 | /******************************************************************************* | 109 | /******************************************************************************* |
188 | * | 110 | * |
189 | * FUNCTION: acpi_tb_sum_table | 111 | * FUNCTION: acpi_tb_checksum |
190 | * | 112 | * |
191 | * PARAMETERS: Buffer - Buffer to sum | 113 | * PARAMETERS: Buffer - Pointer to memory region to be checked |
192 | * Length - Size of the buffer | 114 | * Length - Length of this memory region |
193 | * | 115 | * |
194 | * RETURN: 8 bit sum of buffer | 116 | * RETURN: Checksum (u8) |
195 | * | 117 | * |
196 | * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. | 118 | * DESCRIPTION: Calculates circular checksum of memory region. |
197 | * | 119 | * |
198 | ******************************************************************************/ | 120 | ******************************************************************************/ |
199 | 121 | ||
200 | u8 acpi_tb_sum_table(void *buffer, u32 length) | 122 | u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) |
201 | { | 123 | { |
202 | acpi_native_uint i; | ||
203 | u8 sum = 0; | 124 | u8 sum = 0; |
125 | u8 *end = buffer + length; | ||
204 | 126 | ||
205 | if (!buffer || !length) { | 127 | while (buffer < end) { |
206 | return (0); | 128 | sum = (u8) (sum + *(buffer++)); |
207 | } | 129 | } |
208 | 130 | ||
209 | for (i = 0; i < length; i++) { | 131 | return sum; |
210 | sum = (u8) (sum + ((u8 *) buffer)[i]); | ||
211 | } | ||
212 | return (sum); | ||
213 | } | 132 | } |
214 | 133 | ||
215 | /******************************************************************************* | 134 | /******************************************************************************* |
216 | * | 135 | * |
217 | * FUNCTION: acpi_tb_generate_checksum | 136 | * FUNCTION: acpi_tb_convert_fadt |
218 | * | 137 | * |
219 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 138 | * PARAMETERS: Fadt - FADT table to be converted |
220 | * standard ACPI header) | ||
221 | * | 139 | * |
222 | * RETURN: 8 bit checksum of buffer | 140 | * RETURN: None |
223 | * | 141 | * |
224 | * DESCRIPTION: Computes an 8 bit checksum of the table. | 142 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local |
143 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | ||
144 | * copied to the local FADT. The ACPI CA software uses this | ||
145 | * local FADT. Thus a significant amount of special #ifdef | ||
146 | * type codeing is saved. | ||
225 | * | 147 | * |
226 | ******************************************************************************/ | 148 | ******************************************************************************/ |
227 | 149 | ||
228 | u8 acpi_tb_generate_checksum(struct acpi_table_header * table) | 150 | void acpi_tb_convert_fadt(struct acpi_table_fadt *fadt) |
229 | { | 151 | { |
230 | u8 checksum; | ||
231 | |||
232 | /* Sum the entire table as-is */ | ||
233 | 152 | ||
234 | checksum = acpi_tb_sum_table(table, table->length); | 153 | /* |
154 | * Convert table pointers to 64-bit fields | ||
155 | */ | ||
156 | if (!acpi_gbl_FADT.Xfacs) { | ||
157 | acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; | ||
158 | } | ||
235 | 159 | ||
236 | /* Subtract off the existing checksum value in the table */ | 160 | if (!acpi_gbl_FADT.Xdsdt) { |
161 | acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; | ||
162 | } | ||
237 | 163 | ||
238 | checksum = (u8) (checksum - table->checksum); | 164 | /* |
165 | * Convert the V1.0 block addresses to V2.0 GAS structures | ||
166 | */ | ||
167 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_event_block, | ||
168 | acpi_gbl_FADT.pm1_event_length, | ||
169 | (acpi_physical_address) acpi_gbl_FADT. | ||
170 | pm1a_event_block); | ||
171 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_event_block, | ||
172 | acpi_gbl_FADT.pm1_event_length, | ||
173 | (acpi_physical_address) acpi_gbl_FADT. | ||
174 | pm1b_event_block); | ||
175 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_control_block, | ||
176 | acpi_gbl_FADT.pm1_control_length, | ||
177 | (acpi_physical_address) acpi_gbl_FADT. | ||
178 | pm1a_control_block); | ||
179 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_control_block, | ||
180 | acpi_gbl_FADT.pm1_control_length, | ||
181 | (acpi_physical_address) acpi_gbl_FADT. | ||
182 | pm1b_control_block); | ||
183 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm2_control_block, | ||
184 | acpi_gbl_FADT.pm2_control_length, | ||
185 | (acpi_physical_address) acpi_gbl_FADT. | ||
186 | pm2_control_block); | ||
187 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm_timer_block, | ||
188 | acpi_gbl_FADT.pm_timer_length, | ||
189 | (acpi_physical_address) acpi_gbl_FADT. | ||
190 | pm_timer_block); | ||
191 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe0_block, 0, | ||
192 | (acpi_physical_address) acpi_gbl_FADT. | ||
193 | gpe0_block); | ||
194 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe1_block, 0, | ||
195 | (acpi_physical_address) acpi_gbl_FADT. | ||
196 | gpe1_block); | ||
197 | |||
198 | /* | ||
199 | * Create separate GAS structs for the PM1 Enable registers | ||
200 | */ | ||
201 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
202 | (u8) ACPI_DIV_2(acpi_gbl_FADT. | ||
203 | pm1_event_length), | ||
204 | (acpi_physical_address) | ||
205 | (acpi_gbl_FADT.xpm1a_event_block.address + | ||
206 | ACPI_DIV_2(acpi_gbl_FADT. | ||
207 | pm1_event_length))); | ||
208 | |||
209 | /* | ||
210 | * PM1B is optional; leave null if not present | ||
211 | */ | ||
212 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | ||
213 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
214 | (u8) ACPI_DIV_2(acpi_gbl_FADT. | ||
215 | pm1_event_length), | ||
216 | (acpi_physical_address) | ||
217 | (acpi_gbl_FADT.xpm1b_event_block. | ||
218 | address + | ||
219 | ACPI_DIV_2(acpi_gbl_FADT. | ||
220 | pm1_event_length))); | ||
221 | } | ||
239 | 222 | ||
240 | /* Compute the final checksum */ | 223 | /* Global FADT is the new common V2.0 FADT */ |
241 | 224 | ||
242 | checksum = (u8) (0 - checksum); | 225 | acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); |
243 | return (checksum); | ||
244 | } | 226 | } |
245 | 227 | ||
246 | /******************************************************************************* | 228 | /******************************************************************************* |
247 | * | 229 | * |
248 | * FUNCTION: acpi_tb_set_checksum | 230 | * FUNCTION: acpi_tb_parse_fadt |
249 | * | 231 | * |
250 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 232 | * PARAMETERS: Fadt - Pointer to FADT table |
251 | * standard ACPI header) | 233 | * Flags - Flags |
252 | * | 234 | * |
253 | * RETURN: None. Sets the table checksum field | 235 | * RETURN: none |
254 | * | 236 | * |
255 | * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the | 237 | * DESCRIPTION: This function is called to initialise the FADT, DSDT and FACS |
256 | * checksum into the table header. | 238 | * tables (FADT contains the addresses of the DSDT and FACS) |
257 | * | 239 | * |
258 | ******************************************************************************/ | 240 | ******************************************************************************/ |
259 | 241 | ||
260 | void acpi_tb_set_checksum(struct acpi_table_header *table) | 242 | static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags) |
261 | { | 243 | { |
244 | acpi_physical_address dsdt_address = | ||
245 | (acpi_physical_address) fadt->Xdsdt; | ||
246 | acpi_physical_address facs_address = | ||
247 | (acpi_physical_address) fadt->Xfacs; | ||
248 | struct acpi_table_header *table; | ||
249 | |||
250 | if (!dsdt_address) { | ||
251 | goto no_dsdt; | ||
252 | } | ||
253 | |||
254 | table = | ||
255 | acpi_os_map_memory(dsdt_address, sizeof(struct acpi_table_header)); | ||
256 | if (!table) { | ||
257 | goto no_dsdt; | ||
258 | } | ||
259 | |||
260 | /* Initialize the DSDT table */ | ||
261 | |||
262 | ACPI_MOVE_32_TO_32(& | ||
263 | (acpi_gbl_root_table_list. | ||
264 | tables[ACPI_TABLE_INDEX_DSDT].signature), | ||
265 | ACPI_SIG_DSDT); | ||
266 | |||
267 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].address = | ||
268 | dsdt_address; | ||
269 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
270 | table->length; | ||
271 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = flags; | ||
272 | |||
273 | acpi_tb_print_table_header(dsdt_address, table); | ||
274 | |||
275 | /* Global integer width is based upon revision of the DSDT */ | ||
276 | |||
277 | acpi_ut_set_integer_width(table->revision); | ||
278 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
279 | |||
280 | no_dsdt: | ||
281 | if (!facs_address) { | ||
282 | return; | ||
283 | } | ||
262 | 284 | ||
263 | table->checksum = acpi_tb_generate_checksum(table); | 285 | table = |
286 | acpi_os_map_memory(facs_address, sizeof(struct acpi_table_header)); | ||
287 | if (!table) { | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | /* Initialize the FACS table */ | ||
292 | |||
293 | ACPI_MOVE_32_TO_32(& | ||
294 | (acpi_gbl_root_table_list. | ||
295 | tables[ACPI_TABLE_INDEX_FACS].signature), | ||
296 | ACPI_SIG_FACS); | ||
297 | |||
298 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].address = | ||
299 | facs_address; | ||
300 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].length = | ||
301 | table->length; | ||
302 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].flags = flags; | ||
303 | |||
304 | ACPI_INFO((AE_INFO, "%4.4s @ 0x%p", | ||
305 | table->signature, ACPI_CAST_PTR(void, facs_address))); | ||
306 | |||
307 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
264 | } | 308 | } |
265 | 309 | ||
266 | /******************************************************************************* | 310 | /******************************************************************************* |
267 | * | 311 | * |
268 | * FUNCTION: acpi_tb_verify_table_checksum | 312 | * FUNCTION: acpi_tb_parse_root_table |
269 | * | 313 | * |
270 | * PARAMETERS: *table_header - ACPI table to verify | 314 | * PARAMETERS: Rsdp - Pointer to the RSDP |
315 | * Flags - Flags | ||
316 | * | ||
317 | * RETURN: Status | ||
271 | * | 318 | * |
272 | * RETURN: 8 bit checksum of table | 319 | * DESCRIPTION: This function is called to parse the Root System Description |
320 | * Table (RSDT or XSDT) | ||
273 | * | 321 | * |
274 | * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares | 322 | * NOTE: Tables are mapped (not copied) for efficiency. The FACS must |
275 | * it to the existing checksum value. | 323 | * be mapped and cannot be copied because it contains the actual |
324 | * memory location of the ACPI Global Lock. | ||
276 | * | 325 | * |
277 | ******************************************************************************/ | 326 | ******************************************************************************/ |
278 | 327 | ||
279 | acpi_status | 328 | acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags) |
280 | acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) | ||
281 | { | 329 | { |
330 | struct acpi_table_header *table; | ||
331 | acpi_physical_address address; | ||
332 | u32 length; | ||
333 | u8 *table_entry; | ||
334 | acpi_native_uint i; | ||
335 | acpi_native_uint pointer_size; | ||
336 | u32 table_count; | ||
282 | u8 checksum; | 337 | u8 checksum; |
338 | acpi_status status; | ||
339 | |||
340 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | ||
341 | |||
342 | /* Differentiate between RSDT and XSDT root tables */ | ||
343 | |||
344 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | ||
345 | /* | ||
346 | * Root table is an XSDT (64-bit physical addresses). We must use the | ||
347 | * XSDT if the revision is > 1 and the XSDT pointer is present, as per | ||
348 | * the ACPI specification. | ||
349 | */ | ||
350 | address = (acpi_native_uint) rsdp->xsdt_physical_address; | ||
351 | pointer_size = sizeof(u64); | ||
352 | } else { | ||
353 | /* Root table is an RSDT (32-bit physical addresses) */ | ||
354 | |||
355 | address = (acpi_native_uint) rsdp->rsdt_physical_address; | ||
356 | pointer_size = sizeof(u32); | ||
357 | } | ||
283 | 358 | ||
284 | ACPI_FUNCTION_TRACE(tb_verify_table_checksum); | 359 | /* Map the table header to get the full table length */ |
285 | 360 | ||
286 | /* Compute the checksum on the table */ | 361 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
362 | if (!table) { | ||
363 | return (AE_NO_MEMORY); | ||
364 | } | ||
365 | |||
366 | /* Get the length of the full table, verify length and map entire table */ | ||
367 | |||
368 | length = table->length; | ||
369 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
370 | |||
371 | if (length < sizeof(struct acpi_table_header)) { | ||
372 | ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", | ||
373 | length)); | ||
374 | return (AE_INVALID_TABLE_LENGTH); | ||
375 | } | ||
376 | |||
377 | table = acpi_os_map_memory(address, length); | ||
378 | if (!table) { | ||
379 | return (AE_NO_MEMORY); | ||
380 | } | ||
381 | |||
382 | /* Validate the root table checksum */ | ||
383 | |||
384 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); | ||
385 | #if (ACPI_CHECKSUM_ABORT) | ||
386 | |||
387 | if (checksum) { | ||
388 | acpi_os_unmap_memory(table, length); | ||
389 | return (AE_BAD_CHECKSUM); | ||
390 | } | ||
391 | #endif | ||
392 | |||
393 | acpi_tb_print_table_header(address, table); | ||
394 | |||
395 | /* Calculate the number of tables described in the root table */ | ||
396 | |||
397 | table_count = | ||
398 | (table->length - sizeof(struct acpi_table_header)) / pointer_size; | ||
399 | |||
400 | /* Setup loop */ | ||
287 | 401 | ||
288 | checksum = acpi_tb_generate_checksum(table_header); | 402 | table_entry = |
403 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | ||
404 | acpi_gbl_root_table_list.count = 2; | ||
289 | 405 | ||
290 | /* Checksum ok? */ | 406 | /* |
407 | * Initialize the ACPI table entries | ||
408 | * First two entries in the table array are reserved for the DSDT and FACS | ||
409 | */ | ||
410 | for (i = 0; i < table_count; ++i, table_entry += pointer_size) { | ||
291 | 411 | ||
292 | if (checksum == table_header->checksum) { | 412 | /* Ensure there is room for another table entry */ |
293 | return_ACPI_STATUS(AE_OK); | 413 | |
414 | if (acpi_gbl_root_table_list.count >= | ||
415 | acpi_gbl_root_table_list.size) { | ||
416 | status = acpi_tb_resize_root_table_list(); | ||
417 | if (ACPI_FAILURE(status)) { | ||
418 | ACPI_WARNING((AE_INFO, | ||
419 | "Truncating %u table entries!", | ||
420 | (unsigned) | ||
421 | (acpi_gbl_root_table_list.size - | ||
422 | acpi_gbl_root_table_list. | ||
423 | count))); | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /* Get the physical address (32-bit for RSDT, 64-bit for XSDT) */ | ||
429 | |||
430 | if (pointer_size == sizeof(u32)) { | ||
431 | acpi_gbl_root_table_list. | ||
432 | tables[acpi_gbl_root_table_list.count].address = | ||
433 | (acpi_physical_address) (*ACPI_CAST_PTR | ||
434 | (u32, table_entry)); | ||
435 | } else { | ||
436 | acpi_gbl_root_table_list. | ||
437 | tables[acpi_gbl_root_table_list.count].address = | ||
438 | (acpi_physical_address) (*ACPI_CAST_PTR | ||
439 | (u64, table_entry)); | ||
440 | } | ||
441 | |||
442 | acpi_gbl_root_table_list.count++; | ||
294 | } | 443 | } |
295 | 444 | ||
296 | ACPI_WARNING((AE_INFO, | 445 | /* |
297 | "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", | 446 | * It is not possible to map more than one entry in some environments, |
298 | table_header->signature, table_header->checksum, | 447 | * so unmap the root table here before mapping other tables |
299 | checksum)); | 448 | */ |
449 | acpi_os_unmap_memory(table, length); | ||
450 | |||
451 | /* Initialize all tables other than the DSDT and FACS */ | ||
452 | |||
453 | for (i = 2; i < acpi_gbl_root_table_list.count; i++) { | ||
454 | address = acpi_gbl_root_table_list.tables[i].address; | ||
455 | length = sizeof(struct acpi_table_header); | ||
456 | |||
457 | table = acpi_os_map_memory(address, length); | ||
458 | if (!table) { | ||
459 | continue; | ||
460 | } | ||
461 | |||
462 | acpi_gbl_root_table_list.tables[i].length = table->length; | ||
463 | acpi_gbl_root_table_list.tables[i].flags = flags; | ||
464 | |||
465 | ACPI_MOVE_32_TO_32(& | ||
466 | (acpi_gbl_root_table_list.tables[i]. | ||
467 | signature), table->signature); | ||
468 | |||
469 | acpi_tb_print_table_header(address, table); | ||
470 | |||
471 | /* | ||
472 | * Special case for the FADT because of multiple versions - | ||
473 | * get a local copy and convert to common format | ||
474 | */ | ||
475 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FADT)) { | ||
476 | acpi_os_unmap_memory(table, length); | ||
477 | length = table->length; | ||
478 | |||
479 | table = acpi_os_map_memory(address, length); | ||
480 | if (!table) { | ||
481 | continue; | ||
482 | } | ||
483 | |||
484 | /* Copy the entire FADT locally */ | ||
485 | |||
486 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | ||
487 | ACPI_MIN(table->length, | ||
488 | sizeof(struct acpi_table_fadt))); | ||
489 | |||
490 | /* Small table means old revision, convert to new */ | ||
491 | |||
492 | if (table->length < sizeof(struct acpi_table_fadt)) { | ||
493 | acpi_tb_convert_fadt(ACPI_CAST_PTR | ||
494 | (struct acpi_table_fadt, | ||
495 | table)); | ||
496 | } | ||
497 | |||
498 | /* Unmap original FADT */ | ||
300 | 499 | ||
301 | return_ACPI_STATUS(AE_BAD_CHECKSUM); | 500 | acpi_os_unmap_memory(table, length); |
501 | acpi_tb_parse_fadt(&acpi_gbl_FADT, flags); | ||
502 | } else { | ||
503 | acpi_os_unmap_memory(table, length); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | return_ACPI_STATUS(AE_OK); | ||
302 | } | 508 | } |
303 | 509 | ||
304 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 510 | /****************************************************************************** |
305 | /******************************************************************************* | ||
306 | * | 511 | * |
307 | * FUNCTION: acpi_tb_handle_to_object | 512 | * FUNCTION: acpi_tb_map |
308 | * | 513 | * |
309 | * PARAMETERS: table_id - Id for which the function is searching | 514 | * PARAMETERS: Address - Address to be mapped |
310 | * table_desc - Pointer to return the matching table | 515 | * Length - Length to be mapped |
311 | * descriptor. | 516 | * Flags - Logical or physical addressing mode |
312 | * | 517 | * |
313 | * RETURN: Search the tables to find one with a matching table_id and | 518 | * RETURN: Pointer to mapped region |
314 | * return a pointer to that table descriptor. | ||
315 | * | 519 | * |
316 | ******************************************************************************/ | 520 | * DESCRIPTION: Maps memory according to flag |
521 | * | ||
522 | *****************************************************************************/ | ||
317 | 523 | ||
318 | acpi_status | 524 | void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags) |
319 | acpi_tb_handle_to_object(u16 table_id, | ||
320 | struct acpi_table_desc **return_table_desc) | ||
321 | { | 525 | { |
322 | u32 i; | ||
323 | struct acpi_table_desc *table_desc; | ||
324 | 526 | ||
325 | ACPI_FUNCTION_NAME(tb_handle_to_object); | 527 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { |
528 | return (acpi_os_map_memory(address, length)); | ||
529 | } else { | ||
530 | return (ACPI_CAST_PTR(void, address)); | ||
531 | } | ||
532 | } | ||
326 | 533 | ||
327 | for (i = 0; i < ACPI_TABLE_MAX; i++) { | 534 | /****************************************************************************** |
328 | table_desc = acpi_gbl_table_lists[i].next; | 535 | * |
329 | while (table_desc) { | 536 | * FUNCTION: acpi_tb_unmap |
330 | if (table_desc->table_id == table_id) { | 537 | * |
331 | *return_table_desc = table_desc; | 538 | * PARAMETERS: Pointer - To mapped region |
332 | return (AE_OK); | 539 | * Length - Length to be unmapped |
333 | } | 540 | * Flags - Logical or physical addressing mode |
541 | * | ||
542 | * RETURN: None | ||
543 | * | ||
544 | * DESCRIPTION: Unmaps memory according to flag | ||
545 | * | ||
546 | *****************************************************************************/ | ||
334 | 547 | ||
335 | table_desc = table_desc->next; | 548 | void acpi_tb_unmap(void *pointer, u32 length, u32 flags) |
336 | } | 549 | { |
337 | } | ||
338 | 550 | ||
339 | ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); | 551 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { |
340 | return (AE_BAD_PARAMETER); | 552 | acpi_os_unmap_memory(pointer, length); |
553 | } | ||
341 | } | 554 | } |
342 | #endif | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 5ba9303293ad..77439fc36c32 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -49,80 +49,146 @@ | |||
49 | #define _COMPONENT ACPI_TABLES | 49 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbxface") | 50 | ACPI_MODULE_NAME("tbxface") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | static acpi_status acpi_tb_load_namespace(void); | ||
54 | |||
52 | /******************************************************************************* | 55 | /******************************************************************************* |
53 | * | 56 | * |
54 | * FUNCTION: acpi_load_tables | 57 | * FUNCTION: acpi_initialize_tables |
55 | * | 58 | * |
56 | * PARAMETERS: None | 59 | * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated |
60 | * struct acpi_table_desc structures. If NULL, the | ||
61 | * array is dynamically allocated. | ||
62 | * initial_table_count - Size of initial_table_array, in number of | ||
63 | * struct acpi_table_desc structures | ||
64 | * allow_realloc - Flag to tell Table Manager if resize of | ||
65 | * pre-allocated array is allowed. Ignored | ||
66 | * if initial_table_array is NULL. | ||
57 | * | 67 | * |
58 | * RETURN: Status | 68 | * RETURN: Status |
59 | * | 69 | * |
60 | * DESCRIPTION: This function is called to load the ACPI tables from the | 70 | * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. |
61 | * provided RSDT | 71 | * |
72 | * NOTE: Allows static allocation of the initial table array in order | ||
73 | * to avoid the use of dynamic memory in confined environments | ||
74 | * such as the kernel boot sequence where it may not be available. | ||
75 | * | ||
76 | * If the host OS memory managers are initialized, use NULL for | ||
77 | * initial_table_array, and the table will be dynamically allocated. | ||
62 | * | 78 | * |
63 | ******************************************************************************/ | 79 | ******************************************************************************/ |
64 | acpi_status acpi_load_tables(void) | 80 | |
81 | acpi_status | ||
82 | acpi_initialize_tables(struct acpi_table_desc *initial_table_array, | ||
83 | u32 initial_table_count, u8 allow_resize) | ||
65 | { | 84 | { |
66 | struct acpi_pointer rsdp_address; | 85 | acpi_physical_address address; |
67 | acpi_status status; | 86 | acpi_status status; |
87 | struct acpi_table_rsdp *rsdp; | ||
68 | 88 | ||
69 | ACPI_FUNCTION_TRACE(acpi_load_tables); | 89 | ACPI_FUNCTION_TRACE(acpi_initialize_tables); |
70 | 90 | ||
71 | /* Get the RSDP */ | 91 | /* |
92 | * Set up the Root Table Array | ||
93 | * Allocate the table array if requested | ||
94 | */ | ||
95 | if (!initial_table_array) { | ||
96 | acpi_gbl_root_table_list.size = initial_table_count; | ||
97 | acpi_gbl_root_table_list.flags = ACPI_TABLE_FLAGS_ALLOW_RESIZE; | ||
72 | 98 | ||
73 | status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, | 99 | status = acpi_tb_resize_root_table_list(); |
74 | &rsdp_address); | 100 | if (ACPI_FAILURE(status)) { |
75 | if (ACPI_FAILURE(status)) { | 101 | return_ACPI_STATUS(status); |
76 | ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); | 102 | } |
77 | goto error_exit; | 103 | } else { |
104 | /* Root Table Array has been statically allocated by the host */ | ||
105 | |||
106 | acpi_gbl_root_table_list.tables = initial_table_array; | ||
107 | acpi_gbl_root_table_list.size = initial_table_count; | ||
108 | acpi_gbl_root_table_list.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
109 | if (allow_resize) { | ||
110 | acpi_gbl_root_table_list.flags = | ||
111 | ACPI_TABLE_FLAGS_ALLOW_RESIZE; | ||
112 | } | ||
78 | } | 113 | } |
79 | 114 | ||
80 | /* Map and validate the RSDP */ | 115 | /* Get the RSDP and map it */ |
81 | 116 | ||
82 | acpi_gbl_table_flags = rsdp_address.pointer_type; | 117 | address = acpi_os_get_root_pointer(); |
118 | if (!address) { | ||
119 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
120 | } | ||
83 | 121 | ||
84 | status = acpi_tb_verify_rsdp(&rsdp_address); | 122 | rsdp = acpi_os_map_memory(address, sizeof(struct acpi_table_rsdp)); |
85 | if (ACPI_FAILURE(status)) { | 123 | if (!rsdp) { |
86 | ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); | 124 | return_ACPI_STATUS(AE_NO_MEMORY); |
87 | goto error_exit; | ||
88 | } | 125 | } |
89 | 126 | ||
90 | /* Get the RSDT via the RSDP */ | 127 | ACPI_INFO((AE_INFO, "%.8s @ 0x%p", |
128 | rsdp->signature, ACPI_CAST_PTR(void, address))); | ||
91 | 129 | ||
92 | status = acpi_tb_get_table_rsdt(); | 130 | /* |
93 | if (ACPI_FAILURE(status)) { | 131 | * Get the root table (RSDT or XSDT) and extract all entries to the local |
94 | ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); | 132 | * Root Table Array. This array contains the information of the RSDT/XSDT |
95 | goto error_exit; | 133 | * in a common, more useable format. |
96 | } | 134 | */ |
135 | status = acpi_tb_parse_root_table(rsdp, ACPI_TABLE_ORIGIN_MAPPED); | ||
136 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | ||
137 | return_ACPI_STATUS(status); | ||
138 | } | ||
97 | 139 | ||
98 | /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ | 140 | ACPI_EXPORT_SYMBOL(acpi_initialize_tables) |
99 | 141 | ||
100 | status = acpi_tb_get_required_tables(); | 142 | /******************************************************************************* |
101 | if (ACPI_FAILURE(status)) { | 143 | * |
102 | ACPI_EXCEPTION((AE_INFO, status, | 144 | * FUNCTION: acpi_reallocate_root_table |
103 | "Could not get all required tables (DSDT/FADT/FACS)")); | 145 | * |
104 | goto error_exit; | 146 | * PARAMETERS: None |
147 | * | ||
148 | * RETURN: Status | ||
149 | * | ||
150 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the | ||
151 | * root list from the previously provided scratch area. Should | ||
152 | * be called once dynamic memory allocation is available in the | ||
153 | * kernel | ||
154 | * | ||
155 | ******************************************************************************/ | ||
156 | acpi_status acpi_reallocate_root_table(void) | ||
157 | { | ||
158 | struct acpi_table_desc *tables; | ||
159 | acpi_size new_size; | ||
160 | |||
161 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | ||
162 | |||
163 | /* | ||
164 | * Only reallocate the root table if the host provided a static buffer | ||
165 | * for the table array in the call to acpi_initialize_tables. | ||
166 | */ | ||
167 | if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) != | ||
168 | ACPI_TABLE_ORIGIN_UNKNOWN) { | ||
169 | return_ACPI_STATUS(AE_SUPPORT); | ||
105 | } | 170 | } |
106 | 171 | ||
107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); | 172 | new_size = |
173 | (acpi_gbl_root_table_list.count + | ||
174 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); | ||
108 | 175 | ||
109 | /* Load the namespace from the tables */ | 176 | /* Create new array and copy the old array */ |
110 | 177 | ||
111 | status = acpi_ns_load_namespace(); | 178 | tables = ACPI_ALLOCATE_ZEROED(new_size); |
112 | if (ACPI_FAILURE(status)) { | 179 | if (!tables) { |
113 | ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); | 180 | return_ACPI_STATUS(AE_NO_MEMORY); |
114 | goto error_exit; | ||
115 | } | 181 | } |
116 | 182 | ||
117 | return_ACPI_STATUS(AE_OK); | 183 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); |
118 | 184 | ||
119 | error_exit: | 185 | acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; |
120 | ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); | 186 | acpi_gbl_root_table_list.tables = tables; |
121 | return_ACPI_STATUS(status); | 187 | acpi_gbl_root_table_list.flags = |
122 | } | 188 | ACPI_TABLE_ORIGIN_ALLOCATED | ACPI_TABLE_FLAGS_ALLOW_RESIZE; |
123 | |||
124 | ACPI_EXPORT_SYMBOL(acpi_load_tables) | ||
125 | 189 | ||
190 | return_ACPI_STATUS(AE_OK); | ||
191 | } | ||
126 | /******************************************************************************* | 192 | /******************************************************************************* |
127 | * | 193 | * |
128 | * FUNCTION: acpi_load_table | 194 | * FUNCTION: acpi_load_table |
@@ -141,342 +207,358 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables) | |||
141 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) | 207 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) |
142 | { | 208 | { |
143 | acpi_status status; | 209 | acpi_status status; |
144 | struct acpi_table_desc table_info; | 210 | acpi_native_uint table_index; |
145 | struct acpi_pointer address; | ||
146 | |||
147 | ACPI_FUNCTION_TRACE(acpi_load_table); | ||
148 | |||
149 | if (!table_ptr) { | ||
150 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
151 | } | ||
152 | 211 | ||
153 | /* Copy the table to a local buffer */ | 212 | /* |
154 | 213 | * Install the new table into the local data structures | |
155 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | 214 | */ |
156 | address.pointer.logical = table_ptr; | 215 | status = acpi_tb_add_table(table_ptr, &table_index); |
157 | |||
158 | status = acpi_tb_get_table_body(&address, table_ptr, &table_info); | ||
159 | if (ACPI_FAILURE(status)) { | ||
160 | return_ACPI_STATUS(status); | ||
161 | } | ||
162 | |||
163 | /* Check signature for a valid table type */ | ||
164 | |||
165 | status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); | ||
166 | if (ACPI_FAILURE(status)) { | 216 | if (ACPI_FAILURE(status)) { |
167 | return_ACPI_STATUS(status); | 217 | return_ACPI_STATUS(status); |
168 | } | 218 | } |
219 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | ||
220 | return_ACPI_STATUS(status); | ||
221 | } | ||
169 | 222 | ||
170 | /* Install the new table into the local data structures */ | 223 | ACPI_EXPORT_SYMBOL(acpi_load_table) |
171 | |||
172 | status = acpi_tb_install_table(&table_info); | ||
173 | if (ACPI_FAILURE(status)) { | ||
174 | if (status == AE_ALREADY_EXISTS) { | ||
175 | 224 | ||
176 | /* Table already exists, no error */ | 225 | /****************************************************************************** |
226 | * | ||
227 | * FUNCTION: acpi_get_table_header | ||
228 | * | ||
229 | * PARAMETERS: Signature - ACPI signature of needed table | ||
230 | * Instance - Which instance (for SSDTs) | ||
231 | * out_table_header - Where the pointer to the table header | ||
232 | * is returned | ||
233 | * | ||
234 | * RETURN: Status and pointer to mapped table header | ||
235 | * | ||
236 | * DESCRIPTION: Finds an ACPI table header. | ||
237 | * | ||
238 | * NOTE: Caller is responsible in unmapping the header with | ||
239 | * acpi_os_unmap_memory | ||
240 | * | ||
241 | *****************************************************************************/ | ||
242 | acpi_status | ||
243 | acpi_get_table_header(char *signature, | ||
244 | acpi_native_uint instance, | ||
245 | struct acpi_table_header **out_table_header) | ||
246 | { | ||
247 | acpi_native_uint i; | ||
248 | acpi_native_uint j; | ||
177 | 249 | ||
178 | status = AE_OK; | 250 | /* |
251 | * Walk the root table list | ||
252 | */ | ||
253 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
254 | if (!ACPI_COMPARE_NAME | ||
255 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
256 | signature)) { | ||
257 | continue; | ||
179 | } | 258 | } |
180 | 259 | ||
181 | /* Free table allocated by acpi_tb_get_table_body */ | 260 | if (++j < instance) { |
182 | 261 | continue; | |
183 | acpi_tb_delete_single_table(&table_info); | 262 | } |
184 | return_ACPI_STATUS(status); | ||
185 | } | ||
186 | |||
187 | /* Convert the table to common format if necessary */ | ||
188 | |||
189 | switch (table_info.type) { | ||
190 | case ACPI_TABLE_ID_FADT: | ||
191 | |||
192 | status = acpi_tb_convert_table_fadt(); | ||
193 | break; | ||
194 | |||
195 | case ACPI_TABLE_ID_FACS: | ||
196 | |||
197 | status = acpi_tb_build_common_facs(&table_info); | ||
198 | break; | ||
199 | |||
200 | default: | ||
201 | /* Load table into namespace if it contains executable AML */ | ||
202 | |||
203 | status = | ||
204 | acpi_ns_load_table(table_info.installed_desc, | ||
205 | acpi_gbl_root_node); | ||
206 | break; | ||
207 | } | ||
208 | 263 | ||
209 | if (ACPI_FAILURE(status)) { | 264 | *out_table_header = |
265 | acpi_tb_map(acpi_gbl_root_table_list.tables[i].address, | ||
266 | (u32) sizeof(struct acpi_table_header), | ||
267 | acpi_gbl_root_table_list.tables[i]. | ||
268 | flags & ACPI_TABLE_ORIGIN_MASK); | ||
210 | 269 | ||
211 | /* Uninstall table and free the buffer */ | 270 | if (!out_table_header) { |
271 | return (AE_NO_MEMORY); | ||
272 | } | ||
212 | 273 | ||
213 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | 274 | return (AE_OK); |
214 | } | 275 | } |
215 | 276 | ||
216 | return_ACPI_STATUS(status); | 277 | return (AE_NOT_FOUND); |
217 | } | 278 | } |
218 | 279 | ||
219 | ACPI_EXPORT_SYMBOL(acpi_load_table) | 280 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) |
220 | 281 | ||
221 | /******************************************************************************* | 282 | |
283 | /****************************************************************************** | ||
222 | * | 284 | * |
223 | * FUNCTION: acpi_unload_table_id | 285 | * FUNCTION: acpi_unload_table_id |
224 | * | 286 | * |
225 | * PARAMETERS: table_type - Type of table to be unloaded | 287 | * PARAMETERS: id - Owner ID of the table to be removed. |
226 | * id - Owner ID of the table to be removed. | ||
227 | * | 288 | * |
228 | * RETURN: Status | 289 | * RETURN: Status |
229 | * | 290 | * |
230 | * DESCRIPTION: This routine is used to force the unload of a table (by id) | 291 | * DESCRIPTION: This routine is used to force the unload of a table (by id) |
231 | * | 292 | * |
232 | ******************************************************************************/ | 293 | ******************************************************************************/ |
233 | acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) | 294 | acpi_status acpi_unload_table_id(acpi_owner_id id) |
234 | { | 295 | { |
235 | struct acpi_table_desc *table_desc; | 296 | int i; |
236 | acpi_status status; | 297 | acpi_status status = AE_NOT_EXIST; |
237 | 298 | ||
238 | ACPI_FUNCTION_TRACE(acpi_unload_table); | 299 | ACPI_FUNCTION_TRACE(acpi_unload_table); |
239 | 300 | ||
240 | /* Parameter validation */ | ||
241 | if (table_type > ACPI_TABLE_ID_MAX) | ||
242 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
243 | |||
244 | /* Find table from the requested type list */ | 301 | /* Find table from the requested type list */ |
245 | table_desc = acpi_gbl_table_lists[table_type].next; | 302 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
246 | while (table_desc && table_desc->owner_id != id) | 303 | if (id != acpi_gbl_root_table_list.tables[i].owner_id) { |
247 | table_desc = table_desc->next; | 304 | continue; |
248 | 305 | } | |
249 | if (!table_desc) | 306 | /* |
250 | return_ACPI_STATUS(AE_NOT_EXIST); | 307 | * Delete all namespace objects owned by this table. Note that these |
251 | 308 | * objects can appear anywhere in the namespace by virtue of the AML | |
252 | /* | 309 | * "Scope" operator. Thus, we need to track ownership by an ID, not |
253 | * Delete all namespace objects owned by this table. Note that these | 310 | * simply a position within the hierarchy |
254 | * objects can appear anywhere in the namespace by virtue of the AML | 311 | */ |
255 | * "Scope" operator. Thus, we need to track ownership by an ID, not | 312 | acpi_tb_delete_namespace_by_owner(i); |
256 | * simply a position within the hierarchy | 313 | acpi_tb_release_owner_id(i); |
257 | */ | 314 | acpi_tb_set_table_loaded_flag(i, FALSE); |
258 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | 315 | } |
259 | 316 | return_ACPI_STATUS(status); | |
260 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
261 | if (ACPI_FAILURE(status)) | ||
262 | return_ACPI_STATUS(status); | ||
263 | |||
264 | (void)acpi_tb_uninstall_table(table_desc); | ||
265 | |||
266 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
267 | |||
268 | return_ACPI_STATUS(AE_OK); | ||
269 | } | 317 | } |
270 | 318 | ||
271 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) | 319 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) |
272 | 320 | ||
273 | #ifdef ACPI_FUTURE_USAGE | ||
274 | /******************************************************************************* | 321 | /******************************************************************************* |
275 | * | 322 | * |
276 | * FUNCTION: acpi_unload_table | 323 | * FUNCTION: acpi_get_table |
277 | * | 324 | * |
278 | * PARAMETERS: table_type - Type of table to be unloaded | 325 | * PARAMETERS: Signature - ACPI signature of needed table |
326 | * Instance - Which instance (for SSDTs) | ||
327 | * out_table - Where the pointer to the table is returned | ||
279 | * | 328 | * |
280 | * RETURN: Status | 329 | * RETURN: Status and pointer to table |
281 | * | 330 | * |
282 | * DESCRIPTION: This routine is used to force the unload of a table | 331 | * DESCRIPTION: Finds and verifies an ACPI table. |
283 | * | 332 | * |
284 | ******************************************************************************/ | 333 | *****************************************************************************/ |
285 | acpi_status acpi_unload_table(acpi_table_type table_type) | 334 | acpi_status |
335 | acpi_get_table(char *signature, | ||
336 | acpi_native_uint instance, struct acpi_table_header ** out_table) | ||
286 | { | 337 | { |
287 | struct acpi_table_desc *table_desc; | 338 | acpi_native_uint i; |
288 | 339 | acpi_native_uint j; | |
289 | ACPI_FUNCTION_TRACE(acpi_unload_table); | 340 | acpi_status status; |
290 | |||
291 | /* Parameter validation */ | ||
292 | 341 | ||
293 | if (table_type > ACPI_TABLE_ID_MAX) { | 342 | /* |
294 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 343 | * Walk the root table list |
295 | } | 344 | */ |
345 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
346 | if (!ACPI_COMPARE_NAME | ||
347 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
348 | signature)) { | ||
349 | continue; | ||
350 | } | ||
296 | 351 | ||
297 | /* Find all tables of the requested type */ | 352 | if (++j < instance) { |
353 | continue; | ||
354 | } | ||
298 | 355 | ||
299 | table_desc = acpi_gbl_table_lists[table_type].next; | 356 | status = |
300 | if (!table_desc) { | 357 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); |
301 | return_ACPI_STATUS(AE_NOT_EXIST); | 358 | if (ACPI_SUCCESS(status)) { |
302 | } | 359 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
360 | } | ||
303 | 361 | ||
304 | while (table_desc) { | 362 | return (status); |
305 | /* | ||
306 | * Delete all namespace objects owned by this table. Note that these | ||
307 | * objects can appear anywhere in the namespace by virtue of the AML | ||
308 | * "Scope" operator. Thus, we need to track ownership by an ID, not | ||
309 | * simply a position within the hierarchy | ||
310 | */ | ||
311 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | ||
312 | table_desc = table_desc->next; | ||
313 | } | 363 | } |
314 | 364 | ||
315 | /* Delete (or unmap) all tables of this type */ | 365 | return (AE_NOT_FOUND); |
316 | |||
317 | acpi_tb_delete_tables_by_type(table_type); | ||
318 | return_ACPI_STATUS(AE_OK); | ||
319 | } | 366 | } |
320 | 367 | ||
321 | ACPI_EXPORT_SYMBOL(acpi_unload_table) | 368 | ACPI_EXPORT_SYMBOL(acpi_get_table) |
322 | 369 | ||
323 | /******************************************************************************* | 370 | /******************************************************************************* |
324 | * | 371 | * |
325 | * FUNCTION: acpi_get_table_header | 372 | * FUNCTION: acpi_get_table_by_index |
326 | * | 373 | * |
327 | * PARAMETERS: table_type - one of the defined table types | 374 | * PARAMETERS: table_index - Table index |
328 | * Instance - the non zero instance of the table, allows | 375 | * Table - Where the pointer to the table is returned |
329 | * support for multiple tables of the same type | ||
330 | * see acpi_gbl_acpi_table_flag | ||
331 | * out_table_header - pointer to the struct acpi_table_header if successful | ||
332 | * | 376 | * |
333 | * DESCRIPTION: This function is called to get an ACPI table header. The caller | 377 | * RETURN: Status and pointer to the table |
334 | * supplies an pointer to a data area sufficient to contain an ACPI | ||
335 | * struct acpi_table_header structure. | ||
336 | * | 378 | * |
337 | * The header contains a length field that can be used to determine | 379 | * DESCRIPTION: Obtain a table by an index into the global table list. |
338 | * the size of the buffer needed to contain the entire table. This | ||
339 | * function is not valid for the RSD PTR table since it does not | ||
340 | * have a standard header and is fixed length. | ||
341 | * | 380 | * |
342 | ******************************************************************************/ | 381 | ******************************************************************************/ |
343 | acpi_status | 382 | acpi_status |
344 | acpi_get_table_header(acpi_table_type table_type, | 383 | acpi_get_table_by_index(acpi_native_uint table_index, |
345 | u32 instance, struct acpi_table_header *out_table_header) | 384 | struct acpi_table_header ** table) |
346 | { | 385 | { |
347 | struct acpi_table_header *tbl_ptr; | ||
348 | acpi_status status; | 386 | acpi_status status; |
349 | 387 | ||
350 | ACPI_FUNCTION_TRACE(acpi_get_table_header); | 388 | ACPI_FUNCTION_TRACE(acpi_get_table_by_index); |
351 | 389 | ||
352 | if ((instance == 0) || | 390 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
353 | (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { | ||
354 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
355 | } | ||
356 | 391 | ||
357 | /* Check the table type and instance */ | 392 | /* Validate index */ |
358 | 393 | ||
359 | if ((table_type > ACPI_TABLE_ID_MAX) || | 394 | if (table_index >= acpi_gbl_root_table_list.count) { |
360 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 395 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
361 | instance > 1)) { | ||
362 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 396 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
363 | } | 397 | } |
364 | 398 | ||
365 | /* Get a pointer to the entire table */ | 399 | if (!acpi_gbl_root_table_list.tables[table_index].pointer) { |
366 | 400 | ||
367 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | 401 | /* Table is not mapped, map it */ |
368 | if (ACPI_FAILURE(status)) { | ||
369 | return_ACPI_STATUS(status); | ||
370 | } | ||
371 | 402 | ||
372 | /* The function will return a NULL pointer if the table is not loaded */ | 403 | status = |
373 | 404 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | |
374 | if (tbl_ptr == NULL) { | 405 | tables[table_index]); |
375 | return_ACPI_STATUS(AE_NOT_EXIST); | 406 | if (ACPI_FAILURE(status)) { |
407 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
408 | return_ACPI_STATUS(status); | ||
409 | } | ||
376 | } | 410 | } |
377 | 411 | ||
378 | /* Copy the header to the caller's buffer */ | 412 | *table = acpi_gbl_root_table_list.tables[table_index].pointer; |
379 | 413 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | |
380 | ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), | 414 | return_ACPI_STATUS(AE_OK); |
381 | ACPI_CAST_PTR(void, tbl_ptr), | ||
382 | sizeof(struct acpi_table_header)); | ||
383 | |||
384 | return_ACPI_STATUS(status); | ||
385 | } | 415 | } |
386 | 416 | ||
387 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) | 417 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) |
388 | #endif /* ACPI_FUTURE_USAGE */ | ||
389 | 418 | ||
390 | /******************************************************************************* | 419 | /******************************************************************************* |
391 | * | 420 | * |
392 | * FUNCTION: acpi_get_table | 421 | * FUNCTION: acpi_tb_load_namespace |
393 | * | 422 | * |
394 | * PARAMETERS: table_type - one of the defined table types | 423 | * PARAMETERS: None |
395 | * Instance - the non zero instance of the table, allows | ||
396 | * support for multiple tables of the same type | ||
397 | * see acpi_gbl_acpi_table_flag | ||
398 | * ret_buffer - pointer to a structure containing a buffer to | ||
399 | * receive the table | ||
400 | * | 424 | * |
401 | * RETURN: Status | 425 | * RETURN: Status |
402 | * | 426 | * |
403 | * DESCRIPTION: This function is called to get an ACPI table. The caller | 427 | * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in |
404 | * supplies an out_buffer large enough to contain the entire ACPI | 428 | * the RSDT/XSDT. |
405 | * table. The caller should call the acpi_get_table_header function | ||
406 | * first to determine the buffer size needed. Upon completion | ||
407 | * the out_buffer->Length field will indicate the number of bytes | ||
408 | * copied into the out_buffer->buf_ptr buffer. This table will be | ||
409 | * a complete table including the header. | ||
410 | * | 429 | * |
411 | ******************************************************************************/ | 430 | ******************************************************************************/ |
412 | acpi_status | 431 | static acpi_status acpi_tb_load_namespace(void) |
413 | acpi_get_table(acpi_table_type table_type, | ||
414 | u32 instance, struct acpi_buffer *ret_buffer) | ||
415 | { | 432 | { |
416 | struct acpi_table_header *tbl_ptr; | ||
417 | acpi_status status; | 433 | acpi_status status; |
418 | acpi_size table_length; | 434 | struct acpi_table_header *table; |
435 | acpi_native_uint i; | ||
419 | 436 | ||
420 | ACPI_FUNCTION_TRACE(acpi_get_table); | 437 | ACPI_FUNCTION_TRACE(tb_load_namespace); |
421 | 438 | ||
422 | /* Parameter validation */ | 439 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
423 | 440 | ||
424 | if (instance == 0) { | 441 | /* |
425 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 442 | * Load the namespace. The DSDT is required, but any SSDT and PSDT tables |
443 | * are optional. | ||
444 | */ | ||
445 | if (!acpi_gbl_root_table_list.count || | ||
446 | !ACPI_COMPARE_NAME(& | ||
447 | (acpi_gbl_root_table_list. | ||
448 | tables[ACPI_TABLE_INDEX_DSDT].signature), | ||
449 | ACPI_SIG_DSDT) | ||
450 | || | ||
451 | ACPI_FAILURE(acpi_tb_verify_table | ||
452 | (&acpi_gbl_root_table_list. | ||
453 | tables[ACPI_TABLE_INDEX_DSDT]))) { | ||
454 | status = AE_NO_ACPI_TABLES; | ||
455 | goto unlock_and_exit; | ||
426 | } | 456 | } |
427 | 457 | ||
428 | status = acpi_ut_validate_buffer(ret_buffer); | 458 | /* |
429 | if (ACPI_FAILURE(status)) { | 459 | * Find DSDT table |
430 | return_ACPI_STATUS(status); | 460 | */ |
461 | status = | ||
462 | acpi_os_table_override(acpi_gbl_root_table_list. | ||
463 | tables[ACPI_TABLE_INDEX_DSDT].pointer, | ||
464 | &table); | ||
465 | if (ACPI_SUCCESS(status) && table) { | ||
466 | /* | ||
467 | * DSDT table has been found | ||
468 | */ | ||
469 | acpi_tb_delete_table(ACPI_TABLE_INDEX_DSDT); | ||
470 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = | ||
471 | table; | ||
472 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
473 | table->length; | ||
474 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = | ||
475 | ACPI_TABLE_ORIGIN_UNKNOWN; | ||
476 | |||
477 | ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); | ||
478 | acpi_tb_print_table_header(0, table); | ||
431 | } | 479 | } |
432 | 480 | ||
433 | /* Check the table type and instance */ | 481 | status = |
482 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
483 | tables[ACPI_TABLE_INDEX_DSDT]); | ||
484 | if (ACPI_FAILURE(status)) { | ||
485 | |||
486 | /* A valid DSDT is required */ | ||
434 | 487 | ||
435 | if ((table_type > ACPI_TABLE_ID_MAX) || | 488 | status = AE_NO_ACPI_TABLES; |
436 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 489 | goto unlock_and_exit; |
437 | instance > 1)) { | ||
438 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
439 | } | 490 | } |
440 | 491 | ||
441 | /* Get a pointer to the entire table */ | 492 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
442 | 493 | ||
443 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | 494 | /* |
495 | * Load and parse tables. | ||
496 | */ | ||
497 | status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); | ||
444 | if (ACPI_FAILURE(status)) { | 498 | if (ACPI_FAILURE(status)) { |
445 | return_ACPI_STATUS(status); | 499 | return_ACPI_STATUS(status); |
446 | } | 500 | } |
447 | 501 | ||
448 | /* | 502 | /* |
449 | * acpi_tb_get_table_ptr will return a NULL pointer if the | 503 | * Load any SSDT or PSDT tables. Note: Loop leaves tables locked |
450 | * table is not loaded. | ||
451 | */ | 504 | */ |
452 | if (tbl_ptr == NULL) { | 505 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
453 | return_ACPI_STATUS(AE_NOT_EXIST); | 506 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
507 | if ((!ACPI_COMPARE_NAME | ||
508 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
509 | ACPI_SIG_SSDT) | ||
510 | && | ||
511 | !ACPI_COMPARE_NAME(& | ||
512 | (acpi_gbl_root_table_list.tables[i]. | ||
513 | signature), ACPI_SIG_PSDT)) | ||
514 | || | ||
515 | ACPI_FAILURE(acpi_tb_verify_table | ||
516 | (&acpi_gbl_root_table_list.tables[i]))) { | ||
517 | continue; | ||
518 | } | ||
519 | |||
520 | /* Ignore errors while loading tables, get as many as possible */ | ||
521 | |||
522 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
523 | (void)acpi_ns_load_table(i, acpi_gbl_root_node); | ||
524 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
454 | } | 525 | } |
455 | 526 | ||
456 | /* Get the table length */ | 527 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); |
457 | 528 | ||
458 | if (table_type == ACPI_TABLE_ID_RSDP) { | 529 | unlock_and_exit: |
530 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
531 | return_ACPI_STATUS(status); | ||
532 | } | ||
459 | 533 | ||
460 | /* RSD PTR is the only "table" without a header */ | 534 | /******************************************************************************* |
535 | * | ||
536 | * FUNCTION: acpi_load_tables | ||
537 | * | ||
538 | * PARAMETERS: None | ||
539 | * | ||
540 | * RETURN: Status | ||
541 | * | ||
542 | * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT | ||
543 | * | ||
544 | ******************************************************************************/ | ||
461 | 545 | ||
462 | table_length = sizeof(struct rsdp_descriptor); | 546 | acpi_status acpi_load_tables(void) |
463 | } else { | 547 | { |
464 | table_length = (acpi_size) tbl_ptr->length; | 548 | acpi_status status; |
465 | } | ||
466 | 549 | ||
467 | /* Validate/Allocate/Clear caller buffer */ | 550 | ACPI_FUNCTION_TRACE(acpi_load_tables); |
468 | 551 | ||
469 | status = acpi_ut_initialize_buffer(ret_buffer, table_length); | 552 | /* |
553 | * Load the namespace from the tables | ||
554 | */ | ||
555 | status = acpi_tb_load_namespace(); | ||
470 | if (ACPI_FAILURE(status)) { | 556 | if (ACPI_FAILURE(status)) { |
471 | return_ACPI_STATUS(status); | 557 | ACPI_EXCEPTION((AE_INFO, status, |
558 | "While loading namespace from ACPI tables")); | ||
472 | } | 559 | } |
473 | 560 | ||
474 | /* Copy the table to the buffer */ | 561 | return_ACPI_STATUS(status); |
475 | |||
476 | ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), | ||
477 | ACPI_CAST_PTR(void, tbl_ptr), table_length); | ||
478 | |||
479 | return_ACPI_STATUS(AE_OK); | ||
480 | } | 562 | } |
481 | 563 | ||
482 | ACPI_EXPORT_SYMBOL(acpi_get_table) | 564 | ACPI_EXPORT_SYMBOL(acpi_load_tables) |
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index da2648bbdbc0..5c6e88251c1a 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -48,16 +48,15 @@ | |||
48 | ACPI_MODULE_NAME("tbxfroot") | 48 | ACPI_MODULE_NAME("tbxfroot") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | static acpi_status | ||
52 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); | ||
53 | |||
54 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | 51 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); |
55 | 52 | ||
53 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | ||
54 | |||
56 | /******************************************************************************* | 55 | /******************************************************************************* |
57 | * | 56 | * |
58 | * FUNCTION: acpi_tb_validate_rsdp | 57 | * FUNCTION: acpi_tb_validate_rsdp |
59 | * | 58 | * |
60 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | 59 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP |
61 | * | 60 | * |
62 | * RETURN: Status | 61 | * RETURN: Status |
63 | * | 62 | * |
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | |||
65 | * | 64 | * |
66 | ******************************************************************************/ | 65 | ******************************************************************************/ |
67 | 66 | ||
68 | acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | 67 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) |
69 | { | 68 | { |
70 | ACPI_FUNCTION_ENTRY(); | 69 | ACPI_FUNCTION_ENTRY(); |
71 | 70 | ||
72 | /* | 71 | /* |
73 | * The signature and checksum must both be correct | 72 | * The signature and checksum must both be correct |
73 | * | ||
74 | * Note: Sometimes there exists more than one RSDP in memory; the valid | ||
75 | * RSDP has a valid checksum, all others have an invalid checksum. | ||
74 | */ | 76 | */ |
75 | if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { | 77 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) |
78 | != 0) { | ||
76 | 79 | ||
77 | /* Nope, BAD Signature */ | 80 | /* Nope, BAD Signature */ |
78 | 81 | ||
@@ -81,330 +84,141 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | |||
81 | 84 | ||
82 | /* Check the standard checksum */ | 85 | /* Check the standard checksum */ |
83 | 86 | ||
84 | if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | 87 | if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { |
85 | return (AE_BAD_CHECKSUM); | 88 | return (AE_BAD_CHECKSUM); |
86 | } | 89 | } |
87 | 90 | ||
88 | /* Check extended checksum if table version >= 2 */ | 91 | /* Check extended checksum if table version >= 2 */ |
89 | 92 | ||
90 | if ((rsdp->revision >= 2) && | 93 | if ((rsdp->revision >= 2) && |
91 | (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { | 94 | (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { |
92 | return (AE_BAD_CHECKSUM); | 95 | return (AE_BAD_CHECKSUM); |
93 | } | 96 | } |
94 | 97 | ||
95 | return (AE_OK); | 98 | return (AE_OK); |
96 | } | 99 | } |
97 | 100 | ||
101 | #if ACPI_MACHINE_WIDTH != 16 | ||
102 | |||
98 | /******************************************************************************* | 103 | /******************************************************************************* |
99 | * | 104 | * |
100 | * FUNCTION: acpi_tb_find_table | 105 | * FUNCTION: acpi_tb_find_rsdp |
101 | * | ||
102 | * PARAMETERS: Signature - String with ACPI table signature | ||
103 | * oem_id - String with the table OEM ID | ||
104 | * oem_table_id - String with the OEM Table ID | ||
105 | * table_ptr - Where the table pointer is returned | ||
106 | * | ||
107 | * RETURN: Status | ||
108 | * | 106 | * |
109 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | 107 | * PARAMETERS: table_address - Where the table pointer is returned |
110 | * Signature, OEM ID and OEM Table ID. | ||
111 | * | 108 | * |
112 | ******************************************************************************/ | 109 | * RETURN: Status, RSDP physical address |
113 | |||
114 | acpi_status | ||
115 | acpi_tb_find_table(char *signature, | ||
116 | char *oem_id, | ||
117 | char *oem_table_id, struct acpi_table_header ** table_ptr) | ||
118 | { | ||
119 | acpi_status status; | ||
120 | struct acpi_table_header *table; | ||
121 | |||
122 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
123 | |||
124 | /* Validate string lengths */ | ||
125 | |||
126 | if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || | ||
127 | (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || | ||
128 | (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { | ||
129 | return_ACPI_STATUS(AE_AML_STRING_LIMIT); | ||
130 | } | ||
131 | |||
132 | if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { | ||
133 | /* | ||
134 | * The DSDT pointer is contained in the FADT, not the RSDT. | ||
135 | * This code should suffice, because the only code that would perform | ||
136 | * a "find" on the DSDT is the data_table_region() AML opcode -- in | ||
137 | * which case, the DSDT is guaranteed to be already loaded. | ||
138 | * If this becomes insufficient, the FADT will have to be found first. | ||
139 | */ | ||
140 | if (!acpi_gbl_DSDT) { | ||
141 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
142 | } | ||
143 | table = acpi_gbl_DSDT; | ||
144 | } else { | ||
145 | /* Find the table */ | ||
146 | |||
147 | status = acpi_get_firmware_table(signature, 1, | ||
148 | ACPI_LOGICAL_ADDRESSING, | ||
149 | &table); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | return_ACPI_STATUS(status); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Check oem_id and oem_table_id */ | ||
156 | |||
157 | if ((oem_id[0] && | ||
158 | ACPI_STRNCMP(oem_id, table->oem_id, | ||
159 | sizeof(table->oem_id))) || | ||
160 | (oem_table_id[0] && | ||
161 | ACPI_STRNCMP(oem_table_id, table->oem_table_id, | ||
162 | sizeof(table->oem_table_id)))) { | ||
163 | return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); | ||
164 | } | ||
165 | |||
166 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", | ||
167 | table->signature)); | ||
168 | |||
169 | *table_ptr = table; | ||
170 | return_ACPI_STATUS(AE_OK); | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_get_firmware_table | ||
176 | * | 110 | * |
177 | * PARAMETERS: Signature - Any ACPI table signature | 111 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor |
178 | * Instance - the non zero instance of the table, allows | 112 | * pointer structure. If it is found, set *RSDP to point to it. |
179 | * support for multiple tables of the same type | ||
180 | * Flags - Physical/Virtual support | ||
181 | * table_pointer - Where a buffer containing the table is | ||
182 | * returned | ||
183 | * | 113 | * |
184 | * RETURN: Status | 114 | * NOTE1: The RSDP must be either in the first 1_k of the Extended |
115 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
116 | * Only a 32-bit physical address is necessary. | ||
185 | * | 117 | * |
186 | * DESCRIPTION: This function is called to get an ACPI table. A buffer is | 118 | * NOTE2: This function is always available, regardless of the |
187 | * allocated for the table and returned in table_pointer. | 119 | * initialization state of the rest of ACPI. |
188 | * This table will be a complete table including the header. | ||
189 | * | 120 | * |
190 | ******************************************************************************/ | 121 | ******************************************************************************/ |
191 | 122 | ||
192 | acpi_status | 123 | acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) |
193 | acpi_get_firmware_table(acpi_string signature, | ||
194 | u32 instance, | ||
195 | u32 flags, struct acpi_table_header **table_pointer) | ||
196 | { | 124 | { |
197 | acpi_status status; | 125 | u8 *table_ptr; |
198 | struct acpi_pointer address; | 126 | u8 *mem_rover; |
199 | struct acpi_table_header *header = NULL; | 127 | u32 physical_address; |
200 | struct acpi_table_desc *table_info = NULL; | ||
201 | struct acpi_table_desc *rsdt_info; | ||
202 | u32 table_count; | ||
203 | u32 i; | ||
204 | u32 j; | ||
205 | |||
206 | ACPI_FUNCTION_TRACE(acpi_get_firmware_table); | ||
207 | |||
208 | /* | ||
209 | * Ensure that at least the table manager is initialized. We don't | ||
210 | * require that the entire ACPI subsystem is up for this interface. | ||
211 | * If we have a buffer, we must have a length too | ||
212 | */ | ||
213 | if ((instance == 0) || (!signature) || (!table_pointer)) { | ||
214 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
215 | } | ||
216 | |||
217 | /* Ensure that we have a RSDP */ | ||
218 | |||
219 | if (!acpi_gbl_RSDP) { | ||
220 | |||
221 | /* Get the RSDP */ | ||
222 | |||
223 | status = acpi_os_get_root_pointer(flags, &address); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); | ||
226 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
227 | } | ||
228 | |||
229 | /* Map and validate the RSDP */ | ||
230 | |||
231 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
232 | status = acpi_os_map_memory(address.pointer.physical, | ||
233 | sizeof(struct | ||
234 | rsdp_descriptor), | ||
235 | (void *)&acpi_gbl_RSDP); | ||
236 | if (ACPI_FAILURE(status)) { | ||
237 | return_ACPI_STATUS(status); | ||
238 | } | ||
239 | } else { | ||
240 | acpi_gbl_RSDP = address.pointer.logical; | ||
241 | } | ||
242 | |||
243 | /* The RDSP signature and checksum must both be correct */ | ||
244 | |||
245 | status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); | ||
246 | if (ACPI_FAILURE(status)) { | ||
247 | return_ACPI_STATUS(status); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /* Get the RSDT address via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
255 | "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", | ||
256 | acpi_gbl_RSDP, | ||
257 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
258 | 128 | ||
259 | /* Insert processor_mode flags */ | 129 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); |
260 | 130 | ||
261 | address.pointer_type |= flags; | 131 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ |
262 | 132 | ||
263 | /* Get and validate the RSDT */ | 133 | table_ptr = acpi_os_map_memory((acpi_physical_address) |
134 | ACPI_EBDA_PTR_LOCATION, | ||
135 | ACPI_EBDA_PTR_LENGTH); | ||
136 | if (!table_ptr) { | ||
137 | ACPI_ERROR((AE_INFO, | ||
138 | "Could not map memory at %8.8X for length %X", | ||
139 | ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); | ||
264 | 140 | ||
265 | rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | ||
266 | if (!rsdt_info) { | ||
267 | return_ACPI_STATUS(AE_NO_MEMORY); | 141 | return_ACPI_STATUS(AE_NO_MEMORY); |
268 | } | 142 | } |
269 | 143 | ||
270 | status = acpi_tb_get_table(&address, rsdt_info); | 144 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto cleanup; | ||
273 | } | ||
274 | |||
275 | status = acpi_tb_validate_rsdt(rsdt_info->pointer); | ||
276 | if (ACPI_FAILURE(status)) { | ||
277 | goto cleanup; | ||
278 | } | ||
279 | |||
280 | /* Allocate a scratch table header and table descriptor */ | ||
281 | |||
282 | header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | ||
283 | if (!header) { | ||
284 | status = AE_NO_MEMORY; | ||
285 | goto cleanup; | ||
286 | } | ||
287 | 145 | ||
288 | table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); | 146 | /* Convert segment part to physical address */ |
289 | if (!table_info) { | ||
290 | status = AE_NO_MEMORY; | ||
291 | goto cleanup; | ||
292 | } | ||
293 | 147 | ||
294 | /* Get the number of table pointers within the RSDT */ | 148 | physical_address <<= 4; |
149 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); | ||
295 | 150 | ||
296 | table_count = | 151 | /* EBDA present? */ |
297 | acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); | ||
298 | address.pointer_type = acpi_gbl_table_flags | flags; | ||
299 | 152 | ||
300 | /* | 153 | if (physical_address > 0x400) { |
301 | * Search the RSDT/XSDT for the correct instance of the | ||
302 | * requested table | ||
303 | */ | ||
304 | for (i = 0, j = 0; i < table_count; i++) { | ||
305 | /* | 154 | /* |
306 | * Get the next table pointer, handle RSDT vs. XSDT | 155 | * 1b) Search EBDA paragraphs (EBDA is required to be a |
307 | * RSDT pointers are 32 bits, XSDT pointers are 64 bits | 156 | * minimum of 1_k length) |
308 | */ | 157 | */ |
309 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | 158 | table_ptr = acpi_os_map_memory((acpi_native_uint) |
310 | address.pointer.value = | 159 | physical_address, |
311 | (ACPI_CAST_PTR | 160 | ACPI_EBDA_WINDOW_SIZE); |
312 | (struct rsdt_descriptor, | 161 | if (!table_ptr) { |
313 | rsdt_info->pointer))->table_offset_entry[i]; | 162 | ACPI_ERROR((AE_INFO, |
314 | } else { | 163 | "Could not map memory at %8.8X for length %X", |
315 | address.pointer.value = | 164 | physical_address, ACPI_EBDA_WINDOW_SIZE)); |
316 | (ACPI_CAST_PTR | ||
317 | (struct xsdt_descriptor, | ||
318 | rsdt_info->pointer))->table_offset_entry[i]; | ||
319 | } | ||
320 | |||
321 | /* Get the table header */ | ||
322 | 165 | ||
323 | status = acpi_tb_get_table_header(&address, header); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
324 | if (ACPI_FAILURE(status)) { | ||
325 | goto cleanup; | ||
326 | } | 167 | } |
327 | 168 | ||
328 | /* Compare table signatures and table instance */ | 169 | mem_rover = |
329 | 170 | acpi_tb_scan_memory_for_rsdp(table_ptr, | |
330 | if (ACPI_COMPARE_NAME(header->signature, signature)) { | 171 | ACPI_EBDA_WINDOW_SIZE); |
331 | 172 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | |
332 | /* An instance of the table was found */ | ||
333 | 173 | ||
334 | j++; | 174 | if (mem_rover) { |
335 | if (j >= instance) { | ||
336 | 175 | ||
337 | /* Found the correct instance, get the entire table */ | 176 | /* Return the physical address */ |
338 | 177 | ||
339 | status = | 178 | physical_address += |
340 | acpi_tb_get_table_body(&address, header, | 179 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); |
341 | table_info); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | goto cleanup; | ||
344 | } | ||
345 | 180 | ||
346 | *table_pointer = table_info->pointer; | 181 | *table_address = physical_address; |
347 | goto cleanup; | 182 | return_ACPI_STATUS(AE_OK); |
348 | } | ||
349 | } | 183 | } |
350 | } | 184 | } |
351 | 185 | ||
352 | /* Did not find the table */ | 186 | /* |
187 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
188 | */ | ||
189 | table_ptr = acpi_os_map_memory((acpi_physical_address) | ||
190 | ACPI_HI_RSDP_WINDOW_BASE, | ||
191 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
353 | 192 | ||
354 | status = AE_NOT_EXIST; | 193 | if (!table_ptr) { |
194 | ACPI_ERROR((AE_INFO, | ||
195 | "Could not map memory at %8.8X for length %X", | ||
196 | ACPI_HI_RSDP_WINDOW_BASE, | ||
197 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
355 | 198 | ||
356 | cleanup: | 199 | return_ACPI_STATUS(AE_NO_MEMORY); |
357 | if (rsdt_info->pointer) { | ||
358 | acpi_os_unmap_memory(rsdt_info->pointer, | ||
359 | (acpi_size) rsdt_info->pointer->length); | ||
360 | } | 200 | } |
361 | ACPI_FREE(rsdt_info); | ||
362 | 201 | ||
363 | if (header) { | 202 | mem_rover = |
364 | ACPI_FREE(header); | 203 | acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
365 | } | 204 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
366 | if (table_info) { | ||
367 | ACPI_FREE(table_info); | ||
368 | } | ||
369 | return_ACPI_STATUS(status); | ||
370 | } | ||
371 | 205 | ||
372 | ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) | 206 | if (mem_rover) { |
373 | 207 | ||
374 | /* TBD: Move to a new file */ | 208 | /* Return the physical address */ |
375 | #if ACPI_MACHINE_WIDTH != 16 | ||
376 | /******************************************************************************* | ||
377 | * | ||
378 | * FUNCTION: acpi_find_root_pointer | ||
379 | * | ||
380 | * PARAMETERS: Flags - Logical/Physical addressing | ||
381 | * rsdp_address - Where to place the RSDP address | ||
382 | * | ||
383 | * RETURN: Status, Physical address of the RSDP | ||
384 | * | ||
385 | * DESCRIPTION: Find the RSDP | ||
386 | * | ||
387 | ******************************************************************************/ | ||
388 | acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) | ||
389 | { | ||
390 | struct acpi_table_desc table_info; | ||
391 | acpi_status status; | ||
392 | |||
393 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); | ||
394 | 209 | ||
395 | /* Get the RSDP */ | 210 | physical_address = (u32) |
211 | (ACPI_HI_RSDP_WINDOW_BASE + | ||
212 | ACPI_PTR_DIFF(mem_rover, table_ptr)); | ||
396 | 213 | ||
397 | status = acpi_tb_find_rsdp(&table_info, flags); | 214 | *table_address = physical_address; |
398 | if (ACPI_FAILURE(status)) { | 215 | return_ACPI_STATUS(AE_OK); |
399 | ACPI_EXCEPTION((AE_INFO, status, | ||
400 | "RSDP structure not found - Flags=%X", flags)); | ||
401 | |||
402 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
403 | } | 216 | } |
404 | 217 | ||
405 | rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; | 218 | /* A valid RSDP was not found */ |
406 | rsdp_address->pointer.physical = table_info.physical_address; | 219 | |
407 | return_ACPI_STATUS(AE_OK); | 220 | ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); |
221 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
408 | } | 222 | } |
409 | 223 | ||
410 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) | 224 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) |
@@ -440,7 +254,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
440 | 254 | ||
441 | status = | 255 | status = |
442 | acpi_tb_validate_rsdp(ACPI_CAST_PTR | 256 | acpi_tb_validate_rsdp(ACPI_CAST_PTR |
443 | (struct rsdp_descriptor, mem_rover)); | 257 | (struct acpi_table_rsdp, mem_rover)); |
444 | if (ACPI_SUCCESS(status)) { | 258 | if (ACPI_SUCCESS(status)) { |
445 | 259 | ||
446 | /* Sig and checksum valid, we have found a real RSDP */ | 260 | /* Sig and checksum valid, we have found a real RSDP */ |
@@ -462,188 +276,4 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
462 | return_PTR(NULL); | 276 | return_PTR(NULL); |
463 | } | 277 | } |
464 | 278 | ||
465 | /******************************************************************************* | ||
466 | * | ||
467 | * FUNCTION: acpi_tb_find_rsdp | ||
468 | * | ||
469 | * PARAMETERS: table_info - Where the table info is returned | ||
470 | * Flags - Current memory mode (logical vs. | ||
471 | * physical addressing) | ||
472 | * | ||
473 | * RETURN: Status, RSDP physical address | ||
474 | * | ||
475 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor | ||
476 | * pointer structure. If it is found, set *RSDP to point to it. | ||
477 | * | ||
478 | * NOTE1: The RSDP must be either in the first 1_k of the Extended | ||
479 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
480 | * Only a 32-bit physical address is necessary. | ||
481 | * | ||
482 | * NOTE2: This function is always available, regardless of the | ||
483 | * initialization state of the rest of ACPI. | ||
484 | * | ||
485 | ******************************************************************************/ | ||
486 | |||
487 | static acpi_status | ||
488 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) | ||
489 | { | ||
490 | u8 *table_ptr; | ||
491 | u8 *mem_rover; | ||
492 | u32 physical_address; | ||
493 | acpi_status status; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_find_rsdp); | ||
496 | |||
497 | /* | ||
498 | * Scan supports either logical addressing or physical addressing | ||
499 | */ | ||
500 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
501 | |||
502 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ | ||
503 | |||
504 | status = acpi_os_map_memory((acpi_physical_address) | ||
505 | ACPI_EBDA_PTR_LOCATION, | ||
506 | ACPI_EBDA_PTR_LENGTH, | ||
507 | (void *)&table_ptr); | ||
508 | if (ACPI_FAILURE(status)) { | ||
509 | ACPI_ERROR((AE_INFO, | ||
510 | "Could not map memory at %8.8X for length %X", | ||
511 | ACPI_EBDA_PTR_LOCATION, | ||
512 | ACPI_EBDA_PTR_LENGTH)); | ||
513 | |||
514 | return_ACPI_STATUS(status); | ||
515 | } | ||
516 | |||
517 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); | ||
518 | |||
519 | /* Convert segment part to physical address */ | ||
520 | |||
521 | physical_address <<= 4; | ||
522 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); | ||
523 | |||
524 | /* EBDA present? */ | ||
525 | |||
526 | if (physical_address > 0x400) { | ||
527 | /* | ||
528 | * 1b) Search EBDA paragraphs (EBDA is required to be a | ||
529 | * minimum of 1_k length) | ||
530 | */ | ||
531 | status = acpi_os_map_memory((acpi_physical_address) | ||
532 | physical_address, | ||
533 | ACPI_EBDA_WINDOW_SIZE, | ||
534 | (void *)&table_ptr); | ||
535 | if (ACPI_FAILURE(status)) { | ||
536 | ACPI_ERROR((AE_INFO, | ||
537 | "Could not map memory at %8.8X for length %X", | ||
538 | physical_address, | ||
539 | ACPI_EBDA_WINDOW_SIZE)); | ||
540 | |||
541 | return_ACPI_STATUS(status); | ||
542 | } | ||
543 | |||
544 | mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
545 | ACPI_EBDA_WINDOW_SIZE); | ||
546 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | ||
547 | |||
548 | if (mem_rover) { | ||
549 | |||
550 | /* Return the physical address */ | ||
551 | |||
552 | physical_address += | ||
553 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); | ||
554 | |||
555 | table_info->physical_address = | ||
556 | (acpi_physical_address) physical_address; | ||
557 | return_ACPI_STATUS(AE_OK); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
563 | */ | ||
564 | status = acpi_os_map_memory((acpi_physical_address) | ||
565 | ACPI_HI_RSDP_WINDOW_BASE, | ||
566 | ACPI_HI_RSDP_WINDOW_SIZE, | ||
567 | (void *)&table_ptr); | ||
568 | |||
569 | if (ACPI_FAILURE(status)) { | ||
570 | ACPI_ERROR((AE_INFO, | ||
571 | "Could not map memory at %8.8X for length %X", | ||
572 | ACPI_HI_RSDP_WINDOW_BASE, | ||
573 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
574 | |||
575 | return_ACPI_STATUS(status); | ||
576 | } | ||
577 | |||
578 | mem_rover = | ||
579 | acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
580 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
581 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | ||
582 | |||
583 | if (mem_rover) { | ||
584 | |||
585 | /* Return the physical address */ | ||
586 | |||
587 | physical_address = (u32) | ||
588 | (ACPI_HI_RSDP_WINDOW_BASE + | ||
589 | ACPI_PTR_DIFF(mem_rover, table_ptr)); | ||
590 | |||
591 | table_info->physical_address = | ||
592 | (acpi_physical_address) physical_address; | ||
593 | return_ACPI_STATUS(AE_OK); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * Physical addressing | ||
599 | */ | ||
600 | else { | ||
601 | /* 1a) Get the location of the EBDA */ | ||
602 | |||
603 | ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); | ||
604 | physical_address <<= 4; /* Convert segment to physical address */ | ||
605 | |||
606 | /* EBDA present? */ | ||
607 | |||
608 | if (physical_address > 0x400) { | ||
609 | /* | ||
610 | * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of | ||
611 | * 1_k length) | ||
612 | */ | ||
613 | mem_rover = | ||
614 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
615 | (physical_address), | ||
616 | ACPI_EBDA_WINDOW_SIZE); | ||
617 | if (mem_rover) { | ||
618 | |||
619 | /* Return the physical address */ | ||
620 | |||
621 | table_info->physical_address = | ||
622 | ACPI_TO_INTEGER(mem_rover); | ||
623 | return_ACPI_STATUS(AE_OK); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ | ||
628 | |||
629 | mem_rover = | ||
630 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
631 | (ACPI_HI_RSDP_WINDOW_BASE), | ||
632 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
633 | if (mem_rover) { | ||
634 | |||
635 | /* Found it, return the physical address */ | ||
636 | |||
637 | table_info->physical_address = | ||
638 | ACPI_TO_INTEGER(mem_rover); | ||
639 | return_ACPI_STATUS(AE_OK); | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* A valid RSDP was not found */ | ||
644 | |||
645 | ACPI_ERROR((AE_INFO, "No valid RSDP was found")); | ||
646 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
647 | } | ||
648 | |||
649 | #endif | 279 | #endif |