]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: tbconvrt - ACPI Table conversion utilities | |
4 | * | |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | |
9 | * All rights reserved. | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions, and the following disclaimer, | |
16 | * without modification. | |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | |
20 | * including a substantially similar Disclaimer requirement for further | |
21 | * binary redistribution. | |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | |
23 | * of any contributors may be used to endorse or promote products derived | |
24 | * from this software without specific prior written permission. | |
25 | * | |
26 | * Alternatively, this software may be distributed under the terms of the | |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | |
28 | * Software Foundation. | |
29 | * | |
30 | * NO WARRANTY | |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
41 | * POSSIBILITY OF SUCH DAMAGES. | |
42 | */ | |
43 | ||
44 | #include <linux/module.h> | |
45 | ||
46 | #include <acpi/acpi.h> | |
47 | #include <acpi/actables.h> | |
48 | ||
49 | ||
50 | #define _COMPONENT ACPI_TABLES | |
51 | ACPI_MODULE_NAME ("tbconvrt") | |
52 | ||
53 | ||
54 | u8 acpi_fadt_is_v1; | |
55 | EXPORT_SYMBOL(acpi_fadt_is_v1); | |
56 | ||
57 | /******************************************************************************* | |
58 | * | |
59 | * FUNCTION: acpi_tb_get_table_count | |
60 | * | |
61 | * PARAMETERS: RSDP - Pointer to the RSDP | |
62 | * RSDT - Pointer to the RSDT/XSDT | |
63 | * | |
64 | * RETURN: The number of tables pointed to by the RSDT or XSDT. | |
65 | * | |
66 | * DESCRIPTION: Calculate the number of tables. Automatically handles either | |
67 | * an RSDT or XSDT. | |
68 | * | |
69 | ******************************************************************************/ | |
70 | ||
71 | u32 | |
72 | acpi_tb_get_table_count ( | |
73 | struct rsdp_descriptor *RSDP, | |
74 | struct acpi_table_header *RSDT) | |
75 | { | |
76 | u32 pointer_size; | |
77 | ||
78 | ||
79 | ACPI_FUNCTION_ENTRY (); | |
80 | ||
81 | ||
82 | if (RSDP->revision < 2) { | |
83 | pointer_size = sizeof (u32); | |
84 | } | |
85 | else { | |
86 | pointer_size = sizeof (u64); | |
87 | } | |
88 | ||
89 | /* | |
90 | * Determine the number of tables pointed to by the RSDT/XSDT. | |
91 | * This is defined by the ACPI Specification to be the number of | |
92 | * pointers contained within the RSDT/XSDT. The size of the pointers | |
93 | * is architecture-dependent. | |
94 | */ | |
95 | return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size); | |
96 | } | |
97 | ||
98 | ||
99 | /******************************************************************************* | |
100 | * | |
101 | * FUNCTION: acpi_tb_convert_to_xsdt | |
102 | * | |
103 | * PARAMETERS: table_info - Info about the RSDT | |
104 | * | |
105 | * RETURN: Status | |
106 | * | |
107 | * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) | |
108 | * | |
109 | ******************************************************************************/ | |
110 | ||
111 | acpi_status | |
112 | acpi_tb_convert_to_xsdt ( | |
113 | struct acpi_table_desc *table_info) | |
114 | { | |
115 | acpi_size table_size; | |
116 | u32 i; | |
117 | XSDT_DESCRIPTOR *new_table; | |
118 | ||
119 | ||
120 | ACPI_FUNCTION_ENTRY (); | |
121 | ||
122 | ||
123 | /* Compute size of the converted XSDT */ | |
124 | ||
125 | table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) + | |
126 | sizeof (struct acpi_table_header); | |
127 | ||
128 | /* Allocate an XSDT */ | |
129 | ||
130 | new_table = ACPI_MEM_CALLOCATE (table_size); | |
131 | if (!new_table) { | |
132 | return (AE_NO_MEMORY); | |
133 | } | |
134 | ||
135 | /* Copy the header and set the length */ | |
136 | ||
137 | ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header)); | |
138 | new_table->length = (u32) table_size; | |
139 | ||
140 | /* Copy the table pointers */ | |
141 | ||
142 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | |
143 | if (acpi_gbl_RSDP->revision < 2) { | |
144 | ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], | |
145 | (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]); | |
146 | } | |
147 | else { | |
148 | new_table->table_offset_entry[i] = | |
149 | (ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i]; | |
150 | } | |
151 | } | |
152 | ||
153 | /* Delete the original table (either mapped or in a buffer) */ | |
154 | ||
155 | acpi_tb_delete_single_table (table_info); | |
156 | ||
157 | /* Point the table descriptor to the new table */ | |
158 | ||
159 | table_info->pointer = ACPI_CAST_PTR (struct acpi_table_header, new_table); | |
160 | table_info->length = table_size; | |
161 | table_info->allocation = ACPI_MEM_ALLOCATED; | |
162 | ||
163 | return (AE_OK); | |
164 | } | |
165 | ||
166 | ||
167 | /****************************************************************************** | |
168 | * | |
169 | * FUNCTION: acpi_tb_init_generic_address | |
170 | * | |
171 | * PARAMETERS: new_gas_struct - GAS struct to be initialized | |
172 | * register_bit_width - Width of this register | |
173 | * Address - Address of the register | |
174 | * | |
175 | * RETURN: None | |
176 | * | |
177 | * DESCRIPTION: Initialize a GAS structure. | |
178 | * | |
179 | ******************************************************************************/ | |
180 | ||
181 | static void | |
182 | acpi_tb_init_generic_address ( | |
183 | struct acpi_generic_address *new_gas_struct, | |
184 | u8 register_bit_width, | |
185 | acpi_physical_address address) | |
186 | { | |
187 | ||
188 | ACPI_STORE_ADDRESS (new_gas_struct->address, address); | |
189 | ||
190 | new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; | |
191 | new_gas_struct->register_bit_width = register_bit_width; | |
192 | new_gas_struct->register_bit_offset = 0; | |
193 | new_gas_struct->access_width = 0; | |
194 | } | |
195 | ||
196 | ||
197 | /******************************************************************************* | |
198 | * | |
199 | * FUNCTION: acpi_tb_convert_fadt1 | |
200 | * | |
201 | * PARAMETERS: local_fadt - Pointer to new FADT | |
202 | * original_fadt - Pointer to old FADT | |
203 | * | |
204 | * RETURN: Populates local_fadt | |
205 | * | |
206 | * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format | |
207 | * | |
208 | ******************************************************************************/ | |
209 | ||
210 | static void | |
211 | acpi_tb_convert_fadt1 ( | |
212 | struct fadt_descriptor_rev2 *local_fadt, | |
213 | struct fadt_descriptor_rev1 *original_fadt) | |
214 | { | |
215 | ||
216 | ||
217 | /* ACPI 1.0 FACS */ | |
218 | /* The BIOS stored FADT should agree with Revision 1.0 */ | |
219 | acpi_fadt_is_v1 = 1; | |
220 | ||
221 | /* | |
222 | * Copy the table header and the common part of the tables. | |
223 | * | |
224 | * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 | |
225 | * table can be copied first, then expand some fields to 64 bits. | |
226 | */ | |
227 | ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1)); | |
228 | ||
229 | /* Convert table pointers to 64-bit fields */ | |
230 | ||
231 | ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl); | |
232 | ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt); | |
233 | ||
234 | /* | |
235 | * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;) | |
236 | */ | |
237 | ||
238 | /* | |
239 | * This field is set by the OEM to convey the preferred power management | |
240 | * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't | |
241 | * know what kind of 32-bit system this is, we will use "unspecified". | |
242 | */ | |
243 | local_fadt->prefer_PM_profile = PM_UNSPECIFIED; | |
244 | ||
245 | /* | |
246 | * Processor Performance State Control. This is the value OSPM writes to | |
247 | * the SMI_CMD register to assume processor performance state control | |
248 | * responsibility. There isn't any equivalence in 1.0, but as many 1.x | |
249 | * ACPI tables contain _PCT and _PSS we also keep this value, unless | |
250 | * acpi_strict is set. | |
251 | */ | |
252 | if (acpi_strict) | |
253 | local_fadt->pstate_cnt = 0; | |
254 | ||
255 | /* | |
256 | * Support for the _CST object and C States change notification. | |
257 | * This data item hasn't any 1.0 equivalence so leave it zero. | |
258 | */ | |
259 | local_fadt->cst_cnt = 0; | |
260 | ||
261 | /* | |
262 | * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. | |
263 | * It primarily adds the FADT reset mechanism. | |
264 | */ | |
265 | if ((original_fadt->revision == 2) && | |
266 | (original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) { | |
267 | /* | |
268 | * Grab the entire generic address struct, plus the 1-byte reset value | |
269 | * that immediately follows. | |
270 | */ | |
271 | ACPI_MEMCPY (&local_fadt->reset_register, | |
272 | &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register, | |
273 | sizeof (struct acpi_generic_address) + 1); | |
274 | } | |
275 | else { | |
276 | /* | |
277 | * Since there isn't any equivalence in 1.0 and since it is highly | |
278 | * likely that a 1.0 system has legacy support. | |
279 | */ | |
280 | local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; | |
281 | } | |
282 | ||
283 | /* | |
284 | * Convert the V1.0 block addresses to V2.0 GAS structures | |
285 | */ | |
286 | acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, | |
287 | (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); | |
288 | acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, | |
289 | (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); | |
290 | acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, | |
291 | (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); | |
292 | acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, | |
293 | (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); | |
294 | acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, | |
295 | (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); | |
296 | acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, | |
297 | (acpi_physical_address) local_fadt->V1_pm_tmr_blk); | |
298 | acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0, | |
299 | (acpi_physical_address) local_fadt->V1_gpe0_blk); | |
300 | acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0, | |
301 | (acpi_physical_address) local_fadt->V1_gpe1_blk); | |
302 | ||
303 | /* Create separate GAS structs for the PM1 Enable registers */ | |
304 | ||
305 | acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, | |
306 | (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), | |
307 | (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + | |
308 | ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); | |
309 | ||
310 | /* PM1B is optional; leave null if not present */ | |
311 | ||
312 | if (local_fadt->xpm1b_evt_blk.address) { | |
313 | acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, | |
314 | (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), | |
315 | (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + | |
316 | ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); | |
317 | } | |
318 | } | |
319 | ||
320 | ||
321 | /******************************************************************************* | |
322 | * | |
323 | * FUNCTION: acpi_tb_convert_fadt2 | |
324 | * | |
325 | * PARAMETERS: local_fadt - Pointer to new FADT | |
326 | * original_fadt - Pointer to old FADT | |
327 | * | |
328 | * RETURN: Populates local_fadt | |
329 | * | |
330 | * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. | |
331 | * Handles optional "X" fields. | |
332 | * | |
333 | ******************************************************************************/ | |
334 | ||
335 | static void | |
336 | acpi_tb_convert_fadt2 ( | |
337 | struct fadt_descriptor_rev2 *local_fadt, | |
338 | struct fadt_descriptor_rev2 *original_fadt) | |
339 | { | |
340 | ||
341 | /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ | |
342 | ||
343 | ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2)); | |
344 | ||
345 | /* | |
346 | * "X" fields are optional extensions to the original V1.0 fields, so | |
347 | * we must selectively expand V1.0 fields if the corresponding X field | |
348 | * is zero. | |
349 | */ | |
350 | if (!(local_fadt->xfirmware_ctrl)) { | |
351 | ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl); | |
352 | } | |
353 | ||
354 | if (!(local_fadt->Xdsdt)) { | |
355 | ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt); | |
356 | } | |
357 | ||
358 | if (!(local_fadt->xpm1a_evt_blk.address)) { | |
359 | acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, | |
360 | local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); | |
361 | } | |
362 | ||
363 | if (!(local_fadt->xpm1b_evt_blk.address)) { | |
364 | acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, | |
365 | local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); | |
366 | } | |
367 | ||
368 | if (!(local_fadt->xpm1a_cnt_blk.address)) { | |
369 | acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, | |
370 | local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); | |
371 | } | |
372 | ||
373 | if (!(local_fadt->xpm1b_cnt_blk.address)) { | |
374 | acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, | |
375 | local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); | |
376 | } | |
377 | ||
378 | if (!(local_fadt->xpm2_cnt_blk.address)) { | |
379 | acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, | |
380 | local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); | |
381 | } | |
382 | ||
383 | if (!(local_fadt->xpm_tmr_blk.address)) { | |
384 | acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, | |
385 | local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk); | |
386 | } | |
387 | ||
388 | if (!(local_fadt->xgpe0_blk.address)) { | |
389 | acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, | |
390 | 0, (acpi_physical_address) local_fadt->V1_gpe0_blk); | |
391 | } | |
392 | ||
393 | if (!(local_fadt->xgpe1_blk.address)) { | |
394 | acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, | |
395 | 0, (acpi_physical_address) local_fadt->V1_gpe1_blk); | |
396 | } | |
397 | ||
398 | /* Create separate GAS structs for the PM1 Enable registers */ | |
399 | ||
400 | acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, | |
401 | (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), | |
402 | (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + | |
403 | ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); | |
404 | acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id; | |
405 | ||
406 | /* PM1B is optional; leave null if not present */ | |
407 | ||
408 | if (local_fadt->xpm1b_evt_blk.address) { | |
409 | acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, | |
410 | (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), | |
411 | (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + | |
412 | ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); | |
413 | acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id; | |
414 | } | |
415 | } | |
416 | ||
417 | ||
418 | /******************************************************************************* | |
419 | * | |
420 | * FUNCTION: acpi_tb_convert_table_fadt | |
421 | * | |
422 | * PARAMETERS: None | |
423 | * | |
424 | * RETURN: Status | |
425 | * | |
426 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local | |
427 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | |
428 | * copied to the local FADT. The ACPI CA software uses this | |
429 | * local FADT. Thus a significant amount of special #ifdef | |
430 | * type codeing is saved. | |
431 | * | |
432 | ******************************************************************************/ | |
433 | ||
434 | acpi_status | |
435 | acpi_tb_convert_table_fadt (void) | |
436 | { | |
437 | struct fadt_descriptor_rev2 *local_fadt; | |
438 | struct acpi_table_desc *table_desc; | |
439 | ||
440 | ||
441 | ACPI_FUNCTION_TRACE ("tb_convert_table_fadt"); | |
442 | ||
443 | ||
444 | /* | |
445 | * acpi_gbl_FADT is valid. Validate the FADT length. The table must be | |
446 | * at least as long as the version 1.0 FADT | |
447 | */ | |
448 | if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) { | |
449 | ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length)); | |
450 | return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); | |
451 | } | |
452 | ||
453 | /* Allocate buffer for the ACPI 2.0(+) FADT */ | |
454 | ||
455 | local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2)); | |
456 | if (!local_fadt) { | |
457 | return_ACPI_STATUS (AE_NO_MEMORY); | |
458 | } | |
459 | ||
460 | if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { | |
461 | if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) { | |
462 | /* Length is too short to be a V2.0 table */ | |
463 | ||
464 | ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", | |
465 | acpi_gbl_FADT->length, acpi_gbl_FADT->revision)); | |
466 | ||
467 | acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT); | |
468 | } | |
469 | else { | |
470 | /* Valid V2.0 table */ | |
471 | ||
472 | acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT); | |
473 | } | |
474 | } | |
475 | else { | |
476 | /* Valid V1.0 table */ | |
477 | ||
478 | acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT); | |
479 | } | |
480 | ||
481 | /* | |
482 | * Global FADT pointer will point to the new common V2.0 FADT | |
483 | */ | |
484 | acpi_gbl_FADT = local_fadt; | |
485 | acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR); | |
486 | ||
487 | /* Free the original table */ | |
488 | ||
489 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next; | |
490 | acpi_tb_delete_single_table (table_desc); | |
491 | ||
492 | /* Install the new table */ | |
493 | ||
494 | table_desc->pointer = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT); | |
495 | table_desc->allocation = ACPI_MEM_ALLOCATED; | |
496 | table_desc->length = sizeof (struct fadt_descriptor_rev2); | |
497 | ||
498 | /* Dump the entire FADT */ | |
499 | ||
500 | ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, | |
501 | "Hex dump of common internal FADT, size %d (%X)\n", | |
502 | acpi_gbl_FADT->length, acpi_gbl_FADT->length)); | |
503 | ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length); | |
504 | ||
505 | return_ACPI_STATUS (AE_OK); | |
506 | } | |
507 | ||
508 | ||
509 | /******************************************************************************* | |
510 | * | |
511 | * FUNCTION: acpi_tb_convert_table_facs | |
512 | * | |
513 | * PARAMETERS: table_info - Info for currently installed FACS | |
514 | * | |
515 | * RETURN: Status | |
516 | * | |
517 | * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal | |
518 | * table format. | |
519 | * | |
520 | ******************************************************************************/ | |
521 | ||
522 | acpi_status | |
523 | acpi_tb_build_common_facs ( | |
524 | struct acpi_table_desc *table_info) | |
525 | { | |
526 | ||
527 | ACPI_FUNCTION_TRACE ("tb_build_common_facs"); | |
528 | ||
529 | ||
530 | /* Absolute minimum length is 24, but the ACPI spec says 64 */ | |
531 | ||
532 | if (acpi_gbl_FACS->length < 24) { | |
533 | ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length)); | |
534 | return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); | |
535 | } | |
536 | ||
537 | if (acpi_gbl_FACS->length < 64) { | |
538 | ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n", | |
539 | acpi_gbl_FACS->length)); | |
540 | } | |
541 | ||
542 | /* Copy fields to the new FACS */ | |
543 | ||
544 | acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); | |
545 | ||
546 | if ((acpi_gbl_RSDP->revision < 2) || | |
547 | (acpi_gbl_FACS->length < 32) || | |
548 | (!(acpi_gbl_FACS->xfirmware_waking_vector))) { | |
549 | /* ACPI 1.0 FACS or short table or optional X_ field is zero */ | |
550 | ||
551 | acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector)); | |
552 | acpi_gbl_common_fACS.vector_width = 32; | |
553 | } | |
554 | else { | |
555 | /* ACPI 2.0 FACS with valid X_ field */ | |
556 | ||
557 | acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector; | |
558 | acpi_gbl_common_fACS.vector_width = 64; | |
559 | } | |
560 | ||
561 | return_ACPI_STATUS (AE_OK); | |
562 | } | |
563 | ||
564 |