/*
 * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>

#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <lib/spinlock.h>

#include "gicv3_private.h"

const gicv3_driver_data_t *gicv3_driver_data;

/*
 * Spinlock to guard registers needing read-modify-write. APIs protected by this
 * spinlock are used either at boot time (when only a single CPU is active), or
 * when the system is fully coherent.
 */
static spinlock_t gic_lock;

/*
 * Redistributor power operations are weakly bound so that they can be
 * overridden
 */
#pragma weak gicv3_rdistif_off
#pragma weak gicv3_rdistif_on

/* Check interrupt ID for SGI/(E)PPI and (E)SPIs */
static bool is_sgi_ppi(unsigned int id);

/*
 * Helper macros to save and restore GICR and GICD registers
 * corresponding to their numbers to and from the context
 */
#define RESTORE_GICR_REG(base, ctx, name, i)	\
	gicr_write_##name((base), (i), (ctx)->gicr_##name[(i)])

#define SAVE_GICR_REG(base, ctx, name, i)	\
	(ctx)->gicr_##name[(i)] = gicr_read_##name((base), (i))

/* Helper macros to save and restore GICD registers to and from the context */
#define RESTORE_GICD_REGS(base, ctx, intr_num, reg, REG)		\
	do {								\
		for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\
				int_id += (1U << REG##R_SHIFT)) {	\
			gicd_write_##reg((base), int_id,		\
				(ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >> \
							REG##R_SHIFT]);	\
		}							\
	} while (false)

#define SAVE_GICD_REGS(base, ctx, intr_num, reg, REG)			\
	do {								\
		for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\
				int_id += (1U << REG##R_SHIFT)) {	\
			(ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >>	\
			REG##R_SHIFT] = gicd_read_##reg((base), int_id); \
		}							\
	} while (false)

#if GIC_EXT_INTID
#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG)		\
	do {								\
		for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\
				int_id += (1U << REG##R_SHIFT)) {	\
			gicd_write_##reg((base), int_id,		\
			(ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID -	\
			round_up(TOTAL_SPI_INTR_NUM, 1U << REG##R_SHIFT)))\
						>> REG##R_SHIFT]);	\
		}							\
	} while (false)

#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG)			\
	do {								\
		for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\
				int_id += (1U << REG##R_SHIFT)) {	\
			(ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID -	\
			round_up(TOTAL_SPI_INTR_NUM, 1U << REG##R_SHIFT)))\
			>> REG##R_SHIFT] = gicd_read_##reg((base), int_id);\
		}							\
	} while (false)
#else
#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG)
#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG)
#endif /* GIC_EXT_INTID */

/*******************************************************************************
 * This function initialises the ARM GICv3 driver in EL3 with provided platform
 * inputs.
 ******************************************************************************/
void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
{
	unsigned int gic_version;
	unsigned int gicv2_compat;

	assert(plat_driver_data != NULL);
	assert(plat_driver_data->gicd_base != 0U);
	assert(plat_driver_data->rdistif_num != 0U);
	assert(plat_driver_data->rdistif_base_addrs != NULL);

	assert(IS_IN_EL3());

	assert((plat_driver_data->interrupt_props_num != 0U) ?
	       (plat_driver_data->interrupt_props != NULL) : 1);

	/* Check for system register support */
#ifndef __aarch64__
	assert((read_id_pfr1() &
			(ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)) != 0U);
#else
	assert((read_id_aa64pfr0_el1() &
			(ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U);
#endif /* !__aarch64__ */

	gic_version = gicd_read_pidr2(plat_driver_data->gicd_base);
	gic_version >>= PIDR2_ARCH_REV_SHIFT;
	gic_version &= PIDR2_ARCH_REV_MASK;

	/* Check GIC version */
#if !GIC_ENABLE_V4_EXTN
	assert(gic_version == ARCH_REV_GICV3);
#endif
	/*
	 * Find out whether the GIC supports the GICv2 compatibility mode.
	 * The ARE_S bit resets to 0 if supported
	 */
	gicv2_compat = gicd_read_ctlr(plat_driver_data->gicd_base);
	gicv2_compat >>= CTLR_ARE_S_SHIFT;
	gicv2_compat = gicv2_compat & CTLR_ARE_S_MASK;

	if (plat_driver_data->gicr_base != 0U) {
		/*
		 * Find the base address of each implemented Redistributor interface.
		 * The number of interfaces should be equal to the number of CPUs in the
		 * system. The memory for saving these addresses has to be allocated by
		 * the platform port
		 */
		gicv3_rdistif_base_addrs_probe(plat_driver_data->rdistif_base_addrs,
						   plat_driver_data->rdistif_num,
						   plat_driver_data->gicr_base,
						   plat_driver_data->mpidr_to_core_pos);
#if !HW_ASSISTED_COHERENCY
		/*
		 * Flush the rdistif_base_addrs[] contents linked to the GICv3 driver.
		 */
		flush_dcache_range((uintptr_t)(plat_driver_data->rdistif_base_addrs),
			plat_driver_data->rdistif_num *
			sizeof(*(plat_driver_data->rdistif_base_addrs)));
#endif
	}
	gicv3_driver_data = plat_driver_data;

	/*
	 * The GIC driver data is initialized by the primary CPU with caches
	 * enabled. When the secondary CPU boots up, it initializes the
	 * GICC/GICR interface with the caches disabled. Hence flush the
	 * driver data to ensure coherency. This is not required if the
	 * platform has HW_ASSISTED_COHERENCY enabled.
	 */
#if !HW_ASSISTED_COHERENCY
	flush_dcache_range((uintptr_t)&gicv3_driver_data,
		sizeof(gicv3_driver_data));
	flush_dcache_range((uintptr_t)gicv3_driver_data,
		sizeof(*gicv3_driver_data));
#endif
	gicv3_check_erratas_applies(plat_driver_data->gicd_base);

	INFO("GICv%u with%s legacy support detected.\n", gic_version,
				(gicv2_compat == 0U) ? "" : "out");
	INFO("ARM GICv%u driver initialized in EL3\n", gic_version);
}

/*******************************************************************************
 * This function initialises the GIC distributor interface based upon the data
 * provided by the platform while initialising the driver.
 ******************************************************************************/
void __init gicv3_distif_init(void)
{
	unsigned int bitmap;

	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);

	assert(IS_IN_EL3());

	/*
	 * Clear the "enable" bits for G0/G1S/G1NS interrupts before configuring
	 * the ARE_S bit. The Distributor might generate a system error
	 * otherwise.
	 */
	gicd_clr_ctlr(gicv3_driver_data->gicd_base,
		      CTLR_ENABLE_G0_BIT |
		      CTLR_ENABLE_G1S_BIT |
		      CTLR_ENABLE_G1NS_BIT,
		      RWP_TRUE);

	/* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */
	gicd_set_ctlr(gicv3_driver_data->gicd_base,
			CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE);

	/* Set the default attribute of all (E)SPIs */
	gicv3_spis_config_defaults(gicv3_driver_data->gicd_base);

	bitmap = gicv3_secure_spis_config_props(
			gicv3_driver_data->gicd_base,
			gicv3_driver_data->interrupt_props,
			gicv3_driver_data->interrupt_props_num);

	/* Enable the secure (E)SPIs now that they have been configured */
	gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE);
}

/*******************************************************************************
 * This function initialises the GIC Redistributor interface of the calling CPU
 * (identified by the 'proc_num' parameter) based upon the data provided by the
 * platform while initialising the driver.
 ******************************************************************************/
void gicv3_rdistif_init(unsigned int proc_num)
{
	uintptr_t gicr_base;
	unsigned int bitmap;
	uint32_t ctlr;

	assert(gicv3_driver_data != NULL);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);

	ctlr = gicd_read_ctlr(gicv3_driver_data->gicd_base);
	assert((ctlr & CTLR_ARE_S_BIT) != 0U);

	assert(IS_IN_EL3());

	/* Power on redistributor */
	gicv3_rdistif_on(proc_num);

	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
	assert(gicr_base != 0U);

	/* Set the default attribute of all SGIs and (E)PPIs */
	gicv3_ppi_sgi_config_defaults(gicr_base);

	bitmap = gicv3_secure_ppi_sgi_config_props(gicr_base,
			gicv3_driver_data->interrupt_props,
			gicv3_driver_data->interrupt_props_num);

	/* Enable interrupt groups as required, if not already */
	if ((ctlr & bitmap) != bitmap) {
		gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE);
	}
}

/*******************************************************************************
 * Functions to perform power operations on GIC Redistributor
 ******************************************************************************/
void gicv3_rdistif_off(unsigned int proc_num)
{
}

void gicv3_rdistif_on(unsigned int proc_num)
{
}

/*******************************************************************************
 * This function enables the GIC CPU interface of the calling CPU using only
 * system register accesses.
 ******************************************************************************/
void gicv3_cpuif_enable(unsigned int proc_num)
{
	uintptr_t gicr_base;
	u_register_t scr_el3;
	unsigned int icc_sre_el3;

	assert(gicv3_driver_data != NULL);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
	assert(IS_IN_EL3());

	/* Mark the connected core as awake */
	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
	gicv3_rdistif_mark_core_awake(gicr_base);

	/* Disable the legacy interrupt bypass */
	icc_sre_el3 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT;

	/*
	 * Enable system register access for EL3 and allow lower exception
	 * levels to configure the same for themselves. If the legacy mode is
	 * not supported, the SRE bit is RAO/WI
	 */
	icc_sre_el3 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);
	write_icc_sre_el3(read_icc_sre_el3() | icc_sre_el3);

	scr_el3 = read_scr_el3();

	/*
	 * Switch to NS state to write Non secure ICC_SRE_EL1 and
	 * ICC_SRE_EL2 registers.
	 */
	write_scr_el3(scr_el3 | SCR_NS_BIT);
	isb();

	write_icc_sre_el2(read_icc_sre_el2() | icc_sre_el3);
	write_icc_sre_el1(ICC_SRE_SRE_BIT);
	isb();

	/* Switch to secure state. */
	write_scr_el3(scr_el3 & (~SCR_NS_BIT));
	isb();

	/* Write the secure ICC_SRE_EL1 register */
	write_icc_sre_el1(ICC_SRE_SRE_BIT);
	isb();

	/* Program the idle priority in the PMR */
	write_icc_pmr_el1(GIC_PRI_MASK);

	/* Enable Group0 interrupts */
	write_icc_igrpen0_el1(IGRPEN1_EL1_ENABLE_G0_BIT);

	/* Enable Group1 Secure interrupts */
	write_icc_igrpen1_el3(read_icc_igrpen1_el3() |
				IGRPEN1_EL3_ENABLE_G1S_BIT);
	isb();
	/* Add DSB to ensure visibility of System register writes */
	dsb();
}

/*******************************************************************************
 * This function disables the GIC CPU interface of the calling CPU using
 * only system register accesses.
 ******************************************************************************/
void gicv3_cpuif_disable(unsigned int proc_num)
{
	uintptr_t gicr_base;

	assert(gicv3_driver_data != NULL);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	assert(IS_IN_EL3());

	/* Disable legacy interrupt bypass */
	write_icc_sre_el3(read_icc_sre_el3() |
			  (ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT));

	/* Disable Group0 interrupts */
	write_icc_igrpen0_el1(read_icc_igrpen0_el1() &
			      ~IGRPEN1_EL1_ENABLE_G0_BIT);

	/* Disable Group1 Secure and Non-Secure interrupts */
	write_icc_igrpen1_el3(read_icc_igrpen1_el3() &
			      ~(IGRPEN1_EL3_ENABLE_G1NS_BIT |
			      IGRPEN1_EL3_ENABLE_G1S_BIT));

	/* Synchronise accesses to group enable registers */
	isb();
	/* Add DSB to ensure visibility of System register writes */
	dsb();

	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
	assert(gicr_base != 0UL);

	/*
	 * dsb() already issued previously after clearing the CPU group
	 * enabled, apply below workaround to toggle the "DPG*"
	 * bits of GICR_CTLR register for unblocking event.
	 */
	gicv3_apply_errata_wa_2384374(gicr_base);

	/* Mark the connected core as asleep */
	gicv3_rdistif_mark_core_asleep(gicr_base);
}

/*******************************************************************************
 * This function returns the id of the highest priority pending interrupt at
 * the GIC cpu interface.
 ******************************************************************************/
unsigned int gicv3_get_pending_interrupt_id(void)
{
	unsigned int id;

	assert(IS_IN_EL3());
	id = (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;

	/*
	 * If the ID is special identifier corresponding to G1S or G1NS
	 * interrupt, then read the highest pending group 1 interrupt.
	 */
	if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) {
		return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK;
	}

	return id;
}

/*******************************************************************************
 * This function returns the type of the highest priority pending interrupt at
 * the GIC cpu interface. The return values can be one of the following :
 *   PENDING_G1S_INTID  : The interrupt type is secure Group 1.
 *   PENDING_G1NS_INTID : The interrupt type is non secure Group 1.
 *   0 - 1019           : The interrupt type is secure Group 0.
 *   GIC_SPURIOUS_INTERRUPT : there is no pending interrupt with
 *                            sufficient priority to be signaled
 ******************************************************************************/
unsigned int gicv3_get_pending_interrupt_type(void)
{
	assert(IS_IN_EL3());
	return (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;
}

/*******************************************************************************
 * This function returns the type of the interrupt id depending upon the group
 * this interrupt has been configured under by the interrupt controller i.e.
 * group0 or group1 Secure / Non Secure. The return value can be one of the
 * following :
 *    INTR_GROUP0  : The interrupt type is a Secure Group 0 interrupt
 *    INTR_GROUP1S : The interrupt type is a Secure Group 1 secure interrupt
 *    INTR_GROUP1NS: The interrupt type is a Secure Group 1 non secure
 *                   interrupt.
 ******************************************************************************/
unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num)
{
	unsigned int igroup, grpmodr;
	uintptr_t gicr_base;

	assert(IS_IN_EL3());
	assert(gicv3_driver_data != NULL);

	/* Ensure the parameters are valid */
	assert((id < PENDING_G1S_INTID) || (id >= MIN_LPI_ID));
	assert(proc_num < gicv3_driver_data->rdistif_num);

	/* All LPI interrupts are Group 1 non secure */
	if (id >= MIN_LPI_ID) {
		return INTR_GROUP1NS;
	}

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */
		assert(gicv3_driver_data->rdistif_base_addrs != NULL);
		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
		igroup = gicr_get_igroupr(gicr_base, id);
		grpmodr = gicr_get_igrpmodr(gicr_base, id);
	} else {
		/* SPIs: 32-1019, ESPIs: 4096-5119 */
		assert(gicv3_driver_data->gicd_base != 0U);
		igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id);
		grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id);
	}

	/*
	 * If the IGROUP bit is set, then it is a Group 1 Non secure
	 * interrupt
	 */
	if (igroup != 0U) {
		return INTR_GROUP1NS;
	}

	/* If the GRPMOD bit is set, then it is a Group 1 Secure interrupt */
	if (grpmodr != 0U) {
		return INTR_GROUP1S;
	}

	/* Else it is a Group 0 Secure interrupt */
	return INTR_GROUP0;
}

/*****************************************************************************
 * Function to save and disable the GIC ITS register context. The power
 * management of GIC ITS is implementation-defined and this function doesn't
 * save any memory structures required to support ITS. As the sequence to save
 * this state is implementation defined, it should be executed in platform
 * specific code. Calling this function alone and then powering down the GIC and
 * ITS without implementing the aforementioned platform specific code will
 * corrupt the ITS state.
 *
 * This function must be invoked after the GIC CPU interface is disabled.
 *****************************************************************************/
void gicv3_its_save_disable(uintptr_t gits_base,
				gicv3_its_ctx_t * const its_ctx)
{
	unsigned int i;

	assert(gicv3_driver_data != NULL);
	assert(IS_IN_EL3());
	assert(its_ctx != NULL);
	assert(gits_base != 0U);

	its_ctx->gits_ctlr = gits_read_ctlr(gits_base);

	/* Disable the ITS */
	gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT);

	/* Wait for quiescent state */
	gits_wait_for_quiescent_bit(gits_base);

	its_ctx->gits_cbaser = gits_read_cbaser(gits_base);
	its_ctx->gits_cwriter = gits_read_cwriter(gits_base);

	for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) {
		its_ctx->gits_baser[i] = gits_read_baser(gits_base, i);
	}
}

/*****************************************************************************
 * Function to restore the GIC ITS register context. The power
 * management of GIC ITS is implementation defined and this function doesn't
 * restore any memory structures required to support ITS. The assumption is
 * that these structures are in memory and are retained during system suspend.
 *
 * This must be invoked before the GIC CPU interface is enabled.
 *****************************************************************************/
void gicv3_its_restore(uintptr_t gits_base,
			const gicv3_its_ctx_t * const its_ctx)
{
	unsigned int i;

	assert(gicv3_driver_data != NULL);
	assert(IS_IN_EL3());
	assert(its_ctx != NULL);
	assert(gits_base != 0U);

	/* Assert that the GITS is disabled and quiescent */
	assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
	assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) != 0U);

	gits_write_cbaser(gits_base, its_ctx->gits_cbaser);
	gits_write_cwriter(gits_base, its_ctx->gits_cwriter);

	for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) {
		gits_write_baser(gits_base, i, its_ctx->gits_baser[i]);
	}

	/* Restore the ITS CTLR but leave the ITS disabled */
	gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT);
}

/*****************************************************************************
 * Function to save the GIC Redistributor register context. This function
 * must be invoked after CPU interface disable and prior to Distributor save.
 *****************************************************************************/
void gicv3_rdistif_save(unsigned int proc_num,
			gicv3_redist_ctx_t * const rdist_ctx)
{
	uintptr_t gicr_base;
	unsigned int i, ppi_regs_num, regs_num;

	assert(gicv3_driver_data != NULL);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
	assert(IS_IN_EL3());
	assert(rdist_ctx != NULL);

	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];

#if GIC_EXT_INTID
	/* Calculate number of PPI registers */
	ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >>
			TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1;
	/* All other values except PPInum [0-2] are reserved */
	if (ppi_regs_num > 3U) {
		ppi_regs_num = 1U;
	}
#else
	ppi_regs_num = 1U;
#endif
	/*
	 * Wait for any write to GICR_CTLR to complete before trying to save any
	 * state.
	 */
	gicr_wait_for_pending_write(gicr_base);

	rdist_ctx->gicr_ctlr = gicr_read_ctlr(gicr_base);

	rdist_ctx->gicr_propbaser = gicr_read_propbaser(gicr_base);
	rdist_ctx->gicr_pendbaser = gicr_read_pendbaser(gicr_base);

	/* 32 interrupt IDs per register */
	for (i = 0U; i < ppi_regs_num; ++i) {
		SAVE_GICR_REG(gicr_base, rdist_ctx, igroupr, i);
		SAVE_GICR_REG(gicr_base, rdist_ctx, isenabler, i);
		SAVE_GICR_REG(gicr_base, rdist_ctx, ispendr, i);
		SAVE_GICR_REG(gicr_base, rdist_ctx, isactiver, i);
		SAVE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i);
	}

	/* 16 interrupt IDs per GICR_ICFGR register */
	regs_num = ppi_regs_num << 1;
	for (i = 0U; i < regs_num; ++i) {
		SAVE_GICR_REG(gicr_base, rdist_ctx, icfgr, i);
	}

	rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base);

	/* 4 interrupt IDs per GICR_IPRIORITYR register */
	regs_num = ppi_regs_num << 3;
	for (i = 0U; i < regs_num; ++i) {
		rdist_ctx->gicr_ipriorityr[i] =
		gicr_ipriorityr_read(gicr_base, i);
	}

	/*
	 * Call the pre-save hook that implements the IMP DEF sequence that may
	 * be required on some GIC implementations. As this may need to access
	 * the Redistributor registers, we pass it proc_num.
	 */
	gicv3_distif_pre_save(proc_num);
}

/*****************************************************************************
 * Function to restore the GIC Redistributor register context. We disable
 * LPI and per-cpu interrupts before we start restore of the Redistributor.
 * This function must be invoked after Distributor restore but prior to
 * CPU interface enable. The pending and active interrupts are restored
 * after the interrupts are fully configured and enabled.
 *****************************************************************************/
void gicv3_rdistif_init_restore(unsigned int proc_num,
				const gicv3_redist_ctx_t * const rdist_ctx)
{
	uintptr_t gicr_base;
	unsigned int i, ppi_regs_num, regs_num;

	assert(gicv3_driver_data != NULL);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
	assert(IS_IN_EL3());
	assert(rdist_ctx != NULL);

	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];

#if GIC_EXT_INTID
	/* Calculate number of PPI registers */
	ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >>
			TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1;
	/* All other values except PPInum [0-2] are reserved */
	if (ppi_regs_num > 3U) {
		ppi_regs_num = 1U;
	}
#else
	ppi_regs_num = 1U;
#endif
	/* Power on redistributor */
	gicv3_rdistif_on(proc_num);

	/*
	 * Call the post-restore hook that implements the IMP DEF sequence that
	 * may be required on some GIC implementations. As this may need to
	 * access the Redistributor registers, we pass it proc_num.
	 */
	gicv3_distif_post_restore(proc_num);

	/*
	 * Disable all SGIs (imp. def.)/(E)PPIs before configuring them.
	 * This is a more scalable approach as it avoids clearing the enable
	 * bits in the GICD_CTLR.
	 */
	for (i = 0U; i < ppi_regs_num; ++i) {
		gicr_write_icenabler(gicr_base, i, ~0U);
	}

	/* Wait for pending writes to GICR_ICENABLER */
	gicr_wait_for_pending_write(gicr_base);

	/*
	 * Disable the LPIs to avoid unpredictable behavior when writing to
	 * GICR_PROPBASER and GICR_PENDBASER.
	 */
	gicr_write_ctlr(gicr_base,
			rdist_ctx->gicr_ctlr & ~(GICR_CTLR_EN_LPIS_BIT));

	/* Restore registers' content */
	gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser);
	gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser);

	/* 32 interrupt IDs per register */
	for (i = 0U; i < ppi_regs_num; ++i) {
		RESTORE_GICR_REG(gicr_base, rdist_ctx, igroupr, i);
		RESTORE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i);
	}

	/* 4 interrupt IDs per GICR_IPRIORITYR register */
	regs_num = ppi_regs_num << 3;
	for (i = 0U; i < regs_num; ++i) {
		gicr_ipriorityr_write(gicr_base, i,
					rdist_ctx->gicr_ipriorityr[i]);
	}

	/* 16 interrupt IDs per GICR_ICFGR register */
	regs_num = ppi_regs_num << 1;
	for (i = 0U; i < regs_num; ++i) {
		RESTORE_GICR_REG(gicr_base, rdist_ctx, icfgr, i);
	}

	gicr_write_nsacr(gicr_base, rdist_ctx->gicr_nsacr);

	/* Restore after group and priorities are set.
	 * 32 interrupt IDs per register
	 */
	for (i = 0U; i < ppi_regs_num; ++i) {
		RESTORE_GICR_REG(gicr_base, rdist_ctx, ispendr, i);
		RESTORE_GICR_REG(gicr_base, rdist_ctx, isactiver, i);
	}

	/*
	 * Wait for all writes to the Distributor to complete before enabling
	 * the SGI and (E)PPIs.
	 */
	gicr_wait_for_upstream_pending_write(gicr_base);

	/* 32 interrupt IDs per GICR_ISENABLER register */
	for (i = 0U; i < ppi_regs_num; ++i) {
		RESTORE_GICR_REG(gicr_base, rdist_ctx, isenabler, i);
	}

	/*
	 * Restore GICR_CTLR.Enable_LPIs bit and wait for pending writes in case
	 * the first write to GICR_CTLR was still in flight (this write only
	 * restores GICR_CTLR.Enable_LPIs and no waiting is required for this
	 * bit).
	 */
	gicr_write_ctlr(gicr_base, rdist_ctx->gicr_ctlr);
	gicr_wait_for_pending_write(gicr_base);
}

/*****************************************************************************
 * Function to save the GIC Distributor register context. This function
 * must be invoked after CPU interface disable and Redistributor save.
 *****************************************************************************/
void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(IS_IN_EL3());
	assert(dist_ctx != NULL);

	uintptr_t gicd_base = gicv3_driver_data->gicd_base;
	unsigned int num_ints = gicv3_get_spi_limit(gicd_base);
#if GIC_EXT_INTID
	unsigned int num_eints = gicv3_get_espi_limit(gicd_base);
#endif

	/* Wait for pending write to complete */
	gicd_wait_for_pending_write(gicd_base);

	/* Save the GICD_CTLR */
	dist_ctx->gicd_ctlr = gicd_read_ctlr(gicd_base);

	/* Save GICD_IGROUPR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP);

	/* Save GICD_IGROUPRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP);

	/* Save GICD_ISENABLER for INT_IDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE);

	/* Save GICD_ISENABLERE for INT_IDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE);

	/* Save GICD_ISPENDR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND);

	/* Save GICD_ISPENDRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints,	ispendr, ISPEND);

	/* Save GICD_ISACTIVER for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE);

	/* Save GICD_ISACTIVERE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE);

	/* Save GICD_IPRIORITYR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY);

	/* Save GICD_IPRIORITYRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY);

	/* Save GICD_ICFGR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG);

	/* Save GICD_ICFGRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG);

	/* Save GICD_IGRPMODR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD);

	/* Save GICD_IGRPMODRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD);

	/* Save GICD_NSACR for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC);

	/* Save GICD_NSACRE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC);

	/* Save GICD_IROUTER for INTIDs 32 - 1019 */
	SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE);

	/* Save GICD_IROUTERE for INTIDs 4096 - 5119 */
	SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE);

	/*
	 * GICD_ITARGETSR<n> and GICD_SPENDSGIR<n> are RAZ/WI when
	 * GICD_CTLR.ARE_(S|NS) bits are set which is the case for our GICv3
	 * driver.
	 */
}

/*****************************************************************************
 * Function to restore the GIC Distributor register context. We disable G0, G1S
 * and G1NS interrupt groups before we start restore of the Distributor. This
 * function must be invoked prior to Redistributor restore and CPU interface
 * enable. The pending and active interrupts are restored after the interrupts
 * are fully configured and enabled.
 *****************************************************************************/
void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(IS_IN_EL3());
	assert(dist_ctx != NULL);

	uintptr_t gicd_base = gicv3_driver_data->gicd_base;

	/*
	 * Clear the "enable" bits for G0/G1S/G1NS interrupts before configuring
	 * the ARE_S bit. The Distributor might generate a system error
	 * otherwise.
	 */
	gicd_clr_ctlr(gicd_base,
		      CTLR_ENABLE_G0_BIT |
		      CTLR_ENABLE_G1S_BIT |
		      CTLR_ENABLE_G1NS_BIT,
		      RWP_TRUE);

	/* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */
	gicd_set_ctlr(gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE);

	unsigned int num_ints = gicv3_get_spi_limit(gicd_base);
#if GIC_EXT_INTID
	unsigned int num_eints = gicv3_get_espi_limit(gicd_base);
#endif
	/* Restore GICD_IGROUPR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP);

	/* Restore GICD_IGROUPRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP);

	/* Restore GICD_IPRIORITYR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY);

	/* Restore GICD_IPRIORITYRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY);

	/* Restore GICD_ICFGR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG);

	/* Restore GICD_ICFGRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG);

	/* Restore GICD_IGRPMODR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD);

	/* Restore GICD_IGRPMODRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD);

	/* Restore GICD_NSACR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC);

	/* Restore GICD_NSACRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC);

	/* Restore GICD_IROUTER for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE);

	/* Restore GICD_IROUTERE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE);

	/*
	 * Restore ISENABLER(E), ISPENDR(E) and ISACTIVER(E) after
	 * the interrupts are configured.
	 */

	/* Restore GICD_ISENABLER for INT_IDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE);

	/* Restore GICD_ISENABLERE for INT_IDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE);

	/* Restore GICD_ISPENDR for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND);

	/* Restore GICD_ISPENDRE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ispendr, ISPEND);

	/* Restore GICD_ISACTIVER for INTIDs 32 - 1019 */
	RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE);

	/* Restore GICD_ISACTIVERE for INTIDs 4096 - 5119 */
	RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE);

	/* Restore the GICD_CTLR */
	gicd_write_ctlr(gicd_base, dist_ctx->gicd_ctlr);
	gicd_wait_for_pending_write(gicd_base);
}

/*******************************************************************************
 * This function gets the priority of the interrupt the processor is currently
 * servicing.
 ******************************************************************************/
unsigned int gicv3_get_running_priority(void)
{
	return (unsigned int)read_icc_rpr_el1();
}

/*******************************************************************************
 * This function checks if the interrupt identified by id is active (whether the
 * state is either active, or active and pending). The proc_num is used if the
 * interrupt is SGI or (E)PPI and programs the corresponding Redistributor
 * interface.
 ******************************************************************************/
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		return gicr_get_isactiver(
			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
	}

	/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
	return gicd_get_isactiver(gicv3_driver_data->gicd_base, id);
}

/*******************************************************************************
 * This function enables the interrupt identified by id. The proc_num
 * is used if the interrupt is SGI or PPI, and programs the corresponding
 * Redistributor interface.
 ******************************************************************************/
void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/*
	 * Ensure that any shared variable updates depending on out of band
	 * interrupt trigger are observed before enabling interrupt.
	 */
	dsbishst();

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_set_isenabler(
			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
		gicd_set_isenabler(gicv3_driver_data->gicd_base, id);
	}
}

/*******************************************************************************
 * This function disables the interrupt identified by id. The proc_num
 * is used if the interrupt is SGI or PPI, and programs the corresponding
 * Redistributor interface.
 ******************************************************************************/
void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/*
	 * Disable interrupt, and ensure that any shared variable updates
	 * depending on out of band interrupt trigger are observed afterwards.
	 */

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_set_icenabler(
			gicv3_driver_data->rdistif_base_addrs[proc_num], id);

		/* Write to clear enable requires waiting for pending writes */
		gicr_wait_for_pending_write(
			gicv3_driver_data->rdistif_base_addrs[proc_num]);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
		gicd_set_icenabler(gicv3_driver_data->gicd_base, id);

		/* Write to clear enable requires waiting for pending writes */
		gicd_wait_for_pending_write(gicv3_driver_data->gicd_base);
	}

	dsbishst();
}

/*******************************************************************************
 * This function sets the interrupt priority as supplied for the given interrupt
 * id.
 ******************************************************************************/
void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
		unsigned int priority)
{
	uintptr_t gicr_base;

	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
		gicr_set_ipriorityr(gicr_base, id, priority);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
		gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority);
	}
}

/*******************************************************************************
 * This function assigns group for the interrupt identified by id. The proc_num
 * is used if the interrupt is SGI or (E)PPI, and programs the corresponding
 * Redistributor interface. The group can be any of GICV3_INTR_GROUP*
 ******************************************************************************/
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
		unsigned int type)
{
	bool igroup = false, grpmod = false;
	uintptr_t gicr_base;

	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	switch (type) {
	case INTR_GROUP1S:
		igroup = false;
		grpmod = true;
		break;
	case INTR_GROUP0:
		igroup = false;
		grpmod = false;
		break;
	case INTR_GROUP1NS:
		igroup = true;
		grpmod = false;
		break;
	default:
		assert(false);
		break;
	}

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];

		igroup ? gicr_set_igroupr(gicr_base, id) :
			 gicr_clr_igroupr(gicr_base, id);
		grpmod ? gicr_set_igrpmodr(gicr_base, id) :
			 gicr_clr_igrpmodr(gicr_base, id);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */

		/* Serialize read-modify-write to Distributor registers */
		spin_lock(&gic_lock);

		igroup ? gicd_set_igroupr(gicv3_driver_data->gicd_base, id) :
			 gicd_clr_igroupr(gicv3_driver_data->gicd_base, id);
		grpmod ? gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id) :
			 gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id);

		spin_unlock(&gic_lock);
	}
}

/*******************************************************************************
 * This function raises the specified Secure Group 0 SGI.
 *
 * The target parameter must be a valid MPIDR in the system.
 ******************************************************************************/
void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target)
{
	unsigned int tgt, aff3, aff2, aff1, aff0;
	uint64_t sgi_val;

	/* Verify interrupt number is in the SGI range */
	assert((sgi_num >= MIN_SGI_ID) && (sgi_num < MIN_PPI_ID));

	/* Extract affinity fields from target */
	aff0 = MPIDR_AFFLVL0_VAL(target);
	aff1 = MPIDR_AFFLVL1_VAL(target);
	aff2 = MPIDR_AFFLVL2_VAL(target);
	aff3 = MPIDR_AFFLVL3_VAL(target);

	/*
	 * Make target list from affinity 0, and ensure GICv3 SGI can target
	 * this PE.
	 */
	assert(aff0 < GICV3_MAX_SGI_TARGETS);
	tgt = BIT_32(aff0);

	/* Raise SGI to PE specified by its affinity */
	sgi_val = GICV3_SGIR_VALUE(aff3, aff2, aff1, sgi_num, SGIR_IRM_TO_AFF,
			tgt);

	/*
	 * Ensure that any shared variable updates depending on out of band
	 * interrupt trigger are observed before raising SGI.
	 */
	dsbishst();
	write_icc_sgi0r_el1(sgi_val);
	isb();
}

/*******************************************************************************
 * This function sets the interrupt routing for the given (E)SPI interrupt id.
 * The interrupt routing is specified in routing mode and mpidr.
 *
 * The routing mode can be either of:
 *  - GICV3_IRM_ANY
 *  - GICV3_IRM_PE
 *
 * The mpidr is the affinity of the PE to which the interrupt will be routed,
 * and is ignored for routing mode GICV3_IRM_ANY.
 ******************************************************************************/
void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr)
{
	unsigned long long aff;
	uint64_t router;

	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);

	assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE));

	assert(IS_SPI(id));

	aff = gicd_irouter_val_from_mpidr(mpidr, irm);
	gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff);

	/*
	 * In implementations that do not require 1 of N distribution of SPIs,
	 * IRM might be RAZ/WI. Read back and verify IRM bit.
	 */
	if (irm == GICV3_IRM_ANY) {
		router = gicd_read_irouter(gicv3_driver_data->gicd_base, id);
		if (((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK) == 0U) {
			ERROR("GICv3 implementation doesn't support routing ANY\n");
			panic();
		}
	}
}

/*******************************************************************************
 * This function clears the pending status of an interrupt identified by id.
 * The proc_num is used if the interrupt is SGI or (E)PPI, and programs the
 * corresponding Redistributor interface.
 ******************************************************************************/
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/*
	 * Clear pending interrupt, and ensure that any shared variable updates
	 * depending on out of band interrupt trigger are observed afterwards.
	 */

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_set_icpendr(
			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
		gicd_set_icpendr(gicv3_driver_data->gicd_base, id);
	}

	dsbishst();
}

/*******************************************************************************
 * This function sets the pending status of an interrupt identified by id.
 * The proc_num is used if the interrupt is SGI or PPI and programs the
 * corresponding Redistributor interface.
 ******************************************************************************/
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
{
	assert(gicv3_driver_data != NULL);
	assert(gicv3_driver_data->gicd_base != 0U);
	assert(proc_num < gicv3_driver_data->rdistif_num);
	assert(gicv3_driver_data->rdistif_base_addrs != NULL);

	/*
	 * Ensure that any shared variable updates depending on out of band
	 * interrupt trigger are observed before setting interrupt pending.
	 */
	dsbishst();

	/* Check interrupt ID */
	if (is_sgi_ppi(id)) {
		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
		gicr_set_ispendr(
			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
	} else {
		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
		gicd_set_ispendr(gicv3_driver_data->gicd_base, id);
	}
}

/*******************************************************************************
 * This function sets the PMR register with the supplied value. Returns the
 * original PMR.
 ******************************************************************************/
unsigned int gicv3_set_pmr(unsigned int mask)
{
	unsigned int old_mask;

	old_mask = (unsigned int)read_icc_pmr_el1();

	/*
	 * Order memory updates w.r.t. PMR write, and ensure they're visible
	 * before potential out of band interrupt trigger because of PMR update.
	 * PMR system register writes are self-synchronizing, so no ISB required
	 * thereafter.
	 */
	dsbishst();
	write_icc_pmr_el1(mask);

	return old_mask;
}

/*******************************************************************************
 * This function delegates the responsibility of discovering the corresponding
 * Redistributor frames to each CPU itself. It is a modified version of
 * gicv3_rdistif_base_addrs_probe() and is executed by each CPU in the platform
 * unlike the previous way in which only the Primary CPU did the discovery of
 * all the Redistributor frames for every CPU. It also handles the scenario in
 * which the frames of various CPUs are not contiguous in physical memory.
 ******************************************************************************/
int gicv3_rdistif_probe(const uintptr_t gicr_frame)
{
	u_register_t mpidr, mpidr_self;
	unsigned int proc_num;
	uint64_t typer_val;
	uintptr_t rdistif_base;
	bool gicr_frame_found = false;

	assert(gicv3_driver_data->gicr_base == 0U);

	/* Ensure this function is called with Data Cache enabled */
#ifndef __aarch64__
	assert((read_sctlr() & SCTLR_C_BIT) != 0U);
#else
	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
#endif /* !__aarch64__ */

	mpidr_self = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
	rdistif_base = gicr_frame;
	do {
		typer_val = gicr_read_typer(rdistif_base);
		mpidr = mpidr_from_gicr_typer(typer_val);
		if (gicv3_driver_data->mpidr_to_core_pos != NULL) {
			proc_num = gicv3_driver_data->mpidr_to_core_pos(mpidr);
		} else {
			proc_num = (unsigned int)(typer_val >>
				TYPER_PROC_NUM_SHIFT) & TYPER_PROC_NUM_MASK;
		}
		if (mpidr == mpidr_self) {
			/* The base address doesn't need to be initialized on
			 * every warm boot.
			 */
			if (gicv3_driver_data->rdistif_base_addrs[proc_num]
								!= 0U) {
				return 0;
			}
			gicv3_driver_data->rdistif_base_addrs[proc_num] =
			rdistif_base;
			gicr_frame_found = true;
			break;
		}
		rdistif_base += gicv3_redist_size(typer_val);
	} while ((typer_val & TYPER_LAST_BIT) == 0U);

	if (!gicr_frame_found) {
		return -1;
	}

	/*
	 * Flush the driver data to ensure coherency. This is
	 * not required if platform has HW_ASSISTED_COHERENCY
	 * enabled.
	 */
#if !HW_ASSISTED_COHERENCY
	/*
	 * Flush the rdistif_base_addrs[] contents linked to the GICv3 driver.
	 */
	flush_dcache_range((uintptr_t)&(gicv3_driver_data->rdistif_base_addrs[proc_num]),
		sizeof(*(gicv3_driver_data->rdistif_base_addrs)));
#endif
	return 0; /* Found matching GICR frame */
}

/******************************************************************************
 * This function checks the interrupt ID and returns true for SGIs and (E)PPIs
 * and false for (E)SPIs IDs.
 *****************************************************************************/
static bool is_sgi_ppi(unsigned int id)
{
	/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */
	if (IS_SGI_PPI(id)) {
		return true;
	}

	/* SPIs: 32-1019, ESPIs: 4096-5119 */
	if (IS_SPI(id)) {
		return false;
	}

	assert(false);
	panic();
}
