summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-28 09:44:11 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-28 09:44:11 -0600
commit142a43827d2e2eb2884284b6b28a04ed5e1ba7bb (patch)
tree4edaa3059ed558deda6a594db1f9c57a9dcd1184
parent57671b26d31d64293ace547f556893fa3c0cefda (diff)
downloadnuttx-142a43827d2e2eb2884284b6b28a04ed5e1ba7bb.tar.gz
nuttx-142a43827d2e2eb2884284b6b28a04ed5e1ba7bb.tar.bz2
nuttx-142a43827d2e2eb2884284b6b28a04ed5e1ba7bb.zip
SAMA5: Correct vector mapping
-rwxr-xr-xnuttx/arch/arm/src/armv7-a/arm_cache.S48
-rw-r--r--nuttx/arch/arm/src/armv7-a/cache.h16
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h78
-rw-r--r--nuttx/arch/arm/src/sama5/sam_boot.c46
-rw-r--r--nuttx/arch/arm/src/sama5/sam_irq.c19
5 files changed, 111 insertions, 96 deletions
diff --git a/nuttx/arch/arm/src/armv7-a/arm_cache.S b/nuttx/arch/arm/src/armv7-a/arm_cache.S
index 36349b362..f12a4ccb6 100755
--- a/nuttx/arch/arm/src/armv7-a/arm_cache.S
+++ b/nuttx/arch/arm/src/armv7-a/arm_cache.S
@@ -94,10 +94,10 @@
* Public Symbols
****************************************************************************/
- .globl cp15_coherent_dcache_for_dma
- .globl cp15_invalidate_dcache_for_dma
- .globl cp15_clean_dcache_for_dma
- .globl cp15_flush_dcache_for_dma
+ .globl cp15_coherent_dcache
+ .globl cp15_invalidate_dcache
+ .globl cp15_clean_dcache
+ .globl cp15_flush_dcache
/****************************************************************************
* Public Functions
@@ -106,7 +106,7 @@
.text
/****************************************************************************
- * Name: cp15_coherent_dcache_for_dma
+ * Name: cp15_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
@@ -123,10 +123,10 @@
*
****************************************************************************/
- .globl cp15_coherent_dcache_for_dma
- .type cp15_coherent_dcache_for_dma, function
+ .globl cp15_coherent_dcache
+ .type cp15_coherent_dcache, function
-cp15_coherent_dcache_for_dma:
+cp15_coherent_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
@@ -167,10 +167,10 @@ cp15_coherent_dcache_for_dma:
dsb
isb
bx lr
- .size cp15_coherent_dcache_for_dma, . - cp15_coherent_dcache_for_dma
+ .size cp15_coherent_dcache, . - cp15_coherent_dcache
/****************************************************************************
- * Name: cp15_invalidate_dcache_for_dma
+ * Name: cp15_invalidate_dcache
*
* Description:
* Invalidate the data cache within the specified region; we will be
@@ -186,10 +186,10 @@ cp15_coherent_dcache_for_dma:
*
****************************************************************************/
- .globl cp15_invalidate_dcache_for_dma
- .type cp15_invalidate_dcache_for_dma, function
+ .globl cp15_invalidate_dcache
+ .type cp15_invalidate_dcache, function
-cp15_invalidate_dcache_for_dma:
+cp15_invalidate_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
@@ -216,10 +216,10 @@ cp15_invalidate_dcache_for_dma:
dsb
bx lr
- .size cp15_coherent_dcache_for_dma, . - cp15_coherent_dcache_for_dma
+ .size cp15_coherent_dcache, . - cp15_coherent_dcache
/****************************************************************************
- * Name: cp15_clean_dcache_for_dma
+ * Name: cp15_clean_dcache
*
* Description:
* Clean the data cache within the specified region by flushing the
@@ -234,10 +234,10 @@ cp15_invalidate_dcache_for_dma:
*
****************************************************************************/
- .globl cp15_clean_dcache_for_dma
- .type cp15_clean_dcache_for_dma, function
+ .globl cp15_clean_dcache
+ .type cp15_clean_dcache, function
-cp15_clean_dcache_for_dma:
+cp15_clean_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
@@ -258,10 +258,10 @@ cp15_clean_dcache_for_dma:
dsb
bx lr
- .size cp15_clean_dcache_for_dma, . - cp15_clean_dcache_for_dma
+ .size cp15_clean_dcache, . - cp15_clean_dcache
/****************************************************************************
- * Name: cp15_flush_dcache_for_dma
+ * Name: cp15_flush_dcache
*
* Description:
* Flush the data cache within the specified region by cleaning and
@@ -276,10 +276,10 @@ cp15_clean_dcache_for_dma:
*
****************************************************************************/
- .globl cp15_flush_dcache_for_dma
- .type cp15_flush_dcache_for_dma, function
+ .globl cp15_flush_dcache
+ .type cp15_flush_dcache, function
-cp15_flush_dcache_for_dma:
+cp15_flush_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
@@ -300,5 +300,5 @@ cp15_flush_dcache_for_dma:
dsb
bx lr
- .size cp15_flush_dcache_for_dma, . - cp15_flush_dcache_for_dma
+ .size cp15_flush_dcache, . - cp15_flush_dcache
.end
diff --git a/nuttx/arch/arm/src/armv7-a/cache.h b/nuttx/arch/arm/src/armv7-a/cache.h
index 76982153d..ac88f1461 100644
--- a/nuttx/arch/arm/src/armv7-a/cache.h
+++ b/nuttx/arch/arm/src/armv7-a/cache.h
@@ -765,7 +765,7 @@ extern "C" {
****************************************************************************/
/****************************************************************************
- * Name: cp15_coherent_dcache_for_dma
+ * Name: cp15_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
@@ -782,10 +782,10 @@ extern "C" {
*
****************************************************************************/
-void cp15_coherent_dcache_for_dma(uintptr_t start, uintptr_t end);
+void cp15_coherent_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
- * Name: cp15_invalidate_dcache_for_dma
+ * Name: cp15_invalidate_dcache
*
* Description:
* Invalidate the data cache within the specified region; we will be
@@ -801,10 +801,10 @@ void cp15_coherent_dcache_for_dma(uintptr_t start, uintptr_t end);
*
****************************************************************************/
-void cp15_invalidate_dcache_for_dma(uintptr_t start, uintptr_t end);
+void cp15_invalidate_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
- * Name: cp15_clean_dcache_for_dma
+ * Name: cp15_clean_dcache
*
* Description:
* Clean the data cache within the specified region by flushing the
@@ -819,10 +819,10 @@ void cp15_invalidate_dcache_for_dma(uintptr_t start, uintptr_t end);
*
****************************************************************************/
-void cp15_clean_dcache_for_dma(uintptr_t start, uintptr_t end);
+void cp15_clean_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
- * Name: cp15_flush_dcache_for_dma
+ * Name: cp15_flush_dcache
*
* Description:
* Flush the data cache within the specified region by cleaning and
@@ -837,7 +837,7 @@ void cp15_clean_dcache_for_dma(uintptr_t start, uintptr_t end);
*
****************************************************************************/
-void cp15_flush_dcache_for_dma(uintptr_t start, uintptr_t end);
+void cp15_flush_dcache(uintptr_t start, uintptr_t end);
#undef EXTERN
#ifdef __cplusplus
diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
index b07f9043c..dd8093f0d 100644
--- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
+++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
@@ -486,55 +486,69 @@
*
* 0x80000000-0xefffffff: Undefined (1.75 GB)
*
- * That is the offset where the main L2 page table will be positioned. This
- * corresponds to page table offsets 0x000002000 through 0x000003c00. That
+ * That is the offset where the main L2 page tables will be positioned. This
+ * corresponds to page table offsets 0x000002000 up to 0x000003c00. That
* is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual
* address space)
- */
-
-#define PGTABLE_L2_OFFSET 0x000002000
-#define PGTABLE_L2_SIZE 0x000001c00
-
-/* This other small region is reserved for the vector table L2 page table
*
- * 0x00a00000-0x0fffffff: Undefined (246 MB)
+ * Up to two L2 page tables may be used:
+ *
+ * 1) One mapping the vector table. However, L2 page tables must be aligned
+ * to 1KB address boundaries, so the minimum L2 page table size is then
+ * 1KB, mapping up a full megabyte of virtual address space.
+ *
+ * This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not*
+ * defined. The SAMA5 boot-up logic will map the beginning of the boot
+ * memory to address 0x0000:0000 using both the MMU and the AXI matrix
+ * REMAP register. So no L2 page table is required.
*
- * This corresponds to page table offsets 0x000000028 through 0x00000400.
- * That is 246 entries each mapping 4KB of address each for a total of 984KB
- * of virtual address space). For low vectors, this L2 page table can can
- * span: 0x0000:0000 through 0x000f:6000 leaving up to the full 984KB for
- * vector logic. For high vectors located at 0xffff:0000, this L2 page
- * table can cover only 0xfff0:0000 through 0xffff:6000 which leaves 5KB for
- * vectors.
+ * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional
+ * L2 page table is needed. This page table will use the remainder of
+ * the address space.
*/
-#define VECTOR_L2_OFFSET 0x000000028
-#define VECTOR_L2_SIZE 0x000000400
+#ifndef CONFIG_ARCH_LOWVECTORS
+/* Vector L2 page table offset/size */
-/* If we need more L2 page tables, there additional entries can be obtained
- * from other unused areas in the physical memory map:
- *
- * 0x0003c000-0x07ffffff: Reserved (127.8 MB)
- * 0x00044000-0x00ffbfff: Reserved ( 15.7 MB)
+# define VECTOR_L2_OFFSET 0x000002000
+# define VECTOR_L2_SIZE 0x000000400
+
+/* Vector L2 page table base addresses */
+
+# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET)
+# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET)
+
+/* Vector L2 page table end addresses */
+
+# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE)
+# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE)
+
+/* Paging L2 page table offset/size */
+
+# define PGTABLE_L2_OFFSET 0x000002400
+# define PGTABLE_L2_SIZE 0x000001800
+
+#else
+/* Paging L2 page table offset/size */
+
+# define PGTABLE_L2_OFFSET 0x000002000
+# define PGTABLE_L2_SIZE 0x000001c00
+#endif
+
+/* Paging L2 page table base addresses
*
- * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual address
- * of the page table.
+ * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual
+ * address of the page table.
*/
#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET)
#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET)
-#define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET)
-#define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET)
-
-/* Page table end addresses: */
+/* Paging L2 page table end addresses */
#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE)
#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE)
-#define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE)
-#define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE)
-
/* Base address of the interrupt vector table.
*
* SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
diff --git a/nuttx/arch/arm/src/sama5/sam_boot.c b/nuttx/arch/arm/src/sama5/sam_boot.c
index d353d25ac..c92a49b12 100644
--- a/nuttx/arch/arm/src/sama5/sam_boot.c
+++ b/nuttx/arch/arm/src/sama5/sam_boot.c
@@ -66,23 +66,23 @@
/* The vectors are, by default, positioned at the beginning of the text
* section. Under what conditions do we have to remap the these vectors?
*
- * 1) If we are using high vectors. In this case, the vectors will lie at
- * virtual address 0xfffc0000 and we will need to a) copy the vectors to
- * another location, and 2) map the vectors to that address.
- * 2) If we are using low vectors but the .text region is not already mapped
- * to address 0x0000:0000
- * 3) We are not using a ROM page table. We cannot set any custom mappings in
+ * 1) If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case,
+ * the vectors will lie at virtual address 0xffff:000 and we will need
+ * to a) copy the vectors to another location, and b) map the vectors
+ * to that address, and
+ *
+ * For the case of CONFIG_ARCH_LOWVECTORS=y, defined. The SAMA5 boot-up
+ * logic will map the beginning of the boot memory to address 0x0000:0000
+ * using both the MMU and the AXI matrix REMAP register. No vector copy
+ * is required because the vectors are position at the beginning of the
+ * boot memory at link time and no additional MMU mapping required.
+ *
+ * 2) We are not using a ROM page table. We cannot set any custom mappings in
* the case and the build must conform to the ROM page table properties
*/
-#undef NEED_VECTORMAP
-#if !defined(CONFIG_ARCH_LOWVECTORS) || (NUTTX_START_VADDR & 0xfff00000) != 0
-
-# if defined(CONFIG_ARCH_ROMPGTABLE)
-# error Vector remap cannot be performed if we are using a ROM page table
-# endif
-
-# define NEED_VECTORMAP
+#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE)
+# error High vector remap cannot be performed if we are using a ROM page table
#endif
/****************************************************************************
@@ -117,10 +117,8 @@ static const struct section_mapping_s section_mapping[] =
{
/* SAMA5 Internal Memories */
-#ifndef CONFIG_ARCH_LOWVECTORS
{ SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS},
-#endif
{ SAM_ROM_PSECTION, SAM_ROM_VSECTION,
SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS},
{ SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION,
@@ -261,7 +259,8 @@ static void sam_setupmappings(void)
*
****************************************************************************/
-#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
+#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \
+ defined(CONFIG_PAGING)
static void sam_vectorpermissions(uint32_t mmuflags)
{
/* The PTE for the beginning of ISRAM is at the base of the L2 page table */
@@ -304,7 +303,7 @@ static void sam_vectorpermissions(uint32_t mmuflags)
*
****************************************************************************/
-#ifdef NEED_VECTORMAP
+#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS)
static void sam_vectormapping(void)
{
uint32_t vector_paddr = SAM_VECTOR_PADDR & PTE_SMALL_PADDR_MASK;
@@ -312,7 +311,7 @@ static void sam_vectormapping(void)
uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start;
uint32_t end_paddr = SAM_VECTOR_PADDR + vector_size;
- /* REVISIT: Can really assert in this context */
+ /* REVISIT: Cannot really assert in this context */
DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE);
@@ -363,7 +362,7 @@ static void sam_copyvectorblock(void)
* read only, then temparily mark the mapping write-able (non-buffered).
*/
-#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
+#ifdef CONFIG_PAGING
sam_vectorpermissions(MMU_L2_VECTRWFLAGS);
#endif
@@ -387,7 +386,7 @@ static void sam_copyvectorblock(void)
/* Make the vectors read-only, cacheable again */
-#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
+#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING)
sam_vectorpermissions(MMU_L2_VECTORFLAGS);
#endif
}
@@ -407,9 +406,7 @@ static void sam_copyvectorblock(void)
static inline void sam_wdtdisable(void)
{
-#if 0 // REVISIT
putreg32(WDT_MR_WDDIS, SAM_WDT_MR);
-#endif
}
/****************************************************************************
@@ -501,13 +498,12 @@ void up_boot(void)
sam_vectormapping();
-
/* The SRAM address hold the the page table is probably buffered. Make sure
* that the modified contents of the page table are flushed into physical
* memory.
*/
- cp15_clean_dcache_for_dma(VECTOR_L2_VBASE, VECTOR_L2_VBASE + PGTABLE_SIZE);
+ cp15_clean_dcache(PGTABLE_BASE_VADDR, PGTABLE_BASE_VADDR + PGTABLE_SIZE);
#endif /* CONFIG_ARCH_ROMPGTABLE */
diff --git a/nuttx/arch/arm/src/sama5/sam_irq.c b/nuttx/arch/arm/src/sama5/sam_irq.c
index 2f20b169d..a72eb8c85 100644
--- a/nuttx/arch/arm/src/sama5/sam_irq.c
+++ b/nuttx/arch/arm/src/sama5/sam_irq.c
@@ -283,14 +283,17 @@ void up_irqinitialize(void)
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
-#ifndef CONFIG_ARCH_LOWVECTORS
- /* Set remap state 0:
+#ifdef CONFIG_ARCH_LOWVECTORS
+ /* 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.
+ * 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
@@ -299,6 +302,8 @@ void up_irqinitialize(void)
putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable remap */
putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */
+
+ /* It might be wise to flush the instruction cache here */
#endif
/* currents_regs is non-NULL only while processing an interrupt */