[PATCH] ACPI: Add new ACPI 5.1 MADT stuctures and checks (LP: #1348581)
Colin King
colin.king at canonical.com
Fri Jul 25 11:05:41 UTC 2014
From: Colin Ian King <colin.king at canonical.com>
ACPI 5.1 sections 5.2.12.14 to 5.2.12.17 describe new MADT
structures, so add these structures to fwts and update the acpidump
and acpitables tests accordingly.
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
src/acpi/acpidump/acpidump.c | 65 ++++++++++++++++++++--------
src/acpi/acpitables/acpitables.c | 93 +++++++++++++++++++++++++++++++++-------
src/lib/include/fwts_acpi.h | 46 +++++++++++++++++++-
3 files changed, 169 insertions(+), 35 deletions(-)
diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
index ee148b0..15a4e5d 100644
--- a/src/acpi/acpidump/acpidump.c
+++ b/src/acpi/acpidump/acpidump.c
@@ -813,7 +813,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
offset += sizeof(fwts_acpi_madt_sub_table_header);
switch (hdr->type) {
- case 0: {
+ case FWTS_ACPI_MADT_LOCAL_APIC: {
static const fwts_acpidump_field fields_processor_local_apic[] = {
FIELD_UINT(" ACPI CPU ID", fwts_acpi_madt_processor_local_apic, acpi_processor_id),
FIELD_UINT(" APIC ID", fwts_acpi_madt_processor_local_apic, apic_id),
@@ -825,7 +825,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_processor_local_apic);
}
break;
- case 1: {
+ case FWTS_ACPI_MADT_IO_APIC: {
static const fwts_acpidump_field fields_io_apic[] = {
FIELD_UINT(" I/O APIC ID", fwts_acpi_madt_io_apic, io_apic_id),
FIELD_UINT(" I/O APIC Addr", fwts_acpi_madt_io_apic, io_apic_phys_address),
@@ -836,7 +836,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_io_apic);
}
break;
- case 2: {
+ case FWTS_ACPI_MADT_INTERRUPT_OVERRIDE: {
static const fwts_acpidump_field fields_madt_interrupt_override[] = {
FIELD_UINT(" Bus", fwts_acpi_madt_interrupt_override, bus),
FIELD_UINT(" Source", fwts_acpi_madt_interrupt_override, source),
@@ -850,7 +850,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_interrupt_override);
}
break;
- case 3: {
+ case FWTS_ACPI_MADT_NMI_SOURCE: {
static const fwts_acpidump_field fields_madt_nmi[] = {
FIELD_UINT(" Flags", fwts_acpi_madt_nmi, flags),
FIELD_UINT(" Gbl Sys Int", fwts_acpi_madt_nmi, gsi),
@@ -860,7 +860,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_nmi);
}
break;
- case 4: {
+ case FWTS_ACPI_MADT_LOCAL_APIC_NMI: {
static const fwts_acpidump_field fields_madt_local_apic_nmi[] = {
FIELD_UINT(" ACPI CPU ID", fwts_acpi_madt_local_apic_nmi, acpi_processor_id),
FIELD_UINT(" Flags", fwts_acpi_madt_local_apic_nmi, flags),
@@ -871,7 +871,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_local_apic_nmi);
}
break;
- case 5: {
+ case FWTS_ACPI_MADT_LOCAL_APIC_OVERRIDE: {
static const fwts_acpidump_field fields_madt_local_apic_addr_override[] = {
FIELD_UINT(" Local APIC Addr", fwts_acpi_madt_local_apic_addr_override, address),
FIELD_END
@@ -880,7 +880,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_local_apic_addr_override);
}
break;
- case 6: {
+ case FWTS_ACPI_MADT_IO_SAPIC: {
static const fwts_acpidump_field fields_madt_io_sapic[] = {
FIELD_UINT(" I/O SAPIC ID", fwts_acpi_madt_io_sapic, io_sapic_id),
FIELD_UINT(" Gbl Sys Int", fwts_acpi_madt_io_sapic, gsi),
@@ -891,7 +891,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
skip = sizeof(fwts_acpi_madt_io_sapic);
}
break;
- case 7: {
+ case FWTS_ACPI_MADT_LOCAL_SAPIC: {
fwts_acpi_madt_local_sapic *local_sapic = (fwts_acpi_madt_local_sapic *)data;
static const fwts_acpidump_field fields_madt_local_sapic[] = {
FIELD_UINT(" ACPI CPU ID", fwts_acpi_madt_local_sapic, acpi_processor_id),
@@ -907,7 +907,7 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
strlen(local_sapic->uid_string) + 1);
}
break;
- case 8: {
+ case FWTS_ACPI_MADT_INTERRUPT_SOURCE: {
static const fwts_acpidump_field fields_madt_local_sapic[] = {
FIELD_UINT(" Flags", fwts_acpi_madt_platform_int_source, flags),
FIELD_UINT(" Type", fwts_acpi_madt_platform_int_source, type),
@@ -919,10 +919,10 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
FIELD_END
};
__acpi_dump_table_fields(fw, data, fields_madt_local_sapic, offset);
- skip = (sizeof(fwts_acpi_madt_platform_int_source));
+ skip = sizeof(fwts_acpi_madt_platform_int_source);
}
break;
- case 9: {
+ case FWTS_ACPI_MADT_LOCAL_X2APIC: {
static const fwts_acpidump_field fields_madt_local_x2apic[] = {
FIELD_UINT(" x2APIC ID", fwts_acpi_madt_local_x2apic, x2apic_id),
FIELD_UINT(" Flags", fwts_acpi_madt_local_x2apic, flags),
@@ -930,10 +930,10 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
FIELD_END
};
__acpi_dump_table_fields(fw, data, fields_madt_local_x2apic, offset);
- skip = (sizeof(fwts_acpi_madt_local_x2apic));
+ skip = sizeof(fwts_acpi_madt_local_x2apic);
}
break;
- case 10: {
+ case FWTS_ACPI_MADT_LOCAL_X2APIC_NMI: {
static const fwts_acpidump_field fields_madt_local_x2apic_nmi[] = {
FIELD_UINT(" Flags", fwts_acpi_madt_local_x2apic_nmi, flags),
FIELD_UINT(" Processor UID", fwts_acpi_madt_local_x2apic_nmi, processor_uid),
@@ -941,10 +941,10 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
FIELD_END
};
__acpi_dump_table_fields(fw, data, fields_madt_local_x2apic_nmi, offset);
- skip = (sizeof(fwts_acpi_madt_local_x2apic_nmi));
+ skip = sizeof(fwts_acpi_madt_local_x2apic_nmi);
}
break;
- case 11: {
+ case FWTS_ACPI_MADT_GIC_C_CPU_INTERFACE: {
static const fwts_acpidump_field fields_madt_gic[] = {
FIELD_UINT(" Reserved", fwts_acpi_madt_gic, reserved),
FIELD_UINT(" GIC ID", fwts_acpi_madt_gic, gic_id),
@@ -954,12 +954,17 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
FIELD_UINT(" Perf. Int. GSIV", fwts_acpi_madt_gic, performance_interrupt_gsiv),
FIELD_UINT(" Parked Address", fwts_acpi_madt_gic, parked_address),
FIELD_UINT(" Phys. Base. Addr",fwts_acpi_madt_gic, physical_base_address),
+ FIELD_UINT(" GICV", fwts_acpi_madt_gic, gicv),
+ FIELD_UINT(" GICH", fwts_acpi_madt_gic, gich),
+ FIELD_UINT(" VGIC Interrupt", fwts_acpi_madt_gic, vgic),
+ FIELD_UINT(" GICR Base. Addr", fwts_acpi_madt_gic, gicr_base_address),
+ FIELD_UINT(" MPIDR", fwts_acpi_madt_gic, mpidr),
};
__acpi_dump_table_fields(fw, data, fields_madt_gic, offset);
- skip = (sizeof(fwts_acpi_madt_gic));
+ skip = sizeof(fwts_acpi_madt_gic);
}
break;
- case 12: {
+ case FWTS_ACPI_MADT_GIC_D_GOC_DISTRIBUTOR: {
static const fwts_acpidump_field fields_madt_gicd[] = {
FIELD_UINT(" Reserved", fwts_acpi_madt_gicd, reserved),
FIELD_UINT(" GIC ID", fwts_acpi_madt_gicd, gic_id),
@@ -968,7 +973,31 @@ static void acpidump_madt(fwts_framework *fw, const fwts_acpi_table_info *table)
FIELD_UINT(" Reserved", fwts_acpi_madt_gicd, reserved2),
};
__acpi_dump_table_fields(fw, data, fields_madt_gicd, offset);
- skip = (sizeof(fwts_acpi_madt_gicd));
+ skip = sizeof(fwts_acpi_madt_gicd);
+ }
+ break;
+ case FWTS_ACPI_MADT_GIC_V2M_MSI_FRAME: {
+ static const fwts_acpidump_field fields_madt_gic_msi[] = {
+ FIELD_UINT(" Reserved", fwts_acpi_madt_gic_msi, reserved),
+ FIELD_UINT(" Frame ID", fwts_acpi_madt_gic_msi, frame_id),
+ FIELD_UINT(" Phys. Base. Addr",fwts_acpi_madt_gic_msi, physical_base_address),
+ FIELD_UINT(" Flags", fwts_acpi_madt_gic_msi, flags),
+ FIELD_UINT(" SPI Count", fwts_acpi_madt_gic_msi, spi_count),
+ FIELD_UINT(" SPI Base", fwts_acpi_madt_gic_msi, spi_base),
+ FIELD_UINT(" SPI Flags", fwts_acpi_madt_gic_msi, spi_flags),
+ };
+ __acpi_dump_table_fields(fw, data, fields_madt_gic_msi, offset);
+ skip = sizeof(fwts_acpi_madt_gic_msi);
+ }
+ break;
+ case FWTS_ACPI_MADT_GIC_R_REDISTRIBUTOR: {
+ static const fwts_acpidump_field fields_madt_gicr[] = {
+ FIELD_UINT(" Reserved", fwts_acpi_madt_gicr, reserved),
+ FIELD_UINT(" Disc. Base Addr", fwts_acpi_madt_gicr, discovery_range_base_address),
+ FIELD_UINT(" Disc. Range Len", fwts_acpi_madt_gicr, discovery_range_length),
+ };
+ __acpi_dump_table_fields(fw, data, fields_madt_gicr, offset);
+ skip = sizeof(fwts_acpi_madt_gicr);
}
break;
default:
diff --git a/src/acpi/acpitables/acpitables.c b/src/acpi/acpitables/acpitables.c
index 46cd3bf..255261c 100644
--- a/src/acpi/acpitables/acpitables.c
+++ b/src/acpi/acpitables/acpitables.c
@@ -309,10 +309,13 @@ static void acpi_table_check_xsdt(fwts_framework *fw, fwts_acpi_table_info *tabl
static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *table)
{
fwts_acpi_table_madt *madt = (fwts_acpi_table_madt*)table->data;
+ fwts_list msi_frame_ids;
const uint8_t *data = table->data;
size_t length = table->length;
int i = 0;
+ fwts_list_init(&msi_frame_ids);
+
if (madt->flags & 0xfffffffe)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTFlagsNonZero",
"MADT flags field, bits 1..31 are reserved and "
@@ -331,7 +334,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
length -= sizeof(fwts_acpi_madt_sub_table_header);
switch (hdr->type) {
- case 0: {
+ case FWTS_ACPI_MADT_LOCAL_APIC: {
fwts_acpi_madt_processor_local_apic *lapic = (fwts_acpi_madt_processor_local_apic *)data;
if (lapic->flags & 0xfffffffe)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTAPICFlagsNonZero",
@@ -341,7 +344,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = sizeof(fwts_acpi_madt_processor_local_apic);
}
break;
- case 1: {
+ case FWTS_ACPI_MADT_IO_APIC: {
fwts_acpi_madt_io_apic *ioapic = (fwts_acpi_madt_io_apic*)data;
if (ioapic->io_apic_phys_address == 0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTIOAPICAddrZero", "MADT IO APIC address is zero, appears not to be defined.");
@@ -352,7 +355,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = sizeof(fwts_acpi_madt_io_apic);
}
break;
- case 2: {
+ case FWTS_ACPI_MADT_INTERRUPT_OVERRIDE: {
fwts_acpi_madt_interrupt_override *int_override = (fwts_acpi_madt_interrupt_override*)data;
if (int_override->bus != 0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTIRQSrcISA", "MADT Interrupt Source Override Bus should be 0 for ISA bus.");
@@ -364,7 +367,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = sizeof(fwts_acpi_madt_interrupt_override);
}
break;
- case 3: {
+ case FWTS_ACPI_MADT_NMI_SOURCE: {
fwts_acpi_madt_nmi *nmi = (fwts_acpi_madt_nmi*)data;
if (nmi->flags & 0xfffffff0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTNMISrcFlags",
@@ -374,7 +377,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = sizeof(fwts_acpi_madt_nmi);
}
break;
- case 4: {
+ case FWTS_ACPI_MADT_LOCAL_APIC_NMI: {
fwts_acpi_madt_local_apic_nmi *nmi = (fwts_acpi_madt_local_apic_nmi*)data;
if (nmi->flags & 0xfffffff0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTLAPICNMIFlags",
@@ -384,22 +387,22 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = sizeof(fwts_acpi_madt_local_apic_nmi);
}
break;
- case 5:
+ case FWTS_ACPI_MADT_LOCAL_APIC_OVERRIDE:
skip = sizeof(fwts_acpi_madt_local_apic_addr_override);
break;
- case 6: {
+ case FWTS_ACPI_MADT_IO_SAPIC: {
fwts_acpi_madt_io_sapic *sapic = (fwts_acpi_madt_io_sapic*)data;
if (sapic->address == 0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADIOSPAICAddrZero", "MADT I/O SAPIC address is zero, appears not to be defined.");
skip = sizeof(fwts_acpi_madt_io_sapic);
}
break;
- case 7: {
+ case FWTS_ACPI_MADT_LOCAL_SAPIC: {
fwts_acpi_madt_local_sapic *local_sapic = (fwts_acpi_madt_local_sapic*)data;
skip = sizeof(fwts_acpi_madt_local_sapic) + strlen(local_sapic->uid_string) + 1;
}
break;
- case 8: {
+ case FWTS_ACPI_MADT_INTERRUPT_SOURCE: {
fwts_acpi_madt_platform_int_source *src = (fwts_acpi_madt_platform_int_source*)data;
if (src->flags & 0xfffffff0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTPlatIRQSrcFlags",
@@ -421,10 +424,10 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = (sizeof(fwts_acpi_madt_platform_int_source));
}
break;
- case 9:
+ case FWTS_ACPI_MADT_LOCAL_X2APIC:
skip = (sizeof(fwts_acpi_madt_local_x2apic));
break;
- case 10: {
+ case FWTS_ACPI_MADT_LOCAL_X2APIC_NMI: {
fwts_acpi_madt_local_x2apic_nmi *nmi = (fwts_acpi_madt_local_x2apic_nmi*)data;
if (nmi->flags & 0xfffffff0)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTLAPICX2APICNMIFlags",
@@ -434,21 +437,80 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
skip = (sizeof(fwts_acpi_madt_local_x2apic_nmi));
}
break;
- case 11: {
+ case FWTS_ACPI_MADT_GIC_C_CPU_INTERFACE: {
fwts_acpi_madt_gic *gic = (fwts_acpi_madt_gic*)data;
+ if (gic->reserved)
+ fwts_failed(fw, LOG_LEVEL_LOW, "MADTGICCReservedNonZero",
+ "MADT GIC C Structure reserved field should be zero, "
+ "instead got 0x%" PRIx32 ".", gic->reserved);
+
if (gic->flags & 0xfffffffc)
fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTGICFLags",
"MADT GIC, flags, bits 2..31 are reserved "
"and should be zero, but are set as: %" PRIx32 ".",
- gic->flags);
+ gic->flags & 0xfffffffc);
+
skip = sizeof(fwts_acpi_madt_gic);
}
break;
- case 12:
- /* Not much to sanity check */
+ case FWTS_ACPI_MADT_GIC_D_GOC_DISTRIBUTOR: {
+ fwts_acpi_madt_gicd *gicd = (fwts_acpi_madt_gicd*)data;
+
+ if (gicd->reserved)
+ fwts_failed(fw, LOG_LEVEL_LOW, "MADTGICDReservedNonZero",
+ "MADT GIC Distributor Structure reserved field should be zero, "
+ "instead got 0x%" PRIx32 ".", gicd->reserved);
+ if (gicd->reserved2)
+ fwts_failed(fw, LOG_LEVEL_LOW, "MADTGICDReserved2NonZero",
+ "MADT GIC Distributor Structure second reserved field should be zero, "
+ "instead got 0x%" PRIx32 ".", gicd->reserved2);
+ }
skip = sizeof(fwts_acpi_madt_gicd);
break;
+ case FWTS_ACPI_MADT_GIC_V2M_MSI_FRAME: {
+ fwts_acpi_madt_gic_msi *gic_msi = (fwts_acpi_madt_gic_msi*)data;
+ fwts_list_link *item;
+
+ if (gic_msi->reserved)
+ fwts_failed(fw, LOG_LEVEL_LOW, "MADTGICMSIReservedNonZero",
+ "MADT GIC MSI Structure reserved field should be zero, "
+ "instead got 0x%" PRIx32 ".", gic_msi->reserved);
+
+ if (gic_msi->flags & 0xfffffffe) {
+ fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTGICMSIFLags",
+ "MADT GIC MSI Frame, flags, bits 1..31 are reserved "
+ "and should be zero, but are set as: %" PRIx32 ".",
+ gic_msi->flags);
+ }
+
+ /* Check against previously IDs to see if unique */
+ fwts_list_foreach(item, &msi_frame_ids) {
+ uint32_t *frame_id = fwts_list_data(uint32_t *, item);
+
+ /* Frame ID must be unique according to the spec */
+ if (*frame_id == gic_msi->frame_id) {
+ fwts_failed(fw, LOG_LEVEL_MEDIUM, "MADTGICMSINonUniqueFrameId",
+ "MADT GIC MSI Frame ID 0x%" PRIx32 " is not unique "
+ "and has already be defined in a previous GIC MSI "
+ "Frame.", gic_msi->frame_id);
+ } else {
+ fwts_list_append(&msi_frame_ids, &(gic_msi->frame_id));
+ }
+ }
+ }
+ skip = sizeof(fwts_acpi_madt_gic_msi);
+ break;
+ case FWTS_ACPI_MADT_GIC_R_REDISTRIBUTOR: {
+ fwts_acpi_madt_gicr *gicr = (fwts_acpi_madt_gicr*)data;
+
+ if (gicr->reserved)
+ fwts_failed(fw, LOG_LEVEL_LOW, "MADTGICRReservedNonZero",
+ "MADT GIC Redistributor Structure reserved field should be zero, "
+ "instead got 0x%" PRIx32 ".", gicr->reserved);
+ }
+ skip = sizeof(fwts_acpi_madt_gicr);
+ break;
default:
skip = 0;
break;
@@ -456,6 +518,7 @@ static void acpi_table_check_madt(fwts_framework *fw, fwts_acpi_table_info *tabl
data += skip;
length -= skip;
}
+ fwts_list_free_items(&msi_frame_ids, NULL);
}
static void acpi_table_check_mcfg(fwts_framework *fw, fwts_acpi_table_info *table)
diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
index 1ea0daf..ceb6507 100644
--- a/src/lib/include/fwts_acpi.h
+++ b/src/lib/include/fwts_acpi.h
@@ -333,15 +333,21 @@ typedef enum {
FWTS_ACPI_MADT_INTERRUPT_SOURCE,
FWTS_ACPI_MADT_LOCAL_X2APIC,
FWTS_ACPI_MADT_LOCAL_X2APIC_NMI,
+ FWTS_ACPI_MADT_GIC_C_CPU_INTERFACE,
+ FWTS_ACPI_MADT_GIC_D_GOC_DISTRIBUTOR,
+ FWTS_ACPI_MADT_GIC_V2M_MSI_FRAME,
+ FWTS_ACPI_MADT_GIC_R_REDISTRIBUTOR,
FWTS_ACPI_MADT_RESERVED
} fwts_acpi_madt_type;
+/* Type 0, FWTS_ACPI_MADT_LOCAL_APIC */
typedef struct {
uint8_t acpi_processor_id;
uint8_t apic_id;
uint32_t flags;
} __attribute__ ((packed)) fwts_acpi_madt_processor_local_apic;
+/* Type 1, FWTS_ACPI_MADT_IO_APIC */
typedef struct {
uint8_t io_apic_id;
uint8_t reserved;
@@ -349,6 +355,7 @@ typedef struct {
uint32_t global_irq_base;
} __attribute__ ((packed)) fwts_acpi_madt_io_apic;
+/* Type 2, FWTS_ACPI_MADT_INTERRUPT_OVERRIDE */
typedef struct {
uint8_t bus;
uint8_t source;
@@ -356,22 +363,26 @@ typedef struct {
uint16_t flags;
} __attribute__ ((packed)) fwts_acpi_madt_interrupt_override;
+/* Type 3, FWTS_ACPI_MADT_NMI_SOURCE */
typedef struct {
uint16_t flags;
uint32_t gsi;
} __attribute__ ((packed)) fwts_acpi_madt_nmi;
+/* Type 4, FWTS_ACPI_MADT_LOCAL_APIC_NMI */
typedef struct {
uint8_t acpi_processor_id;
uint16_t flags;
uint8_t local_apic_lint;
} __attribute__ ((packed)) fwts_acpi_madt_local_apic_nmi;
+/* Type 5, FWTS_ACPI_MADT_LOCAL_APIC_OVERRIDE */
typedef struct {
uint16_t reserved;
uint64_t address;
} __attribute__ ((packed)) fwts_acpi_madt_local_apic_addr_override;
+/* Type 6, FWTS_ACPI_MADT_IO_SAPIC */
typedef struct {
uint8_t io_sapic_id;
uint8_t reserved;
@@ -379,6 +390,7 @@ typedef struct {
uint64_t address;
} __attribute__ ((packed)) fwts_acpi_madt_io_sapic;
+/* Type 7, FWTS_ACPI_MADT_LOCAL_SAPIC */
typedef struct {
uint8_t acpi_processor_id;
uint8_t local_sapic_id;
@@ -389,6 +401,7 @@ typedef struct {
char uid_string[0];
} __attribute__ ((packed)) fwts_acpi_madt_local_sapic;
+/* Type 8, FWTS_ACPI_MADT_INTERRUPT_SOURCE */
typedef struct {
uint16_t flags;
uint8_t type;
@@ -399,6 +412,7 @@ typedef struct {
uint32_t pis_flags;
} __attribute__ ((packed)) fwts_acpi_madt_platform_int_source;
+/* Type 9, FWTS_ACPI_MADT_LOCAL_X2APIC */
typedef struct {
uint16_t reserved;
uint32_t x2apic_id;
@@ -406,6 +420,7 @@ typedef struct {
uint32_t processor_uid;
} __attribute__ ((packed)) fwts_acpi_madt_local_x2apic;
+/* Type 10, FWTS_ACPI_MADT_LOCAL_X2APIC_NMI */
typedef struct {
uint16_t flags;
uint32_t processor_uid;
@@ -413,9 +428,10 @@ typedef struct {
uint8_t reserved[3];
} __attribute__ ((packed)) fwts_acpi_madt_local_x2apic_nmi;
+/* Type 11, FWTS_ACPI_MADT_GIC_C_CPU_INTERFACE */
/* New in ACPI 5.0, GIC, section 5.2.12.14 */
typedef struct {
- uint8_t reserved[2];
+ uint16_t reserved;
uint32_t gic_id;
uint32_t processor_uid;
uint32_t flags;
@@ -423,17 +439,43 @@ typedef struct {
uint32_t performance_interrupt_gsiv;
uint64_t parked_address;
uint64_t physical_base_address;
+ uint64_t gicv;
+ uint64_t gich;
+ uint32_t vgic;
+ uint64_t gicr_base_address;
+ uint64_t mpidr;
} __attribute__ ((packed)) fwts_acpi_madt_gic;
/* New in ACPI 5.0, GICD, section 5.2.12.15 */
+/* Type 12, FWTS_ACPI_MADT_GIC_D_GOC_DISTRIBUTOR */
typedef struct {
- uint8_t reserved[2];
+ uint16_t reserved;
uint32_t gic_id;
uint64_t physical_base_address;
uint32_t system_vector_base;
uint32_t reserved2;
} __attribute__ ((packed)) fwts_acpi_madt_gicd;
+/* New in ACPI 5.1, GIC MSI Frame structure, 5.2.12.16 */
+/* Type 13, FWTS_ACPI_MADT_GIC_V2M_MSI_FRAME */
+typedef struct {
+ uint16_t reserved;
+ uint32_t frame_id;
+ uint64_t physical_base_address;
+ uint32_t flags;
+ uint16_t spi_count;
+ uint16_t spi_base;
+ uint32_t spi_flags; /* bit 0 just used at the moment */
+} __attribute__ ((packed)) fwts_acpi_madt_gic_msi;
+
+/* New in ACPI 5.1, GICR structure, 5.2.12.17 */
+/* Type 14, FWTS_ACPI_MADT_GIC_R_REDISTRIBUTOR */
+typedef struct {
+ uint16_t reserved;
+ uint64_t discovery_range_base_address;
+ uint32_t discovery_range_length;
+} __attribute__ ((packed)) fwts_acpi_madt_gicr;
+
/* From http://www.kuro5hin.org/story/2002/10/27/16622/530,
and also http://www.cl.cam.ac.uk/~rja14/tcpa-faq.html */
typedef struct {
--
2.0.1
More information about the fwts-devel
mailing list