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)
+{
+ int i;
+
+ assert(gicv3_driver_data);
+ assert(IS_IN_EL3());
+ assert(its_ctx);
+ assert(gits_base);
+
+ 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 = 0; 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)
+{
+ int i;
+
+ assert(gicv3_driver_data);
+ assert(IS_IN_EL3());
+ assert(its_ctx);
+ assert(gits_base);
+
+ /* Assert that the GITS is disabled and quiescent */
+ assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0);
+ assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 1);
+
+ gits_write_cbaser(gits_base, its_ctx->gits_cbaser);
+ gits_write_cwriter(gits_base, its_ctx->gits_cwriter);
+
+ for (i = 0; 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.
mmio_write_32(base + GICR_PENDBASER, val);
}
+/*******************************************************************************
+ * GIC ITS functions to read and write entire ITS registers.
+ ******************************************************************************/
+static inline uint32_t gits_read_ctlr(uintptr_t base)
+{
+ return mmio_read_32(base + GITS_CTLR);
+}
+
+static inline void gits_write_ctlr(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GITS_CTLR, val);
+}
+
+static inline uint64_t gits_read_cbaser(uintptr_t base)
+{
+ return mmio_read_64(base + GITS_CBASER);
+}
+
+static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
+{
+ mmio_write_32(base + GITS_CBASER, val);
+}
+
+static inline uint64_t gits_read_cwriter(uintptr_t base)
+{
+ return mmio_read_64(base + GITS_CWRITER);
+}
+
+static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
+{
+ mmio_write_32(base + GITS_CWRITER, val);
+}
+
+static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id)
+{
+ assert(its_table_id < 8);
+ return mmio_read_64(base + GITS_BASER + (8 * its_table_id));
+}
+
+static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val)
+{
+ assert(its_table_id < 8);
+ mmio_write_64(base + GITS_BASER + (8 * its_table_id), val);
+}
+
+/*
+ * Wait for Quiescent bit when GIC ITS is disabled
+ */
+static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
+{
+ assert(!(gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT));
+ while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0)
+ ;
+}
+
+
#endif /* __GICV3_PRIVATE_H__ */
#define IAR1_EL1_INTID_SHIFT 0
#define IAR1_EL1_INTID_MASK 0xffffff
+/*****************************************************************************
+ * GICv3 ITS registers and constants
+ *****************************************************************************/
+
+#define GITS_CTLR 0x0
+#define GITS_IIDR 0x4
+#define GITS_TYPER 0x8
+#define GITS_CBASER 0x80
+#define GITS_CWRITER 0x88
+#define GITS_CREADR 0x90
+#define GITS_BASER 0x100
+
+/* GITS_CTLR bit definitions */
+#define GITS_CTLR_ENABLED_BIT 1
+#define GITS_CTLR_QUIESCENT_SHIFT 31
+#define GITS_CTLR_QUIESCENT_BIT (1U << GITS_CTLR_QUIESCENT_SHIFT)
+
#ifndef __ASSEMBLY__
#include <gic_common.h>
uint32_t gicd_nsacr[GICD_NUM_REGS(NSACR)];
} gicv3_dist_ctx_t;
+typedef struct gicv3_its_ctx {
+ /* 64 bits registers */
+ uint64_t gits_cbaser;
+ uint64_t gits_cwriter;
+ uint64_t gits_baser[8];
+
+ /* 32 bits registers */
+ uint32_t gits_ctlr;
+} gicv3_its_ctx_t;
+
/*******************************************************************************
* GICv3 EL3 driver API
******************************************************************************/
void gicv3_distif_pre_save(unsigned int proc_num);
void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx);
void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx);
+void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx);
+void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx);
#endif /* __ASSEMBLY__ */
#endif /* __GICV3_H__ */