blob: 9f498a313aa1811edc3d4ab3817043d814a415fd [file] [log] [blame]
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Provides the low-level initialization function that called on chip startup.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "board.h"
#if defined(ENABLE_TCM) && defined(__GNUC__)
extern char _itcm_lma, _sitcm, _eitcm;
#endif
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/* Default memory map
Address range Memory region Memory type Shareability Cache policy
0x00000000- 0x1FFFFFFF Code Normal Non-shareable WT
0x20000000- 0x3FFFFFFF SRAM Normal Non-shareable WBWA
0x40000000- 0x5FFFFFFF Peripheral Device Non-shareable -
0x60000000- 0x7FFFFFFF RAM Normal Non-shareable WBWA
0x80000000- 0x9FFFFFFF RAM Normal Non-shareable WT
0xA0000000- 0xBFFFFFFF Device Device Shareable
0xC0000000- 0xDFFFFFFF Device Device Non Shareable
0xE0000000- 0xFFFFFFFF System - -
*/
/**
* \brief Set up a memory region.
*/
void _SetupMemoryRegion( void )
{
uint32_t dwRegionBaseAddr;
uint32_t dwRegionAttr;
memory_barrier();
/***************************************************
ITCM memory region --- Normal
START_Addr:- 0x00000000UL
END_Addr:- 0x00400000UL
****************************************************/
dwRegionBaseAddr =
ITCM_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_ITCM_REGION; // 1
dwRegionAttr =
MPU_AP_PRIVILEGED_READ_WRITE |
MPU_CalMPURegionSize(ITCM_END_ADDRESS - ITCM_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
Internal flash memory region --- Normal read-only
(update to Strongly ordered in write accesses)
START_Addr:- 0x00400000UL
END_Addr:- 0x00600000UL
******************************************************/
dwRegionBaseAddr =
IFLASH_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_IFLASH_REGION; //2
dwRegionAttr =
MPU_AP_READONLY |
INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) |
MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
DTCM memory region --- Normal
START_Addr:- 0x20000000L
END_Addr:- 0x20400000UL
******************************************************/
/* DTCM memory region */
dwRegionBaseAddr =
DTCM_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_DTCM_REGION; //3
dwRegionAttr =
MPU_AP_PRIVILEGED_READ_WRITE |
MPU_CalMPURegionSize(DTCM_END_ADDRESS - DTCM_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
SRAM Cacheable memory region --- Normal
START_Addr:- 0x20400000UL
END_Addr:- 0x2043FFFFUL
******************************************************/
/* SRAM memory region */
dwRegionBaseAddr =
SRAM_FIRST_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_SRAM_REGION_1; //4
dwRegionAttr =
MPU_AP_FULL_ACCESS |
INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) |
MPU_CalMPURegionSize(SRAM_FIRST_END_ADDRESS - SRAM_FIRST_START_ADDRESS)
| MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
Internal SRAM second partition memory region --- Normal
START_Addr:- 0x20440000UL
END_Addr:- 0x2045FFFFUL
******************************************************/
/* SRAM memory region */
dwRegionBaseAddr =
SRAM_SECOND_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_SRAM_REGION_2; //5
dwRegionAttr =
MPU_AP_FULL_ACCESS |
INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) |
MPU_CalMPURegionSize(SRAM_SECOND_END_ADDRESS - SRAM_SECOND_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
Peripheral memory region --- DEVICE Shareable
START_Addr:- 0x40000000UL
END_Addr:- 0x5FFFFFFFUL
******************************************************/
dwRegionBaseAddr =
PERIPHERALS_START_ADDRESS |
MPU_REGION_VALID |
MPU_PERIPHERALS_REGION; //6
dwRegionAttr = MPU_AP_FULL_ACCESS |
MPU_REGION_EXECUTE_NEVER |
SHAREABLE_DEVICE_TYPE |
MPU_CalMPURegionSize(PERIPHERALS_END_ADDRESS - PERIPHERALS_START_ADDRESS)
|MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
External EBI memory memory region --- Strongly Ordered
START_Addr:- 0x60000000UL
END_Addr:- 0x6FFFFFFFUL
******************************************************/
dwRegionBaseAddr =
EXT_EBI_START_ADDRESS |
MPU_REGION_VALID |
MPU_EXT_EBI_REGION;
dwRegionAttr =
MPU_AP_FULL_ACCESS |
/* External memory Must be defined with 'Device' or 'Strongly Ordered'
attribute for write accesses (AXI) */
STRONGLY_ORDERED_SHAREABLE_TYPE |
MPU_CalMPURegionSize(EXT_EBI_END_ADDRESS - EXT_EBI_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
SDRAM Cacheable memory region --- Normal
START_Addr:- 0x70000000UL
END_Addr:- 0x7FFFFFFFUL
******************************************************/
dwRegionBaseAddr =
SDRAM_START_ADDRESS |
MPU_REGION_VALID |
MPU_DEFAULT_SDRAM_REGION; //7
dwRegionAttr =
MPU_AP_FULL_ACCESS |
INNER_NORMAL_WB_RWA_TYPE( SHAREABLE ) |
MPU_CalMPURegionSize(SDRAM_END_ADDRESS - SDRAM_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
QSPI memory region --- Strongly ordered
START_Addr:- 0x80000000UL
END_Addr:- 0x9FFFFFFFUL
******************************************************/
dwRegionBaseAddr =
QSPI_START_ADDRESS |
MPU_REGION_VALID |
MPU_QSPIMEM_REGION; //8
dwRegionAttr =
MPU_AP_FULL_ACCESS |
STRONGLY_ORDERED_SHAREABLE_TYPE |
MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/****************************************************
USB RAM Memory region --- Device
START_Addr:- 0xA0100000UL
END_Addr:- 0xA01FFFFFUL
******************************************************/
dwRegionBaseAddr =
USBHSRAM_START_ADDRESS |
MPU_REGION_VALID |
MPU_USBHSRAM_REGION; //9
dwRegionAttr =
MPU_AP_FULL_ACCESS |
MPU_REGION_EXECUTE_NEVER |
SHAREABLE_DEVICE_TYPE |
MPU_CalMPURegionSize(USBHSRAM_END_ADDRESS - USBHSRAM_START_ADDRESS) |
MPU_REGION_ENABLE;
MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
/* Enable the memory management fault , Bus Fault, Usage Fault exception */
SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk
| SCB_SHCSR_USGFAULTENA_Msk);
/* Enable the MPU region */
MPU_Enable( MPU_ENABLE | MPU_PRIVDEFENA);
memory_sync();
}
#ifdef ENABLE_TCM
#if defined ( __ICCARM__ ) /* IAR Ewarm */
#pragma section = "CSTACK"
#pragma section = "CSTACK_DTCM"
#define SRAM_STACK_BASE (__section_begin("CSTACK"))
#define DTCM_STACK_BASE (__section_begin("CSTACK_DTCM"))
#define SRAM_STACK_LIMIT (__section_end("CSTACK"))
#define DTCM_STACK_LIMIT (__section_end("CSTACK_DTCM"))
#elif defined (__CC_ARM) /* MDK */
extern uint32_t Image$$ARM_LIB_STACK$$Base;
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
extern uint32_t Image$$DTCM_STACK$$Base;
extern uint32_t Image$$DTCM_STACK$$ZI$$Limit;
#define SRAM_STACK_BASE (&Image$$ARM_LIB_STACK$$Base)
#define DTCM_STACK_BASE (&Image$$DTCM_STACK$$Base)
#define SRAM_STACK_LIMIT (&Image$$ARM_LIB_STACK$$ZI$$Limit)
#define DTCM_STACK_LIMIT (&Image$$DTCM_STACK$$ZI$$Limit)
#elif defined ( __GNUC__ ) /* GCC */
extern char _sdtcm_stack, _edtcm_stack, _sstack, _estack;
#define SRAM_STACK_BASE ((void *)(&_sstack))
#define DTCM_STACK_BASE ((void *)(&_sdtcm_stack))
#define SRAM_STACK_LIMIT ((void *)(&_estack))
#define DTCM_STACK_LIMIT ((void *)(&_edtcm_stack))
#endif
/** \brief Change stack's location to DTCM
The function changes the stack's location from SRAM to DTCM
*/
void TCM_StackInit(void);
void TCM_StackInit(void)
{
uint32_t offset = (uint32_t)SRAM_STACK_LIMIT - (uint32_t)DTCM_STACK_LIMIT;
volatile char *dst = (volatile char *)DTCM_STACK_LIMIT;
volatile char *src = (volatile char *)SRAM_STACK_LIMIT;
/* copy code_TCM from flash to ITCM */
while(src > (volatile char *)SRAM_STACK_BASE){
*--dst = *--src;
}
__set_MSP(__get_MSP() - offset);
}
#endif
/**
* \brief Performs the low-level initialization of the chip.
*/
extern WEAK void LowLevelInit( void )
{
SystemInit();
#ifndef MPU_EXAMPLE_FEATURE
_SetupMemoryRegion();
#endif
#if defined(ENABLE_TCM) && defined(__GNUC__)
volatile char *dst = &_sitcm;
volatile char *src = &_itcm_lma;
/* copy code_TCM from flash to ITCM */
while(dst < &_eitcm){
*dst++ = *src++;
}
#endif
}