summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/TODO9
-rw-r--r--nuttx/arch/arm/Kconfig1
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_allocpage.c12
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_checkmapping.c8
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_copyarmstate.c2
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_dataabort.c9
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_doirq.c7
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c7
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_syscall.c13
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c3
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_va2pte.c4
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_vectors.S73
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_copyarmstate.c3
-rw-r--r--nuttx/arch/arm/src/common/up_internal.h67
-rw-r--r--nuttx/arch/arm/src/sama5/sam_irq.c15
-rw-r--r--nuttx/configs/sama5d3x-ek/ostest/defconfig2
-rw-r--r--nuttx/configs/sama5d3x-ek/scripts/ddram.ld5
-rw-r--r--nuttx/configs/sama5d3x-ek/scripts/isram.ld8
-rw-r--r--nuttx/configs/sama5d3x-ek/scripts/pg-sram.ld3
19 files changed, 187 insertions, 64 deletions
diff --git a/nuttx/TODO b/nuttx/TODO
index 441ff7eb3..6090304a0 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated July 23, 2013)
+NuttX TODO List (Last updated July 24, 2013)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -1390,8 +1390,11 @@ o ARM (arch/arm/)
Description: ARM interrupt handling performance could be improved in some
ways. One easy way is to use a pointer to the context save
area in current_regs instead of using up_copystate so much.
- see handling of 'current_regs" in arch/arm/src/armv7-m/* for
- examples of how this might be done.
+
+ 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
diff --git a/nuttx/arch/arm/Kconfig b/nuttx/arch/arm/Kconfig
index c38f9cc04..4c723f854 100644
--- a/nuttx/arch/arm/Kconfig
+++ b/nuttx/arch/arm/Kconfig
@@ -113,6 +113,7 @@ config ARCH_CHIP_SAMA5
bool "Atmel AT91SAMA5"
select ARCH_CORTEXA5
select ARCH_HAVE_FPU
+ select ARCH_HAVE_LOWVECTORS
---help---
Atmel AT91SAMA5 (ARM Cortex-A5)
diff --git a/nuttx/arch/arm/src/armv7-a/arm_allocpage.c b/nuttx/arch/arm/src/armv7-a/arm_allocpage.c
index 3856dc531..cb8710b47 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_allocpage.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_allocpage.c
@@ -117,7 +117,7 @@ static bool g_pgwrap;
****************************************************************************/
/****************************************************************************
- * Name: up_allocpage()
+ * Name: arm_allocpage()
*
* Description:
* This architecture-specific function will set aside page in memory and map
@@ -136,9 +136,9 @@ static bool g_pgwrap;
* NOTE 2: If an in-use page is un-mapped, it may be necessary to flush the
* instruction cache in some architectures.
*
- * NOTE 3: Allocating and filling a page is a two step process. up_allocpage()
+ * NOTE 3: Allocating and filling a page is a two step process. arm_allocpage()
* allocates the page, and up_fillpage() fills it with data from some non-
- * volatile storage device. This distinction is made because up_allocpage()
+ * volatile storage device. This distinction is made because arm_allocpage()
* can probably be implemented in board-independent logic whereas up_fillpage()
* probably must be implemented as board-specific logic.
*
@@ -165,7 +165,7 @@ static bool g_pgwrap;
*
****************************************************************************/
-int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage)
+int arm_allocpage(FAR struct tcb_s *tcb, FAR void **vpage)
{
uintptr_t vaddr;
uintptr_t paddr;
@@ -203,7 +203,7 @@ int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage)
*/
uintptr_t oldvaddr = PG_POOL_NDX2VA(g_ptemap[pgndx]);
- pte = up_va2pte(oldvaddr);
+ pte = arm_va2pte(oldvaddr);
*pte = 0;
/* Invalidate the instruction TLB corresponding to the virtual address */
@@ -227,7 +227,7 @@ int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage)
* non-cached (MMU_L2_ALLOCFLAGS)
*/
- pte = up_va2pte(vaddr);
+ pte = arm_va2pte(vaddr);
*pte = (paddr | MMU_L2_ALLOCFLAGS);
/* And save the new L1 index */
diff --git a/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c b/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c
index 50f05cf7e..4f20d2205 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c
@@ -68,10 +68,10 @@
****************************************************************************/
/****************************************************************************
- * Name: up_checkmapping()
+ * Name: arm_checkmapping()
*
* Description:
- * The function up_checkmapping() returns an indication if the page fill
+ * The function arm_checkmapping() returns an indication if the page fill
* still needs to performed or not. In certain conditions, the page fault
* may occur on several threads and be queued multiple times. This function
* will prevent the same page from be filled multiple times.
@@ -97,7 +97,7 @@
*
****************************************************************************/
-bool up_checkmapping(FAR struct tcb_s *tcb)
+bool arm_checkmapping(FAR struct tcb_s *tcb)
{
uintptr_t vaddr;
uint32_t *pte;
@@ -113,7 +113,7 @@ bool up_checkmapping(FAR struct tcb_s *tcb)
/* Get the PTE associated with this virtual address */
- pte = up_va2pte(vaddr);
+ pte = arm_va2pte(vaddr);
/* Return true if this virtual address is mapped. */
diff --git a/nuttx/arch/arm/src/armv7-a/arm_copyarmstate.c b/nuttx/arch/arm/src/armv7-a/arm_copyarmstate.c
index 5feebfee9..5de72aef9 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_copyarmstate.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_copyarmstate.c
@@ -71,8 +71,6 @@
*
****************************************************************************/
-/* A little faster than most memcpy's */
-
void up_copyarmstate(uint32_t *dest, uint32_t *src)
{
int i;
diff --git a/nuttx/arch/arm/src/armv7-a/arm_dataabort.c b/nuttx/arch/arm/src/armv7-a/arm_dataabort.c
index 25df4f8f2..06ff0ba35 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_dataabort.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_dataabort.c
@@ -101,7 +101,7 @@
#ifdef CONFIG_PAGING
-void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
+uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
{
DFAR struct tcb_s *tcb = (DFAR struct tcb_s *)g_readytorun.head;
uint32_t *savestate;
@@ -110,7 +110,6 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
* for register dumps and possibly context switching.
*/
-
savestate = (uint32_t*)current_regs;
current_regs = regs;
@@ -172,17 +171,18 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
*/
current_regs = savestate;
- return;
+ return regs;
segfault:
lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n",
regs[REG_PC], dfar, dfsr);
PANIC();
+ return regs; /* To keep the compiler happy */
}
#else /* CONFIG_PAGING */
-void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
+uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
{
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
@@ -195,6 +195,7 @@ void arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n",
regs[REG_PC], dfar, dfsr);
PANIC();
+ return regs; /* To keep the compiler happy */
}
#endif /* CONFIG_PAGING */
diff --git a/nuttx/arch/arm/src/armv7-a/arm_doirq.c b/nuttx/arch/arm/src/armv7-a/arm_doirq.c
index d7ec6fc91..154c52c1d 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_doirq.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_doirq.c
@@ -70,7 +70,7 @@
* Public Functions
****************************************************************************/
-void up_doirq(int irq, uint32_t *regs)
+uint32_t *arm_doirq(int irq, uint32_t *regs)
{
up_ledon(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -100,22 +100,27 @@ void up_doirq(int irq, uint32_t *regs)
* point state before returning from the interrupt.
*/
+#ifdef CONFIG_ARCH_FPU
if (regs != current_regs)
{
/* Restore floating point registers */
up_restorefpu((uint32_t*)current_regs);
}
+#endif
/* Set current_regs to NULL to indicate that we are no longer in an
* interrupt handler.
*/
+ regs = current_regs;
current_regs = NULL;
/* Unmask the last interrupt (global interrupts are still disabled) */
up_enable_irq(irq);
#endif
+
up_ledoff(LED_INIRQ);
+ return regs;
}
diff --git a/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c b/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c
index 3f5c55c70..89a6bf904 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c
@@ -89,7 +89,7 @@
#ifdef CONFIG_PAGING
-void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
+uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
{
uint32_t *savestate;
@@ -150,11 +150,13 @@ void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
regs[REG_PC], ifar, ifsr);
PANIC();
}
+
+ return regs;
}
#else /* CONFIG_PAGING */
-void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
+uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
{
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
@@ -167,6 +169,7 @@ void arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n",
regs[REG_PC], ifar, ifsr);
PANIC();
+ return regs; /* To keep the compiler happy */
}
#endif /* CONFIG_PAGING */
diff --git a/nuttx/arch/arm/src/armv7-a/arm_syscall.c b/nuttx/arch/arm/src/armv7-a/arm_syscall.c
index c3e6b2174..bfeddc831 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_syscall.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_syscall.c
@@ -76,19 +76,18 @@
****************************************************************************/
/****************************************************************************
- * Name: up_syscall
+ * Name: arm_syscall
*
* Description:
- * SWI interrupts will vection here with insn=the SWI
- * instruction and xcp=the interrupt context
+ * SWI interrupts will vection here with insn=the SWI instruction and
+ * xcp=the interrupt context
*
- * The handler may get the SWI number be de-referencing
- * the return address saved in the xcp and decoding
- * the SWI instruction
+ * The handler may get the SWI number be de-referencing the return
+ * address saved in the xcp and decoding the SWI instruction
*
****************************************************************************/
-void up_syscall(uint32_t *regs)
+uint32_t *arm_syscall(uint32_t *regs)
{
lldbg("Syscall from 0x%x\n", regs[REG_PC]);
current_regs = regs;
diff --git a/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c b/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c
index 4c63b467f..af240cf56 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c
@@ -73,9 +73,10 @@
* Name: arm_undefinedinsn
****************************************************************************/
-void arm_undefinedinsn(uint32_t *regs)
+uint32_t *arm_undefinedinsn(uint32_t *regs)
{
lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]);
current_regs = regs;
PANIC();
+ return regs; /* To keep the compiler happy */
}
diff --git a/nuttx/arch/arm/src/armv7-a/arm_va2pte.c b/nuttx/arch/arm/src/armv7-a/arm_va2pte.c
index 1d3aec414..6b3decbca 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_va2pte.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_va2pte.c
@@ -69,7 +69,7 @@
****************************************************************************/
/****************************************************************************
- * Name: up_va2pte
+ * Name: arm_va2pte
*
* Description:
* Convert a virtual address within the paged text region into a pointer to
@@ -89,7 +89,7 @@
*
****************************************************************************/
-uint32_t *up_va2pte(uintptr_t vaddr)
+uint32_t *arm_va2pte(uintptr_t vaddr)
{
uint32_t L1;
uint32_t *L2;
diff --git a/nuttx/arch/arm/src/armv7-a/arm_vectors.S b/nuttx/arch/arm/src/armv7-a/arm_vectors.S
index 74bffde6e..e8fe5dced 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_vectors.S
+++ b/nuttx/arch/arm/src/armv7-a/arm_vectors.S
@@ -136,20 +136,27 @@ arm_vectorirq:
str r0, [sp] /* Save the user stack pointer */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
- bl up_decodeirq /* Call the handler */
+ bl arm_decodeirq /* Call the handler */
ldr sp, [r4] /* Restore the user stack pointer */
#else
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
- bl up_decodeirq /* Call the handler */
+ bl arm_decodeirq /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
#endif
- /* Restore the CPSR, SVC modr registers and return */
+ /* Upon return from arm_decodeirq, r0 holds the pointer to the register
+ * state save area to use to restore the registers. This may or may not
+ * be the same value that was passed to arm_decodeirq: It will differ if a
+ * context switch is required.
+ */
+
+ /* Restore the CPSR, SVC mode registers and return */
+
.Lnoirqset:
- ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
- msr spsr, r0
- ldmia sp, {r0-r15}^ /* Return */
+ ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
+ msr spsr, r1
+ ldmia r0, {r0-r15}^ /* Return */
.Lirqtmp:
.word g_irqtmp
@@ -162,7 +169,7 @@ arm_vectorirq:
/************************************************************************************
* Function: arm_vectorswi
- *
+ *
* Description:
* SWI interrupt. We enter the SWI in SVC mode.
*
@@ -192,21 +199,27 @@ arm_vectorswi:
stmia r0, {r1-r4}
/* Then call the SWI handler with interrupts disabled.
- * void up_syscall(struct xcptcontext *xcp)
+ * void arm_syscall(struct xcptcontext *xcp)
*/
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
- bl up_syscall /* Call the handler */
+ bl arm_syscall /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
+ /* Upon return from arm_syscall, r0 holds the pointer to the register
+ * state save area to use to restore the registers. This may or may not
+ * be the same value that was passed to arm_syscall: It will differ if a
+ * context switch is required.
+ */
+
/* Restore the CPSR, SVC modr registers and return */
- ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
- msr spsr, r0
- ldmia sp, {r0-r15}^ /* Return */
+ ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
+ msr spsr, r1
+ ldmia r0, {r0-r15}^ /* Return */
.size arm_vectorswi, . - arm_vectorswi
.align 5
@@ -275,11 +288,17 @@ arm_vectordata:
bl arm_dataabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
+ /* Upon return from arm_dataabort, r0 holds the pointer to the register
+ * state save area to use to restore the registers. This may or may not
+ * be the same value that was passed to arm_dataabort: It will differ if a
+ * context switch is required.
+ */
+
/* Restore the CPSR, SVC modr registers and return */
- ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
- msr spsr_cxsf, r0
- ldmia sp, {r0-r15}^ /* Return */
+ ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
+ msr spsr_cxsf, r1
+ ldmia r0, {r1-r15}^ /* Return */
.Ldaborttmp:
.word g_aborttmp
@@ -351,11 +370,17 @@ arm_vectorprefetch:
bl arm_prefetchabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
+ /* Upon return from arm_prefetchabort, r0 holds the pointer to the register
+ * state save area to use to restore the registers. This may or may not
+ * be the same value that was passed to arm_prefetchabort: It will differ if a
+ * context switch is required.
+ */
+
/* Restore the CPSR, SVC modr registers and return */
- ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
- msr spsr_cxsf, r0
- ldmia sp, {r0-r15}^ /* Return */
+ ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
+ msr spsr_cxsf, r1
+ ldmia r0, {r0-r15}^ /* Return */
.Lpaborttmp:
.word g_aborttmp
@@ -422,11 +447,17 @@ arm_vectorundefinsn:
bl arm_undefinedinsn /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
+ /* Upon return from arm_undefinedinsn, r0 holds the pointer to the register
+ * state save area to use to restore the registers. This may or may not
+ * be the same value that was passed to arm_undefinedinsn: It will differ if a
+ * context switch is required.
+ */
+
/* Restore the CPSR, SVC modr registers and return */
- ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
- msr spsr_cxsf, r0
- ldmia sp, {r0-r15}^ /* Return */
+ ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
+ msr spsr_cxsf, r1
+ ldmia r0, {r0-r15}^ /* Return */
.Lundeftmp:
.word g_undeftmp
diff --git a/nuttx/arch/arm/src/armv7-m/up_copyarmstate.c b/nuttx/arch/arm/src/armv7-m/up_copyarmstate.c
index 32c7fce06..b705be5ea 100644
--- a/nuttx/arch/arm/src/armv7-m/up_copyarmstate.c
+++ b/nuttx/arch/arm/src/armv7-m/up_copyarmstate.c
@@ -99,7 +99,8 @@ void up_copyarmstate(uint32_t *dest, uint32_t *src)
/* Skip over the floating point registers and save the block of ARM
* registers that were saved by the hardware when the interrupt was
- * taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through (HW_XCPT_REGS-1)
+ * taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through
+ * (XCPTCONTEXT_REGS-1)
*/
src += SW_FPU_REGS;
diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h
index 495b51b24..25887770d 100644
--- a/nuttx/arch/arm/src/common/up_internal.h
+++ b/nuttx/arch/arm/src/common/up_internal.h
@@ -134,8 +134,25 @@
# endif
# define up_restorestate(regs) (current_regs = regs)
-/* Otherwise, for the ARM7, ARM9, and Cortex-A5. The state is copied in full
- * from stack to stack. This is not very efficient.
+/* The Cortex-A5 supports the same mechanism, but only lazy floating point
+ * register save/restore.
+ */
+
+#elif defined(CONFIG_ARCH_CORTEXA5)
+
+ /* If the floating point unit is present and enabled, then save the
+ * floating point registers as well as normal ARM registers.
+ */
+
+# if defined(CONFIG_ARCH_FPU)
+# define up_savestate(regs) up_copyarmstate(regs, (uint32_t*)current_regs)
+# else
+# define up_savestate(regs) up_copyfullstate(regs, (uint32_t*)current_regs)
+# endif
+# define up_restorestate(regs) (current_regs = regs)
+
+/* Otherwise, for the ARM7 and ARM9. The state is copied in full from stack
+ * to stack. This is not very efficient and should be fixed to match Cortex-A5.
*/
#else
@@ -289,10 +306,17 @@ void up_systemreset(void) noreturn_function;
void up_irqinitialize(void);
void up_maskack_irq(int irq);
+/* Exception handling logic unique to the Cortex-M family */
+
#if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \
defined(CONFIG_ARCH_CORTEXM4)
+/* Interrupt dispatch */
+
uint32_t *up_doirq(int irq, uint32_t *regs);
+
+/* Exception Handlers */
+
int up_svcall(int irq, FAR void *context);
int up_hardfault(int irq, FAR void *context);
@@ -301,9 +325,43 @@ int up_hardfault(int irq, FAR void *context);
int up_memfault(int irq, FAR void *context);
# endif /* CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */
-#else /* CONFIG_ARCH_CORTEXM0 || CONFIG_ARCH_CORTEXM3 || CONFIG_ARCH_CORTEXM4 */
+
+/* Exception handling logic unique to the Cortex-A family (but should be
+ * back-ported to the ARM7 and ARM9 families).
+ */
+
+#elif defined(CONFIG_ARCH_CORTEXA5)
+
+/* Interrupt dispatch */
+
+uint32_t *arm_doirq(int irq, uint32_t *regs);
+
+/* Paging support */
+
+#ifdef CONFIG_PAGING
+void arm_pginitialize(void);
+uint32_t *arm_va2pte(uintptr_t vaddr);
+#else /* CONFIG_PAGING */
+# define up_pginitialize()
+#endif /* CONFIG_PAGING */
+
+/* Exception Handlers */
+
+uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr);
+uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr);
+uint32_t *arm_syscall(uint32_t *regs);
+uint32_t *arm_undefinedinsn(uint32_t *regs);
+
+/* Exception handling logic common to other ARM7 and ARM9 family. */
+
+#else /* ARM7 | ARM9 */
+
+/* Interrupt dispatch */
void up_doirq(int irq, uint32_t *regs);
+
+/* Paging support (and exception handlers) */
+
#ifdef CONFIG_PAGING
void up_pginitialize(void);
uint32_t *up_va2pte(uintptr_t vaddr);
@@ -312,6 +370,9 @@ void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr);
# define up_pginitialize()
void up_dataabort(uint32_t *regs);
#endif /* CONFIG_PAGING */
+
+/* Exception handlers */
+
void up_prefetchabort(uint32_t *regs);
void up_syscall(uint32_t *regs);
void up_undefinedinsn(uint32_t *regs);
diff --git a/nuttx/arch/arm/src/sama5/sam_irq.c b/nuttx/arch/arm/src/sama5/sam_irq.c
index 615f0c5cc..2f20b169d 100644
--- a/nuttx/arch/arm/src/sama5/sam_irq.c
+++ b/nuttx/arch/arm/src/sama5/sam_irq.c
@@ -283,6 +283,7 @@ void up_irqinitialize(void)
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
+#ifndef CONFIG_ARCH_LOWVECTORS
/* Set remap state 0:
*
* Boot state: ROM is seen at address 0x00000000
@@ -290,10 +291,15 @@ void up_irqinitialize(void)
* 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 */
+#endif
/* currents_regs is non-NULL only while processing an interrupt */
@@ -315,13 +321,13 @@ void up_irqinitialize(void)
}
/****************************************************************************
- * Name: up_decodeirq
+ * Name: arm_decodeirq
*
* Description:
* This function is called from the IRQ vector handler in arm_vectors.S.
* At this point, the interrupt has been taken and the registers have
* been saved on the stack. This function simply needs to determine the
- * the irq number of the interrupt and then to call up_doirq to dispatch
+ * the irq number of the interrupt and then to call arm_doirq to dispatch
* the interrupt.
*
* Input paramters:
@@ -329,7 +335,7 @@ void up_irqinitialize(void)
*
****************************************************************************/
-void up_decodeirq(uint32_t *regs)
+uint32_t *arm_decodeirq(uint32_t *regs)
{
uint32_t regval;
@@ -376,11 +382,12 @@ void up_decodeirq(uint32_t *regs)
/* Dispatch the interrupt */
- up_doirq((int)regval, regs);
+ regs = arm_doirq((int)regval, regs);
/* Acknowledge interrupt */
putreg32(AIC_EOICR_ENDIT, SAM_AIC_EOICR);
+ return regs;
}
/****************************************************************************
diff --git a/nuttx/configs/sama5d3x-ek/ostest/defconfig b/nuttx/configs/sama5d3x-ek/ostest/defconfig
index 827524b48..f527d055c 100644
--- a/nuttx/configs/sama5d3x-ek/ostest/defconfig
+++ b/nuttx/configs/sama5d3x-ek/ostest/defconfig
@@ -93,6 +93,8 @@ CONFIG_ARCH_CHIP="sama5"
CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_FPU=y
# CONFIG_ARCH_HAVE_MPU is not set
+CONFIG_ARCH_HAVE_LOWVECTORS=y
+CONFIG_ARCH_LOWVECTORS=y
CONFIG_PGTABLE_VADDR=0x20000000
# CONFIG_ARCH_ROMPGTABLE is not set
# CONFIG_PAGING is not set
diff --git a/nuttx/configs/sama5d3x-ek/scripts/ddram.ld b/nuttx/configs/sama5d3x-ek/scripts/ddram.ld
index bebda34a5..fcc213f61 100644
--- a/nuttx/configs/sama5d3x-ek/scripts/ddram.ld
+++ b/nuttx/configs/sama5d3x-ek/scripts/ddram.ld
@@ -36,11 +36,14 @@
/* The SAMA5D3 has 128 KB of ISRAM beginning at virtual address 0x0030:0000.
* This memory configuration, however, loads into the 64 MB SDRAM on board
* the SAMA5D3x-EK which lies at 0x2000:0000
+ *
+ * Vectors in low memory are assumed and 16KB of ISRAM is reserved at the
+ * high end of ISRAM for the page table.
*/
MEMORY
{
- isram (W!RX) : ORIGIN = 0x300000, LENGTH = 128K
+ isram (W!RX) : ORIGIN = 0x300000, LENGTH = 128K - 16K
sdram (W!RX) : ORIGIN = 0x20000000, LENGTH = 64M
}
diff --git a/nuttx/configs/sama5d3x-ek/scripts/isram.ld b/nuttx/configs/sama5d3x-ek/scripts/isram.ld
index 9ffe7fbf0..035fd5747 100644
--- a/nuttx/configs/sama5d3x-ek/scripts/isram.ld
+++ b/nuttx/configs/sama5d3x-ek/scripts/isram.ld
@@ -33,11 +33,15 @@
*
****************************************************************************/
-/* The SAMA5D3 has 128 KB of ISRAM beginning at virtual address 0x0030:0000. */
+/* The SAMA5D3 has 128 KB of ISRAM beginning at virtual address 0x0030:0000.
+ *
+ * Vectors in low memory are assumed and 16KB of ISRAM is reserved at the
+ * high end of ISRAM for the page table.
+ */
MEMORY
{
- isram (W!RX) : ORIGIN = 0x300000, LENGTH = 128K
+ isram (W!RX) : ORIGIN = 0x300000, LENGTH = 128K - 16K
}
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
diff --git a/nuttx/configs/sama5d3x-ek/scripts/pg-sram.ld b/nuttx/configs/sama5d3x-ek/scripts/pg-sram.ld
index 17eb81d56..6cf0591a2 100644
--- a/nuttx/configs/sama5d3x-ek/scripts/pg-sram.ld
+++ b/nuttx/configs/sama5d3x-ek/scripts/pg-sram.ld
@@ -60,6 +60,9 @@
* get a link time error saying that the locked region is full, you may have to
* re-organize this memory layout (here and in defconfig) to make the locked
* region even bigger.
+ *
+ * NOTE 3: Vectors in low memory are assumed and 16KB of ISRAM is reserved at
+ * the high end of ISRAM for the page table (?).
*/
MEMORY