summaryrefslogtreecommitdiff
path: root/drivers/arm/gic/v3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/arm/gic/v3')
-rw-r--r--drivers/arm/gic/v3/arm_gicv3_common.c105
-rw-r--r--drivers/arm/gic/v3/gic500.c22
-rw-r--r--drivers/arm/gic/v3/gic600.c13
-rw-r--r--drivers/arm/gic/v3/gicv3_main.c295
-rw-r--r--drivers/arm/gic/v3/gicv3_private.h81
5 files changed, 513 insertions, 3 deletions
diff --git a/drivers/arm/gic/v3/arm_gicv3_common.c b/drivers/arm/gic/v3/arm_gicv3_common.c
new file mode 100644
index 00000000..8d552ca5
--- /dev/null
+++ b/drivers/arm/gic/v3/arm_gicv3_common.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Driver for implementation defined features that are identical in ARM GICv3
+* implementations (GIC-500 and GIC-600 for now). This driver only overrides
+* APIs that are different to those generic ones in GICv3 driver.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <gicv3.h>
+
+#include "gicv3_private.h"
+#include "arm_gicv3_common.h"
+
+/*
+ * Flush the internal GIC cache of the LPIs pending tables to memory before
+ * saving the state of the Redistributor. This is required before powering off
+ * the GIC when the pending status must be preserved.
+ * `rdist_proc_num` is the processor number corresponding to the Redistributor of the
+ * current CPU.
+ */
+void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
+{
+ uintptr_t gicr_base = 0;
+
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+
+ /*
+ * The GICR_WAKER.Sleep bit should be set only when both
+ * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
+ * all the Redistributors.
+ */
+ for (unsigned int i = 0; i < gicv3_driver_data->rdistif_num; i++) {
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[i];
+ assert(gicr_base);
+ assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT);
+ assert(gicr_read_waker(gicr_base) & WAKER_PS_BIT);
+ }
+
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
+ /*
+ * According to the TRM, there is only one instance of the
+ * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
+ * through any of the Redistributor.
+ */
+
+ /*
+ * Set GICR_WAKER.Sleep
+ * After this point, the system must be configured so that the
+ * wake_request signals for the right cores are asserted when a wakeup
+ * interrupt is detected. The GIC will not be able to do that anymore
+ * when the GICR_WAKER.Sleep bit is set to 1.
+ */
+ gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);
+
+ /* Wait until the GICR_WAKER.Quiescent bit is set */
+ while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
+ ;
+}
+
+/*
+ * Allow the LPIs pending state to be read back from the tables in memory after
+ * having restored the state of the GIC Redistributor.
+ */
+void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num)
+{
+ uintptr_t gicr_base;
+
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+
+ /*
+ * According to the TRM, there is only one instance of the
+ * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
+ * through any of the Redistributor.
+ */
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
+ assert(gicr_base);
+
+ /*
+ * Writes to GICR_WAKER.Sleep bit are ignored if GICR_WAKER.Quiescent
+ * bit is not set. We should be alright on power on path, therefore
+ * coming out of sleep and Quiescent should be set, but we assert in
+ * case.
+ */
+ assert(gicr_read_waker(gicr_base) & WAKER_QSC_BIT);
+
+ /* Clear GICR_WAKER.Sleep */
+ gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_SL_BIT);
+
+ /*
+ * We don't know if the effects of setting GICR_WAKER.Sleep bit is
+ * instantaneous, so we wait until the interface is not Quiescent
+ * anymore.
+ */
+ while (gicr_read_waker(gicr_base) & WAKER_QSC_BIT)
+ ;
+}
+
diff --git a/drivers/arm/gic/v3/gic500.c b/drivers/arm/gic/v3/gic500.c
new file mode 100644
index 00000000..f03e33f8
--- /dev/null
+++ b/drivers/arm/gic/v3/gic500.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Driver for GIC500-specific features. This driver only overrides APIs that are
+ * different to those generic ones in GICv3 driver.
+ */
+#include "gicv3_private.h"
+
+void gicv3_distif_pre_save(unsigned int proc_num)
+{
+ arm_gicv3_distif_pre_save(proc_num);
+}
+
+void gicv3_distif_post_restore(unsigned int proc_num)
+{
+ arm_gicv3_distif_post_restore(proc_num);
+}
+
diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic600.c
index 217c08fd..eb4fc548 100644
--- a/drivers/arm/gic/v3/gic600.c
+++ b/drivers/arm/gic/v3/gic600.c
@@ -32,9 +32,6 @@
#define PWRR_ON (0 << PWRR_RDPD_SHIFT)
#define PWRR_OFF (1 << PWRR_RDPD_SHIFT)
-/* Generic GICv3 resources */
-extern const gicv3_driver_data_t *gicv3_driver_data;
-
/* GIC600-specific accessor functions */
static void gicr_write_pwrr(uintptr_t base, unsigned int val)
{
@@ -82,6 +79,16 @@ static void gic600_pwr_off(uintptr_t base)
}
}
+void gicv3_distif_pre_save(unsigned int proc_num)
+{
+ arm_gicv3_distif_pre_save(proc_num);
+}
+
+void gicv3_distif_post_restore(unsigned int proc_num)
+{
+ arm_gicv3_distif_post_restore(proc_num);
+}
+
/*
* Power off GIC600 redistributor
*/
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index b68d9988..83bf430f 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -21,6 +21,27 @@ static unsigned int gicv2_compat;
#pragma weak gicv3_rdistif_off
#pragma weak gicv3_rdistif_on
+
+/* 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 += (1 << REG##_SHIFT)) { \
+ gicd_write_##reg(base, int_id, \
+ ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT]); \
+ } \
+ } while (0)
+
+#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 += (1 << REG##_SHIFT)) { \
+ ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT] =\
+ gicd_read_##reg(base, int_id); \
+ } \
+ } while (0)
+
+
/*******************************************************************************
* This function initialises the ARM GICv3 driver in EL3 with provided platform
* inputs.
@@ -406,3 +427,277 @@ unsigned int gicv3_get_interrupt_type(unsigned int id,
/* Else it is a Group 0 Secure interrupt */
return INTR_GROUP0;
}
+
+/*****************************************************************************
+ * 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 int_id;
+
+ assert(gicv3_driver_data);
+ assert(proc_num < gicv3_driver_data->rdistif_num);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(IS_IN_EL3());
+ assert(rdist_ctx);
+
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+ /*
+ * 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);
+
+ rdist_ctx->gicr_igroupr0 = gicr_read_igroupr0(gicr_base);
+ rdist_ctx->gicr_isenabler0 = gicr_read_isenabler0(gicr_base);
+ rdist_ctx->gicr_ispendr0 = gicr_read_ispendr0(gicr_base);
+ rdist_ctx->gicr_isactiver0 = gicr_read_isactiver0(gicr_base);
+ rdist_ctx->gicr_icfgr0 = gicr_read_icfgr0(gicr_base);
+ rdist_ctx->gicr_icfgr1 = gicr_read_icfgr1(gicr_base);
+ rdist_ctx->gicr_igrpmodr0 = gicr_read_igrpmodr0(gicr_base);
+ rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base);
+ for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM;
+ int_id += (1 << IPRIORITYR_SHIFT)) {
+ rdist_ctx->gicr_ipriorityr[(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT] =
+ gicr_read_ipriorityr(gicr_base, int_id);
+ }
+
+
+ /*
+ * 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 int_id;
+
+ assert(gicv3_driver_data);
+ assert(proc_num < gicv3_driver_data->rdistif_num);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(IS_IN_EL3());
+ assert(rdist_ctx);
+
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+ /* 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.)/PPIs before configuring them. This is a
+ * more scalable approach as it avoids clearing the enable bits in the
+ * GICD_CTLR
+ */
+ gicr_write_icenabler0(gicr_base, ~0);
+ /* 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);
+
+ gicr_write_igroupr0(gicr_base, rdist_ctx->gicr_igroupr0);
+
+ for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM;
+ int_id += (1 << IPRIORITYR_SHIFT)) {
+ gicr_write_ipriorityr(gicr_base, int_id,
+ rdist_ctx->gicr_ipriorityr[
+ (int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT]);
+ }
+
+ gicr_write_icfgr0(gicr_base, rdist_ctx->gicr_icfgr0);
+ gicr_write_icfgr1(gicr_base, rdist_ctx->gicr_icfgr1);
+ gicr_write_igrpmodr0(gicr_base, rdist_ctx->gicr_igrpmodr0);
+ gicr_write_nsacr(gicr_base, rdist_ctx->gicr_nsacr);
+
+ /* Restore after group and priorities are set */
+ gicr_write_ispendr0(gicr_base, rdist_ctx->gicr_ispendr0);
+ gicr_write_isactiver0(gicr_base, rdist_ctx->gicr_isactiver0);
+
+ /*
+ * Wait for all writes to the Distributor to complete before enabling
+ * the SGI and PPIs.
+ */
+ gicr_wait_for_upstream_pending_write(gicr_base);
+ gicr_write_isenabler0(gicr_base, rdist_ctx->gicr_isenabler0);
+
+ /*
+ * 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)
+{
+ unsigned int num_ints;
+
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->gicd_base);
+ assert(IS_IN_EL3());
+ assert(dist_ctx);
+
+ uintptr_t gicd_base = gicv3_driver_data->gicd_base;
+
+ num_ints = gicd_read_typer(gicd_base);
+ num_ints &= TYPER_IT_LINES_NO_MASK;
+ num_ints = (num_ints + 1) << 5;
+
+ assert(num_ints <= MAX_SPI_ID + 1);
+
+ /* 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 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR);
+
+ /* Save GICD_ISENABLER for INT_IDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER);
+
+ /* Save GICD_ISPENDR for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR);
+
+ /* Save GICD_ISACTIVER for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER);
+
+ /* Save GICD_IPRIORITYR for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR);
+
+ /* Save GICD_ICFGR for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR);
+
+ /* Save GICD_IGRPMODR for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR);
+
+ /* Save GICD_NSACR for INTIDs 32 - 1020 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR);
+
+ /* Save GICD_IROUTER for INTIDs 32 - 1024 */
+ SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER);
+
+ /*
+ * 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)
+{
+ unsigned int num_ints = 0;
+
+ assert(gicv3_driver_data);
+ assert(gicv3_driver_data->gicd_base);
+ assert(IS_IN_EL3());
+ assert(dist_ctx);
+
+ 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);
+
+ num_ints = gicd_read_typer(gicd_base);
+ num_ints &= TYPER_IT_LINES_NO_MASK;
+ num_ints = (num_ints + 1) << 5;
+
+ assert(num_ints <= MAX_SPI_ID + 1);
+
+ /* Restore GICD_IGROUPR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR);
+
+ /* Restore GICD_IPRIORITYR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR);
+
+ /* Restore GICD_ICFGR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR);
+
+ /* Restore GICD_IGRPMODR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR);
+
+ /* Restore GICD_NSACR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR);
+
+ /* Restore GICD_IROUTER for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER);
+
+ /*
+ * Restore ISENABLER, ISPENDR and ISACTIVER after the interrupts are
+ * configured.
+ */
+
+ /* Restore GICD_ISENABLER for INT_IDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER);
+
+ /* Restore GICD_ISPENDR for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR);
+
+ /* Restore GICD_ISACTIVER for INTIDs 32 - 1020 */
+ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER);
+
+ /* Restore the GICD_CTLR */
+ gicd_write_ctlr(gicd_base, dist_ctx->gicd_ctlr);
+ gicd_wait_for_pending_write(gicd_base);
+
+}
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index da4bcbf7..7224e067 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -7,6 +7,7 @@
#ifndef __GICV3_PRIVATE_H__
#define __GICV3_PRIVATE_H__
+#include <assert.h>
#include <gic_common.h>
#include <gicv3.h>
#include <mmio.h>
@@ -43,6 +44,11 @@
#endif
/*******************************************************************************
+ * GICv3 private global variables declarations
+ ******************************************************************************/
+extern const gicv3_driver_data_t *gicv3_driver_data;
+
+/*******************************************************************************
* Private GICv3 function prototypes for accessing entire registers.
* Note: The raw register values correspond to multiple interrupt IDs and
* the number of interrupt IDs involved depends on the register accessed.
@@ -150,6 +156,11 @@ static inline unsigned long long gicr_read_ctlr(uintptr_t base)
return mmio_read_64(base + GICR_CTLR);
}
+static inline void gicr_write_ctlr(uintptr_t base, uint64_t val)
+{
+ mmio_write_64(base + GICR_CTLR, val);
+}
+
static inline unsigned long long gicr_read_typer(uintptr_t base)
{
return mmio_read_64(base + GICR_TYPER);
@@ -178,6 +189,16 @@ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
;
}
+static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
+{
+ while (gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT)
+ ;
+}
+
+/* Private implementation of Distributor power control hooks */
+void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num);
+void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
+
/*******************************************************************************
* GIC Re-distributor functions for accessing entire registers.
* Note: The raw register values correspond to multiple interrupt IDs and
@@ -208,6 +229,16 @@ static inline unsigned int gicr_read_igroupr0(uintptr_t base)
return mmio_read_32(base + GICR_IGROUPR0);
}
+static inline unsigned int gicr_read_ispendr0(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_ISPENDR0);
+}
+
+static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_ISPENDR0, val);
+}
+
static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val)
{
mmio_write_32(base + GICR_IGROUPR0, val);
@@ -223,14 +254,64 @@ static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val)
mmio_write_32(base + GICR_IGRPMODR0, val);
}
+static inline unsigned int gicr_read_nsacr(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_NSACR);
+}
+
+static inline void gicr_write_nsacr(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_NSACR, val);
+}
+
+static inline unsigned int gicr_read_isactiver0(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_ISACTIVER0);
+}
+
+static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_ISACTIVER0, val);
+}
+
+static inline unsigned int gicr_read_icfgr0(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_ICFGR0);
+}
+
static inline unsigned int gicr_read_icfgr1(uintptr_t base)
{
return mmio_read_32(base + GICR_ICFGR1);
}
+static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_ICFGR0, val);
+}
+
static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val)
{
mmio_write_32(base + GICR_ICFGR1, val);
}
+static inline unsigned int gicr_read_propbaser(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_PROPBASER);
+}
+
+static inline void gicr_write_propbaser(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_PROPBASER, val);
+}
+
+static inline unsigned int gicr_read_pendbaser(uintptr_t base)
+{
+ return mmio_read_32(base + GICR_PENDBASER);
+}
+
+static inline void gicr_write_pendbaser(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GICR_PENDBASER, val);
+}
+
#endif /* __GICV3_PRIVATE_H__ */