summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-03-19 10:59:38 -0700
committerRandall Spangler <rspangler@chromium.org>2012-03-19 15:41:14 -0700
commitb2ac77b37b66ce2e6e621743d5cd1510457cc19f (patch)
tree53a66e7092d8a1fc74f04178c805ec05eb77f637 /core
parent1fd7062b29c685d98be8586ded4587e5e1e169ee (diff)
downloadchrome-ec-b2ac77b37b66ce2e6e621743d5cd1510457cc19f.tar.gz
Support warm reboot from one EC image to another.
This is necessary at init-time for verified boot to jump from RO to one of the RW images. It's also used by factory EC update to update one image and then jump to the updated image to finish the update. In this case, the x86 does NOT reboot. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:8449 TEST=manual 1) power on x86 and log in 2) sysjump a --> system is in a; x86 has not rebooted 3) sysjump ro --> system is back in RO; x86 has not rebooted 4) reboot -> system is in RO; x86 HAS rebooted Change-Id: I9dbadcf9775e146a0718abfd4ee0758b65350a87
Diffstat (limited to 'core')
-rw-r--r--core/cortex-m/cpu.h1
-rw-r--r--core/cortex-m/init.S8
-rw-r--r--core/cortex-m/task.c22
3 files changed, 24 insertions, 7 deletions
diff --git a/core/cortex-m/cpu.h b/core/cortex-m/cpu.h
index 1ec95442fe..bd94e179fe 100644
--- a/core/cortex-m/cpu.h
+++ b/core/cortex-m/cpu.h
@@ -16,6 +16,7 @@
/* Nested Vectored Interrupt Controller */
#define CPU_NVIC_EN(x) CPUREG(0xe000e100 + 4 * (x))
#define CPU_NVIC_DIS(x) CPUREG(0xe000e180 + 4 * (x))
+#define CPU_NVIC_UNPEND(x) CPUREG(0xe000e280 + 4 * (x))
#define CPU_NVIC_PRI(x) CPUREG(0xe000e400 + 4 * (x))
#define CPU_NVIC_APINT CPUREG(0xe000ed0c)
#define CPU_NVIC_SWTRIG CPUREG(0xe000ef00)
diff --git a/core/cortex-m/init.S b/core/cortex-m/init.S
index f8fa196dee..a2c0d0b71e 100644
--- a/core/cortex-m/init.S
+++ b/core/cortex-m/init.S
@@ -302,7 +302,13 @@ vector_irq 254 @ IRQ 254 handler
.global reset
.thumb_func
reset:
- /* set the vector table on our current code */
+ /* Ensure we're in privileged mode with main stack.
+ * Necessary if we've jumped directly here from another image
+ * after task_start(). */
+ mov r0, #0
+ msr control, r0 @ use : priv. mode / main stack / no floating point
+ isb @ ensure the write is done
+ /* Set the vector table on our current code */
ldr r1, =vectors
ldr r2, =0xE000ED08 /* VTABLE register in SCB*/
str r1, [r2]
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index 41b91de348..246147b7c7 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -299,18 +299,28 @@ void task_trigger_irq(int irq)
}
-/**
- * Enable all used IRQ in the NVIC and set their priorities
- * as defined by the DECLARE_IRQ statements
- */
+/* Initialize IRQs in the NVIC and set their priorities as defined by the
+ * DECLARE_IRQ statements. */
static void __nvic_init_irqs(void)
{
- /* get the IRQ priorities section from the linker */
+ /* Get the IRQ priorities section from the linker */
extern struct irq_priority __irqprio[];
extern struct irq_priority __irqprio_end[];
int irq_count = __irqprio_end - __irqprio;
int i;
+ /* Mask and clear all pending interrupts */
+ for (i = 0; i < 5; i++) {
+ CPU_NVIC_DIS(i) = 0xffffffff;
+ CPU_NVIC_UNPEND(i) = 0xffffffff;
+ }
+
+ /* Re-enable global interrupts in case they're disabled. On a reboot,
+ * they're already enabled; if we've jumped here from another image,
+ * they're not. */
+ interrupt_enable();
+
+ /* Set priorities */
for (i = 0; i < irq_count; i++) {
uint8_t irq = __irqprio[i].irq;
uint8_t prio = __irqprio[i].priority;
@@ -405,7 +415,7 @@ DECLARE_CONSOLE_COMMAND(taskready, command_task_ready);
#endif
-int task_init(void)
+int task_pre_init(void)
{
/* sanity checks about static task invariants */
BUILD_ASSERT(TASK_ID_COUNT <= sizeof(unsigned) * 8);