x86/acpi: Add ACPI table revision function
Use a single function to set ACPI table versions. This allows us to keep revisions synced to the correct levels for coreboot. This is a partial fix for the bug: FAILED [MEDIUM] SPECMADTFADTRevisions: Test 2, MADT revision is not in sync with the FADT revision; MADT 1 expects FADT 3.0 but found 4.0 instead. BUG=b:112476331 TEST-Run FWTS Change-Id: Ie9a486380e72b1754677c3cdf8190e3ceff9412b Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/28276 Reviewed-by: Martin Roth <martinroth@google.com> Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
f2592f9bce
commit
93a51766aa
|
@ -218,7 +218,7 @@ void acpi_create_madt(acpi_madt_t *madt)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_madt_t);
|
header->length = sizeof(acpi_madt_t);
|
||||||
header->revision = 1; /* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
header->revision = get_acpi_table_revision(MADT);
|
||||||
|
|
||||||
madt->lapic_addr = LOCAL_APIC_ADDR;
|
madt->lapic_addr = LOCAL_APIC_ADDR;
|
||||||
madt->flags = 0x1; /* PCAT_COMPAT */
|
madt->flags = 0x1; /* PCAT_COMPAT */
|
||||||
|
@ -246,7 +246,7 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_mcfg_t);
|
header->length = sizeof(acpi_mcfg_t);
|
||||||
header->revision = 1;
|
header->revision = get_acpi_table_revision(MCFG);
|
||||||
|
|
||||||
current = acpi_fill_mcfg(current);
|
current = acpi_fill_mcfg(current);
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_tcpa_t);
|
header->length = sizeof(acpi_tcpa_t);
|
||||||
header->revision = 2;
|
header->revision = get_acpi_table_revision(TCPA);
|
||||||
|
|
||||||
tcpa->platform_class = 0;
|
tcpa->platform_class = 0;
|
||||||
tcpa->laml = tcpa_log_len;
|
tcpa->laml = tcpa_log_len;
|
||||||
|
@ -339,7 +339,7 @@ void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id)
|
||||||
memset((void *)ssdt, 0, sizeof(acpi_header_t));
|
memset((void *)ssdt, 0, sizeof(acpi_header_t));
|
||||||
|
|
||||||
memcpy(&ssdt->signature, "SSDT", 4);
|
memcpy(&ssdt->signature, "SSDT", 4);
|
||||||
ssdt->revision = 2; /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */
|
ssdt->revision = get_acpi_table_revision(SSDT);
|
||||||
memcpy(&ssdt->oem_id, OEM_ID, 6);
|
memcpy(&ssdt->oem_id, OEM_ID, 6);
|
||||||
memcpy(&ssdt->oem_table_id, oem_table_id, 8);
|
memcpy(&ssdt->oem_table_id, oem_table_id, 8);
|
||||||
ssdt->oem_revision = 42;
|
ssdt->oem_revision = 42;
|
||||||
|
@ -410,7 +410,7 @@ void acpi_create_srat(acpi_srat_t *srat,
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_srat_t);
|
header->length = sizeof(acpi_srat_t);
|
||||||
header->revision = 1; /* ACPI 1.0: N/A, 2.0: 1, 3.0: 2, 4.0: 3 */
|
header->revision = get_acpi_table_revision(SRAT);
|
||||||
|
|
||||||
srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */
|
srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_dmar_t);
|
header->length = sizeof(acpi_dmar_t);
|
||||||
header->revision = 1;
|
header->revision = get_acpi_table_revision(DMAR);
|
||||||
|
|
||||||
dmar->host_address_width = cpu_phys_address_size() - 1;
|
dmar->host_address_width = cpu_phys_address_size() - 1;
|
||||||
dmar->flags = flags;
|
dmar->flags = flags;
|
||||||
|
@ -569,7 +569,7 @@ void acpi_create_slit(acpi_slit_t *slit,
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_slit_t);
|
header->length = sizeof(acpi_slit_t);
|
||||||
header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */
|
header->revision = get_acpi_table_revision(SLIT);
|
||||||
|
|
||||||
current = acpi_fill_slit(current);
|
current = acpi_fill_slit(current);
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ void acpi_create_hpet(acpi_hpet_t *hpet)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_hpet_t);
|
header->length = sizeof(acpi_hpet_t);
|
||||||
header->revision = 1; /* Currently 1. Table added in ACPI 2.0. */
|
header->revision = get_acpi_table_revision(HPET);
|
||||||
|
|
||||||
/* Fill out HPET address. */
|
/* Fill out HPET address. */
|
||||||
addr->space_id = 0; /* Memory */
|
addr->space_id = 0; /* Memory */
|
||||||
|
@ -626,7 +626,7 @@ void acpi_create_vfct(struct device *device,
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(struct acpi_vfct);
|
header->length = sizeof(struct acpi_vfct);
|
||||||
header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */
|
header->revision = get_acpi_table_revision(VFCT);
|
||||||
|
|
||||||
current = acpi_fill_vfct(device, vfct, current);
|
current = acpi_fill_vfct(device, vfct, current);
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs,
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_ivrs_t);
|
header->length = sizeof(acpi_ivrs_t);
|
||||||
header->revision = IVRS_FORMAT_FIXED;
|
header->revision = get_acpi_table_revision(IVRS);
|
||||||
|
|
||||||
current = acpi_fill_ivrs(ivrs, current);
|
current = acpi_fill_ivrs(ivrs, current);
|
||||||
|
|
||||||
|
@ -696,7 +696,7 @@ void acpi_create_dbg2(acpi_dbg2_header_t *dbg2,
|
||||||
current = (uintptr_t)dbg2;
|
current = (uintptr_t)dbg2;
|
||||||
memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
|
memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
|
||||||
header = &(dbg2->header);
|
header = &(dbg2->header);
|
||||||
header->revision = 0;
|
header->revision = get_acpi_table_revision(DBG2);
|
||||||
memcpy(header->signature, "DBG2", 4);
|
memcpy(header->signature, "DBG2", 4);
|
||||||
memcpy(header->oem_id, OEM_ID, 6);
|
memcpy(header->oem_id, OEM_ID, 6);
|
||||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||||
|
@ -807,7 +807,7 @@ void acpi_create_facs(acpi_facs_t *facs)
|
||||||
facs->flags = 0;
|
facs->flags = 0;
|
||||||
facs->x_firmware_waking_vector_l = 0;
|
facs->x_firmware_waking_vector_l = 0;
|
||||||
facs->x_firmware_waking_vector_h = 0;
|
facs->x_firmware_waking_vector_h = 0;
|
||||||
facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */
|
facs->version = get_acpi_table_revision(FACS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
|
static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
|
||||||
|
@ -821,7 +821,7 @@ static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_rsdt_t);
|
header->length = sizeof(acpi_rsdt_t);
|
||||||
header->revision = 1; /* ACPI 1.0/2.0/3.0/4.0: 1 */
|
header->revision = get_acpi_table_revision(RSDT);
|
||||||
|
|
||||||
/* Entries are filled in later, we come with an empty set. */
|
/* Entries are filled in later, we come with an empty set. */
|
||||||
|
|
||||||
|
@ -840,7 +840,7 @@ static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id)
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
|
||||||
header->length = sizeof(acpi_xsdt_t);
|
header->length = sizeof(acpi_xsdt_t);
|
||||||
header->revision = 1; /* ACPI 1.0: N/A, 2.0/3.0/4.0: 1 */
|
header->revision = get_acpi_table_revision(XSDT);
|
||||||
|
|
||||||
/* Entries are filled in later, we come with an empty set. */
|
/* Entries are filled in later, we come with an empty set. */
|
||||||
|
|
||||||
|
@ -870,7 +870,7 @@ static void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt,
|
||||||
rsdp->revision = 0;
|
rsdp->revision = 0;
|
||||||
} else {
|
} else {
|
||||||
rsdp->xsdt_address = (u64)(uintptr_t)xsdt;
|
rsdp->xsdt_address = (u64)(uintptr_t)xsdt;
|
||||||
rsdp->revision = 2;
|
rsdp->revision = get_acpi_table_revision(RSDP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate checksums. */
|
/* Calculate checksums. */
|
||||||
|
@ -950,7 +950,7 @@ void acpi_write_hest(acpi_hest_t *hest,
|
||||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
header->length += sizeof(acpi_hest_t);
|
header->length += sizeof(acpi_hest_t);
|
||||||
header->revision = 1;
|
header->revision = get_acpi_table_revision(HEST);
|
||||||
|
|
||||||
acpi_fill_hest(hest);
|
acpi_fill_hest(hest);
|
||||||
|
|
||||||
|
@ -966,7 +966,7 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
|
||||||
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
|
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
|
||||||
memcpy(header->signature, "FACP", 4);
|
memcpy(header->signature, "FACP", 4);
|
||||||
header->length = sizeof(acpi_fadt_t);
|
header->length = sizeof(acpi_fadt_t);
|
||||||
header->revision = 4;
|
header->revision = get_acpi_table_revision(FADT);
|
||||||
memcpy(header->oem_id, OEM_ID, 6);
|
memcpy(header->oem_id, OEM_ID, 6);
|
||||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||||
|
@ -1256,3 +1256,48 @@ __weak int acpi_get_gpe(int gpe)
|
||||||
{
|
{
|
||||||
return -1; /* implemented by SOC */
|
return -1; /* implemented by SOC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_acpi_table_revision(enum acpi_tables table)
|
||||||
|
{
|
||||||
|
switch (table) {
|
||||||
|
case FADT:
|
||||||
|
return ACPI_FADT_REV_ACPI_3_0;
|
||||||
|
case MADT: /* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
||||||
|
return 1;
|
||||||
|
case MCFG:
|
||||||
|
return 1;
|
||||||
|
case TCPA:
|
||||||
|
return 2;
|
||||||
|
case SSDT: /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */
|
||||||
|
return 2;
|
||||||
|
case SRAT: /* ACPI 1.0: N/A, 2.0: 1, 3.0: 2, 4.0: 3 */
|
||||||
|
return 1; /* TODO Should probably be upgraded to 2 */
|
||||||
|
case DMAR:
|
||||||
|
return 1;
|
||||||
|
case SLIT: /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */
|
||||||
|
return 1;
|
||||||
|
case HPET: /* Currently 1. Table added in ACPI 2.0. */
|
||||||
|
return 1;
|
||||||
|
case VFCT: /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */
|
||||||
|
return 1;
|
||||||
|
case IVRS:
|
||||||
|
return IVRS_FORMAT_FIXED;
|
||||||
|
case DBG2:
|
||||||
|
return 0;
|
||||||
|
case FACS: /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */
|
||||||
|
return 1;
|
||||||
|
case RSDT: /* ACPI 1.0/2.0/3.0/4.0: 1 */
|
||||||
|
return 1;
|
||||||
|
case XSDT: /* ACPI 1.0: N/A, 2.0/3.0/4.0: 1 */
|
||||||
|
return 1;
|
||||||
|
case RSDP: /* ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2. */
|
||||||
|
return 2;
|
||||||
|
case HEST:
|
||||||
|
return 1;
|
||||||
|
case NHLT:
|
||||||
|
return 5;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,18 @@ enum coreboot_acpi_ids {
|
||||||
COREBOOT_ACPI_ID_MAX = 0xFFFF, /* BOOTFFFF */
|
COREBOOT_ACPI_ID_MAX = 0xFFFF, /* BOOTFFFF */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Table 5-30 DESCRIPTION_HEADER Signatures for tables defined by ACPI 6.2a
|
||||||
|
* Additional tables mssing in 5-30: MADT, RSDP, VFCT, NHLT
|
||||||
|
*/
|
||||||
|
enum acpi_tables {
|
||||||
|
APIC, BERT, BGRT, CPEP, DSDT, ECDT, EINJ, ERST, FACP, FADT, FACS,
|
||||||
|
FPDT, GTDT, HEST, MSCT, MPST, NFIT, OEMX, PCCT, PMTT, PSDT, RASF,
|
||||||
|
RSDT, SBST, SDEV, SLIT, SRAT, SSDT, XSDT, BOOT, CSRT, DBG2, DBGP,
|
||||||
|
DMAR, DPPT, DRTM, ETDT, HPET, IBFT, IORT, IVRS, LPIT, MCFG, MCHI,
|
||||||
|
MSDM, SDEI, SLIC, SPCR, SPMI, STAO, TCPA, TPM2, WAET, WDAT, WDRT,
|
||||||
|
WPBT, WSMT, XENV, MADT, RSDP, VFCT, NHLT
|
||||||
|
};
|
||||||
|
|
||||||
/* RSDP (Root System Description Pointer) */
|
/* RSDP (Root System Description Pointer) */
|
||||||
typedef struct acpi_rsdp {
|
typedef struct acpi_rsdp {
|
||||||
char signature[8]; /* RSDP signature */
|
char signature[8]; /* RSDP signature */
|
||||||
|
@ -845,6 +857,12 @@ static inline uintptr_t acpi_align_current(uintptr_t current)
|
||||||
return ALIGN(current, 16);
|
return ALIGN(current, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ACPI table revisions should match the revision of the ACPI spec
|
||||||
|
* supported. This function keeps the table versions synced. This could
|
||||||
|
* be made into a weak function if there is ever a need to override the
|
||||||
|
* coreboot default ACPI spec version supported. */
|
||||||
|
int get_acpi_table_revision(enum acpi_tables table);
|
||||||
|
|
||||||
#endif // !defined(__ASSEMBLER__) && !defined(__ACPI__) && !defined(__ROMC__)
|
#endif // !defined(__ASSEMBLER__) && !defined(__ACPI__) && !defined(__ROMC__)
|
||||||
|
|
||||||
#endif /* __ASM_ACPI_H */
|
#endif /* __ASM_ACPI_H */
|
||||||
|
|
Loading…
Reference in New Issue