acpi: Add functions to declare ARM GIC V3 hardware
For GICD and GICR a SOC needs to implement 2 callbacks to get the base of those interrupt controllers. For all the cpu GIC the code loops over all the DEVICE_PATH_GICC_V3 devices in a similar fashion to how x86 lapics are added. It's up to the SOC to add those devices to the tree. Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Change-Id: I5074d0a76316e854b7801e14b3241f88e805b02f Reviewed-on: https://review.coreboot.org/c/coreboot/+/76132 Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
fca612497d
commit
3df6cc9de6
|
@ -53,6 +53,10 @@ config ACPI_COMMON_MADT_LAPIC
|
|||
config ACPI_COMMON_MADT_IOAPIC
|
||||
bool
|
||||
|
||||
config ACPI_COMMON_MADT_GICC_V3
|
||||
bool
|
||||
depends on ARCH_ARM64
|
||||
|
||||
config ACPI_NO_PCAT_8259
|
||||
bool
|
||||
help
|
||||
|
|
|
@ -20,6 +20,7 @@ ramstage-y += pld.c
|
|||
ramstage-y += sata.c
|
||||
ramstage-y += soundwire.c
|
||||
ramstage-y += fadt_filler.c
|
||||
ramstage-$(CONFIG_ACPI_COMMON_MADT_GICC_V3) += acpi_gic.c
|
||||
|
||||
all-y += acpi_pm.c
|
||||
smm-y += acpi_pm.c
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
|
||||
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 OSPM if GICR is present */
|
||||
gicc->processor_power_efficiency_class = 0; /* Ignore for now */
|
||||
/* For platforms implementing GIC V3 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 & 0xff00fffffful;
|
||||
|
||||
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 = platform_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 = platform_get_gicr_base();
|
||||
gicr->discovery_range_length = GICV3_REDIST_SIZE * CONFIG_MAX_CPUS;
|
||||
|
||||
return current + gicr->length;
|
||||
}
|
||||
|
||||
unsigned long acpi_arch_fill_madt(acpi_madt_t *madt, unsigned long current)
|
||||
{
|
||||
current = acpi_create_madt_giccs_v3(current);
|
||||
current = acpi_create_madt_gicd_v3(current);
|
||||
current = acpi_create_madt_gicr_v3(current);
|
||||
|
||||
return current;
|
||||
}
|
|
@ -1566,6 +1566,9 @@ unsigned long acpi_create_madt_one_lapic(unsigned long current, u32 cpu, u32 api
|
|||
|
||||
unsigned long acpi_create_madt_lapic_nmis(unsigned long current);
|
||||
|
||||
uintptr_t platform_get_gicd_base(void);
|
||||
uintptr_t platform_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,
|
||||
|
|
|
@ -23,6 +23,7 @@ enum device_path_type {
|
|||
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 @@ enum device_path_type {
|
|||
"DEVICE_PATH_MMIO", \
|
||||
"DEVICE_PATH_GPIO", \
|
||||
"DEVICE_PATH_MDIO", \
|
||||
"DEVICE_PATH_GICC_V3", \
|
||||
}
|
||||
|
||||
struct domain_path {
|
||||
|
@ -120,6 +122,12 @@ struct mdio_path {
|
|||
unsigned int addr;
|
||||
};
|
||||
|
||||
struct gicc_v3_path {
|
||||
unsigned long long mpidr;
|
||||
unsigned int vgic_mi;
|
||||
unsigned int pi_gsiv;
|
||||
};
|
||||
|
||||
struct device_path {
|
||||
enum device_path_type type;
|
||||
union {
|
||||
|
@ -138,6 +146,7 @@ struct device_path {
|
|||
struct mmio_path mmio;
|
||||
struct gpio_path gpio;
|
||||
struct mdio_path mdio;
|
||||
struct gicc_v3_path gicc_v3;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue