/home/lenb/src/to-akpm branch 'acpi-2.6.12'
[sfrench/cifs-2.6.git] / drivers / acpi / tables / tbconvrt.c
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 /* Local prototypes */
54
55 static void
56 acpi_tb_init_generic_address (
57         struct acpi_generic_address     *new_gas_struct,
58         u8                              register_bit_width,
59         acpi_physical_address           address);
60
61 static void
62 acpi_tb_convert_fadt1 (
63         struct fadt_descriptor_rev2    *local_fadt,
64         struct fadt_descriptor_rev1    *original_fadt);
65
66 static void
67 acpi_tb_convert_fadt2 (
68         struct fadt_descriptor_rev2    *local_fadt,
69         struct fadt_descriptor_rev2    *original_fadt);
70
71
72 u8 acpi_fadt_is_v1;
73 EXPORT_SYMBOL(acpi_fadt_is_v1);
74
75 /*******************************************************************************
76  *
77  * FUNCTION:    acpi_tb_get_table_count
78  *
79  * PARAMETERS:  RSDP            - Pointer to the RSDP
80  *              RSDT            - Pointer to the RSDT/XSDT
81  *
82  * RETURN:      The number of tables pointed to by the RSDT or XSDT.
83  *
84  * DESCRIPTION: Calculate the number of tables.  Automatically handles either
85  *              an RSDT or XSDT.
86  *
87  ******************************************************************************/
88
89 u32
90 acpi_tb_get_table_count (
91         struct rsdp_descriptor          *RSDP,
92         struct acpi_table_header        *RSDT)
93 {
94         u32                             pointer_size;
95
96
97         ACPI_FUNCTION_ENTRY ();
98
99
100         /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
101
102         if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
103                 pointer_size = sizeof (u32);
104         }
105         else {
106                 pointer_size = sizeof (u64);
107         }
108
109         /*
110          * Determine the number of tables pointed to by the RSDT/XSDT.
111          * This is defined by the ACPI Specification to be the number of
112          * pointers contained within the RSDT/XSDT.  The size of the pointers
113          * is architecture-dependent.
114          */
115         return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size);
116 }
117
118
119 /*******************************************************************************
120  *
121  * FUNCTION:    acpi_tb_convert_to_xsdt
122  *
123  * PARAMETERS:  table_info      - Info about the RSDT
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: Convert an RSDT to an XSDT (internal common format)
128  *
129  ******************************************************************************/
130
131 acpi_status
132 acpi_tb_convert_to_xsdt (
133         struct acpi_table_desc          *table_info)
134 {
135         acpi_size                       table_size;
136         u32                             i;
137         XSDT_DESCRIPTOR         *new_table;
138
139
140         ACPI_FUNCTION_ENTRY ();
141
142
143         /* Compute size of the converted XSDT */
144
145         table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) +
146                           sizeof (struct acpi_table_header);
147
148         /* Allocate an XSDT */
149
150         new_table = ACPI_MEM_CALLOCATE (table_size);
151         if (!new_table) {
152                 return (AE_NO_MEMORY);
153         }
154
155         /* Copy the header and set the length */
156
157         ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
158         new_table->length = (u32) table_size;
159
160         /* Copy the table pointers */
161
162         for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
163                 /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
164
165                 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
166                         ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
167                                 (ACPI_CAST_PTR (struct rsdt_descriptor_rev1,
168                                         table_info->pointer))->table_offset_entry[i]);
169                 }
170                 else {
171                         new_table->table_offset_entry[i] =
172                                 (ACPI_CAST_PTR (XSDT_DESCRIPTOR,
173                                         table_info->pointer))->table_offset_entry[i];
174                 }
175         }
176
177         /* Delete the original table (either mapped or in a buffer) */
178
179         acpi_tb_delete_single_table (table_info);
180
181         /* Point the table descriptor to the new table */
182
183         table_info->pointer     = ACPI_CAST_PTR (struct acpi_table_header, new_table);
184         table_info->length      = table_size;
185         table_info->allocation  = ACPI_MEM_ALLOCATED;
186
187         return (AE_OK);
188 }
189
190
191 /*******************************************************************************
192  *
193  * FUNCTION:    acpi_tb_init_generic_address
194  *
195  * PARAMETERS:  new_gas_struct      - GAS struct to be initialized
196  *              register_bit_width  - Width of this register
197  *              Address             - Address of the register
198  *
199  * RETURN:      None
200  *
201  * DESCRIPTION: Initialize a GAS structure.
202  *
203  ******************************************************************************/
204
205 static void
206 acpi_tb_init_generic_address (
207         struct acpi_generic_address     *new_gas_struct,
208         u8                              register_bit_width,
209         acpi_physical_address           address)
210 {
211
212         ACPI_STORE_ADDRESS (new_gas_struct->address, address);
213
214         new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
215         new_gas_struct->register_bit_width = register_bit_width;
216         new_gas_struct->register_bit_offset = 0;
217         new_gas_struct->access_width    = 0;
218 }
219
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    acpi_tb_convert_fadt1
224  *
225  * PARAMETERS:  local_fadt      - Pointer to new FADT
226  *              original_fadt   - Pointer to old FADT
227  *
228  * RETURN:      None, populates local_fadt
229  *
230  * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
231  *
232  ******************************************************************************/
233
234 static void
235 acpi_tb_convert_fadt1 (
236         struct fadt_descriptor_rev2    *local_fadt,
237         struct fadt_descriptor_rev1    *original_fadt)
238 {
239
240         /* ACPI 1.0 FACS */
241         /* The BIOS stored FADT should agree with Revision 1.0 */
242         acpi_fadt_is_v1 = 1;
243
244         /*
245          * Copy the table header and the common part of the tables.
246          *
247          * The 2.0 table is an extension of the 1.0 table, so the entire 1.0
248          * table can be copied first, then expand some fields to 64 bits.
249          */
250         ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1));
251
252         /* Convert table pointers to 64-bit fields */
253
254         ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
255         ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
256
257         /*
258          * System Interrupt Model isn't used in ACPI 2.0
259          * (local_fadt->Reserved1 = 0;)
260          */
261
262         /*
263          * This field is set by the OEM to convey the preferred power management
264          * profile to OSPM. It doesn't have any 1.0 equivalence.  Since we don't
265          * know what kind of 32-bit system this is, we will use "unspecified".
266          */
267         local_fadt->prefer_PM_profile = PM_UNSPECIFIED;
268
269         /*
270          * Processor Performance State Control. This is the value OSPM writes to
271          * the SMI_CMD register to assume processor performance state control
272          * responsibility. There isn't any equivalence in 1.0, but as many 1.x
273          * ACPI tables contain _PCT and _PSS we also keep this value, unless
274          * acpi_strict is set.
275          */
276         if (acpi_strict)
277                 local_fadt->pstate_cnt = 0;
278
279         /*
280          * Support for the _CST object and C States change notification.
281          * This data item hasn't any 1.0 equivalence so leave it zero.
282          */
283         local_fadt->cst_cnt = 0;
284
285         /*
286          * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
287          * It primarily adds the FADT reset mechanism.
288          */
289         if ((original_fadt->revision == 2) &&
290                 (original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) {
291                 /*
292                  * Grab the entire generic address struct, plus the 1-byte reset value
293                  * that immediately follows.
294                  */
295                 ACPI_MEMCPY (&local_fadt->reset_register,
296                         &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus,
297                                 original_fadt))->reset_register,
298                         sizeof (struct acpi_generic_address) + 1);
299         }
300         else {
301                 /*
302                  * Since there isn't any equivalence in 1.0 and since it is highly
303                  * likely that a 1.0 system has legacy support.
304                  */
305                 local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
306         }
307
308         /*
309          * Convert the V1.0 block addresses to V2.0 GAS structures
310          */
311         acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
312                           (acpi_physical_address)   local_fadt->V1_pm1a_evt_blk);
313         acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
314                           (acpi_physical_address)   local_fadt->V1_pm1b_evt_blk);
315         acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
316                           (acpi_physical_address)   local_fadt->V1_pm1a_cnt_blk);
317         acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
318                           (acpi_physical_address)   local_fadt->V1_pm1b_cnt_blk);
319         acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
320                           (acpi_physical_address)   local_fadt->V1_pm2_cnt_blk);
321         acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
322                           (acpi_physical_address)   local_fadt->V1_pm_tmr_blk);
323         acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
324                           (acpi_physical_address)   local_fadt->V1_gpe0_blk);
325         acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
326                           (acpi_physical_address)   local_fadt->V1_gpe1_blk);
327
328         /* Create separate GAS structs for the PM1 Enable registers */
329
330         acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
331                  (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
332                  (acpi_physical_address)
333                         (local_fadt->xpm1a_evt_blk.address +
334                         ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
335
336         /* PM1B is optional; leave null if not present */
337
338         if (local_fadt->xpm1b_evt_blk.address) {
339                 acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
340                          (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
341                          (acpi_physical_address)
342                                 (local_fadt->xpm1b_evt_blk.address +
343                                 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
344         }
345 }
346
347
348 /*******************************************************************************
349  *
350  * FUNCTION:    acpi_tb_convert_fadt2
351  *
352  * PARAMETERS:  local_fadt      - Pointer to new FADT
353  *              original_fadt   - Pointer to old FADT
354  *
355  * RETURN:      None, populates local_fadt
356  *
357  * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
358  *              Handles optional "X" fields.
359  *
360  ******************************************************************************/
361
362 static void
363 acpi_tb_convert_fadt2 (
364         struct fadt_descriptor_rev2    *local_fadt,
365         struct fadt_descriptor_rev2    *original_fadt)
366 {
367
368         /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
369
370         ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2));
371
372         /*
373          * "X" fields are optional extensions to the original V1.0 fields, so
374          * we must selectively expand V1.0 fields if the corresponding X field
375          * is zero.
376          */
377         if (!(local_fadt->xfirmware_ctrl)) {
378                 ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl,
379                         local_fadt->V1_firmware_ctrl);
380         }
381
382         if (!(local_fadt->Xdsdt)) {
383                 ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
384         }
385
386         if (!(local_fadt->xpm1a_evt_blk.address)) {
387                 acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
388                         local_fadt->pm1_evt_len,
389                         (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
390         }
391
392         if (!(local_fadt->xpm1b_evt_blk.address)) {
393                 acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
394                         local_fadt->pm1_evt_len,
395                         (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
396         }
397
398         if (!(local_fadt->xpm1a_cnt_blk.address)) {
399                 acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
400                         local_fadt->pm1_cnt_len,
401                         (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
402         }
403
404         if (!(local_fadt->xpm1b_cnt_blk.address)) {
405                 acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
406                         local_fadt->pm1_cnt_len,
407                         (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
408         }
409
410         if (!(local_fadt->xpm2_cnt_blk.address)) {
411                 acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
412                         local_fadt->pm2_cnt_len,
413                         (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
414         }
415
416         if (!(local_fadt->xpm_tmr_blk.address)) {
417                 acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
418                         local_fadt->pm_tm_len,
419                         (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
420         }
421
422         if (!(local_fadt->xgpe0_blk.address)) {
423                 acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
424                         0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
425         }
426
427         if (!(local_fadt->xgpe1_blk.address)) {
428                 acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
429                         0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
430         }
431
432         /* Create separate GAS structs for the PM1 Enable registers */
433
434         acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
435                 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
436                 (acpi_physical_address)
437                         (local_fadt->xpm1a_evt_blk.address +
438                         ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
439
440         acpi_gbl_xpm1a_enable.address_space_id =
441                 local_fadt->xpm1a_evt_blk.address_space_id;
442
443         /* PM1B is optional; leave null if not present */
444
445         if (local_fadt->xpm1b_evt_blk.address) {
446                 acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
447                         (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
448                         (acpi_physical_address)
449                                 (local_fadt->xpm1b_evt_blk.address +
450                                 ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
451
452                 acpi_gbl_xpm1b_enable.address_space_id =
453                         local_fadt->xpm1b_evt_blk.address_space_id;
454         }
455 }
456
457
458 /*******************************************************************************
459  *
460  * FUNCTION:    acpi_tb_convert_table_fadt
461  *
462  * PARAMETERS:  None
463  *
464  * RETURN:      Status
465  *
466  * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local
467  *              ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
468  *              copied to the local FADT.  The ACPI CA software uses this
469  *              local FADT. Thus a significant amount of special #ifdef
470  *              type codeing is saved.
471  *
472  ******************************************************************************/
473
474 acpi_status
475 acpi_tb_convert_table_fadt (
476         void)
477 {
478         struct fadt_descriptor_rev2    *local_fadt;
479         struct acpi_table_desc         *table_desc;
480
481
482         ACPI_FUNCTION_TRACE ("tb_convert_table_fadt");
483
484
485         /*
486          * acpi_gbl_FADT is valid. Validate the FADT length. The table must be
487          * at least as long as the version 1.0 FADT
488          */
489         if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
490                 ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n",
491                         acpi_gbl_FADT->length));
492                 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
493         }
494
495         /* Allocate buffer for the ACPI 2.0(+) FADT */
496
497         local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
498         if (!local_fadt) {
499                 return_ACPI_STATUS (AE_NO_MEMORY);
500         }
501
502         if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
503                 if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
504                         /* Length is too short to be a V2.0 table */
505
506                         ACPI_REPORT_WARNING ((
507                                 "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
508                                 acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
509
510                         acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
511                 }
512                 else {
513                         /* Valid V2.0 table */
514
515                         acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT);
516                 }
517         }
518         else {
519                 /* Valid V1.0 table */
520
521                 acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
522         }
523
524         /* Global FADT pointer will point to the new common V2.0 FADT */
525
526         acpi_gbl_FADT = local_fadt;
527         acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
528
529         /* Free the original table */
530
531         table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
532         acpi_tb_delete_single_table (table_desc);
533
534         /* Install the new table */
535
536         table_desc->pointer     = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT);
537         table_desc->allocation  = ACPI_MEM_ALLOCATED;
538         table_desc->length      = sizeof (struct fadt_descriptor_rev2);
539
540         /* Dump the entire FADT */
541
542         ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
543                 "Hex dump of common internal FADT, size %d (%X)\n",
544                 acpi_gbl_FADT->length, acpi_gbl_FADT->length));
545         ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
546
547         return_ACPI_STATUS (AE_OK);
548 }
549
550
551 /*******************************************************************************
552  *
553  * FUNCTION:    acpi_tb_build_common_facs
554  *
555  * PARAMETERS:  table_info      - Info for currently installed FACS
556  *
557  * RETURN:      Status
558  *
559  * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal
560  *              table format.
561  *
562  ******************************************************************************/
563
564 acpi_status
565 acpi_tb_build_common_facs (
566         struct acpi_table_desc          *table_info)
567 {
568
569         ACPI_FUNCTION_TRACE ("tb_build_common_facs");
570
571
572         /* Absolute minimum length is 24, but the ACPI spec says 64 */
573
574         if (acpi_gbl_FACS->length < 24) {
575                 ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n",
576                         acpi_gbl_FACS->length));
577                 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
578         }
579
580         if (acpi_gbl_FACS->length < 64) {
581                 ACPI_REPORT_WARNING ((
582                         "FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
583                         acpi_gbl_FACS->length));
584         }
585
586         /* Copy fields to the new FACS */
587
588         acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock);
589
590         if ((acpi_gbl_RSDP->revision < 2) ||
591                 (acpi_gbl_FACS->length < 32) ||
592                 (!(acpi_gbl_FACS->xfirmware_waking_vector))) {
593                 /* ACPI 1.0 FACS or short table or optional X_ field is zero */
594
595                 acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64,
596                                 &(acpi_gbl_FACS->firmware_waking_vector));
597                 acpi_gbl_common_fACS.vector_width = 32;
598         }
599         else {
600                 /* ACPI 2.0 FACS with valid X_ field */
601
602                 acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector;
603                 acpi_gbl_common_fACS.vector_width = 64;
604         }
605
606         return_ACPI_STATUS (AE_OK);
607 }
608
609