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