diff options
Diffstat (limited to 'source/components/tables/tbfadt.c')
-rw-r--r-- | source/components/tables/tbfadt.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c index 789161d..22c09d2 100644 --- a/source/components/tables/tbfadt.c +++ b/source/components/tables/tbfadt.c @@ -58,7 +58,8 @@ AcpiTbInitGenericAddress ( UINT8 SpaceId, UINT8 ByteWidth, UINT64 Address, - char *RegisterName); + char *RegisterName, + UINT8 Flags); static void AcpiTbConvertFadt ( @@ -84,13 +85,14 @@ typedef struct acpi_fadt_info UINT16 Address32; UINT16 Length; UINT8 DefaultLength; - UINT8 Type; + UINT8 Flags; } ACPI_FADT_INFO; #define ACPI_FADT_OPTIONAL 0 #define ACPI_FADT_REQUIRED 1 #define ACPI_FADT_SEPARATE_LENGTH 2 +#define ACPI_FADT_GPE_REGISTER 4 static ACPI_FADT_INFO FadtInfoTable[] = { @@ -141,14 +143,14 @@ static ACPI_FADT_INFO FadtInfoTable[] = ACPI_FADT_OFFSET (Gpe0Block), ACPI_FADT_OFFSET (Gpe0BlockLength), 0, - ACPI_FADT_SEPARATE_LENGTH}, + ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}, {"Gpe1Block", ACPI_FADT_OFFSET (XGpe1Block), ACPI_FADT_OFFSET (Gpe1Block), ACPI_FADT_OFFSET (Gpe1BlockLength), 0, - ACPI_FADT_SEPARATE_LENGTH} + ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER} }; #define ACPI_FADT_INFO_ENTRIES \ @@ -212,21 +214,31 @@ AcpiTbInitGenericAddress ( UINT8 SpaceId, UINT8 ByteWidth, UINT64 Address, - char *RegisterName) + char *RegisterName, + UINT8 Flags) { UINT8 BitWidth; - /* Bit width field in the GAS is only one byte long, 255 max */ - + /* + * Bit width field in the GAS is only one byte long, 255 max. + * Check for BitWidth overflow in GAS. + */ BitWidth = (UINT8) (ByteWidth * 8); - - if (ByteWidth > 31) /* (31*8)=248 */ + if (ByteWidth > 31) /* (31*8)=248, (32*8)=256 */ { - ACPI_ERROR ((AE_INFO, - "%s - 32-bit FADT register is too long (%u bytes, %u bits) " - "to convert to GAS struct - 255 bits max, truncating", - RegisterName, ByteWidth, (ByteWidth * 8))); + /* + * No error for GPE blocks, because we do not use the BitWidth + * for GPEs, the legacy length (ByteWidth) is used instead to + * allow for a large number of GPEs. + */ + if (!(Flags & ACPI_FADT_GPE_REGISTER)) + { + ACPI_ERROR ((AE_INFO, + "%s - 32-bit FADT register is too long (%u bytes, %u bits) " + "to convert to GAS struct - 255 bits max, truncating", + RegisterName, ByteWidth, (ByteWidth * 8))); + } BitWidth = 255; } @@ -492,6 +504,7 @@ AcpiTbConvertFadt ( ACPI_GENERIC_ADDRESS *Address64; UINT32 Address32; UINT8 Length; + UINT8 Flags; UINT32 i; @@ -556,6 +569,7 @@ AcpiTbConvertFadt ( &AcpiGbl_FADT, FadtInfoTable[i].Length); Name = FadtInfoTable[i].Name; + Flags = FadtInfoTable[i].Flags; /* * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" @@ -592,7 +606,7 @@ AcpiTbConvertFadt ( ACPI_ADR_SPACE_SYSTEM_IO, *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length), - (UINT64) Address32, Name); + (UINT64) Address32, Name, Flags); } else if (Address64->Address != (UINT64) Address32) { @@ -613,7 +627,7 @@ AcpiTbConvertFadt ( ACPI_ADR_SPACE_SYSTEM_IO, *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length), - (UINT64) Address32, Name); + (UINT64) Address32, Name, Flags); } } } @@ -634,7 +648,7 @@ AcpiTbConvertFadt ( Name, ACPI_MUL_8 (Length), Address64->BitWidth)); } - if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED) + if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED) { /* * Field is required (PM1aEvent, PM1aControl). @@ -648,7 +662,7 @@ AcpiTbConvertFadt ( Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); } } - else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH) + else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH) { /* * Field is optional (PM2Control, GPE0, GPE1) AND has its own @@ -755,7 +769,7 @@ AcpiTbSetupFadtRegisters ( Source64->SpaceId, Pm1RegisterByteWidth, Source64->Address + (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth), - "PmRegisters"); + "PmRegisters", 0); } } } |