summaryrefslogtreecommitdiff
path: root/chip
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 /chip
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 'chip')
-rw-r--r--chip/lm4/gpio.c26
-rw-r--r--chip/lm4/peci.c3
-rw-r--r--chip/lm4/system.c3
-rw-r--r--chip/lm4/uart.c11
-rw-r--r--chip/lm4/watchdog.c12
-rw-r--r--chip/stm32l/uart.c12
6 files changed, 55 insertions, 12 deletions
diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c
index 81b7312f03..a7c4f96163 100644
--- a/chip/lm4/gpio.c
+++ b/chip/lm4/gpio.c
@@ -16,7 +16,7 @@
/* 0-terminated list of GPIO bases */
-const uint32_t gpio_bases[] = {
+static const uint32_t gpio_bases[] = {
LM4_GPIO_A, LM4_GPIO_B, LM4_GPIO_C, LM4_GPIO_D,
LM4_GPIO_E, LM4_GPIO_F, LM4_GPIO_G, LM4_GPIO_H,
LM4_GPIO_J, LM4_GPIO_K, LM4_GPIO_L, LM4_GPIO_M,
@@ -45,12 +45,18 @@ int gpio_pre_init(void)
{
volatile uint32_t scratch __attribute__((unused));
const struct gpio_info *g = gpio_list;
+ int is_warm = 0;
int i;
- /* Enable clocks to all the GPIO blocks (since we use all of them as
- * GPIOs) */
- LM4_SYSTEM_RCGCGPIO |= 0x7fff;
- scratch = LM4_SYSTEM_RCGCGPIO; /* Delay a few clocks */
+ if (LM4_SYSTEM_RCGCGPIO == 0x7fff) {
+ /* This is a warm reboot */
+ is_warm = 1;
+ } else {
+ /* Enable clocks to all the GPIO blocks (since we use all of
+ * them as GPIOs) */
+ LM4_SYSTEM_RCGCGPIO |= 0x7fff;
+ scratch = LM4_SYSTEM_RCGCGPIO; /* Delay a few clocks */
+ }
/* Disable GPIO commit control for PD7 and PF0, since we don't use the
* NMI pin function. */
@@ -64,6 +70,10 @@ int gpio_pre_init(void)
/* Clear SSI0 alternate function on PA2:5 */
LM4_GPIO_AFSEL(LM4_GPIO_A) &= ~0x3c;
+ /* Mask all GPIO interrupts */
+ for (i = 0; gpio_bases[i]; i++)
+ LM4_GPIO_IM(gpio_bases[i]) = 0;
+
/* Set all GPIOs to defaults */
for (i = 0; i < GPIO_COUNT; i++, g++) {
@@ -76,7 +86,11 @@ int gpio_pre_init(void)
LM4_GPIO_DIR(g->port) |= g->mask;
/* Must set level after direction; writes to GPIO_DATA
* before direction is output appear to be ignored. */
- gpio_set_level(i, g->flags & GPIO_HIGH);
+ /* Only set level on a cold reboot; on a warm reboot we
+ * want to leave things where they were or we'll shut
+ * off the x86. */
+ if (!is_warm)
+ gpio_set_level(i, g->flags & GPIO_HIGH);
} else {
/* Input */
if (g->flags & GPIO_PULL) {
diff --git a/chip/lm4/peci.c b/chip/lm4/peci.c
index f3479821e2..75946a4e61 100644
--- a/chip/lm4/peci.c
+++ b/chip/lm4/peci.c
@@ -97,6 +97,9 @@ int peci_init(void)
/* Configure GPIOs */
configure_gpios();
+ /* Disable polling while reconfiguring */
+ LM4_PECI_CTL = 0;
+
/* Calculate baud setting from desired rate, compensating for internal
* and external delays. */
baud = CPU_CLOCK / (4 * PECI_BAUD_RATE) - 2;
diff --git a/chip/lm4/system.c b/chip/lm4/system.c
index 200cd6c73c..4915bb242f 100644
--- a/chip/lm4/system.c
+++ b/chip/lm4/system.c
@@ -61,7 +61,8 @@ static void check_reset_cause(void)
} else if (raw_reset_cause) {
reset_cause = SYSTEM_RESET_OTHER;
} else {
- reset_cause = SYSTEM_RESET_UNKNOWN;
+ /* Reset cause is still 0, so this is a warm reset. */
+ reset_cause = SYSTEM_RESET_SOFT_WARM;
}
system_set_reset_cause(reset_cause);
}
diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c
index fa9ddb005f..652f1edf37 100644
--- a/chip/lm4/uart.c
+++ b/chip/lm4/uart.c
@@ -19,6 +19,15 @@
/* Baud rate for UARTs */
#define BAUD_RATE 115200
+
+static int init_done;
+
+
+int uart_init_done(void)
+{
+ return init_done;
+}
+
void uart_tx_start(void)
{
/* Re-enable the transmit interrupt, then forcibly trigger the
@@ -186,6 +195,8 @@ int uart_init(void)
*/
task_enable_irq(LM4_IRQ_UART0);
+ init_done = 1;
+
return EC_SUCCESS;
}
diff --git a/chip/lm4/watchdog.c b/chip/lm4/watchdog.c
index 5a3080dcdb..74fe3e5fbd 100644
--- a/chip/lm4/watchdog.c
+++ b/chip/lm4/watchdog.c
@@ -114,10 +114,13 @@ int watchdog_init(int period_ms)
/* Enable watchdog 0 clock */
LM4_SYSTEM_RCGCWD |= 0x1;
- /* wait 3 clock cycles before using the module */
+ /* Wait 3 clock cycles before using the module */
scratch = LM4_SYSTEM_RCGCWD;
- /* set the time-out period */
+ /* Unlock watchdog registers */
+ LM4_WATCHDOG_LOCK(0) = LM4_WATCHDOG_MAGIC_WORD;
+
+ /* Set the time-out period */
watchdog_period = period_ms * (CPU_CLOCK / 1000);
LM4_WATCHDOG_LOAD(0) = watchdog_period;
@@ -129,7 +132,10 @@ int watchdog_init(int period_ms)
*/
LM4_WATCHDOG_CTL(0) = 0x3;
- /* lock watchdog registers against unintended accesses */
+ /* Reset watchdog interrupt bits */
+ LM4_WATCHDOG_ICR(0) = LM4_WATCHDOG_RIS(0);
+
+ /* Lock watchdog registers against unintended accesses */
LM4_WATCHDOG_LOCK(0) = 0xdeaddead;
/* Enable watchdog interrupt */
diff --git a/chip/stm32l/uart.c b/chip/stm32l/uart.c
index 9d5dd139f7..9da697debe 100644
--- a/chip/stm32l/uart.c
+++ b/chip/stm32l/uart.c
@@ -20,8 +20,14 @@
/* Console USART index */
#define UARTN CONFIG_CONSOLE_UART
-/* record last TX control action */
-static int should_stop;
+static int init_done; /* Initialization done? */
+static int should_stop; /* Last TX control action */
+
+
+int uart_init_done(void)
+{
+ return init_done;
+}
void uart_tx_start(void)
{
@@ -138,5 +144,7 @@ int uart_init(void)
/* Enable interrupts */
task_enable_irq(STM32L_IRQ_USART(UARTN));
+ init_done = 1;
+
return EC_SUCCESS;
}