[V2][PATCH 2/2] acpi: acpitables: FADT: Ignore fields at offset 46 through 108 for HW_REDUCED_ACPI
Heyi Guo
heyi.guo at linaro.org
Tue Apr 7 05:44:39 UTC 2015
According to ACPI spec 5.1, section 5.2.9, "If the HW_REDUCED_ACPI flag in the table is set, OSPM will ignore fields related to the ACPI HW register interface: Fields at offsets 46 through 108 and 148 through 232, as well as FADT Flag bits 1, 2, 3,7,8,12,13, 14, 16 and 17).", add precondition of checking SMI_CMD, PM_TMR_LEN, etc. As the code becomes a little complex, split it into small functions for each important field check.
Signed-off-by: Heyi Guo <heyi.guo at linaro.org>
---
src/acpi/acpitables/acpitables.c | 90 +++++++++++++++++++++++++++++++---------
1 file changed, 70 insertions(+), 20 deletions(-)
diff --git a/src/acpi/acpitables/acpitables.c b/src/acpi/acpitables/acpitables.c
index e5fffff..52b6659 100644
--- a/src/acpi/acpitables/acpitables.c
+++ b/src/acpi/acpitables/acpitables.c
@@ -69,12 +69,10 @@ static void acpi_table_check_hpet(fwts_framework *fw, fwts_acpi_table_info *tabl
}
-static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *table)
+static void acpi_table_check_fadt_firmware_control(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
{
- fwts_acpi_table_fadt *fadt = (fwts_acpi_table_fadt*)table->data;
-
if (fadt->firmware_control == 0) {
- if (table->length >= 140) {
+ if (fadt->header.length >= 140) {
if ((fadt->x_firmware_ctrl == 0) && !(fwts_acpi_is_reduced_hardware(fadt))) {
fwts_failed(fw, LOG_LEVEL_CRITICAL, "FADTFACSZero", "FADT 32 bit FIRMWARE_CONTROL and 64 bit X_FIRMWARE_CONTROL (FACS address) are null.");
fwts_advice(fw, "The 32 bit FIRMWARE_CTRL or 64 bit X_FIRMWARE_CTRL should point to a valid "
@@ -88,7 +86,7 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
"bug and needs to be fixed.");
}
} else {
- if (table->length >= 140) {
+ if (fadt->header.length >= 140) {
if (fadt->x_firmware_ctrl != 0) {
if (((uint64_t)fadt->firmware_control != fadt->x_firmware_ctrl)) {
fwts_failed(fw, LOG_LEVEL_MEDIUM, "FwCtrl32and64Differ",
@@ -103,10 +101,14 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
}
}
}
+}
+static void acpi_table_check_fadt_dsdt(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
+{
if (fadt->dsdt == 0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTDSTNull", "FADT DSDT address is null.");
- if (table->length >= 148) {
+
+ if (fadt->header.length >= 148) {
if (fadt->x_dsdt == 0) {
fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTXDSTDNull", "FADT X_DSDT address is null.");
fwts_advice(fw, "An ACPI 2.0 FADT is being used however the 64 bit X_DSDT is null."
@@ -121,6 +123,16 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
"The kernel works around this by using the 64 bit X_DSDT pointer to the DSDT. ");
}
}
+}
+
+
+static void acpi_table_check_fadt_smi(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
+{
+ if (fwts_acpi_is_reduced_hardware(fadt)) {
+ if (fadt->smi_cmd != 0)
+ fwts_warning(fw, "FADT SMI_CMD is not zero but should be in reduced hardware mode.");
+ return;
+ }
/*
* Section 5.2.9 (Fixed ACPI Description Table) of the ACPI 5.0
@@ -153,6 +165,15 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
"specific functions will not work.");
}
}
+}
+
+static void acpi_table_check_fadt_pm_tmr(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
+{
+ if (fwts_acpi_is_reduced_hardware(fadt)) {
+ if (fadt->pm_tmr_len != 0)
+ fwts_warning(fw, "FADT PM_TMR_LEN is not zero but should be in reduced hardware mode.");
+ return;
+ }
if (fadt->pm_tmr_len != 4) {
fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTBadPMTMRLEN",
@@ -161,6 +182,18 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
"This fields value must be 4. If it is not the correct size then the kernel "
"will not request a region for the pm timer block. ");
}
+}
+
+static void acpi_table_check_fadt_gpe(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
+{
+ if (fwts_acpi_is_reduced_hardware(fadt)) {
+ if (fadt->gpe0_blk_len != 0)
+ fwts_warning(fw, "FADT GPE0_BLK_LEN is not zero but should be in reduced hardware mode.");
+ if (fadt->gpe1_blk_len != 0)
+ fwts_warning(fw, "FADT GPE1_BLK_LEN is not zero but should be in reduced hardware mode.");
+ return;
+ }
+
if (fadt->gpe0_blk_len & 1) {
fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTBadGPEBLKLEN", "FADT GPE0_BLK_LEN is %" PRIu8
", should a multiple of 2.", fadt->gpe0_blk_len);
@@ -175,6 +208,36 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
"not map in the GPE1 region. This could mean that General Purpose Events will not "
"function correctly (for example lid or ac-power events).");
}
+}
+
+static void acpi_table_check_fadt_reset(fwts_framework *fw, fwts_acpi_table_fadt *fadt)
+{
+ if (fadt->header.length>=129) {
+ if ((fadt->reset_reg.address_space_id != 0) &&
+ (fadt->reset_reg.address_space_id != 1) &&
+ (fadt->reset_reg.address_space_id != 2)) {
+ fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTBadRESETREG",
+ "FADT RESET_REG address space ID was %" PRIu8 ", must be System Memory space (0), "
+ "System I/O space (1), or PCI configuration space (2).",
+ fadt->reset_reg.address_space_id);
+ fwts_advice(fw, "If the FADT RESET_REG address space ID is not set correctly then ACPI writes "
+ "to this register *may* nor work correctly, meaning a reboot via this mechanism may not work.");
+ }
+ if ((fadt->reset_value == 0) && (fadt->reset_reg.address != 0))
+ fwts_warning(fw, "FADT RESET_VALUE is zero, which may be incorrect, it is usually non-zero.");
+ }
+}
+
+static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *table)
+{
+ fwts_acpi_table_fadt *fadt = (fwts_acpi_table_fadt*)table->data;
+
+ acpi_table_check_fadt_firmware_control(fw, fadt);
+ acpi_table_check_fadt_dsdt(fw, fadt);
+ acpi_table_check_fadt_smi(fw, fadt);
+ acpi_table_check_fadt_pm_tmr(fw, fadt);
+ acpi_table_check_fadt_gpe(fw, fadt);
+
/*
* Bug LP: /833644
*
@@ -208,20 +271,7 @@ static void acpi_table_check_fadt(fwts_framework *fw, fwts_acpi_table_info *tabl
fwts_warning(fw, "FADT CENTURY is zero, RTC does not support centenary feature is not supported.");
*/
- if (table->length>=129) {
- if ((fadt->reset_reg.address_space_id != 0) &&
- (fadt->reset_reg.address_space_id != 1) &&
- (fadt->reset_reg.address_space_id != 2)) {
- fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTBadRESETREG",
- "FADT RESET_REG address space ID was %" PRIu8 ", must be System Memory space (0), "
- "System I/O space (1), or PCI configuration space (2).",
- fadt->reset_reg.address_space_id);
- fwts_advice(fw, "If the FADT RESET_REG address space ID is not set correctly then ACPI writes "
- "to this register *may* nor work correctly, meaning a reboot via this mechanism may not work.");
- }
- if ((fadt->reset_value == 0) && (fadt->reset_reg.address != 0))
- fwts_warning(fw, "FADT RESET_VALUE is zero, which may be incorrect, it is usually non-zero.");
- }
+ acpi_table_check_fadt_reset(fw, fadt);
}
static void acpi_table_check_rsdp(fwts_framework *fw, fwts_acpi_table_info *table)
--
2.1.4
More information about the fwts-devel
mailing list