armv8/secmon: Disable and Enable GIC in PSCI path
Disable and enable GIC before switching off a CPU and after bringing
it up back respectively.
BUG=None
BRANCH=None
TEST=Compiles successfully and psci commands work for ryu.
Change-Id: Ib43af60e994e3d072e897a59595775d0b2dcef83
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: d5271d731f0a569583c2b32ef6726dadbfa846d3
Original-Change-Id: I672945fcb0ff416008a1aad5ed625cfa91bb9cbd
Original-Signed-off-by: Furquan Shaikh <furquan@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/265623
Original-Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
Original-Tested-by: Furquan Shaikh <furquan@chromium.org>
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/9926
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Tested-by: build bot (Jenkins)
diff --git a/src/arch/arm64/armv8/secmon/Makefile.inc b/src/arch/arm64/armv8/secmon/Makefile.inc
index 5284d39..ace00b4 100644
--- a/src/arch/arm64/armv8/secmon/Makefile.inc
+++ b/src/arch/arm64/armv8/secmon/Makefile.inc
@@ -39,6 +39,7 @@
secmon-y += ../exception.c
secmon-y += ../../cpu.c
secmon-y += ../../transition_asm.S ../../transition.c
+secmon-y += ../../../../drivers/gic/gic.c
ramstage-srcs += $(SECMON_RAMSTAGE)
diff --git a/src/arch/arm64/armv8/secmon/psci.c b/src/arch/arm64/armv8/secmon/psci.c
index a651b6e..70251b2 100644
--- a/src/arch/arm64/armv8/secmon/psci.c
+++ b/src/arch/arm64/armv8/secmon/psci.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
*/
+#include <gic.h>
#include <string.h>
#include <stdlib.h>
#include <smp/spinlock.h>
@@ -231,6 +232,7 @@
void psci_cpu_entry(void)
{
+ gic_enable();
/*
* Just wait for an action to be performed. Only CPU_ON is supported
* initially. i.e. no power down then wake.
@@ -327,6 +329,8 @@
if (ret != PSCI_RET_SUCCESS)
return ret;
+ gic_disable();
+
/* Should never return. */
ret = soc_psci_ops.cmd_commit(&cmd);
diff --git a/src/drivers/gic/gic.c b/src/drivers/gic/gic.c
index 8972d04..71073a5 100644
--- a/src/drivers/gic/gic.c
+++ b/src/drivers/gic/gic.c
@@ -59,6 +59,11 @@
return &gic;
}
+static inline uint32_t gic_read(uint32_t *base)
+{
+ return read32(base);
+}
+
static inline void gic_write(uint32_t *base, uint32_t val)
{
write32(base, val);
@@ -118,3 +123,31 @@
/* Allow Non-secure access to everything. */
gic_write_regs(&gicd->nsacr[0], gic->num_interrupts / 16, ~0x0);
}
+
+void gic_disable(void)
+{
+ struct gic *gic;
+ struct gicc_mmio *gicc;
+
+ gic = gic_get();
+ gicc = gic->gicc;
+
+ /* Disable secure, non-secure interrupts. */
+ uint32_t val = gic_read(&gicc->ctlr);
+ val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+ gic_write(&gicc->ctlr, val);
+}
+
+void gic_enable(void)
+{
+ struct gic *gic;
+ struct gicc_mmio *gicc;
+
+ gic = gic_get();
+ gicc = gic->gicc;
+
+ /* Enable secure, non-secure interrupts. */
+ uint32_t val = gic_read(&gicc->ctlr);
+ val |= (ENABLE_GRP0 | ENABLE_GRP1);
+ gic_write(&gicc->ctlr, val);
+}
diff --git a/src/include/gic.h b/src/include/gic.h
index 22c5631..2514420 100644
--- a/src/include/gic.h
+++ b/src/include/gic.h
@@ -24,6 +24,8 @@
/* Initialize the GIC on the currently processor, including GICD and GICC. */
void gic_init(void);
+void gic_disable(void);
+void gic_enable(void);
/* Return a pointer to the base of the GIC distributor mmio region. */
void *gicd_base(void);
@@ -34,6 +36,7 @@
#else /* CONFIG_GIC */
static inline void gic_init(void) {}
+static inline void gic_disable(void) {}
#endif /* CONFIG_GIC */