SAMA5: When running from SRAM, vectors must lie in ISRAM

This commit is contained in:
Gregory Nutt 2014-04-02 12:54:15 -06:00
parent 7372485e16
commit 3a1e08bc3c
3 changed files with 82 additions and 29 deletions

View File

@ -594,10 +594,10 @@
* in the way at that position. * in the way at that position.
*/ */
# if defined(CONFIG_BOOT_RUNFROMISRAM) && defined(CONFIG_ARCH_LOWVECTORS) # if defined(CONFIG_SAMA5_BOOT_ISRAM) && defined(CONFIG_ARCH_LOWVECTORS)
/* In this case, table must lie at the top 16Kb of ISRAM1 (or ISRAM0 if ISRAM1 /* In this case, page table must lie at the top 16Kb of ISRAM1 (or ISRAM0
* is not available in this architecture) * if ISRAM1 is not available in this architecture)
* *
* If CONFIG_PAGING is defined, then mmu.h assign the virtual address * If CONFIG_PAGING is defined, then mmu.h assign the virtual address
* of the page table. * of the page table.
@ -620,7 +620,21 @@
# error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration # error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration
# endif # endif
# else /* CONFIG_BOOT_RUNFROMISRAM && CONFIG_ARCH_LOWVECTORS */ # 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 */
/* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps
* elsewhere in internal SRAM). The page table will then be positioned at * elsewhere in internal SRAM). The page table will then be positioned at
@ -638,7 +652,7 @@
# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) # define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE)
# endif # endif
# endif /* CONFIG_BOOT_RUNFROMISRAM && CONFIG_ARCH_LOWVECTORS */ # endif /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */
/* In either case, the page table lies in ISRAM. If ISRAM is not the /* In either case, the page table lies in ISRAM. If ISRAM is not the
* primary RAM region, then we will need to set-up a special mapping for * primary RAM region, then we will need to set-up a special mapping for

View File

@ -56,6 +56,7 @@
#include "up_arch.h" #include "up_arch.h"
#include "chip/sam_wdt.h" #include "chip/sam_wdt.h"
#include "chip/sam_aximx.h"
#include "sam_clockconfig.h" #include "sam_clockconfig.h"
#include "sam_lowputc.h" #include "sam_lowputc.h"
#include "sam_serial.h" #include "sam_serial.h"
@ -104,6 +105,19 @@
# define NEED_SDRAM_REMAPPING 1 # define NEED_SDRAM_REMAPPING 1
#endif #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 * Private Types
****************************************************************************/ ****************************************************************************/
@ -130,37 +144,55 @@ static const struct section_mapping_s section_mapping[] =
/* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the
* beginning of the .text region must appear at address zero. There are * beginning of the .text region must appear at address zero. There are
* two ways to accomplish this: * three ways to accomplish this:
* *
* 1. By explicitly mapping the beginning of .text region with a page * 1. By explicitly mapping the beginning of .text region with a page
* table entry so that the virtual address zero maps to the beginning * table entry so that the virtual address zero maps to the beginning
* of the .text region. * of the .text region.
*
* 2. A second way is to map the use the AXI MATRIX remap register to * 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, * map physical address zero to the beginning of the text region,
* either internal SRAM or EBI CS 0. Then we can set an identity * 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 * mapping to map the boot region at 0x0000:0000 to virtual address
* 0x0000:00000 * 0x0000:00000
* *
* When executing from NOR FLASH, the first level bootloader is supposed * This method is used when booting from NORFLASH. In that case,
* to provide the AXI MATRIX mapping for us at boot time base on the state * vectors must lie at the beginning of NOFR FLASH.
* 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.
* *
* So we do both here. If we are executing from FLASH, then we provide * 3. Set the AXI MATRIX remap register so that SRAM appears at address
* the MMU to map the physical address of FLASH to address 0x0000:0000; * zero, mapping the boot region to address 0, then copying the
* vectors to address zero.
* *
* If we are executing out of ISRAM, then the SAMA5 primary bootloader * This is the method used when booting from either SDRAM or
* probably copied us into ISRAM. If we are executing from external * SRAM.
* SDRAM, then a secondary bootloader must have loaded us into SDRAM. In *
* either case we trust the bootloader to setup the AXI MATRIX mapping on * - When executing from NOR FLASH, the first level bootloader is supposed
* our behalf. * 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.
*
* So we do both here. If we are executing from NOR FLASH, then we provide
* the MMU to map the physical address of FLASH to address 0x0000:0000;
*
* - 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, we will may the BOOT memory,
* set the AXI matrix to locate the ISRAM in boot memory, and copy the vector
* table ISRAM.
*/ */
#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM) && \ #if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM)
!defined(CONFIG_SAMA5_BOOT_SDRAM) # if defined(CONFIG_SAMA5_BOOT_SDRAM)
{ CONFIG_FLASH_VSTART, 0x00000000, { SAM_ISRAM_PSECTION, 0x00000000,
MMU_ROMFLAGS, 1 MMU_ROMFLAGS, 1
}, },
# else
{ CONFIG_FLASH_START, 0x00000000,
MMU_ROMFLAGS, 1
},
# endif
#else #else
{ SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION, { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS
@ -453,11 +485,12 @@ static void sam_vectormapping(void)
* Description: * Description:
* Copy the interrupt block to its final destination. Vectors are already * Copy the interrupt block to its final destination. Vectors are already
* positioned at the beginning of the text region and only need to be * positioned at the beginning of the text region and only need to be
* copied in the case where we are using high vectors. * copied in the case where we are using high vectors or where the beginning
* of the text region cannot be remapped to address zero.
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_ARCH_LOWVECTORS #ifdef NEED_VECTOR_COPY
static void sam_copyvectorblock(void) static void sam_copyvectorblock(void)
{ {
uint32_t *src; uint32_t *src;
@ -465,7 +498,7 @@ static void sam_copyvectorblock(void)
uint32_t *dest; uint32_t *dest;
/* If we are using re-mapped vectors in an area that has been marked /* If we are using re-mapped vectors in an area that has been marked
* read only, then temparily mark the mapping write-able (non-buffered). * read only, then temporarily mark the mapping write-able (non-buffered).
*/ */
#ifdef CONFIG_PAGING #ifdef CONFIG_PAGING
@ -496,6 +529,7 @@ static void sam_copyvectorblock(void)
sam_vectorpermissions(MMU_L2_VECTORFLAGS); sam_vectorpermissions(MMU_L2_VECTORFLAGS);
#endif #endif
} }
#else #else
/* Don't copy the vectors */ /* Don't copy the vectors */
@ -542,7 +576,7 @@ static inline void sam_wdtdisable(void)
* *
* Boot Sequence * Boot Sequence
* *
* This logic may be executing in ISRAM or in external mmemory: CS0, DDR, * This logic may be executing in ISRAM or in external memory: CS0, DDR,
* CS1, CS2, or CS3. It may be executing in CS0 or ISRAM through the * CS1, CS2, or CS3. It may be executing in CS0 or ISRAM through the
* action of the SAMA5 "first level bootloader;" it might be executing in * action of the SAMA5 "first level bootloader;" it might be executing in
* CS1-3 through the action of some second level bootloader that provides * CS1-3 through the action of some second level bootloader that provides

View File

@ -280,16 +280,16 @@ void up_irqinitialize(void)
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR); putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
#if defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_SAMA5_BOOT_ISRAM) #if defined(CONFIG_ARCH_LOWVECTORS)
/* Disable MATRIX write protection */ /* Disable MATRIX write protection */
#if 0 /* Disabled on reset */ #if 0 /* Disabled on reset */
putreg32(MATRIX_WPMR_WPKEY, SAM_MATRIX_WPMR); putreg32(MATRIX_WPMR_WPKEY, SAM_MATRIX_WPMR);
#endif #endif
/* Set remap state 0 if we are running from internal SRAM. If we booted /* Set remap state 0 if we are running from internal SRAM or from SDRAM.
* into NOR FLASH, then the first level bootloader should have already * If we booted into NOR FLASH, then the first level bootloader should
* provided this mapping for us. * have already provided this mapping for us.
* *
* This is done late in the boot sequence. Any exceptions taken before * 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 * this point in time will be handled by the ROM code, not by the NuttX
@ -306,8 +306,13 @@ void up_irqinitialize(void)
* address 0x0000:0000 in that case anyway. * address 0x0000:0000 in that case anyway.
*/ */
putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable remap */ #if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_SDRAM)
putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable Cortex-A5 remap */
putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */ 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 */
#endif
/* Restore MATRIX write protection */ /* Restore MATRIX write protection */