From 048230fb94261299f71deb3abf5bcca6b5cdf071 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Apr 2014 14:09:11 -0600 Subject: [PATCH] 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 --- ChangeLog | 7 +++ arch/arm/src/sama5/chip/sama5d3x_memorymap.h | 16 +----- arch/arm/src/sama5/sam_boot.c | 50 +++++------------ arch/arm/src/sama5/sam_irq.c | 59 +++++++++++++++++--- 4 files changed, 75 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6683cad096..7773572a8a 100644 --- a/ChangeLog +++ b/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/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/arch/arm/src/sama5/chip/sama5d3x_memorymap.h index fe2e02672e..310111fd79 100644 --- a/arch/arm/src/sama5/chip/sama5d3x_memorymap.h +++ b/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/arch/arm/src/sama5/sam_boot.c b/arch/arm/src/sama5/sam_boot.c index 8493c3bf13..e41a382389 100644 --- a/arch/arm/src/sama5/sam_boot.c +++ b/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/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c index 0da4b5a0ec..13f3d2028e 100644 --- a/arch/arm/src/sama5/sam_irq.c +++ b/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 */