summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-04-03 14:09:11 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-04-03 14:09:11 -0600
commit9ffe0def9e5db1fa76cdbe01bc3229582283fb26 (patch)
tree6dba63cfe0c565c95941bfbbf08ac3e5dbdcb1b6
parent4950e35a30bd47bf1633e0e78316e1862b7e1cc3 (diff)
downloadnuttx-9ffe0def9e5db1fa76cdbe01bc3229582283fb26.tar.gz
nuttx-9ffe0def9e5db1fa76cdbe01bc3229582283fb26.tar.bz2
nuttx-9ffe0def9e5db1fa76cdbe01bc3229582283fb26.zip
SAMA5: When booting from SDRAM, don't copy vectors to ISRAM. Instread just set the VBAR register to add address of the vectors in SDRAM
-rw-r--r--nuttx/ChangeLog7
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h16
-rw-r--r--nuttx/arch/arm/src/sama5/sam_boot.c50
-rw-r--r--nuttx/arch/arm/src/sama5/sam_irq.c59
4 files changed, 75 insertions, 57 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 6683cad09..7773572a8 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -7122,3 +7122,10 @@
* arch/arm/src/sama5/sam_irq.c: After we modify the AXI MATRIX, make
sure to invalidate all caches and TLBs (probably un-necessary)
(2014-4-2).
+ * arch/arm/src/sama5/sam_irq.c: Set the VBAR register to zero. If
+ were started by a bootloader (vs. a RESET), then the VBAR register
+ may not be in its reset state (zero, 2014-4-3).
+ * arch/arm/src/sama5/sam_boot.c, sam_irq.c, and chip/sama5d3x_memorymap.h:
+ When booting from SDRAM, don't relocated vectors to ISRAM. Instead,
+ just set the VBAR register to address of the vectors in SDRAM.
+
diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
index fe2e02672..310111fd7 100644
--- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
+++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
@@ -620,21 +620,7 @@
# error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration
# endif
-# elif defined(CONFIG_SAMA5_BOOT_SDRAM) && defined(CONFIG_ARCH_LOWVECTORS)
-
- /* In this case, vectors must lie in ISRAM, followed by the page table,*/
-
-# define PGTABLE_BASE_PADDR (SAM_ISRAM0_PADDR + 0x00004000)
-# ifndef CONFIG_PAGING
-# define PGTABLE_BASE_VADDR (SAM_ISRAM0_VADDR + 0x00004000)
-# endif
-# define PGTABLE_IN_LOWSRAM 1
-
-# ifdef CONFIG_BOOT_SDRAM_DATA
-# error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration
-# endif
-
-# else /* CONFIG_SAMA5_BOOT_SDRAM && CONFIG_ARCH_LOWVECTORS */
+# else /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */
/* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps
* elsewhere in internal SRAM). The page table will then be positioned at
diff --git a/nuttx/arch/arm/src/sama5/sam_boot.c b/nuttx/arch/arm/src/sama5/sam_boot.c
index 8493c3bf1..e41a38238 100644
--- a/nuttx/arch/arm/src/sama5/sam_boot.c
+++ b/nuttx/arch/arm/src/sama5/sam_boot.c
@@ -106,19 +106,6 @@
# define NEED_SDRAM_REMAPPING 1
#endif
-/* We need to copy vectors under two conditions:
- *
- * 1. If vectors lie in high memory because CONFIG_ARCH_LOWVECTORS=n, or
- * 2. If vectors lie in low memory and we are executing from SDRAM.
- */
-
-#undef NEED_VECTOR_COPY
-#if !defined(CONFIG_ARCH_LOWVECTORS)
-# define NEED_VECTOR_COPY 1
-#elif defined(CONFIG_SAMA5_BOOT_SDRAM)
-# define NEED_VECTOR_COPY 1
-#endif
-
/****************************************************************************
* Private Types
****************************************************************************/
@@ -146,28 +133,26 @@ static const struct section_mapping_s section_mapping[] =
/* SAMA5 Internal Memories */
/* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the
- * beginning of the .text region must appear at address zero. There are
- * three ways to accomplish this:
+ * beginning of the .text region must appear at address at the address
+ * specified in the VBAR. There are three ways to accomplish this:
*
* 1. By explicitly mapping the beginning of .text region with a page
* table entry so that the virtual address zero maps to the beginning
- * of the .text region.
+ * of the .text region. VBAR == 0x0000:0000.
*
* 2. A second way is to map the use the AXI MATRIX remap register to
* map physical address zero to the beginning of the text region,
* either internal SRAM or EBI CS 0. Then we can set an identity
* mapping to map the boot region at 0x0000:0000 to virtual address
- * 0x0000:00000
+ * 0x0000:00000. VBAR == 0x0000:0000.
*
- * This method is used when booting from NORFLASH. In that case,
- * vectors must lie at the beginning of NOFR FLASH.
+ * This method is used when booting from ISRAM or NOR FLASH. In
+ & that case, vectors must lie at the beginning of NOFR FLASH.
*
- * 3. Set the AXI MATRIX remap register so that SRAM appears at address
- * zero, mapping the boot region to address 0, then copying the
- * vectors to address zero.
+ * 3. Set the Cortex-A5 VBAR register so that the vector table address
+ * is moved to a location other than 0x0000:0000.
*
- * This is the method used when booting from either SDRAM or
- * SRAM.
+ * This is the method used when booting from SDRAM.
*
* - When executing from NOR FLASH, the first level bootloader is supposed
* to provide the AXI MATRIX mapping for us at boot time base on the state
@@ -181,21 +166,16 @@ static const struct section_mapping_s section_mapping[] =
* probably copied us into ISRAM and set the AXI REMAP bit for us.
*
* - If we are executing from external SDRAM, then a secondary bootloader must
- * have loaded us into SDRAM. In this case, we will may the BOOT memory,
- * set the AXI matrix to locate the ISRAM in boot memory, and copy the vector
- * table ISRAM.
+ * have loaded us into SDRAM. In this case, simply set the VBAR register
+ * to the address of the vector table (not necessary at the beginning
+ * or SDRAM).
*/
-#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM)
-# if defined(CONFIG_SAMA5_BOOT_SDRAM)
- { SAM_ISRAM_PSECTION, 0x00000000,
- MMU_ROMFLAGS, 1
- },
-# else
+#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM) && \
+ !defined(CONFIG_SAMA5_BOOT_SDRAM)
{ CONFIG_FLASH_START, 0x00000000,
MMU_ROMFLAGS, 1
},
-# endif
#else
{ SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS
@@ -512,7 +492,7 @@ static void sam_vectormapping(void)
*
****************************************************************************/
-#ifdef NEED_VECTOR_COPY
+#if !defined(CONFIG_ARCH_LOWVECTORS)
static void sam_copyvectorblock(void)
{
uint32_t *src;
diff --git a/nuttx/arch/arm/src/sama5/sam_irq.c b/nuttx/arch/arm/src/sama5/sam_irq.c
index 0da4b5a0e..13f3d2028 100644
--- a/nuttx/arch/arm/src/sama5/sam_irq.c
+++ b/nuttx/arch/arm/src/sama5/sam_irq.c
@@ -237,7 +237,9 @@ static uint32_t *sam_fiqhandler(int irq, uint32_t *regs)
void up_irqinitialize(void)
{
+#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH)
size_t vectorsize;
+#endif
int i;
/* The following operations need to be atomic, but since this function is
@@ -309,7 +311,44 @@ void up_irqinitialize(void)
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
#if defined(CONFIG_ARCH_LOWVECTORS)
- /* Set the vector base address register to zero */
+ /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the
+ * beginning of the .text region must appear at address at the address
+ * specified in the VBAR. There are three ways to accomplish this:
+ *
+ * 1. By explicitly mapping the beginning of .text region with a page
+ * table entry so that the virtual address zero maps to the beginning
+ * of the .text region. VBAR == 0x0000:0000.
+ *
+ * 2. A second way is to map the use the AXI MATRIX remap register to
+ * map physical address zero to the beginning of the text region,
+ * either internal SRAM or EBI CS 0. Then we can set an identity
+ * mapping to map the boot region at 0x0000:0000 to virtual address
+ * 0x0000:00000. VBAR == 0x0000:0000.
+ *
+ * This method is used when booting from ISRAM or NOR FLASH. In
+ & that case, vectors must lie at the beginning of NOFR FLASH.
+ *
+ * 3. Set the Cortex-A5 VBAR register so that the vector table address
+ * is moved to a location other than 0x0000:0000.
+ *
+ * This is the method used when booting from SDRAM.
+ *
+ * - When executing from NOR FLASH, the first level bootloader is supposed
+ * to provide the AXI MATRIX mapping for us at boot time base on the state
+ * of the BMS pin. However, I have found that in the test environments
+ * that I use, I cannot always be assured of that physical address mapping.
+ *
+ * - If we are executing out of ISRAM, then the SAMA5 primary bootloader
+ * probably copied us into ISRAM and set the AXI REMAP bit for us.
+ *
+ * - If we are executing from external SDRAM, then a secondary bootloader
+ * must have loaded us into SDRAM. In this case, simply set the VBAR
+ * register to the address of the vector table (not necessary at the
+ * beginning or SDRAM).
+ */
+
+#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH)
+ /* Set the vector base address register to 0x0000:0000 */
cp15_wrvbar(0);
@@ -338,12 +377,12 @@ void up_irqinitialize(void)
* address 0x0000:0000 in that case anyway.
*/
-#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_SDRAM)
putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable Cortex-A5 remap */
+
+#if defined(CONFIG_SAMA5_BOOT_ISRAM)
putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */
-#elif defined(CONFIG_SAMA5_BOOT_CS0FLASH)
- putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable Cortex-A5 remap */
- putreg32(AXIMX_REMAP_REMAP1, SAM_AXIMX_REMAP); /* Remap NOR FLASH */
+#else /* elif defined(CONFIG_SAMA5_BOOT_CS0FLASH) */
+ putreg32(AXIMX_REMAP_REMAP1, SAM_AXIMX_REMAP); /* Remap NOR FLASH on CS0 */
#endif
/* Make sure that there is no trace of any previous mapping */
@@ -359,8 +398,14 @@ void up_irqinitialize(void)
putreg32(MATRIX_WPMR_WPKEY | MATRIX_WPMR_WPEN, SAM_MATRIX_WPMR);
#endif
- /* It might be wise to flush the instruction cache here */
-#endif
+#elif defined(CONFIG_SAMA5_BOOT_SDRAM)
+ /* Set the VBAR register to the address of the vector table in SDRAM */
+
+ DEBUGASSERT((((uintptr_t)&_vector_start) & ~VBAR_MASK) == 0);
+ cp15_wrvbar((uint32_t)&_vector_start);
+
+#endif /* CONFIG_SAMA5_BOOT_ISRAM || CONFIG_SAMA5_BOOT_CS0FLASH */
+#endif /* CONFIG_ARCH_LOWVECTORS */
/* currents_regs is non-NULL only while processing an interrupt */