/***************************************************************************** | |
Exception handlers and startup code for ATMEL AT91SAM7. | |
Copyright (c) 2004 Rowley Associates Limited. | |
This file may be distributed under the terms of the License Agreement | |
provided with this software. | |
THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE | |
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
*****************************************************************************/ | |
#define REG_BASE 0xFFFFF000 | |
#define CKGR_MOR_OFFSET 0xC20 | |
#define CKGR_PLLR_OFFSET 0xC2C | |
#define PMC_MCKR_OFFSET 0xC30 | |
#define PMC_SR_OFFSET 0xC68 | |
#define WDT_MR_OFFSET 0xD44 | |
#define MC_RCR_OFFSET 0xF00 | |
#define MC_FMR_OFFSET 0xF60 | |
#define CKGR_MOR_MOSCEN (1 << 0) | |
#define CKGR_MOR_OSCBYPASS (1 << 1) | |
#define CKGR_MOR_OSCOUNT_BIT_OFFSET (8) | |
#define CKGR_PLLR_DIV_BIT_OFFSET (0) | |
#define CKGR_PLLR_PLLCOUNT_BIT_OFFSET (8) | |
#define CKGR_PLLR_OUT_BIT_OFFSET (14) | |
#define CKGR_PLLR_MUL_BIT_OFFSET (16) | |
#define CKGR_PLLR_USBDIV_BIT_OFFSET (28) | |
#define PMC_MCKR_CSS_MAIN_CLOCK (0x1) | |
#define PMC_MCKR_CSS_PLL_CLOCK (0x3) | |
#define PMC_MCKR_PRES_CLK (0) | |
#define PMC_MCKR_PRES_CLK_2 (1 << 2) | |
#define PMC_MCKR_PRES_CLK_4 (2 << 2) | |
#define PMC_MCKR_PRES_CLK_8 (3 << 2) | |
#define PMC_MCKR_PRES_CLK_16 (4 << 2) | |
#define PMC_MCKR_PRES_CLK_32 (5 << 2) | |
#define PMC_MCKR_PRES_CLK_64 (6 << 2) | |
#define PMC_SR_MOSCS (1 << 0) | |
#define PMC_SR_LOCK (1 << 2) | |
#define PMC_SR_MCKRDY (1 << 3) | |
#define PMC_SR_PCKRDY0 (1 << 8) | |
#define PMC_SR_PCKRDY1 (1 << 9) | |
#define PMC_SR_PCKRDY2 (1 << 10) | |
#define MC_RCR_RCB (1 << 0) | |
#define MC_FMR_FWS_0FWS (0) | |
#define MC_FMR_FWS_1FWS (1 << 8) | |
#define MC_FMR_FWS_2FWS (2 << 8) | |
#define MC_FMR_FWS_3FWS (3 << 8) | |
#define MC_FMR_FMCN_BIT_OFFSET 16 | |
#define WDT_MR_WDDIS (1 << 15) | |
.section .vectors, "ax" | |
.code 32 | |
.align 0 | |
/***************************************************************************** | |
Exception Vectors | |
*****************************************************************************/ | |
_vectors: | |
ldr pc, [pc, #reset_handler_address - . - 8] /* reset */ | |
ldr pc, [pc, #undef_handler_address - . - 8] /* undefined instruction */ | |
ldr pc, [pc, #swi_handler_address - . - 8] /* swi handler */ | |
ldr pc, [pc, #pabort_handler_address - . - 8] /* abort prefetch */ | |
ldr pc, [pc, #dabort_handler_address - . - 8] /* abort data */ | |
nop | |
ldr pc, [PC, #-0xF20] /* irq */ | |
ldr pc, [pc, #fiq_handler_address - . - 8] /* fiq */ | |
reset_handler_address: | |
.word reset_handler | |
undef_handler_address: | |
.word undef_handler | |
swi_handler_address: | |
.word swi_handler | |
pabort_handler_address: | |
.word pabort_handler | |
dabort_handler_address: | |
.word dabort_handler | |
irq_handler_address: | |
.word irq_handler | |
fiq_handler_address: | |
.word fiq_handler | |
.section .init, "ax" | |
.code 32 | |
.align 0 | |
/****************************************************************************** | |
Reset handler | |
******************************************************************************/ | |
reset_handler: | |
ldr r10, =REG_BASE | |
/* Set up FLASH wait state */ | |
ldr r0, =(50 << MC_FMR_FMCN_BIT_OFFSET) | MC_FMR_FWS_1FWS | |
str r0, [r10, #MC_FMR_OFFSET] | |
/* Disable Watchdog */ | |
ldr r0, =WDT_MR_WDDIS | |
str r0, [r10, #WDT_MR_OFFSET] | |
/* Enable the main oscillator */ | |
ldr r0, =(6 << CKGR_MOR_OSCOUNT_BIT_OFFSET) | CKGR_MOR_MOSCEN | |
str r0, [r10, #CKGR_MOR_OFFSET] | |
1:/* Wait for main oscillator to stabilize */ | |
ldr r0, [r10, #PMC_SR_OFFSET] | |
tst r0, #PMC_SR_MOSCS | |
beq 1b | |
/* Set up the PLL */ | |
ldr r0, =(5 << CKGR_PLLR_DIV_BIT_OFFSET) | (28 << CKGR_PLLR_PLLCOUNT_BIT_OFFSET) | (25 << CKGR_PLLR_MUL_BIT_OFFSET) | |
str r0, [r10, #CKGR_PLLR_OFFSET] | |
1:/* Wait for PLL to lock */ | |
ldr r0, [r10, #PMC_SR_OFFSET] | |
tst r0, #PMC_SR_LOCK | |
beq 1b | |
/* Select PLL as clock source */ | |
ldr r0, =(PMC_MCKR_CSS_PLL_CLOCK | PMC_MCKR_PRES_CLK_2) | |
str r0, [r10, #PMC_MCKR_OFFSET] | |
#ifdef __FLASH_BUILD | |
/* Copy exception vectors into Internal SRAM */ | |
mov r8, #0x00200000 | |
ldr r9, =_vectors | |
ldmia r9!, {r0-r7} | |
stmia r8!, {r0-r7} | |
ldmia r9!, {r0-r6} | |
stmia r8!, {r0-r6} | |
/* Remap Internal SRAM to 0x00000000 */ | |
ldr r0, =MC_RCR_RCB | |
strb r0, [r10, #MC_RCR_OFFSET] | |
#endif | |
/* Jump to the default C runtime startup code. */ | |
b _start | |
/****************************************************************************** | |
Default exception handlers | |
(These are declared weak symbols so they can be redefined in user code) | |
******************************************************************************/ | |
undef_handler: | |
b undef_handler | |
swi_handler: | |
b swi_handler | |
pabort_handler: | |
b pabort_handler | |
dabort_handler: | |
b dabort_handler | |
irq_handler: | |
b irq_handler | |
fiq_handler: | |
b fiq_handler | |
.weak undef_handler, swi_handler, pabort_handler, dabort_handler, irq_handler, fiq_handler |