mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-30 23:55:18 +00:00

Up until now we relied on the GICs used in our FPGA images to be GICv3 compliant, without the "direct virtual injection" feature (aka GICv4) enabled. To support newer images which have GICv4 compliant GICs, enable the newly introduced GICv4 detection code, and use that also when we adjust the redistributor region size in the devicetree. This allows the same BL31 image to be used with GICv3 or GICv4 FPGA images. Change-Id: I9f6435a6d5150983625efe3650a8b7d1ef11b1d1 Signed-off-by: Andre Przywara <andre.przywara@arm.com>
93 lines
2.3 KiB
C
93 lines
2.3 KiB
C
/*
|
|
* Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <common/debug.h>
|
|
#include <common/fdt_wrappers.h>
|
|
#include <drivers/arm/gicv3.h>
|
|
#include <drivers/arm/gic_common.h>
|
|
#include <lib/mmio.h>
|
|
#include <libfdt.h>
|
|
|
|
#include <platform_def.h>
|
|
#include <plat/common/platform.h>
|
|
#include <platform_def.h>
|
|
|
|
static const interrupt_prop_t fpga_interrupt_props[] = {
|
|
PLATFORM_G1S_PROPS(INTR_GROUP1S),
|
|
PLATFORM_G0_PROPS(INTR_GROUP0)
|
|
};
|
|
|
|
static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
|
|
|
|
static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
|
|
{
|
|
return (unsigned int)plat_core_pos_by_mpidr(mpidr);
|
|
}
|
|
|
|
static gicv3_driver_data_t fpga_gicv3_driver_data = {
|
|
.interrupt_props = fpga_interrupt_props,
|
|
.interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props),
|
|
.rdistif_num = PLATFORM_CORE_COUNT,
|
|
.rdistif_base_addrs = fpga_rdistif_base_addrs,
|
|
.mpidr_to_core_pos = fpga_mpidr_to_core_pos
|
|
};
|
|
|
|
void plat_fpga_gic_init(void)
|
|
{
|
|
const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
|
|
int node, ret;
|
|
|
|
node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
|
|
if (node < 0) {
|
|
WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n");
|
|
return;
|
|
}
|
|
|
|
/* TODO: Assuming only empty "ranges;" properties up the bus path. */
|
|
ret = fdt_get_reg_props_by_index(fdt, node, 0,
|
|
&fpga_gicv3_driver_data.gicd_base, NULL);
|
|
if (ret < 0) {
|
|
WARN("Could not read GIC distributor address from DT.\n");
|
|
return;
|
|
}
|
|
|
|
ret = fdt_get_reg_props_by_index(fdt, node, 1,
|
|
&fpga_gicv3_driver_data.gicr_base, NULL);
|
|
if (ret < 0) {
|
|
WARN("Could not read GIC redistributor address from DT.\n");
|
|
return;
|
|
}
|
|
|
|
gicv3_driver_init(&fpga_gicv3_driver_data);
|
|
gicv3_distif_init();
|
|
gicv3_rdistif_init(plat_my_core_pos());
|
|
gicv3_cpuif_enable(plat_my_core_pos());
|
|
}
|
|
|
|
void fpga_pwr_gic_on_finish(void)
|
|
{
|
|
gicv3_rdistif_init(plat_my_core_pos());
|
|
gicv3_cpuif_enable(plat_my_core_pos());
|
|
}
|
|
|
|
void fpga_pwr_gic_off(void)
|
|
{
|
|
gicv3_cpuif_disable(plat_my_core_pos());
|
|
gicv3_rdistif_off(plat_my_core_pos());
|
|
}
|
|
|
|
unsigned int fpga_get_nr_gic_cores(void)
|
|
{
|
|
return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base);
|
|
}
|
|
|
|
uintptr_t fpga_get_redist_size(void)
|
|
{
|
|
uint64_t typer_val = mmio_read_64(fpga_gicv3_driver_data.gicr_base +
|
|
GICR_TYPER);
|
|
|
|
return gicv3_redist_size(typer_val);
|
|
}
|