Attention is currently required from: Lance Zhao, Tim Wawrzynczak.
Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/76132?usp=email )
Change subject: WIP acpi: Add functions to declare ARM GIC V3 hardware ......................................................................
WIP acpi: Add functions to declare ARM GIC V3 hardware
Signed-off-by: Arthur Heymans arthur@aheymans.xyz Change-Id: I5074d0a76316e854b7801e14b3241f88e805b02f --- M src/acpi/Kconfig M src/acpi/acpi.c M src/include/acpi/acpi.h M src/include/device/path.h 4 files changed, 99 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/76132/1
diff --git a/src/acpi/Kconfig b/src/acpi/Kconfig index a45a68c..26697d8 100644 --- a/src/acpi/Kconfig +++ b/src/acpi/Kconfig @@ -46,6 +46,10 @@ config ACPI_COMMON_MADT_IOAPIC bool
+config ACPI_COMMON_MADT_GICC_V3 + bool + depends on ARCH_ARM64 + config ACPI_NO_PCAT_8259 bool help diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index cfc388b..43fb70a 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -338,6 +338,83 @@ return current; }
+static int acpi_create_madt_one_gicc_v3(acpi_madt_gicc_t *gicc, u32 acpi_uid, u32 pi_gsiv, + uint32_t vgic_mi, uint64_t mpidr) +{ + memset(gicc, 0, sizeof(acpi_madt_gicc_t)); + gicc->type = GICC; + gicc->length = sizeof(acpi_madt_gicc_t); + gicc->reserved = 0; + gicc->cpu_interface_number = 0; /* V3, no compat mode */ + gicc->acpi_processor_uid = acpi_uid; + gicc->flags.enabled = 1; + gicc->parking_protocol_persion = 0; /* Assume PSCI exclusively */ + gicc->performance_interrupt_gsiv = pi_gsiv; + gicc->parked_address = 0; + gicc->physical_base_address = 0; /* V3, no compat mode */ + gicc->vgic_maintenance_interrupt = vgic_mi; + gicc->gicr_base_address = 0; /* ignored by ASPM if GICR is present */ + gicc->processor_power_efficiency_class = 0; /* Ignore for now */ + /* For platforms implementing ARMv8 the format must be: + * Bits [63:40] Must be zero + * Bits [39:32] Aff3 : Match Aff3 of target processor MPIDR + * Bits [31:24] Must be zero + * Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR + * Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR + * Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR + */ + gicc->mpidr = mpidr & 0xff00ffffff; + + return gicc->length; +} + +static unsigned long acpi_create_madt_giccs_v3(unsigned long current) +{ + // Loop over CPUs GIC + uint32_t acpi_id = 0; + for (struct device *dev = dev_find_path(NULL, DEVICE_PATH_GICC_V3); dev; + dev = dev_find_path(dev, DEVICE_PATH_GICC_V3)) { + acpi_madt_gicc_t *gicc = (acpi_madt_gicc_t *)current; + current += acpi_create_madt_one_gicc_v3(gicc, acpi_id++, + dev->path.gicc_v3.pi_gsiv, + dev->path.gicc_v3.vgic_mi, + dev->path.gicc_v3.mpidr); + } + + return current; +} + +static unsigned long acpi_create_madt_gicd_v3(unsigned long current) +{ + acpi_madt_gicd_t *gicd = (acpi_madt_gicd_t *)current; + memset(gicd, 0, sizeof(acpi_madt_gicd_t)); + gicd->type = GICD; + gicd->length = sizeof(acpi_madt_gicd_t); + gicd->physical_base_address = get_gicd_base(); + gicd->system_vector_base = 0; + gicd->gic_version = 3; + + return current + gicd->length; +} + +/* + * The redistributor in GICv3 has two 64KB frames per CPU; in + * GICv4 it has four 64KB frames per CPU. + */ +#define GICV3_REDIST_SIZE 0x20000 +#define GICV4_REDIST_SIZE 0x40000 +static unsigned long acpi_create_madt_gicr_v3(unsigned long current) +{ + acpi_madt_gicr_t *gicr = (acpi_madt_gicr_t *)current; + memset(gicr, 0, sizeof(acpi_madt_gicr_t)); + gicr->type = GICR; + gicr->length = sizeof(acpi_madt_gicr_t); + gicr->discovery_range_base_address = get_gicr_base(); + gicr->discovery_range_length = GICV3_REDIST_SIZE * CONFIG_MAX_CPUS; + + return current + gicr->length; +} + static void acpi_create_madt(acpi_madt_t *madt) { acpi_header_t *header = &(madt->header); @@ -368,6 +445,12 @@ if (CONFIG(ACPI_COMMON_MADT_IOAPIC)) current = acpi_create_madt_ioapic_gsi0_default(current);
+ if (CONFIG(ACPI_COMMON_MADT_GICC_V3)) { + current = acpi_create_madt_giccs_v3(current); + current = acpi_create_madt_gicd_v3(current); + current = acpi_create_madt_gicr_v3(current); + } + if (CONFIG(ACPI_CUSTOM_MADT)) current = acpi_fill_madt(current);
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index 266eb60..64b7613 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -1456,6 +1456,9 @@
unsigned long acpi_create_madt_lapic_nmis(unsigned long current);
+uintptr_t get_gicd_base(void); +uintptr_t get_gicr_base(void); + int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic); int acpi_create_srat_x2apic(acpi_srat_x2apic_t *x2apic, u32 node, u32 apic); int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek, u32 sizek, diff --git a/src/include/device/path.h b/src/include/device/path.h index c0df66b..4912d08 100644 --- a/src/include/device/path.h +++ b/src/include/device/path.h @@ -23,6 +23,7 @@ DEVICE_PATH_MMIO, DEVICE_PATH_GPIO, DEVICE_PATH_MDIO, + DEVICE_PATH_GICC_V3,
/* * When adding path types to this table, please also update the @@ -48,6 +49,7 @@ "DEVICE_PATH_MMIO", \ "DEVICE_PATH_GPIO", \ "DEVICE_PATH_MDIO", \ + "DEVICE_PATH_GICC_V3", \ }
struct domain_path { @@ -120,6 +122,12 @@ unsigned int addr; };
+struct gicc_v3_path { + long long unsigned mpidr; + unsigned int vgic_mi; + unsigned int pi_gsiv; +}; + struct device_path { enum device_path_type type; union { @@ -138,6 +146,7 @@ struct mmio_path mmio; struct gpio_path gpio; struct mdio_path mdio; + struct gicc_v3_path gicc_v3; }; };