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.
*/
# 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
* is not available in this architecture)
/* In this case, page table must lie at the top 16Kb of ISRAM1 (or ISRAM0
* if ISRAM1 is not available in this architecture)
*
* If CONFIG_PAGING is defined, then mmu.h assign the virtual address
* of the page table.
@ -620,7 +620,21 @@
# error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration
# 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
* 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)
# 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
* 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 "chip/sam_wdt.h"
#include "chip/sam_aximx.h"
#include "sam_clockconfig.h"
#include "sam_lowputc.h"
#include "sam_serial.h"
@ -104,6 +105,19 @@
# 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
****************************************************************************/
@ -130,37 +144,55 @@ static const struct section_mapping_s section_mapping[] =
/* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the
* 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
* table entry so that the virtual address zero maps to the beginning
* of the .text region.
*
* 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
*
* 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.
* This method is used when booting from NORFLASH. In that case,
* vectors must lie at the beginning of NOFR FLASH.
*
* So we do both here. If we are executing from FLASH, then we provide
* the MMU to map the physical address of FLASH to address 0x0000:0000;
* 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.
*
* If we are executing out of ISRAM, then the SAMA5 primary bootloader
* probably copied us into ISRAM. If we are executing from external
* 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
* our behalf.
* This is the method used when booting from either SDRAM or
* SRAM.
*
* - 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.
*
* 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) && \
!defined(CONFIG_SAMA5_BOOT_SDRAM)
{ CONFIG_FLASH_VSTART, 0x00000000,
#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM)
# if defined(CONFIG_SAMA5_BOOT_SDRAM)
{ SAM_ISRAM_PSECTION, 0x00000000,
MMU_ROMFLAGS, 1
},
# else
{ CONFIG_FLASH_START, 0x00000000,
MMU_ROMFLAGS, 1
},
# endif
#else
{ SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS
@ -453,11 +485,12 @@ static void sam_vectormapping(void)
* Description:
* Copy the interrupt block to its final destination. Vectors are already
* 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)
{
uint32_t *src;
@ -465,7 +498,7 @@ static void sam_copyvectorblock(void)
uint32_t *dest;
/* 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
@ -496,6 +529,7 @@ static void sam_copyvectorblock(void)
sam_vectorpermissions(MMU_L2_VECTORFLAGS);
#endif
}
#else
/* Don't copy the vectors */
@ -542,7 +576,7 @@ static inline void sam_wdtdisable(void)
*
* 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
* action of the SAMA5 "first level bootloader;" it might be executing in
* 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);
#if defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_SAMA5_BOOT_ISRAM)
#if defined(CONFIG_ARCH_LOWVECTORS)
/* Disable MATRIX write protection */
#if 0 /* Disabled on reset */
putreg32(MATRIX_WPMR_WPKEY, SAM_MATRIX_WPMR);
#endif
/* Set remap state 0 if we are running from internal SRAM. If we booted
* into NOR FLASH, then the first level bootloader should have already
* provided this mapping for us.
/* Set remap state 0 if we are running from internal SRAM or from SDRAM.
* If we booted into NOR FLASH, then the first level bootloader should
* have already provided this mapping for us.
*
* 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
@ -306,8 +306,13 @@ void up_irqinitialize(void)
* 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 */
#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 */