xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/tables/tbfadt.c (revision f2df0cfe93a902842f6f4629ff614f5b3f9bf687)
1 /******************************************************************************
2  *
3  * Module Name: tbfadt   - FADT table utilities
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #include "acpi.h"
117 #include "accommon.h"
118 #include "actables.h"
119 
120 #define _COMPONENT          ACPI_TABLES
121         ACPI_MODULE_NAME    ("tbfadt")
122 
123 /* Local prototypes */
124 
125 static void
126 AcpiTbInitGenericAddress (
127     ACPI_GENERIC_ADDRESS    *GenericAddress,
128     UINT8                   SpaceId,
129     UINT8                   ByteWidth,
130     UINT64                  Address,
131     char                    *RegisterName,
132     UINT8                   Flags);
133 
134 static void
135 AcpiTbConvertFadt (
136     void);
137 
138 static void
139 AcpiTbSetupFadtRegisters (
140     void);
141 
142 static UINT64
143 AcpiTbSelectAddress (
144     char                    *RegisterName,
145     UINT32                  Address32,
146     UINT64                  Address64);
147 
148 
149 /* Table for conversion of FADT to common internal format and FADT validation */
150 
151 typedef struct acpi_fadt_info
152 {
153     char                    *Name;
154     UINT16                  Address64;
155     UINT16                  Address32;
156     UINT16                  Length;
157     UINT8                   DefaultLength;
158     UINT8                   Flags;
159 
160 } ACPI_FADT_INFO;
161 
162 #define ACPI_FADT_OPTIONAL          0
163 #define ACPI_FADT_REQUIRED          1
164 #define ACPI_FADT_SEPARATE_LENGTH   2
165 #define ACPI_FADT_GPE_REGISTER      4
166 
167 static ACPI_FADT_INFO     FadtInfoTable[] =
168 {
169     {"Pm1aEventBlock",
170         ACPI_FADT_OFFSET (XPm1aEventBlock),
171         ACPI_FADT_OFFSET (Pm1aEventBlock),
172         ACPI_FADT_OFFSET (Pm1EventLength),
173         ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
174         ACPI_FADT_REQUIRED},
175 
176     {"Pm1bEventBlock",
177         ACPI_FADT_OFFSET (XPm1bEventBlock),
178         ACPI_FADT_OFFSET (Pm1bEventBlock),
179         ACPI_FADT_OFFSET (Pm1EventLength),
180         ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
181         ACPI_FADT_OPTIONAL},
182 
183     {"Pm1aControlBlock",
184         ACPI_FADT_OFFSET (XPm1aControlBlock),
185         ACPI_FADT_OFFSET (Pm1aControlBlock),
186         ACPI_FADT_OFFSET (Pm1ControlLength),
187         ACPI_PM1_REGISTER_WIDTH,
188         ACPI_FADT_REQUIRED},
189 
190     {"Pm1bControlBlock",
191         ACPI_FADT_OFFSET (XPm1bControlBlock),
192         ACPI_FADT_OFFSET (Pm1bControlBlock),
193         ACPI_FADT_OFFSET (Pm1ControlLength),
194         ACPI_PM1_REGISTER_WIDTH,
195         ACPI_FADT_OPTIONAL},
196 
197     {"Pm2ControlBlock",
198         ACPI_FADT_OFFSET (XPm2ControlBlock),
199         ACPI_FADT_OFFSET (Pm2ControlBlock),
200         ACPI_FADT_OFFSET (Pm2ControlLength),
201         ACPI_PM2_REGISTER_WIDTH,
202         ACPI_FADT_SEPARATE_LENGTH},
203 
204     {"PmTimerBlock",
205         ACPI_FADT_OFFSET (XPmTimerBlock),
206         ACPI_FADT_OFFSET (PmTimerBlock),
207         ACPI_FADT_OFFSET (PmTimerLength),
208         ACPI_PM_TIMER_WIDTH,
209         ACPI_FADT_SEPARATE_LENGTH},         /* ACPI 5.0A: Timer is optional */
210 
211     {"Gpe0Block",
212         ACPI_FADT_OFFSET (XGpe0Block),
213         ACPI_FADT_OFFSET (Gpe0Block),
214         ACPI_FADT_OFFSET (Gpe0BlockLength),
215         0,
216         ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
217 
218     {"Gpe1Block",
219         ACPI_FADT_OFFSET (XGpe1Block),
220         ACPI_FADT_OFFSET (Gpe1Block),
221         ACPI_FADT_OFFSET (Gpe1BlockLength),
222         0,
223         ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
224 };
225 
226 #define ACPI_FADT_INFO_ENTRIES \
227             (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
228 
229 
230 /* Table used to split Event Blocks into separate status/enable registers */
231 
232 typedef struct acpi_fadt_pm_info
233 {
234     ACPI_GENERIC_ADDRESS    *Target;
235     UINT16                  Source;
236     UINT8                   RegisterNum;
237 
238 } ACPI_FADT_PM_INFO;
239 
240 static ACPI_FADT_PM_INFO    FadtPmInfoTable[] =
241 {
242     {&AcpiGbl_XPm1aStatus,
243         ACPI_FADT_OFFSET (XPm1aEventBlock),
244         0},
245 
246     {&AcpiGbl_XPm1aEnable,
247         ACPI_FADT_OFFSET (XPm1aEventBlock),
248         1},
249 
250     {&AcpiGbl_XPm1bStatus,
251         ACPI_FADT_OFFSET (XPm1bEventBlock),
252         0},
253 
254     {&AcpiGbl_XPm1bEnable,
255         ACPI_FADT_OFFSET (XPm1bEventBlock),
256         1}
257 };
258 
259 #define ACPI_FADT_PM_INFO_ENTRIES \
260             (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
261 
262 
263 /*******************************************************************************
264  *
265  * FUNCTION:    AcpiTbInitGenericAddress
266  *
267  * PARAMETERS:  GenericAddress      - GAS struct to be initialized
268  *              SpaceId             - ACPI Space ID for this register
269  *              ByteWidth           - Width of this register
270  *              Address             - Address of the register
271  *              RegisterName        - ASCII name of the ACPI register
272  *
273  * RETURN:      None
274  *
275  * DESCRIPTION: Initialize a Generic Address Structure (GAS)
276  *              See the ACPI specification for a full description and
277  *              definition of this structure.
278  *
279  ******************************************************************************/
280 
281 static void
282 AcpiTbInitGenericAddress (
283     ACPI_GENERIC_ADDRESS    *GenericAddress,
284     UINT8                   SpaceId,
285     UINT8                   ByteWidth,
286     UINT64                  Address,
287     char                    *RegisterName,
288     UINT8                   Flags)
289 {
290     UINT8                   BitWidth;
291 
292 
293     /*
294      * Bit width field in the GAS is only one byte long, 255 max.
295      * Check for BitWidth overflow in GAS.
296      */
297     BitWidth = (UINT8) (ByteWidth * 8);
298     if (ByteWidth > 31)     /* (31*8)=248, (32*8)=256 */
299     {
300         /*
301          * No error for GPE blocks, because we do not use the BitWidth
302          * for GPEs, the legacy length (ByteWidth) is used instead to
303          * allow for a large number of GPEs.
304          */
305         if (!(Flags & ACPI_FADT_GPE_REGISTER))
306         {
307             ACPI_ERROR ((AE_INFO,
308                 "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
309                 "to convert to GAS struct - 255 bits max, truncating",
310                 RegisterName, ByteWidth, (ByteWidth * 8)));
311         }
312 
313         BitWidth = 255;
314     }
315 
316     /*
317      * The 64-bit Address field is non-aligned in the byte packed
318      * GAS struct.
319      */
320     ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
321 
322     /* All other fields are byte-wide */
323 
324     GenericAddress->SpaceId = SpaceId;
325     GenericAddress->BitWidth = BitWidth;
326     GenericAddress->BitOffset = 0;
327     GenericAddress->AccessWidth = 0; /* Access width ANY */
328 }
329 
330 
331 /*******************************************************************************
332  *
333  * FUNCTION:    AcpiTbSelectAddress
334  *
335  * PARAMETERS:  RegisterName        - ASCII name of the ACPI register
336  *              Address32           - 32-bit address of the register
337  *              Address64           - 64-bit address of the register
338  *
339  * RETURN:      The resolved 64-bit address
340  *
341  * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
342  *              the FADT. Used for the FACS and DSDT addresses.
343  *
344  * NOTES:
345  *
346  * Check for FACS and DSDT address mismatches. An address mismatch between
347  * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
348  * DSDT/X_DSDT) could be a corrupted address field or it might indicate
349  * the presence of two FACS or two DSDT tables.
350  *
351  * November 2013:
352  * By default, as per the ACPICA specification, a valid 64-bit address is
353  * used regardless of the value of the 32-bit address. However, this
354  * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.
355  *
356  ******************************************************************************/
357 
358 static UINT64
359 AcpiTbSelectAddress (
360     char                    *RegisterName,
361     UINT32                  Address32,
362     UINT64                  Address64)
363 {
364 
365     if (!Address64)
366     {
367         /* 64-bit address is zero, use 32-bit address */
368 
369         return ((UINT64) Address32);
370     }
371 
372     if (Address32 &&
373        (Address64 != (UINT64) Address32))
374     {
375         /* Address mismatch between 32-bit and 64-bit versions */
376 
377         ACPI_BIOS_WARNING ((AE_INFO,
378             "32/64X %s address mismatch in FADT: "
379             "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
380             RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),
381             AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
382 
383         /* 32-bit address override */
384 
385         if (AcpiGbl_Use32BitFadtAddresses)
386         {
387             return ((UINT64) Address32);
388         }
389     }
390 
391     /* Default is to use the 64-bit address */
392 
393     return (Address64);
394 }
395 
396 
397 /*******************************************************************************
398  *
399  * FUNCTION:    AcpiTbParseFadt
400  *
401  * PARAMETERS:  None
402  *
403  * RETURN:      None
404  *
405  * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
406  *              (FADT contains the addresses of the DSDT and FACS)
407  *
408  ******************************************************************************/
409 
410 void
411 AcpiTbParseFadt (
412     void)
413 {
414     UINT32                  Length;
415     ACPI_TABLE_HEADER       *Table;
416 
417 
418     /*
419      * The FADT has multiple versions with different lengths,
420      * and it contains pointers to both the DSDT and FACS tables.
421      *
422      * Get a local copy of the FADT and convert it to a common format
423      * Map entire FADT, assumed to be smaller than one page.
424      */
425     Length = AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Length;
426 
427     Table = AcpiOsMapMemory (
428         AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Address, Length);
429     if (!Table)
430     {
431         return;
432     }
433 
434     /*
435      * Validate the FADT checksum before we copy the table. Ignore
436      * checksum error as we want to try to get the DSDT and FACS.
437      */
438     (void) AcpiTbVerifyChecksum (Table, Length);
439 
440     /* Create a local copy of the FADT in common ACPI 2.0+ format */
441 
442     AcpiTbCreateLocalFadt (Table, Length);
443 
444     /* All done with the real FADT, unmap it */
445 
446     AcpiOsUnmapMemory (Table, Length);
447 
448     /* Obtain the DSDT and FACS tables via their addresses within the FADT */
449 
450     AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
451         ACPI_SIG_DSDT, &AcpiGbl_DsdtIndex);
452 
453     /* If Hardware Reduced flag is set, there is no FACS */
454 
455     if (!AcpiGbl_ReducedHardware)
456     {
457         if (AcpiGbl_FADT.Facs)
458         {
459             AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,
460                 ACPI_SIG_FACS, &AcpiGbl_FacsIndex);
461         }
462         if (AcpiGbl_FADT.XFacs)
463         {
464             AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
465                 ACPI_SIG_FACS, &AcpiGbl_XFacsIndex);
466         }
467     }
468 }
469 
470 
471 /*******************************************************************************
472  *
473  * FUNCTION:    AcpiTbCreateLocalFadt
474  *
475  * PARAMETERS:  Table               - Pointer to BIOS FADT
476  *              Length              - Length of the table
477  *
478  * RETURN:      None
479  *
480  * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
481  *              Performs validation on some important FADT fields.
482  *
483  * NOTE:        We create a local copy of the FADT regardless of the version.
484  *
485  ******************************************************************************/
486 
487 void
488 AcpiTbCreateLocalFadt (
489     ACPI_TABLE_HEADER       *Table,
490     UINT32                  Length)
491 {
492 
493     /*
494      * Check if the FADT is larger than the largest table that we expect
495      * (the ACPI 5.0 version). If so, truncate the table, and issue
496      * a warning.
497      */
498     if (Length > sizeof (ACPI_TABLE_FADT))
499     {
500         ACPI_BIOS_WARNING ((AE_INFO,
501             "FADT (revision %u) is longer than ACPI 5.0 version, "
502             "truncating length %u to %u",
503             Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
504     }
505 
506     /* Clear the entire local FADT */
507 
508     memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
509 
510     /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
511 
512     memcpy (&AcpiGbl_FADT, Table,
513         ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
514 
515     /* Take a copy of the Hardware Reduced flag */
516 
517     AcpiGbl_ReducedHardware = FALSE;
518     if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
519     {
520         AcpiGbl_ReducedHardware = TRUE;
521     }
522 
523     /* Convert the local copy of the FADT to the common internal format */
524 
525     AcpiTbConvertFadt ();
526 
527     /* Initialize the global ACPI register structures */
528 
529     AcpiTbSetupFadtRegisters ();
530 }
531 
532 
533 /*******************************************************************************
534  *
535  * FUNCTION:    AcpiTbConvertFadt
536  *
537  * PARAMETERS:  None - AcpiGbl_FADT is used.
538  *
539  * RETURN:      None
540  *
541  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
542  *              Expand 32-bit addresses to 64-bit as necessary. Also validate
543  *              important fields within the FADT.
544  *
545  * NOTE:        AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
546  *              contain a copy of the actual BIOS-provided FADT.
547  *
548  * Notes on 64-bit register addresses:
549  *
550  * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
551  * fields of the FADT for all ACPI register addresses.
552  *
553  * The 64-bit X fields are optional extensions to the original 32-bit FADT
554  * V1.0 fields. Even if they are present in the FADT, they are optional and
555  * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
556  * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
557  * originally zero.
558  *
559  * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
560  * fields are expanded to the corresponding 64-bit X fields in the internal
561  * common FADT.
562  *
563  * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
564  * to the corresponding 64-bit X fields, if the 64-bit field is originally
565  * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
566  * field if the 64-bit field is valid, regardless of whether the host OS is
567  * 32-bit or 64-bit.
568  *
569  * Possible additional checks:
570  *  (AcpiGbl_FADT.Pm1EventLength >= 4)
571  *  (AcpiGbl_FADT.Pm1ControlLength >= 2)
572  *  (AcpiGbl_FADT.PmTimerLength >= 4)
573  *  Gpe block lengths must be multiple of 2
574  *
575  ******************************************************************************/
576 
577 static void
578 AcpiTbConvertFadt (
579     void)
580 {
581     char                    *Name;
582     ACPI_GENERIC_ADDRESS    *Address64;
583     UINT32                  Address32;
584     UINT8                   Length;
585     UINT8                   Flags;
586     UINT32                  i;
587 
588 
589     /*
590      * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
591      * should be zero are indeed zero. This will workaround BIOSs that
592      * inadvertently place values in these fields.
593      *
594      * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
595      * at offset 45, 55, 95, and the word located at offset 109, 110.
596      *
597      * Note: The FADT revision value is unreliable. Only the length can be
598      * trusted.
599      */
600     if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
601     {
602         AcpiGbl_FADT.PreferredProfile = 0;
603         AcpiGbl_FADT.PstateControl = 0;
604         AcpiGbl_FADT.CstControl = 0;
605         AcpiGbl_FADT.BootFlags = 0;
606     }
607 
608     /*
609      * Now we can update the local FADT length to the length of the
610      * current FADT version as defined by the ACPI specification.
611      * Thus, we will have a common FADT internally.
612      */
613     AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
614 
615     /*
616      * Expand the 32-bit DSDT addresses to 64-bit as necessary.
617      * Later ACPICA code will always use the X 64-bit field.
618      */
619     AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
620         AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
621 
622     /* If Hardware Reduced flag is set, we are all done */
623 
624     if (AcpiGbl_ReducedHardware)
625     {
626         return;
627     }
628 
629     /* Examine all of the 64-bit extended address fields (X fields) */
630 
631     for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
632     {
633         /*
634          * Get the 32-bit and 64-bit addresses, as well as the register
635          * length and register name.
636          */
637         Address32 = *ACPI_ADD_PTR (UINT32,
638             &AcpiGbl_FADT, FadtInfoTable[i].Address32);
639 
640         Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
641             &AcpiGbl_FADT, FadtInfoTable[i].Address64);
642 
643         Length = *ACPI_ADD_PTR (UINT8,
644             &AcpiGbl_FADT, FadtInfoTable[i].Length);
645 
646         Name = FadtInfoTable[i].Name;
647         Flags = FadtInfoTable[i].Flags;
648 
649         /*
650          * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
651          * generic address structures as necessary. Later code will always use
652          * the 64-bit address structures.
653          *
654          * November 2013:
655          * Now always use the 64-bit address if it is valid (non-zero), in
656          * accordance with the ACPI specification which states that a 64-bit
657          * address supersedes the 32-bit version. This behavior can be
658          * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
659          *
660          * During 64-bit address construction and verification,
661          * these cases are handled:
662          *
663          * Address32 zero, Address64 [don't care]   - Use Address64
664          *
665          * Address32 non-zero, Address64 zero       - Copy/use Address32
666          * Address32 non-zero == Address64 non-zero - Use Address64
667          * Address32 non-zero != Address64 non-zero - Warning, use Address64
668          *
669          * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
670          * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
671          *
672          * Note: SpaceId is always I/O for 32-bit legacy address fields
673          */
674         if (Address32)
675         {
676             if (!Address64->Address)
677             {
678                 /* 64-bit address is zero, use 32-bit address */
679 
680                 AcpiTbInitGenericAddress (Address64,
681                     ACPI_ADR_SPACE_SYSTEM_IO,
682                     *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
683                         FadtInfoTable[i].Length),
684                     (UINT64) Address32, Name, Flags);
685             }
686             else if (Address64->Address != (UINT64) Address32)
687             {
688                 /* Address mismatch */
689 
690                 ACPI_BIOS_WARNING ((AE_INFO,
691                     "32/64X address mismatch in FADT/%s: "
692                     "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
693                     Name, Address32,
694                     ACPI_FORMAT_UINT64 (Address64->Address),
695                     AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
696 
697                 if (AcpiGbl_Use32BitFadtAddresses)
698                 {
699                     /* 32-bit address override */
700 
701                     AcpiTbInitGenericAddress (Address64,
702                         ACPI_ADR_SPACE_SYSTEM_IO,
703                         *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
704                             FadtInfoTable[i].Length),
705                         (UINT64) Address32, Name, Flags);
706                 }
707             }
708         }
709 
710         /*
711          * For each extended field, check for length mismatch between the
712          * legacy length field and the corresponding 64-bit X length field.
713          * Note: If the legacy length field is > 0xFF bits, ignore this
714          * check. (GPE registers can be larger than the 64-bit GAS structure
715          * can accomodate, 0xFF bits).
716          */
717         if (Address64->Address &&
718            (ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
719            (Address64->BitWidth != ACPI_MUL_8 (Length)))
720         {
721             ACPI_BIOS_WARNING ((AE_INFO,
722                 "32/64X length mismatch in FADT/%s: %u/%u",
723                 Name, ACPI_MUL_8 (Length), Address64->BitWidth));
724         }
725 
726         if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
727         {
728             /*
729              * Field is required (PM1aEvent, PM1aControl).
730              * Both the address and length must be non-zero.
731              */
732             if (!Address64->Address || !Length)
733             {
734                 ACPI_BIOS_ERROR ((AE_INFO,
735                     "Required FADT field %s has zero address and/or length: "
736                     "0x%8.8X%8.8X/0x%X",
737                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
738             }
739         }
740         else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
741         {
742             /*
743              * Field is optional (PM2Control, GPE0, GPE1) AND has its own
744              * length field. If present, both the address and length must
745              * be valid.
746              */
747             if ((Address64->Address && !Length) ||
748                 (!Address64->Address && Length))
749             {
750                 ACPI_BIOS_WARNING ((AE_INFO,
751                     "Optional FADT field %s has zero address or length: "
752                     "0x%8.8X%8.8X/0x%X",
753                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
754             }
755         }
756     }
757 }
758 
759 
760 /*******************************************************************************
761  *
762  * FUNCTION:    AcpiTbSetupFadtRegisters
763  *
764  * PARAMETERS:  None, uses AcpiGbl_FADT.
765  *
766  * RETURN:      None
767  *
768  * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
769  *              force FADT register definitions to their default lengths.
770  *
771  ******************************************************************************/
772 
773 static void
774 AcpiTbSetupFadtRegisters (
775     void)
776 {
777     ACPI_GENERIC_ADDRESS    *Target64;
778     ACPI_GENERIC_ADDRESS    *Source64;
779     UINT8                   Pm1RegisterByteWidth;
780     UINT32                  i;
781 
782 
783     /*
784      * Optionally check all register lengths against the default values and
785      * update them if they are incorrect.
786      */
787     if (AcpiGbl_UseDefaultRegisterWidths)
788     {
789         for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
790         {
791             Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
792                 FadtInfoTable[i].Address64);
793 
794             /*
795              * If a valid register (Address != 0) and the (DefaultLength > 0)
796              * (Not a GPE register), then check the width against the default.
797              */
798             if ((Target64->Address) &&
799                 (FadtInfoTable[i].DefaultLength > 0) &&
800                 (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
801             {
802                 ACPI_BIOS_WARNING ((AE_INFO,
803                     "Invalid length for FADT/%s: %u, using default %u",
804                     FadtInfoTable[i].Name, Target64->BitWidth,
805                     FadtInfoTable[i].DefaultLength));
806 
807                 /* Incorrect size, set width to the default */
808 
809                 Target64->BitWidth = FadtInfoTable[i].DefaultLength;
810             }
811         }
812     }
813 
814     /*
815      * Get the length of the individual PM1 registers (enable and status).
816      * Each register is defined to be (event block length / 2). Extra divide
817      * by 8 converts bits to bytes.
818      */
819     Pm1RegisterByteWidth = (UINT8)
820         ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
821 
822     /*
823      * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
824      * registers. These addresses do not appear (directly) in the FADT, so it
825      * is useful to pre-calculate them from the PM1 Event Block definitions.
826      *
827      * The PM event blocks are split into two register blocks, first is the
828      * PM Status Register block, followed immediately by the PM Enable
829      * Register block. Each is of length (Pm1EventLength/2)
830      *
831      * Note: The PM1A event block is required by the ACPI specification.
832      * However, the PM1B event block is optional and is rarely, if ever,
833      * used.
834      */
835 
836     for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
837     {
838         Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
839             FadtPmInfoTable[i].Source);
840 
841         if (Source64->Address)
842         {
843             AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
844                 Source64->SpaceId, Pm1RegisterByteWidth,
845                 Source64->Address +
846                     (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
847                 "PmRegisters", 0);
848         }
849     }
850 }
851