OSDN Git Service

klibc基本機能実装. ACPICAの準備
[vaneos/DivergeMirror.git] / drivers / acpi / components / tables / tbfadt.c
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 - 2015, 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:  TableIndex          - Index for the FADT
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     UINT32                  TableIndex)
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[TableIndex].Length;
426
427     Table = AcpiOsMapMemory (
428                 AcpiGbl_RootTableList.Tables[TableIndex].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, ACPI_TABLE_INDEX_DSDT);
452
453     /* If Hardware Reduced flag is set, there is no FACS */
454
455     if (!AcpiGbl_ReducedHardware)
456     {
457         AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
458             ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
459     }
460 }
461
462
463 /*******************************************************************************
464  *
465  * FUNCTION:    AcpiTbCreateLocalFadt
466  *
467  * PARAMETERS:  Table               - Pointer to BIOS FADT
468  *              Length              - Length of the table
469  *
470  * RETURN:      None
471  *
472  * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
473  *              Performs validation on some important FADT fields.
474  *
475  * NOTE:        We create a local copy of the FADT regardless of the version.
476  *
477  ******************************************************************************/
478
479 void
480 AcpiTbCreateLocalFadt (
481     ACPI_TABLE_HEADER       *Table,
482     UINT32                  Length)
483 {
484
485     /*
486      * Check if the FADT is larger than the largest table that we expect
487      * (the ACPI 5.0 version). If so, truncate the table, and issue
488      * a warning.
489      */
490     if (Length > sizeof (ACPI_TABLE_FADT))
491     {
492         ACPI_BIOS_WARNING ((AE_INFO,
493             "FADT (revision %u) is longer than ACPI 5.0 version, "
494             "truncating length %u to %u",
495             Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
496     }
497
498     /* Clear the entire local FADT */
499
500     ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
501
502     /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
503
504     ACPI_MEMCPY (&AcpiGbl_FADT, Table,
505         ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
506
507     /* Take a copy of the Hardware Reduced flag */
508
509     AcpiGbl_ReducedHardware = FALSE;
510     if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
511     {
512         AcpiGbl_ReducedHardware = TRUE;
513     }
514
515     /* Convert the local copy of the FADT to the common internal format */
516
517     AcpiTbConvertFadt ();
518
519     /* Initialize the global ACPI register structures */
520
521     AcpiTbSetupFadtRegisters ();
522 }
523
524
525 /*******************************************************************************
526  *
527  * FUNCTION:    AcpiTbConvertFadt
528  *
529  * PARAMETERS:  None - AcpiGbl_FADT is used.
530  *
531  * RETURN:      None
532  *
533  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
534  *              Expand 32-bit addresses to 64-bit as necessary. Also validate
535  *              important fields within the FADT.
536  *
537  * NOTE:        AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
538  *              contain a copy of the actual BIOS-provided FADT.
539  *
540  * Notes on 64-bit register addresses:
541  *
542  * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
543  * fields of the FADT for all ACPI register addresses.
544  *
545  * The 64-bit X fields are optional extensions to the original 32-bit FADT
546  * V1.0 fields. Even if they are present in the FADT, they are optional and
547  * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
548  * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
549  * originally zero.
550  *
551  * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
552  * fields are expanded to the corresponding 64-bit X fields in the internal
553  * common FADT.
554  *
555  * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
556  * to the corresponding 64-bit X fields, if the 64-bit field is originally
557  * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
558  * field if the 64-bit field is valid, regardless of whether the host OS is
559  * 32-bit or 64-bit.
560  *
561  * Possible additional checks:
562  *  (AcpiGbl_FADT.Pm1EventLength >= 4)
563  *  (AcpiGbl_FADT.Pm1ControlLength >= 2)
564  *  (AcpiGbl_FADT.PmTimerLength >= 4)
565  *  Gpe block lengths must be multiple of 2
566  *
567  ******************************************************************************/
568
569 static void
570 AcpiTbConvertFadt (
571     void)
572 {
573     char                    *Name;
574     ACPI_GENERIC_ADDRESS    *Address64;
575     UINT32                  Address32;
576     UINT8                   Length;
577     UINT8                   Flags;
578     UINT32                  i;
579
580
581     /*
582      * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
583      * should be zero are indeed zero. This will workaround BIOSs that
584      * inadvertently place values in these fields.
585      *
586      * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
587      * at offset 45, 55, 95, and the word located at offset 109, 110.
588      *
589      * Note: The FADT revision value is unreliable. Only the length can be
590      * trusted.
591      */
592     if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
593     {
594         AcpiGbl_FADT.PreferredProfile = 0;
595         AcpiGbl_FADT.PstateControl = 0;
596         AcpiGbl_FADT.CstControl = 0;
597         AcpiGbl_FADT.BootFlags = 0;
598     }
599
600     /*
601      * Now we can update the local FADT length to the length of the
602      * current FADT version as defined by the ACPI specification.
603      * Thus, we will have a common FADT internally.
604      */
605     AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
606
607     /*
608      * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
609      * Later ACPICA code will always use the X 64-bit field.
610      */
611     AcpiGbl_FADT.XFacs = AcpiTbSelectAddress ("FACS",
612         AcpiGbl_FADT.Facs, AcpiGbl_FADT.XFacs);
613
614     AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
615         AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
616
617     /* If Hardware Reduced flag is set, we are all done */
618
619     if (AcpiGbl_ReducedHardware)
620     {
621         return;
622     }
623
624     /* Examine all of the 64-bit extended address fields (X fields) */
625
626     for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
627     {
628         /*
629          * Get the 32-bit and 64-bit addresses, as well as the register
630          * length and register name.
631          */
632         Address32 = *ACPI_ADD_PTR (UINT32,
633             &AcpiGbl_FADT, FadtInfoTable[i].Address32);
634
635         Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
636             &AcpiGbl_FADT, FadtInfoTable[i].Address64);
637
638         Length = *ACPI_ADD_PTR (UINT8,
639             &AcpiGbl_FADT, FadtInfoTable[i].Length);
640
641         Name = FadtInfoTable[i].Name;
642         Flags = FadtInfoTable[i].Flags;
643
644         /*
645          * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
646          * generic address structures as necessary. Later code will always use
647          * the 64-bit address structures.
648          *
649          * November 2013:
650          * Now always use the 64-bit address if it is valid (non-zero), in
651          * accordance with the ACPI specification which states that a 64-bit
652          * address supersedes the 32-bit version. This behavior can be
653          * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
654          *
655          * During 64-bit address construction and verification,
656          * these cases are handled:
657          *
658          * Address32 zero, Address64 [don't care]   - Use Address64
659          *
660          * Address32 non-zero, Address64 zero       - Copy/use Address32
661          * Address32 non-zero == Address64 non-zero - Use Address64
662          * Address32 non-zero != Address64 non-zero - Warning, use Address64
663          *
664          * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
665          * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
666          *
667          * Note: SpaceId is always I/O for 32-bit legacy address fields
668          */
669         if (Address32)
670         {
671             if (!Address64->Address)
672             {
673                 /* 64-bit address is zero, use 32-bit address */
674
675                 AcpiTbInitGenericAddress (Address64,
676                     ACPI_ADR_SPACE_SYSTEM_IO,
677                     *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
678                         FadtInfoTable[i].Length),
679                     (UINT64) Address32, Name, Flags);
680             }
681             else if (Address64->Address != (UINT64) Address32)
682             {
683                 /* Address mismatch */
684
685                 ACPI_BIOS_WARNING ((AE_INFO,
686                     "32/64X address mismatch in FADT/%s: "
687                     "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
688                     Name, Address32,
689                     ACPI_FORMAT_UINT64 (Address64->Address),
690                     AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
691
692                 if (AcpiGbl_Use32BitFadtAddresses)
693                 {
694                     /* 32-bit address override */
695
696                     AcpiTbInitGenericAddress (Address64,
697                         ACPI_ADR_SPACE_SYSTEM_IO,
698                         *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
699                             FadtInfoTable[i].Length),
700                         (UINT64) Address32, Name, Flags);
701                 }
702             }
703         }
704
705         /*
706          * For each extended field, check for length mismatch between the
707          * legacy length field and the corresponding 64-bit X length field.
708          * Note: If the legacy length field is > 0xFF bits, ignore this
709          * check. (GPE registers can be larger than the 64-bit GAS structure
710          * can accomodate, 0xFF bits).
711          */
712         if (Address64->Address &&
713            (ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
714            (Address64->BitWidth != ACPI_MUL_8 (Length)))
715         {
716             ACPI_BIOS_WARNING ((AE_INFO,
717                 "32/64X length mismatch in FADT/%s: %u/%u",
718                 Name, ACPI_MUL_8 (Length), Address64->BitWidth));
719         }
720
721         if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
722         {
723             /*
724              * Field is required (PM1aEvent, PM1aControl).
725              * Both the address and length must be non-zero.
726              */
727             if (!Address64->Address || !Length)
728             {
729                 ACPI_BIOS_ERROR ((AE_INFO,
730                     "Required FADT field %s has zero address and/or length: "
731                     "0x%8.8X%8.8X/0x%X",
732                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
733             }
734         }
735         else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
736         {
737             /*
738              * Field is optional (PM2Control, GPE0, GPE1) AND has its own
739              * length field. If present, both the address and length must
740              * be valid.
741              */
742             if ((Address64->Address && !Length) ||
743                 (!Address64->Address && Length))
744             {
745                 ACPI_BIOS_WARNING ((AE_INFO,
746                     "Optional FADT field %s has zero address or length: "
747                     "0x%8.8X%8.8X/0x%X",
748                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
749             }
750         }
751     }
752 }
753
754
755 /*******************************************************************************
756  *
757  * FUNCTION:    AcpiTbSetupFadtRegisters
758  *
759  * PARAMETERS:  None, uses AcpiGbl_FADT.
760  *
761  * RETURN:      None
762  *
763  * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
764  *              force FADT register definitions to their default lengths.
765  *
766  ******************************************************************************/
767
768 static void
769 AcpiTbSetupFadtRegisters (
770     void)
771 {
772     ACPI_GENERIC_ADDRESS    *Target64;
773     ACPI_GENERIC_ADDRESS    *Source64;
774     UINT8                   Pm1RegisterByteWidth;
775     UINT32                  i;
776
777
778     /*
779      * Optionally check all register lengths against the default values and
780      * update them if they are incorrect.
781      */
782     if (AcpiGbl_UseDefaultRegisterWidths)
783     {
784         for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
785         {
786             Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
787                 FadtInfoTable[i].Address64);
788
789             /*
790              * If a valid register (Address != 0) and the (DefaultLength > 0)
791              * (Not a GPE register), then check the width against the default.
792              */
793             if ((Target64->Address) &&
794                 (FadtInfoTable[i].DefaultLength > 0) &&
795                 (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
796             {
797                 ACPI_BIOS_WARNING ((AE_INFO,
798                     "Invalid length for FADT/%s: %u, using default %u",
799                     FadtInfoTable[i].Name, Target64->BitWidth,
800                     FadtInfoTable[i].DefaultLength));
801
802                 /* Incorrect size, set width to the default */
803
804                 Target64->BitWidth = FadtInfoTable[i].DefaultLength;
805             }
806         }
807     }
808
809     /*
810      * Get the length of the individual PM1 registers (enable and status).
811      * Each register is defined to be (event block length / 2). Extra divide
812      * by 8 converts bits to bytes.
813      */
814     Pm1RegisterByteWidth = (UINT8)
815         ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
816
817     /*
818      * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
819      * registers. These addresses do not appear (directly) in the FADT, so it
820      * is useful to pre-calculate them from the PM1 Event Block definitions.
821      *
822      * The PM event blocks are split into two register blocks, first is the
823      * PM Status Register block, followed immediately by the PM Enable
824      * Register block. Each is of length (Pm1EventLength/2)
825      *
826      * Note: The PM1A event block is required by the ACPI specification.
827      * However, the PM1B event block is optional and is rarely, if ever,
828      * used.
829      */
830
831     for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
832     {
833         Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
834             FadtPmInfoTable[i].Source);
835
836         if (Source64->Address)
837         {
838             AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
839                 Source64->SpaceId, Pm1RegisterByteWidth,
840                 Source64->Address +
841                     (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
842                 "PmRegisters", 0);
843         }
844     }
845 }