aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/src/os/system_irq.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2014-11-11 22:31:27 +0100
committerHarald Welte <laforge@gnumonks.org>2014-11-11 22:31:27 +0100
commit5a40e2fed18ed75c7b8d62f52cf4a7c660a8e026 (patch)
treebce986dd5ab366dd141456f842c887868b73db7a /firmware/src/os/system_irq.c
parent3c85f8de8d394eaea5ed7f6e2675201d079e227b (diff)
parentb6caca4b64a73d8d3ab4ce6b51cea71b8f1a54b0 (diff)
Merge branch 'minxu-fixes'
Diffstat (limited to 'firmware/src/os/system_irq.c')
-rw-r--r--firmware/src/os/system_irq.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/firmware/src/os/system_irq.c b/firmware/src/os/system_irq.c
index dc787eb..4c1da31 100644
--- a/firmware/src/os/system_irq.c
+++ b/firmware/src/os/system_irq.c
@@ -25,15 +25,15 @@
#include <os/system_irq.h>
#include <os/dbgu.h>
+#include <string.h>
#include "../openpcd.h"
static sysirq_hdlr *sysirq_hdlrs[AT91SAM7_SYSIRQ_COUNT];
-static void sys_irq(void)
+void sys_irq(u_int32_t previous_pc)
{
u_int32_t sr;
- DEBUGP("sys_irq ");
/* Somehow Atmel decided to do really stupid interrupt sharing
* for commonly-used interrupts such as the timer irq */
@@ -139,6 +139,10 @@ static void sys_irq(void)
if (*AT91C_WDTC_WDMR & AT91C_WDTC_WDFIEN) {
sr = *AT91C_WDTC_WDSR;
if (sr) {
+ char dbg_buf[100];
+ sprintf(dbg_buf, "sys_irq [Old PC = %08X]\n\r", previous_pc);
+ AT91F_DBGU_Frame(dbg_buf);
+
DEBUGP("WDT(");
if (sysirq_hdlrs[AT91SAM7_SYSIRQ_WDT]) {
DEBUGP("handler ");
@@ -154,6 +158,14 @@ static void sys_irq(void)
DEBUGPCR("END");
}
+static void sysirq_entry(void)
+{
+ /* DON'T MODIFY THIS SECTION AND Cstartup.S/IRQ_Handler_Entry */
+ register unsigned *previous_pc asm("r0");
+ asm("ADD R1, SP, #16; LDR R0, [R1]");
+ sys_irq(previous_pc);
+}
+
void sysirq_register(enum sysirqs irq, sysirq_hdlr *hdlr)
{
if (irq >= AT91SAM7_SYSIRQ_COUNT)
@@ -167,6 +179,6 @@ void sysirq_init(void)
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS,
OPENPCD_IRQ_PRIO_SYS,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
- &sys_irq);
+ &sysirq_entry);
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
}