summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-04-25 13:04:23 -0700
committerRandall Spangler <rspangler@chromium.org>2012-04-25 14:49:49 -0700
commit1aa57e140e3c8ef02c0140730dde3962d3eb821f (patch)
tree18b39676fa0b9cbae24e3cb50a712336ed3a7528 /core
parent212784b5fab0a1ba30c45e66a9329423a6d998e5 (diff)
downloadchrome-ec-1aa57e140e3c8ef02c0140730dde3962d3eb821f.tar.gz
Watchdog fixes
1) When frequency changes, reload the watchdog timer right away, or it may expire before the next reload. (Only matters when re-enabling the PLL.) 2) Split out the timer/task debug output used by the watchdog into their own routines, instead of assuming it's safe to call the command handlers. Also make the flushes in those print routines safe to call from interrupt level. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=none TEST=waitms 1500; should print task dump again Change-Id: I07e0ed24a526ae499566dab0bbeb0f5755cd5be6
Diffstat (limited to 'core')
-rw-r--r--core/cortex-m/task.c47
-rw-r--r--core/cortex-m/timer.c54
2 files changed, 63 insertions, 38 deletions
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index 3f63797146..b21d2cd59c 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -12,6 +12,7 @@
#include "link_defs.h"
#include "task.h"
#include "timer.h"
+#include "uart.h"
#include "util.h"
/**
@@ -191,9 +192,9 @@ inline int get_interrupt_context(void)
}
-task_id_t task_get_current(void)
+task_id_t task_from_addr(uint32_t addr)
{
- task_id_t id = __get_current() - tasks;
+ task_id_t id = (addr - (uint32_t)tasks) >> TASK_SIZE_LOG2;
if (id >= TASK_ID_COUNT)
id = TASK_ID_INVALID;
@@ -201,6 +202,12 @@ task_id_t task_get_current(void)
}
+task_id_t task_get_current(void)
+{
+ return task_from_addr((uint32_t)__get_current());
+}
+
+
uint32_t *task_get_event_bitmap(task_id_t tskid)
{
task_ *tsk = __task_id_to_ptr(tskid);
@@ -208,9 +215,7 @@ uint32_t *task_get_event_bitmap(task_id_t tskid)
}
-/**
- * scheduling system call
- */
+/* Scheduling system call */
void svc_handler(int desched, task_id_t resched)
{
task_ *current, *next;
@@ -484,24 +489,34 @@ void mutex_unlock(struct mutex *mtx)
}
-#ifdef CONFIG_DEBUG
-
-
-int command_task_info(int argc, char **argv)
+void task_print_list(void)
{
-#ifdef CONFIG_TASK_PROFILING
- int total = 0;
-#endif
int i;
-
ccputs("Task Ready Name Events Time (us)\n");
for (i = 0; i < TASK_ID_COUNT; i++) {
char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' ';
ccprintf("%4d %c %-16s %08x %10ld\n", i, is_ready,
task_names[i], tasks[i].events, tasks[i].runtime);
- cflush();
+ if (in_interrupt_context())
+ uart_emergency_flush();
+ else
+ cflush();
}
+}
+
+
+#ifdef CONFIG_DEBUG
+
+
+int command_task_info(int argc, char **argv)
+{
+#ifdef CONFIG_TASK_PROFILING
+ int total = 0;
+ int i;
+#endif
+
+ task_print_list();
#ifdef CONFIG_TASK_PROFILING
ccputs("IRQ counts by type:\n");
@@ -539,7 +554,9 @@ static int command_task_ready(int argc, char **argv)
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(taskready, command_task_ready);
-#endif
+
+
+#endif /* CONFIG_DEBUG */
int task_pre_init(void)
diff --git a/core/cortex-m/timer.c b/core/cortex-m/timer.c
index 1501b0e269..d8123d1686 100644
--- a/core/cortex-m/timer.c
+++ b/core/cortex-m/timer.c
@@ -23,12 +23,12 @@ static uint32_t timer_running = 0;
/* deadlines of all timers */
static timestamp_t timer_deadline[TASK_ID_COUNT];
-
static uint32_t next_deadline = 0xffffffff;
/* Hardware timer routine IRQ number */
static int timer_irq;
+
static void expire_timer(task_id_t tskid)
{
/* we are done with this timer */
@@ -37,11 +37,7 @@ static void expire_timer(task_id_t tskid)
task_set_event(tskid, TASK_EVENT_TIMER, 0);
}
-/**
- * Search the next deadline and program it in the timer hardware
- *
- * overflow: if true, the 32-bit counter as overflowed since the last call.
- */
+
void process_timers(int overflow)
{
uint32_t check_timer, running_t0;
@@ -86,6 +82,7 @@ reprocess_timers:
//TODO narrow race: deadline might have been reached before
}
+
void udelay(unsigned us)
{
timestamp_t deadline = get_time();
@@ -94,6 +91,7 @@ void udelay(unsigned us)
while (get_time().val < deadline.val) {}
}
+
int timer_arm(timestamp_t tstamp, task_id_t tskid)
{
ASSERT(tskid < TASK_ID_COUNT);
@@ -112,6 +110,7 @@ int timer_arm(timestamp_t tstamp, task_id_t tskid)
return EC_SUCCESS;
}
+
int timer_cancel(task_id_t tskid)
{
ASSERT(tskid < TASK_ID_COUNT);
@@ -152,6 +151,31 @@ timestamp_t get_time(void)
}
+void timer_print_info(void)
+{
+ uint64_t t = get_time().val;
+ uint64_t deadline = (uint64_t)clksrc_high << 32 |
+ __hw_clock_event_get();
+ int tskid;
+
+ ccprintf("Time: 0x%016lx us\n"
+ "Deadline: 0x%016lx -> %10ld us from now\n"
+ "Active timers:\n",
+ t, deadline, deadline - t);
+ for (tskid = 0; tskid < TASK_ID_COUNT; tskid++) {
+ if (timer_running & (1<<tskid)) {
+ ccprintf(" Tsk %2d 0x%016lx -> %10ld %x\n", tskid,
+ timer_deadline[tskid].val,
+ timer_deadline[tskid].val - t, 0xabcd);
+ if (in_interrupt_context())
+ uart_emergency_flush();
+ else
+ cflush();
+ }
+ }
+}
+
+
static int command_wait(int argc, char **argv)
{
if (argc < 2)
@@ -176,23 +200,7 @@ DECLARE_CONSOLE_COMMAND(gettime, command_get_time);
int command_timer_info(int argc, char **argv)
{
- uint64_t t = get_time().val;
- uint64_t deadline = (uint64_t)clksrc_high << 32 |
- __hw_clock_event_get();
- int tskid;
-
- ccprintf("Time: 0x%016lx us\n"
- "Deadline: 0x%016lx -> %10ld us from now\n"
- "Active timers:\n",
- t, deadline, deadline - t);
- for (tskid = 0; tskid < TASK_ID_COUNT; tskid++) {
- if (timer_running & (1<<tskid)) {
- ccprintf(" Tsk %2d 0x%016lx -> %10ld\n", tskid,
- timer_deadline[tskid].val,
- timer_deadline[tskid].val - t);
- cflush();
- }
- }
+ timer_print_info();
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(timerinfo, command_timer_info);