1db2bae30SDana Myers /******************************************************************************
2db2bae30SDana Myers *
3db2bae30SDana Myers * Module Name: tbfadt - FADT table utilities
4db2bae30SDana Myers *
5db2bae30SDana Myers *****************************************************************************/
6db2bae30SDana Myers
726f3cdf0SGordon Ross /*
8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
9db2bae30SDana Myers * All rights reserved.
10db2bae30SDana Myers *
1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross * are met:
1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross * without modification.
1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross * binary redistribution.
2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross * from this software without specific prior written permission.
25db2bae30SDana Myers *
2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross * Software Foundation.
29db2bae30SDana Myers *
3026f3cdf0SGordon Ross * NO WARRANTY
3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross */
43db2bae30SDana Myers
44db2bae30SDana Myers #include "acpi.h"
45aa2aa9a6SDana Myers #include "accommon.h"
46db2bae30SDana Myers #include "actables.h"
47db2bae30SDana Myers
48db2bae30SDana Myers #define _COMPONENT ACPI_TABLES
49db2bae30SDana Myers ACPI_MODULE_NAME ("tbfadt")
50db2bae30SDana Myers
51db2bae30SDana Myers /* Local prototypes */
52db2bae30SDana Myers
53*385cc6b4SJerry Jelinek static void
54db2bae30SDana Myers AcpiTbInitGenericAddress (
55db2bae30SDana Myers ACPI_GENERIC_ADDRESS *GenericAddress,
56aa2aa9a6SDana Myers UINT8 SpaceId,
57aa2aa9a6SDana Myers UINT8 ByteWidth,
58*385cc6b4SJerry Jelinek UINT64 Address,
59*385cc6b4SJerry Jelinek const char *RegisterName,
60*385cc6b4SJerry Jelinek UINT8 Flags);
61db2bae30SDana Myers
62db2bae30SDana Myers static void
63db2bae30SDana Myers AcpiTbConvertFadt (
64db2bae30SDana Myers void);
65db2bae30SDana Myers
66db2bae30SDana Myers static void
67aa2aa9a6SDana Myers AcpiTbSetupFadtRegisters (
68aa2aa9a6SDana Myers void);
69aa2aa9a6SDana Myers
70*385cc6b4SJerry Jelinek static UINT64
71*385cc6b4SJerry Jelinek AcpiTbSelectAddress (
72*385cc6b4SJerry Jelinek char *RegisterName,
73*385cc6b4SJerry Jelinek UINT32 Address32,
74*385cc6b4SJerry Jelinek UINT64 Address64);
75*385cc6b4SJerry Jelinek
76db2bae30SDana Myers
77db2bae30SDana Myers /* Table for conversion of FADT to common internal format and FADT validation */
78db2bae30SDana Myers
79db2bae30SDana Myers typedef struct acpi_fadt_info
80db2bae30SDana Myers {
81*385cc6b4SJerry Jelinek const char *Name;
82*385cc6b4SJerry Jelinek UINT16 Address64;
83*385cc6b4SJerry Jelinek UINT16 Address32;
84*385cc6b4SJerry Jelinek UINT16 Length;
85aa2aa9a6SDana Myers UINT8 DefaultLength;
86*385cc6b4SJerry Jelinek UINT8 Flags;
87db2bae30SDana Myers
88db2bae30SDana Myers } ACPI_FADT_INFO;
89db2bae30SDana Myers
90*385cc6b4SJerry Jelinek #define ACPI_FADT_OPTIONAL 0
91db2bae30SDana Myers #define ACPI_FADT_REQUIRED 1
92db2bae30SDana Myers #define ACPI_FADT_SEPARATE_LENGTH 2
93*385cc6b4SJerry Jelinek #define ACPI_FADT_GPE_REGISTER 4
94db2bae30SDana Myers
95db2bae30SDana Myers static ACPI_FADT_INFO FadtInfoTable[] =
96db2bae30SDana Myers {
97aa2aa9a6SDana Myers {"Pm1aEventBlock",
98aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1aEventBlock),
99db2bae30SDana Myers ACPI_FADT_OFFSET (Pm1aEventBlock),
100aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Pm1EventLength),
101aa2aa9a6SDana Myers ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
102aa2aa9a6SDana Myers ACPI_FADT_REQUIRED},
103db2bae30SDana Myers
104aa2aa9a6SDana Myers {"Pm1bEventBlock",
105aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1bEventBlock),
106db2bae30SDana Myers ACPI_FADT_OFFSET (Pm1bEventBlock),
107aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Pm1EventLength),
108aa2aa9a6SDana Myers ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
109*385cc6b4SJerry Jelinek ACPI_FADT_OPTIONAL},
110db2bae30SDana Myers
111aa2aa9a6SDana Myers {"Pm1aControlBlock",
112aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1aControlBlock),
113db2bae30SDana Myers ACPI_FADT_OFFSET (Pm1aControlBlock),
114aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Pm1ControlLength),
115aa2aa9a6SDana Myers ACPI_PM1_REGISTER_WIDTH,
116aa2aa9a6SDana Myers ACPI_FADT_REQUIRED},
117db2bae30SDana Myers
118aa2aa9a6SDana Myers {"Pm1bControlBlock",
119aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1bControlBlock),
120db2bae30SDana Myers ACPI_FADT_OFFSET (Pm1bControlBlock),
121aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Pm1ControlLength),
122aa2aa9a6SDana Myers ACPI_PM1_REGISTER_WIDTH,
123*385cc6b4SJerry Jelinek ACPI_FADT_OPTIONAL},
124db2bae30SDana Myers
125aa2aa9a6SDana Myers {"Pm2ControlBlock",
126aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm2ControlBlock),
127db2bae30SDana Myers ACPI_FADT_OFFSET (Pm2ControlBlock),
128aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Pm2ControlLength),
129aa2aa9a6SDana Myers ACPI_PM2_REGISTER_WIDTH,
130aa2aa9a6SDana Myers ACPI_FADT_SEPARATE_LENGTH},
131db2bae30SDana Myers
132aa2aa9a6SDana Myers {"PmTimerBlock",
133aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPmTimerBlock),
134db2bae30SDana Myers ACPI_FADT_OFFSET (PmTimerBlock),
135aa2aa9a6SDana Myers ACPI_FADT_OFFSET (PmTimerLength),
136aa2aa9a6SDana Myers ACPI_PM_TIMER_WIDTH,
137*385cc6b4SJerry Jelinek ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */
138db2bae30SDana Myers
139aa2aa9a6SDana Myers {"Gpe0Block",
140aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XGpe0Block),
141db2bae30SDana Myers ACPI_FADT_OFFSET (Gpe0Block),
142aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Gpe0BlockLength),
143aa2aa9a6SDana Myers 0,
144*385cc6b4SJerry Jelinek ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
145db2bae30SDana Myers
146aa2aa9a6SDana Myers {"Gpe1Block",
147aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XGpe1Block),
148db2bae30SDana Myers ACPI_FADT_OFFSET (Gpe1Block),
149aa2aa9a6SDana Myers ACPI_FADT_OFFSET (Gpe1BlockLength),
150aa2aa9a6SDana Myers 0,
151*385cc6b4SJerry Jelinek ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
152db2bae30SDana Myers };
153db2bae30SDana Myers
154aa2aa9a6SDana Myers #define ACPI_FADT_INFO_ENTRIES \
155aa2aa9a6SDana Myers (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
156aa2aa9a6SDana Myers
157aa2aa9a6SDana Myers
158aa2aa9a6SDana Myers /* Table used to split Event Blocks into separate status/enable registers */
159aa2aa9a6SDana Myers
160aa2aa9a6SDana Myers typedef struct acpi_fadt_pm_info
161aa2aa9a6SDana Myers {
162aa2aa9a6SDana Myers ACPI_GENERIC_ADDRESS *Target;
163*385cc6b4SJerry Jelinek UINT16 Source;
164aa2aa9a6SDana Myers UINT8 RegisterNum;
165aa2aa9a6SDana Myers
166aa2aa9a6SDana Myers } ACPI_FADT_PM_INFO;
167aa2aa9a6SDana Myers
168aa2aa9a6SDana Myers static ACPI_FADT_PM_INFO FadtPmInfoTable[] =
169aa2aa9a6SDana Myers {
170aa2aa9a6SDana Myers {&AcpiGbl_XPm1aStatus,
171aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1aEventBlock),
172aa2aa9a6SDana Myers 0},
173aa2aa9a6SDana Myers
174aa2aa9a6SDana Myers {&AcpiGbl_XPm1aEnable,
175aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1aEventBlock),
176aa2aa9a6SDana Myers 1},
177aa2aa9a6SDana Myers
178aa2aa9a6SDana Myers {&AcpiGbl_XPm1bStatus,
179aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1bEventBlock),
180aa2aa9a6SDana Myers 0},
181aa2aa9a6SDana Myers
182aa2aa9a6SDana Myers {&AcpiGbl_XPm1bEnable,
183aa2aa9a6SDana Myers ACPI_FADT_OFFSET (XPm1bEventBlock),
184aa2aa9a6SDana Myers 1}
185aa2aa9a6SDana Myers };
186aa2aa9a6SDana Myers
187aa2aa9a6SDana Myers #define ACPI_FADT_PM_INFO_ENTRIES \
188aa2aa9a6SDana Myers (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
189db2bae30SDana Myers
190db2bae30SDana Myers
191db2bae30SDana Myers /*******************************************************************************
192db2bae30SDana Myers *
193db2bae30SDana Myers * FUNCTION: AcpiTbInitGenericAddress
194db2bae30SDana Myers *
195db2bae30SDana Myers * PARAMETERS: GenericAddress - GAS struct to be initialized
196aa2aa9a6SDana Myers * SpaceId - ACPI Space ID for this register
197*385cc6b4SJerry Jelinek * ByteWidth - Width of this register
198db2bae30SDana Myers * Address - Address of the register
199*385cc6b4SJerry Jelinek * RegisterName - ASCII name of the ACPI register
200db2bae30SDana Myers *
201db2bae30SDana Myers * RETURN: None
202db2bae30SDana Myers *
203db2bae30SDana Myers * DESCRIPTION: Initialize a Generic Address Structure (GAS)
204db2bae30SDana Myers * See the ACPI specification for a full description and
205db2bae30SDana Myers * definition of this structure.
206db2bae30SDana Myers *
207db2bae30SDana Myers ******************************************************************************/
208db2bae30SDana Myers
209*385cc6b4SJerry Jelinek static void
AcpiTbInitGenericAddress(ACPI_GENERIC_ADDRESS * GenericAddress,UINT8 SpaceId,UINT8 ByteWidth,UINT64 Address,const char * RegisterName,UINT8 Flags)210db2bae30SDana Myers AcpiTbInitGenericAddress (
211db2bae30SDana Myers ACPI_GENERIC_ADDRESS *GenericAddress,
212aa2aa9a6SDana Myers UINT8 SpaceId,
213aa2aa9a6SDana Myers UINT8 ByteWidth,
214*385cc6b4SJerry Jelinek UINT64 Address,
215*385cc6b4SJerry Jelinek const char *RegisterName,
216*385cc6b4SJerry Jelinek UINT8 Flags)
217db2bae30SDana Myers {
218*385cc6b4SJerry Jelinek UINT8 BitWidth;
219*385cc6b4SJerry Jelinek
220*385cc6b4SJerry Jelinek
221*385cc6b4SJerry Jelinek /*
222*385cc6b4SJerry Jelinek * Bit width field in the GAS is only one byte long, 255 max.
223*385cc6b4SJerry Jelinek * Check for BitWidth overflow in GAS.
224*385cc6b4SJerry Jelinek */
225*385cc6b4SJerry Jelinek BitWidth = (UINT8) (ByteWidth * 8);
226*385cc6b4SJerry Jelinek if (ByteWidth > 31) /* (31*8)=248, (32*8)=256 */
227*385cc6b4SJerry Jelinek {
228*385cc6b4SJerry Jelinek /*
229*385cc6b4SJerry Jelinek * No error for GPE blocks, because we do not use the BitWidth
230*385cc6b4SJerry Jelinek * for GPEs, the legacy length (ByteWidth) is used instead to
231*385cc6b4SJerry Jelinek * allow for a large number of GPEs.
232*385cc6b4SJerry Jelinek */
233*385cc6b4SJerry Jelinek if (!(Flags & ACPI_FADT_GPE_REGISTER))
234*385cc6b4SJerry Jelinek {
235*385cc6b4SJerry Jelinek ACPI_ERROR ((AE_INFO,
236*385cc6b4SJerry Jelinek "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
237*385cc6b4SJerry Jelinek "to convert to GAS struct - 255 bits max, truncating",
238*385cc6b4SJerry Jelinek RegisterName, ByteWidth, (ByteWidth * 8)));
239*385cc6b4SJerry Jelinek }
240*385cc6b4SJerry Jelinek
241*385cc6b4SJerry Jelinek BitWidth = 255;
242*385cc6b4SJerry Jelinek }
243db2bae30SDana Myers
244db2bae30SDana Myers /*
245db2bae30SDana Myers * The 64-bit Address field is non-aligned in the byte packed
246db2bae30SDana Myers * GAS struct.
247db2bae30SDana Myers */
248db2bae30SDana Myers ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
249db2bae30SDana Myers
250db2bae30SDana Myers /* All other fields are byte-wide */
251db2bae30SDana Myers
252aa2aa9a6SDana Myers GenericAddress->SpaceId = SpaceId;
253*385cc6b4SJerry Jelinek GenericAddress->BitWidth = BitWidth;
254db2bae30SDana Myers GenericAddress->BitOffset = 0;
255aa2aa9a6SDana Myers GenericAddress->AccessWidth = 0; /* Access width ANY */
256db2bae30SDana Myers }
257db2bae30SDana Myers
258db2bae30SDana Myers
259db2bae30SDana Myers /*******************************************************************************
260db2bae30SDana Myers *
261*385cc6b4SJerry Jelinek * FUNCTION: AcpiTbSelectAddress
262*385cc6b4SJerry Jelinek *
263*385cc6b4SJerry Jelinek * PARAMETERS: RegisterName - ASCII name of the ACPI register
264*385cc6b4SJerry Jelinek * Address32 - 32-bit address of the register
265*385cc6b4SJerry Jelinek * Address64 - 64-bit address of the register
266*385cc6b4SJerry Jelinek *
267*385cc6b4SJerry Jelinek * RETURN: The resolved 64-bit address
268*385cc6b4SJerry Jelinek *
269*385cc6b4SJerry Jelinek * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
270*385cc6b4SJerry Jelinek * the FADT. Used for the FACS and DSDT addresses.
271*385cc6b4SJerry Jelinek *
272*385cc6b4SJerry Jelinek * NOTES:
273*385cc6b4SJerry Jelinek *
274*385cc6b4SJerry Jelinek * Check for FACS and DSDT address mismatches. An address mismatch between
275*385cc6b4SJerry Jelinek * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
276*385cc6b4SJerry Jelinek * DSDT/X_DSDT) could be a corrupted address field or it might indicate
277*385cc6b4SJerry Jelinek * the presence of two FACS or two DSDT tables.
278*385cc6b4SJerry Jelinek *
279*385cc6b4SJerry Jelinek * November 2013:
280*385cc6b4SJerry Jelinek * By default, as per the ACPICA specification, a valid 64-bit address is
281*385cc6b4SJerry Jelinek * used regardless of the value of the 32-bit address. However, this
282*385cc6b4SJerry Jelinek * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.
283*385cc6b4SJerry Jelinek *
284*385cc6b4SJerry Jelinek ******************************************************************************/
285*385cc6b4SJerry Jelinek
286*385cc6b4SJerry Jelinek static UINT64
AcpiTbSelectAddress(char * RegisterName,UINT32 Address32,UINT64 Address64)287*385cc6b4SJerry Jelinek AcpiTbSelectAddress (
288*385cc6b4SJerry Jelinek char *RegisterName,
289*385cc6b4SJerry Jelinek UINT32 Address32,
290*385cc6b4SJerry Jelinek UINT64 Address64)
291*385cc6b4SJerry Jelinek {
292*385cc6b4SJerry Jelinek
293*385cc6b4SJerry Jelinek if (!Address64)
294*385cc6b4SJerry Jelinek {
295*385cc6b4SJerry Jelinek /* 64-bit address is zero, use 32-bit address */
296*385cc6b4SJerry Jelinek
297*385cc6b4SJerry Jelinek return ((UINT64) Address32);
298*385cc6b4SJerry Jelinek }
299*385cc6b4SJerry Jelinek
300*385cc6b4SJerry Jelinek if (Address32 &&
301*385cc6b4SJerry Jelinek (Address64 != (UINT64) Address32))
302*385cc6b4SJerry Jelinek {
303*385cc6b4SJerry Jelinek /* Address mismatch between 32-bit and 64-bit versions */
304*385cc6b4SJerry Jelinek
305*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
306*385cc6b4SJerry Jelinek "32/64X %s address mismatch in FADT: "
307*385cc6b4SJerry Jelinek "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
308*385cc6b4SJerry Jelinek RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),
309*385cc6b4SJerry Jelinek AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
310*385cc6b4SJerry Jelinek
311*385cc6b4SJerry Jelinek /* 32-bit address override */
312*385cc6b4SJerry Jelinek
313*385cc6b4SJerry Jelinek if (AcpiGbl_Use32BitFadtAddresses)
314*385cc6b4SJerry Jelinek {
315*385cc6b4SJerry Jelinek return ((UINT64) Address32);
316*385cc6b4SJerry Jelinek }
317*385cc6b4SJerry Jelinek }
318*385cc6b4SJerry Jelinek
319*385cc6b4SJerry Jelinek /* Default is to use the 64-bit address */
320*385cc6b4SJerry Jelinek
321*385cc6b4SJerry Jelinek return (Address64);
322*385cc6b4SJerry Jelinek }
323*385cc6b4SJerry Jelinek
324*385cc6b4SJerry Jelinek
325*385cc6b4SJerry Jelinek /*******************************************************************************
326*385cc6b4SJerry Jelinek *
327db2bae30SDana Myers * FUNCTION: AcpiTbParseFadt
328db2bae30SDana Myers *
329*385cc6b4SJerry Jelinek * PARAMETERS: None
330db2bae30SDana Myers *
331db2bae30SDana Myers * RETURN: None
332db2bae30SDana Myers *
333db2bae30SDana Myers * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
334db2bae30SDana Myers * (FADT contains the addresses of the DSDT and FACS)
335db2bae30SDana Myers *
336db2bae30SDana Myers ******************************************************************************/
337db2bae30SDana Myers
338db2bae30SDana Myers void
AcpiTbParseFadt(void)339db2bae30SDana Myers AcpiTbParseFadt (
340*385cc6b4SJerry Jelinek void)
341db2bae30SDana Myers {
342db2bae30SDana Myers UINT32 Length;
343db2bae30SDana Myers ACPI_TABLE_HEADER *Table;
344db2bae30SDana Myers
345db2bae30SDana Myers
346db2bae30SDana Myers /*
347db2bae30SDana Myers * The FADT has multiple versions with different lengths,
348db2bae30SDana Myers * and it contains pointers to both the DSDT and FACS tables.
349db2bae30SDana Myers *
350db2bae30SDana Myers * Get a local copy of the FADT and convert it to a common format
351db2bae30SDana Myers * Map entire FADT, assumed to be smaller than one page.
352db2bae30SDana Myers */
353*385cc6b4SJerry Jelinek Length = AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Length;
354db2bae30SDana Myers
355db2bae30SDana Myers Table = AcpiOsMapMemory (
356*385cc6b4SJerry Jelinek AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Address, Length);
357db2bae30SDana Myers if (!Table)
358db2bae30SDana Myers {
359db2bae30SDana Myers return;
360db2bae30SDana Myers }
361db2bae30SDana Myers
362db2bae30SDana Myers /*
363db2bae30SDana Myers * Validate the FADT checksum before we copy the table. Ignore
364db2bae30SDana Myers * checksum error as we want to try to get the DSDT and FACS.
365db2bae30SDana Myers */
366db2bae30SDana Myers (void) AcpiTbVerifyChecksum (Table, Length);
367db2bae30SDana Myers
368aa2aa9a6SDana Myers /* Create a local copy of the FADT in common ACPI 2.0+ format */
369db2bae30SDana Myers
370db2bae30SDana Myers AcpiTbCreateLocalFadt (Table, Length);
371db2bae30SDana Myers
372db2bae30SDana Myers /* All done with the real FADT, unmap it */
373db2bae30SDana Myers
374db2bae30SDana Myers AcpiOsUnmapMemory (Table, Length);
375db2bae30SDana Myers
376db2bae30SDana Myers /* Obtain the DSDT and FACS tables via their addresses within the FADT */
377db2bae30SDana Myers
378*385cc6b4SJerry Jelinek AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
379*385cc6b4SJerry Jelinek ACPI_SIG_DSDT, &AcpiGbl_DsdtIndex);
380db2bae30SDana Myers
381*385cc6b4SJerry Jelinek /* If Hardware Reduced flag is set, there is no FACS */
382*385cc6b4SJerry Jelinek
383*385cc6b4SJerry Jelinek if (!AcpiGbl_ReducedHardware)
384*385cc6b4SJerry Jelinek {
385*385cc6b4SJerry Jelinek if (AcpiGbl_FADT.Facs)
386*385cc6b4SJerry Jelinek {
387*385cc6b4SJerry Jelinek AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,
388*385cc6b4SJerry Jelinek ACPI_SIG_FACS, &AcpiGbl_FacsIndex);
389*385cc6b4SJerry Jelinek }
390*385cc6b4SJerry Jelinek if (AcpiGbl_FADT.XFacs)
391*385cc6b4SJerry Jelinek {
392*385cc6b4SJerry Jelinek AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
393*385cc6b4SJerry Jelinek ACPI_SIG_FACS, &AcpiGbl_XFacsIndex);
394*385cc6b4SJerry Jelinek }
395*385cc6b4SJerry Jelinek }
396db2bae30SDana Myers }
397db2bae30SDana Myers
398db2bae30SDana Myers
399db2bae30SDana Myers /*******************************************************************************
400db2bae30SDana Myers *
401db2bae30SDana Myers * FUNCTION: AcpiTbCreateLocalFadt
402db2bae30SDana Myers *
403db2bae30SDana Myers * PARAMETERS: Table - Pointer to BIOS FADT
404db2bae30SDana Myers * Length - Length of the table
405db2bae30SDana Myers *
406db2bae30SDana Myers * RETURN: None
407db2bae30SDana Myers *
408db2bae30SDana Myers * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
409db2bae30SDana Myers * Performs validation on some important FADT fields.
410db2bae30SDana Myers *
411db2bae30SDana Myers * NOTE: We create a local copy of the FADT regardless of the version.
412db2bae30SDana Myers *
413db2bae30SDana Myers ******************************************************************************/
414db2bae30SDana Myers
415db2bae30SDana Myers void
AcpiTbCreateLocalFadt(ACPI_TABLE_HEADER * Table,UINT32 Length)416db2bae30SDana Myers AcpiTbCreateLocalFadt (
417db2bae30SDana Myers ACPI_TABLE_HEADER *Table,
418db2bae30SDana Myers UINT32 Length)
419db2bae30SDana Myers {
420db2bae30SDana Myers
421db2bae30SDana Myers /*
422db2bae30SDana Myers * Check if the FADT is larger than the largest table that we expect
423*385cc6b4SJerry Jelinek * (typically the current ACPI specification version). If so, truncate
424*385cc6b4SJerry Jelinek * the table, and issue a warning.
425db2bae30SDana Myers */
426db2bae30SDana Myers if (Length > sizeof (ACPI_TABLE_FADT))
427db2bae30SDana Myers {
428*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
429*385cc6b4SJerry Jelinek "FADT (revision %u) is longer than %s length, "
43026f3cdf0SGordon Ross "truncating length %u to %u",
431*385cc6b4SJerry Jelinek Table->Revision, ACPI_FADT_CONFORMANCE, Length,
432*385cc6b4SJerry Jelinek (UINT32) sizeof (ACPI_TABLE_FADT)));
433db2bae30SDana Myers }
434db2bae30SDana Myers
435db2bae30SDana Myers /* Clear the entire local FADT */
436db2bae30SDana Myers
437*385cc6b4SJerry Jelinek memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
438db2bae30SDana Myers
439db2bae30SDana Myers /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
440db2bae30SDana Myers
441*385cc6b4SJerry Jelinek memcpy (&AcpiGbl_FADT, Table,
442db2bae30SDana Myers ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
443db2bae30SDana Myers
444*385cc6b4SJerry Jelinek /* Take a copy of the Hardware Reduced flag */
445*385cc6b4SJerry Jelinek
446*385cc6b4SJerry Jelinek AcpiGbl_ReducedHardware = FALSE;
447*385cc6b4SJerry Jelinek if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
448*385cc6b4SJerry Jelinek {
449*385cc6b4SJerry Jelinek AcpiGbl_ReducedHardware = TRUE;
450*385cc6b4SJerry Jelinek }
451*385cc6b4SJerry Jelinek
452aa2aa9a6SDana Myers /* Convert the local copy of the FADT to the common internal format */
453aa2aa9a6SDana Myers
454db2bae30SDana Myers AcpiTbConvertFadt ();
455aa2aa9a6SDana Myers
456aa2aa9a6SDana Myers /* Initialize the global ACPI register structures */
457aa2aa9a6SDana Myers
458aa2aa9a6SDana Myers AcpiTbSetupFadtRegisters ();
459db2bae30SDana Myers }
460db2bae30SDana Myers
461db2bae30SDana Myers
462db2bae30SDana Myers /*******************************************************************************
463db2bae30SDana Myers *
464db2bae30SDana Myers * FUNCTION: AcpiTbConvertFadt
465db2bae30SDana Myers *
466*385cc6b4SJerry Jelinek * PARAMETERS: None - AcpiGbl_FADT is used.
467db2bae30SDana Myers *
468db2bae30SDana Myers * RETURN: None
469db2bae30SDana Myers *
470db2bae30SDana Myers * DESCRIPTION: Converts all versions of the FADT to a common internal format.
471*385cc6b4SJerry Jelinek * Expand 32-bit addresses to 64-bit as necessary. Also validate
472*385cc6b4SJerry Jelinek * important fields within the FADT.
473db2bae30SDana Myers *
474*385cc6b4SJerry Jelinek * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
475*385cc6b4SJerry Jelinek * contain a copy of the actual BIOS-provided FADT.
476db2bae30SDana Myers *
477aa2aa9a6SDana Myers * Notes on 64-bit register addresses:
478db2bae30SDana Myers *
479aa2aa9a6SDana Myers * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
480aa2aa9a6SDana Myers * fields of the FADT for all ACPI register addresses.
481db2bae30SDana Myers *
482*385cc6b4SJerry Jelinek * The 64-bit X fields are optional extensions to the original 32-bit FADT
483aa2aa9a6SDana Myers * V1.0 fields. Even if they are present in the FADT, they are optional and
484aa2aa9a6SDana Myers * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
485*385cc6b4SJerry Jelinek * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
486*385cc6b4SJerry Jelinek * originally zero.
487db2bae30SDana Myers *
488*385cc6b4SJerry Jelinek * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
489*385cc6b4SJerry Jelinek * fields are expanded to the corresponding 64-bit X fields in the internal
490*385cc6b4SJerry Jelinek * common FADT.
491aa2aa9a6SDana Myers *
492aa2aa9a6SDana Myers * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
493*385cc6b4SJerry Jelinek * to the corresponding 64-bit X fields, if the 64-bit field is originally
494*385cc6b4SJerry Jelinek * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
495*385cc6b4SJerry Jelinek * field if the 64-bit field is valid, regardless of whether the host OS is
496*385cc6b4SJerry Jelinek * 32-bit or 64-bit.
497*385cc6b4SJerry Jelinek *
498*385cc6b4SJerry Jelinek * Possible additional checks:
499*385cc6b4SJerry Jelinek * (AcpiGbl_FADT.Pm1EventLength >= 4)
500*385cc6b4SJerry Jelinek * (AcpiGbl_FADT.Pm1ControlLength >= 2)
501*385cc6b4SJerry Jelinek * (AcpiGbl_FADT.PmTimerLength >= 4)
502*385cc6b4SJerry Jelinek * Gpe block lengths must be multiple of 2
503db2bae30SDana Myers *
504db2bae30SDana Myers ******************************************************************************/
505db2bae30SDana Myers
506db2bae30SDana Myers static void
AcpiTbConvertFadt(void)507db2bae30SDana Myers AcpiTbConvertFadt (
508db2bae30SDana Myers void)
509db2bae30SDana Myers {
510*385cc6b4SJerry Jelinek const char *Name;
511aa2aa9a6SDana Myers ACPI_GENERIC_ADDRESS *Address64;
512aa2aa9a6SDana Myers UINT32 Address32;
513*385cc6b4SJerry Jelinek UINT8 Length;
514*385cc6b4SJerry Jelinek UINT8 Flags;
515db2bae30SDana Myers UINT32 i;
516db2bae30SDana Myers
517db2bae30SDana Myers
518db2bae30SDana Myers /*
519db2bae30SDana Myers * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
520db2bae30SDana Myers * should be zero are indeed zero. This will workaround BIOSs that
521db2bae30SDana Myers * inadvertently place values in these fields.
522db2bae30SDana Myers *
523aa2aa9a6SDana Myers * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
524aa2aa9a6SDana Myers * at offset 45, 55, 95, and the word located at offset 109, 110.
52526f3cdf0SGordon Ross *
52626f3cdf0SGordon Ross * Note: The FADT revision value is unreliable. Only the length can be
52726f3cdf0SGordon Ross * trusted.
528db2bae30SDana Myers */
52926f3cdf0SGordon Ross if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
530db2bae30SDana Myers {
531db2bae30SDana Myers AcpiGbl_FADT.PreferredProfile = 0;
532db2bae30SDana Myers AcpiGbl_FADT.PstateControl = 0;
533db2bae30SDana Myers AcpiGbl_FADT.CstControl = 0;
534db2bae30SDana Myers AcpiGbl_FADT.BootFlags = 0;
535db2bae30SDana Myers }
536db2bae30SDana Myers
537db2bae30SDana Myers /*
538*385cc6b4SJerry Jelinek * Now we can update the local FADT length to the length of the
539*385cc6b4SJerry Jelinek * current FADT version as defined by the ACPI specification.
540*385cc6b4SJerry Jelinek * Thus, we will have a common FADT internally.
541db2bae30SDana Myers */
542*385cc6b4SJerry Jelinek AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
543db2bae30SDana Myers
544db2bae30SDana Myers /*
545*385cc6b4SJerry Jelinek * Expand the 32-bit DSDT addresses to 64-bit as necessary.
546*385cc6b4SJerry Jelinek * Later ACPICA code will always use the X 64-bit field.
547db2bae30SDana Myers */
548*385cc6b4SJerry Jelinek AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
549*385cc6b4SJerry Jelinek AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
550*385cc6b4SJerry Jelinek
551*385cc6b4SJerry Jelinek /* If Hardware Reduced flag is set, we are all done */
552*385cc6b4SJerry Jelinek
553*385cc6b4SJerry Jelinek if (AcpiGbl_ReducedHardware)
554db2bae30SDana Myers {
555*385cc6b4SJerry Jelinek return;
556aa2aa9a6SDana Myers }
557aa2aa9a6SDana Myers
558db2bae30SDana Myers /* Examine all of the 64-bit extended address fields (X fields) */
559db2bae30SDana Myers
560db2bae30SDana Myers for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
561db2bae30SDana Myers {
562aa2aa9a6SDana Myers /*
563*385cc6b4SJerry Jelinek * Get the 32-bit and 64-bit addresses, as well as the register
564*385cc6b4SJerry Jelinek * length and register name.
565aa2aa9a6SDana Myers */
566*385cc6b4SJerry Jelinek Address32 = *ACPI_ADD_PTR (UINT32,
567*385cc6b4SJerry Jelinek &AcpiGbl_FADT, FadtInfoTable[i].Address32);
568*385cc6b4SJerry Jelinek
569aa2aa9a6SDana Myers Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
570aa2aa9a6SDana Myers &AcpiGbl_FADT, FadtInfoTable[i].Address64);
571*385cc6b4SJerry Jelinek
572aa2aa9a6SDana Myers Length = *ACPI_ADD_PTR (UINT8,
573aa2aa9a6SDana Myers &AcpiGbl_FADT, FadtInfoTable[i].Length);
574*385cc6b4SJerry Jelinek
575aa2aa9a6SDana Myers Name = FadtInfoTable[i].Name;
576*385cc6b4SJerry Jelinek Flags = FadtInfoTable[i].Flags;
577*385cc6b4SJerry Jelinek
578*385cc6b4SJerry Jelinek /*
579*385cc6b4SJerry Jelinek * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
580*385cc6b4SJerry Jelinek * generic address structures as necessary. Later code will always use
581*385cc6b4SJerry Jelinek * the 64-bit address structures.
582*385cc6b4SJerry Jelinek *
583*385cc6b4SJerry Jelinek * November 2013:
584*385cc6b4SJerry Jelinek * Now always use the 64-bit address if it is valid (non-zero), in
585*385cc6b4SJerry Jelinek * accordance with the ACPI specification which states that a 64-bit
586*385cc6b4SJerry Jelinek * address supersedes the 32-bit version. This behavior can be
587*385cc6b4SJerry Jelinek * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
588*385cc6b4SJerry Jelinek *
589*385cc6b4SJerry Jelinek * During 64-bit address construction and verification,
590*385cc6b4SJerry Jelinek * these cases are handled:
591*385cc6b4SJerry Jelinek *
592*385cc6b4SJerry Jelinek * Address32 zero, Address64 [don't care] - Use Address64
593*385cc6b4SJerry Jelinek *
594*385cc6b4SJerry Jelinek * Address32 non-zero, Address64 zero - Copy/use Address32
595*385cc6b4SJerry Jelinek * Address32 non-zero == Address64 non-zero - Use Address64
596*385cc6b4SJerry Jelinek * Address32 non-zero != Address64 non-zero - Warning, use Address64
597*385cc6b4SJerry Jelinek *
598*385cc6b4SJerry Jelinek * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
599*385cc6b4SJerry Jelinek * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
600*385cc6b4SJerry Jelinek *
601*385cc6b4SJerry Jelinek * Note: SpaceId is always I/O for 32-bit legacy address fields
602*385cc6b4SJerry Jelinek */
603*385cc6b4SJerry Jelinek if (Address32)
604*385cc6b4SJerry Jelinek {
605*385cc6b4SJerry Jelinek if (!Address64->Address)
606*385cc6b4SJerry Jelinek {
607*385cc6b4SJerry Jelinek /* 64-bit address is zero, use 32-bit address */
608*385cc6b4SJerry Jelinek
609*385cc6b4SJerry Jelinek AcpiTbInitGenericAddress (Address64,
610*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_SYSTEM_IO,
611*385cc6b4SJerry Jelinek *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
612*385cc6b4SJerry Jelinek FadtInfoTable[i].Length),
613*385cc6b4SJerry Jelinek (UINT64) Address32, Name, Flags);
614*385cc6b4SJerry Jelinek }
615*385cc6b4SJerry Jelinek else if (Address64->Address != (UINT64) Address32)
616*385cc6b4SJerry Jelinek {
617*385cc6b4SJerry Jelinek /* Address mismatch */
618*385cc6b4SJerry Jelinek
619*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
620*385cc6b4SJerry Jelinek "32/64X address mismatch in FADT/%s: "
621*385cc6b4SJerry Jelinek "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
622*385cc6b4SJerry Jelinek Name, Address32,
623*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (Address64->Address),
624*385cc6b4SJerry Jelinek AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
625*385cc6b4SJerry Jelinek
626*385cc6b4SJerry Jelinek if (AcpiGbl_Use32BitFadtAddresses)
627*385cc6b4SJerry Jelinek {
628*385cc6b4SJerry Jelinek /* 32-bit address override */
629*385cc6b4SJerry Jelinek
630*385cc6b4SJerry Jelinek AcpiTbInitGenericAddress (Address64,
631*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_SYSTEM_IO,
632*385cc6b4SJerry Jelinek *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
633*385cc6b4SJerry Jelinek FadtInfoTable[i].Length),
634*385cc6b4SJerry Jelinek (UINT64) Address32, Name, Flags);
635*385cc6b4SJerry Jelinek }
636*385cc6b4SJerry Jelinek }
637*385cc6b4SJerry Jelinek }
638db2bae30SDana Myers
639aa2aa9a6SDana Myers /*
640aa2aa9a6SDana Myers * For each extended field, check for length mismatch between the
641aa2aa9a6SDana Myers * legacy length field and the corresponding 64-bit X length field.
642*385cc6b4SJerry Jelinek * Note: If the legacy length field is > 0xFF bits, ignore this
643*385cc6b4SJerry Jelinek * check. (GPE registers can be larger than the 64-bit GAS structure
644*385cc6b4SJerry Jelinek * can accomodate, 0xFF bits).
645aa2aa9a6SDana Myers */
646aa2aa9a6SDana Myers if (Address64->Address &&
647*385cc6b4SJerry Jelinek (ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
648aa2aa9a6SDana Myers (Address64->BitWidth != ACPI_MUL_8 (Length)))
649aa2aa9a6SDana Myers {
650*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
651*385cc6b4SJerry Jelinek "32/64X length mismatch in FADT/%s: %u/%u",
652aa2aa9a6SDana Myers Name, ACPI_MUL_8 (Length), Address64->BitWidth));
653aa2aa9a6SDana Myers }
654db2bae30SDana Myers
655*385cc6b4SJerry Jelinek if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
656db2bae30SDana Myers {
657db2bae30SDana Myers /*
658*385cc6b4SJerry Jelinek * Field is required (PM1aEvent, PM1aControl).
659db2bae30SDana Myers * Both the address and length must be non-zero.
660db2bae30SDana Myers */
661db2bae30SDana Myers if (!Address64->Address || !Length)
662db2bae30SDana Myers {
663*385cc6b4SJerry Jelinek ACPI_BIOS_ERROR ((AE_INFO,
664*385cc6b4SJerry Jelinek "Required FADT field %s has zero address and/or length: "
66526f3cdf0SGordon Ross "0x%8.8X%8.8X/0x%X",
666aa2aa9a6SDana Myers Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
667db2bae30SDana Myers }
668db2bae30SDana Myers }
669*385cc6b4SJerry Jelinek else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
670db2bae30SDana Myers {
671db2bae30SDana Myers /*
672db2bae30SDana Myers * Field is optional (PM2Control, GPE0, GPE1) AND has its own
673aa2aa9a6SDana Myers * length field. If present, both the address and length must
674aa2aa9a6SDana Myers * be valid.
675db2bae30SDana Myers */
676aa2aa9a6SDana Myers if ((Address64->Address && !Length) ||
677aa2aa9a6SDana Myers (!Address64->Address && Length))
678db2bae30SDana Myers {
679*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
680*385cc6b4SJerry Jelinek "Optional FADT field %s has valid %s but zero %s: "
681*385cc6b4SJerry Jelinek "0x%8.8X%8.8X/0x%X", Name,
682*385cc6b4SJerry Jelinek (Length ? "Length" : "Address"),
683*385cc6b4SJerry Jelinek (Length ? "Address": "Length"),
684*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (Address64->Address), Length));
685aa2aa9a6SDana Myers }
686aa2aa9a6SDana Myers }
687db2bae30SDana Myers }
688db2bae30SDana Myers }
689db2bae30SDana Myers
690db2bae30SDana Myers
691aa2aa9a6SDana Myers /*******************************************************************************
692aa2aa9a6SDana Myers *
693aa2aa9a6SDana Myers * FUNCTION: AcpiTbSetupFadtRegisters
694aa2aa9a6SDana Myers *
695aa2aa9a6SDana Myers * PARAMETERS: None, uses AcpiGbl_FADT.
696aa2aa9a6SDana Myers *
697aa2aa9a6SDana Myers * RETURN: None
698aa2aa9a6SDana Myers *
699aa2aa9a6SDana Myers * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
700aa2aa9a6SDana Myers * force FADT register definitions to their default lengths.
701aa2aa9a6SDana Myers *
702aa2aa9a6SDana Myers ******************************************************************************/
703aa2aa9a6SDana Myers
704aa2aa9a6SDana Myers static void
AcpiTbSetupFadtRegisters(void)705aa2aa9a6SDana Myers AcpiTbSetupFadtRegisters (
706aa2aa9a6SDana Myers void)
707db2bae30SDana Myers {
708aa2aa9a6SDana Myers ACPI_GENERIC_ADDRESS *Target64;
709aa2aa9a6SDana Myers ACPI_GENERIC_ADDRESS *Source64;
710aa2aa9a6SDana Myers UINT8 Pm1RegisterByteWidth;
711aa2aa9a6SDana Myers UINT32 i;
712aa2aa9a6SDana Myers
713aa2aa9a6SDana Myers
714aa2aa9a6SDana Myers /*
715aa2aa9a6SDana Myers * Optionally check all register lengths against the default values and
716aa2aa9a6SDana Myers * update them if they are incorrect.
717aa2aa9a6SDana Myers */
718aa2aa9a6SDana Myers if (AcpiGbl_UseDefaultRegisterWidths)
719aa2aa9a6SDana Myers {
720aa2aa9a6SDana Myers for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
721aa2aa9a6SDana Myers {
722aa2aa9a6SDana Myers Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
723aa2aa9a6SDana Myers FadtInfoTable[i].Address64);
724aa2aa9a6SDana Myers
725aa2aa9a6SDana Myers /*
726aa2aa9a6SDana Myers * If a valid register (Address != 0) and the (DefaultLength > 0)
727aa2aa9a6SDana Myers * (Not a GPE register), then check the width against the default.
728aa2aa9a6SDana Myers */
729aa2aa9a6SDana Myers if ((Target64->Address) &&
730aa2aa9a6SDana Myers (FadtInfoTable[i].DefaultLength > 0) &&
731aa2aa9a6SDana Myers (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
732aa2aa9a6SDana Myers {
733*385cc6b4SJerry Jelinek ACPI_BIOS_WARNING ((AE_INFO,
734*385cc6b4SJerry Jelinek "Invalid length for FADT/%s: %u, using default %u",
735aa2aa9a6SDana Myers FadtInfoTable[i].Name, Target64->BitWidth,
736aa2aa9a6SDana Myers FadtInfoTable[i].DefaultLength));
737aa2aa9a6SDana Myers
738aa2aa9a6SDana Myers /* Incorrect size, set width to the default */
739aa2aa9a6SDana Myers
740aa2aa9a6SDana Myers Target64->BitWidth = FadtInfoTable[i].DefaultLength;
741aa2aa9a6SDana Myers }
742aa2aa9a6SDana Myers }
743aa2aa9a6SDana Myers }
744aa2aa9a6SDana Myers
745aa2aa9a6SDana Myers /*
746aa2aa9a6SDana Myers * Get the length of the individual PM1 registers (enable and status).
747aa2aa9a6SDana Myers * Each register is defined to be (event block length / 2). Extra divide
748aa2aa9a6SDana Myers * by 8 converts bits to bytes.
749aa2aa9a6SDana Myers */
750aa2aa9a6SDana Myers Pm1RegisterByteWidth = (UINT8)
751aa2aa9a6SDana Myers ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
752aa2aa9a6SDana Myers
753aa2aa9a6SDana Myers /*
754aa2aa9a6SDana Myers * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
755aa2aa9a6SDana Myers * registers. These addresses do not appear (directly) in the FADT, so it
756aa2aa9a6SDana Myers * is useful to pre-calculate them from the PM1 Event Block definitions.
757aa2aa9a6SDana Myers *
758aa2aa9a6SDana Myers * The PM event blocks are split into two register blocks, first is the
759aa2aa9a6SDana Myers * PM Status Register block, followed immediately by the PM Enable
760aa2aa9a6SDana Myers * Register block. Each is of length (Pm1EventLength/2)
761aa2aa9a6SDana Myers *
762aa2aa9a6SDana Myers * Note: The PM1A event block is required by the ACPI specification.
763aa2aa9a6SDana Myers * However, the PM1B event block is optional and is rarely, if ever,
764aa2aa9a6SDana Myers * used.
765aa2aa9a6SDana Myers */
766aa2aa9a6SDana Myers
767aa2aa9a6SDana Myers for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
768aa2aa9a6SDana Myers {
769aa2aa9a6SDana Myers Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
770aa2aa9a6SDana Myers FadtPmInfoTable[i].Source);
771aa2aa9a6SDana Myers
772aa2aa9a6SDana Myers if (Source64->Address)
773aa2aa9a6SDana Myers {
774aa2aa9a6SDana Myers AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
775aa2aa9a6SDana Myers Source64->SpaceId, Pm1RegisterByteWidth,
776aa2aa9a6SDana Myers Source64->Address +
777*385cc6b4SJerry Jelinek (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
778*385cc6b4SJerry Jelinek "PmRegisters", 0);
779db2bae30SDana Myers }
780db2bae30SDana Myers }
781db2bae30SDana Myers }
782