diff --git a/ChangeLog b/ChangeLog index 07519afd40..07e149d686 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5234,4 +5234,7 @@ Wharington, 2013-7-30). * arch/arm/src/stm32/stm32f30xx_i2c.c: An I2C driver for the STM32 F3 family from John Wharington (2013-7-30). + * arch/arm/include/armv7-m: Add irqdisable() (2013-7-30); + * configs/sama5d3-ek/src/nor_main.c: Now disables interrupts + before jumping to NOR flash (2013-7-30). diff --git a/TODO b/TODO index 6090304a0d..6ca81149b3 100644 --- a/TODO +++ b/TODO @@ -24,7 +24,7 @@ nuttx/ (1) Documentation (Documentation/) (6) Build system / Toolchains (5) Linux/Cywgin simulation (arch/sim) - (5) ARM (arch/arm/) + (4) ARM (arch/arm/) (1) ARM/C5471 (arch/arm/src/c5471/) (3) ARM/DM320 (arch/arm/src/dm320/) (2) ARM/i.MX (arch/arm/src/imx/) @@ -1394,9 +1394,10 @@ o ARM (arch/arm/) This approach is already implemented for the ARM Cortex-M0, Cortex-M3, Cortex-M4, and Cortex-A5 families. But still needs to be back-ported to the ARM7 and ARM9 (which are nearly - identical to the Cortex-A5 in this regard). - Status: Open - Priority: Low + identical to the Cortex-A5 in this regard). The change is + *very* simple for this architecture, but not implemented. + Status: Open. But complete on all ARM platforms except ARM7 and ARM9. + Priority: Low. Title: IMPROVED ARM INTERRUPT HANDLING Description: The ARM and Cortex-M3 interrupt handlers restores all regisers @@ -1407,19 +1408,6 @@ o ARM (arch/arm/) Status: Open Priority: Low - Title: ARM INTERRUPTS AND USER MODE - Description: The ARM7/9 interrupt handling (arch/arm/src/arm/up_vectors.S) returns - using 'ldmia sp, {r0-r15}^' My understanding is that this works - fine because everything is in kernel-mode. In an operating model - where applications run in user mode and interrupts/traps run in - kernel-mode, I think that there is a problem with this. This would - like be a problem, for example, if for a kernel build where NuttX - is built as a monolithic, protected kernel and user mode programs - trap into the kernel. - Status: Open - Priority: Low until I get around to implementing security or kernel mode for - an ARM7/9 platform. - Title: CORTEX-M3 STACK OVERFLOW Description: There is bit bit logic inf up_fullcontextrestore() that executes on return from interrupts (and other context switches) that looks like: @@ -1439,7 +1427,7 @@ o ARM (arch/arm/) ldr pc, [sp], #4 - Under conditions of excessivley high interrupt conditions, many + Under conditions of excessively high interrupt conditions, many nested interrupts can oocur just after the 'msr cpsr' instruction. At that time, there are 4 bytes on the stack and, with each interrupt, the stack pointer may increment and possibly overflow. @@ -1453,6 +1441,9 @@ o ARM (arch/arm/) ldmia r0, {r0-r15}^ But this has not been proven to be a solution. + + UPDATE: Other ARM architectures have a similer issue. + Status: Open Priority: Low. The conditions of continous interrupts is really the problem. If your design needs continous interrupts like this, please try diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index 6aeba431ee..51a9702ae8 100755 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -286,6 +286,24 @@ static inline irqstate_t irqenable(void) return cpsr; } +/* Disable IRQs and return the previous IRQ state */ + +static inline irqstate_t irqdisable(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsid i\n" + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + /* Restore saved IRQ & FIQ state */ static inline void irqrestore(irqstate_t flags) diff --git a/configs/sama5d3x-ek/src/nor_main.c b/configs/sama5d3x-ek/src/nor_main.c index 96b576ac2e..51af1372d9 100644 --- a/configs/sama5d3x-ek/src/nor_main.c +++ b/configs/sama5d3x-ek/src/nor_main.c @@ -42,11 +42,16 @@ #include #include +#include + #include "up_arch.h" #include "mmu.h" #include "cache.h" + #include "sam_periphclks.h" #include "chip/sam_hsmc.h" +#include "chip/sam_matrix.h" +#include "chip/sam_aximx.h" #include "sama5d3x-ek.h" @@ -116,6 +121,33 @@ int nor_main(int argc, char *argv) HSMC_MODE_TDFCYCLES(1); putreg32(regval, SAM_HSMC_MODE(HSMC_CS0)); + /* Interrupts must be disabled through the following. In this configuration, + * there should only be timer interupts. Your NuttX configuration must use + * CONFIG_SERIAL_LOWCONSOLE=y or printf() will hang when the interrupts + * are disabled! + */ + + (void)irqdisable(); + + /* Set remap state 0. This is done late in the boot sequence. Any + * exceptions taken before this point in time will be handled by the + * ROM code, not by the NuttX interrupt since which was, up to this + * point, uninitialized. + * + * Boot state: ROM is seen at address 0x00000000 + * Remap State 0: SRAM is seen at address 0x00000000 (through AHB slave + * interface) instead of ROM. + * Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave + * interface) instead of ROM for external boot. + * + * Here we are assuming that vectors reside in the lower end of ISRAM. + * Hmmm... this probably does not matter since we will map a page to + * address 0x0000:0000 in that case anyway. + */ + + putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable remap */ + putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */ + /* Disable the caches and the MMU. Disabling the MMU should be safe here * because there is a 1-to-1 identity mapping between the physical and * virtual addressing.