ACK: [PATCH v2 10/23] FADT: expand compliance checks for DSDT and X_DSDT fields
Alex Hung
alex.hung at canonical.com
Tue Feb 23 09:02:41 UTC 2016
On 02/20/2016 07:39 AM, Al Stone wrote:
> Expand the testing of the DSDT address -- and by extension, the
> X_DSDT address field -- to check for full compliance with the
> spec. Only one or the other may be used at any one time, per 6.1,
> but we also have to acknowledge there are tables that do use both
> the 32- and 64-bit values. At that point, we re-use parts of the
> existing test to verify that they are at least consistent.
>
> Signed-off-by: Al Stone <al.stone at linaro.org>
> ---
> src/acpi/fadt/fadt.c | 112 +++++++++++++++++++++++++++++++--------------------
> 1 file changed, 69 insertions(+), 43 deletions(-)
>
> diff --git a/src/acpi/fadt/fadt.c b/src/acpi/fadt/fadt.c
> index b9e50a4..4a39c01 100644
> --- a/src/acpi/fadt/fadt.c
> +++ b/src/acpi/fadt/fadt.c
> @@ -306,54 +306,80 @@ static void acpi_table_check_fadt_firmware_ctrl(fwts_framework *fw)
> }
> }
>
> -static void acpi_table_check_fadt_dsdt(
> - fwts_framework *fw,
> - const fwts_acpi_table_fadt *fadt,
> - bool *passed)
> +static void acpi_table_check_fadt_dsdt(fwts_framework *fw)
> {
> -
> + /* check out older FADTs */
> if (fadt->header.length < 148) {
> - if (fadt->dsdt == 0) {
> - *passed = false;
> + if (fadt->dsdt == 0)
> fwts_failed(fw, LOG_LEVEL_MEDIUM,
> "FADTDSDTNull",
> "FADT DSDT address is null.");
> - }
> - } else {
> - if (fadt->x_dsdt == 0) {
> - if (fadt->dsdt == 0) {
> - *passed = false;
> - fwts_failed(fw, LOG_LEVEL_MEDIUM,
> - "FADTXDSDTNull",
> - "FADT X_DSDT and DSDT address are null.");
> - } else {
> - *passed = false;
> - fwts_failed(fw, LOG_LEVEL_MEDIUM,
> - "FADTXDSDTNull",
> - "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."
> - "The kernel will fall back to using "
> - "the 32 bit DSDT pointer instead.");
> - }
> - } else if ((uint64_t)fadt->dsdt != fadt->x_dsdt && fadt->dsdt != 0) {
> - *passed = false;
> + }
> +
> + /* if one field is being used, the other should be null */
> + if ((fadt->dsdt != 0 && fadt->x_dsdt == 0) ||
> + (fadt->dsdt == 0 && fadt->x_dsdt != 0))
> + fwts_passed(fw,
> + "FADT has only one of X_DSDT or DSDT addresses "
> + "being used.");
> + else {
> + if (fadt->dsdt == 0 && fadt->x_dsdt == 0)
> fwts_failed(fw, LOG_LEVEL_MEDIUM,
> - "FADT32And64Mismatch",
> - "FADT 32 bit DSDT (0x%" PRIx32 ") "
> - "does not point to same "
> - "physical address as 64 bit X_DSDT "
> - "(0x%" PRIx64 ").",
> - fadt->dsdt, fadt->x_dsdt);
> - fwts_advice(fw,
> - "One would expect the 32 bit DSDT and "
> - "64 bit X_DSDT pointers to point to the "
> - "same DSDT, however they don't which is "
> - "clearly ambiguous and wrong. "
> - "The kernel works around this by using the "
> - "64 bit X_DSDT pointer to the DSDT. ");
> - }
> + "FADTOneDSDTNull",
> + "FADT X_DSDT and DSDT addresses cannot "
> + "both be null.");
> + }
> +
> + /* unexpected use of addresses */
> + if (fadt->dsdt != 0 && fadt->x_dsdt == 0) {
> + fwts_failed(fw, LOG_LEVEL_MEDIUM,
> + "FADTXDSDTNull",
> + "FADT X_DSDT address is null.");
> + fwts_advice(fw,
> + "An ACPI 2.0 or newer FADT is being used but "
> + "the 64 bit X_DSDT is null. "
> + "The kernel will fall back to using "
> + "the 32 bit DSDT pointer instead.");
> + }
> +
> + /*
> + * If you are going to insist on using both fields, even though
> + * that is incorrect, at least make it unambiguous as to which
> + * address is the one to use, by using the same value in both
> + * fields.
> + */
> + if ((uint64_t)fadt->dsdt == fadt->x_dsdt && fadt->dsdt != 0) {
> + fwts_passed(fw,
> + "FADT 32 bit DSDT and 64 bit X_DSDT "
> + "both point to the same physical address "
> + "(0x%" PRIx64 ").", fadt->x_dsdt);
> + fwts_advice(fw,
> + "While it is not correct to use both of the "
> + "32- and 64-bit DSDT address fields in recent "
> + "versions of ACPI, they are at least the same "
> + "address, which keeps the kernel from getting "
> + "confused. At some point, the 32-bit DSDT "
> + "address may get ignored so it is recommended "
> + "that the FADT be upgraded to only use the 64-"
> + "bit X_DSDT field. In the meantime, however, "
> + "ACPI will still behave correctly.");
> + }
> + if ((uint64_t)fadt->dsdt != fadt->x_dsdt && fadt->dsdt != 0) {
> + fwts_failed(fw, LOG_LEVEL_MEDIUM,
> + "FADT32And64Mismatch",
> + "FADT 32 bit DSDT (0x%" PRIx32 ") "
> + "does not point to same "
> + "physical address as 64 bit X_DSDT "
> + "(0x%" PRIx64 ").",
> + fadt->dsdt, fadt->x_dsdt);
> + fwts_advice(fw,
> + "One would expect the 32 bit DSDT and "
> + "64 bit X_DSDT pointers to point to the "
> + "same DSDT, however they don't which is "
> + "clearly ambiguous and wrong. "
> + "The kernel works around this by assuming the "
> + "64 bit X_DSDT pointer to the DSDT is the correct "
> + "one to use.");
> }
> }
>
> @@ -542,7 +568,7 @@ static int fadt_test1(fwts_framework *fw)
> bool passed = true;
>
> acpi_table_check_fadt_firmware_ctrl(fw);
> - acpi_table_check_fadt_dsdt(fw, fadt, &passed);
> + acpi_table_check_fadt_dsdt(fw);
> acpi_table_check_fadt_smi(fw, fadt, &passed);
> acpi_table_check_fadt_pm_tmr(fw, fadt, &passed);
> acpi_table_check_fadt_gpe(fw, fadt, &passed);
>
Acked-by: Alex Hung <alex.hung at canonical.com>
More information about the fwts-devel
mailing list