📄 bootloader.s
字号:
;***************************************************************************
;
; bootloader.s
;
; This assembly code file is used to boot the XA with the intention of being
; able to run multiple images. It is a modification of the code found in
; AN 187. The code performs the following functions:
; Read IDCODE
; Setup PLLs
; Setup Memory Map
; Setup Stripe IO
; Setup SDRAM Controller
; Initialize SDRAM
; Configure PLD
; Check Boot Parameters
; This boot code performs a lot of the same functions that the Altera Bootloader
; performs. This code is used rather than the Altera Bootloader due to the
; fact that the Altera Bootloader was built to handle the majority of the cases and
; makes the assumption that designs will always boot out of EBI0. For this design,
; the default image will boot from EBI0. The other two images will boot from the
; base address of EBI1 and the base address of EBI1 + 0x200000(half of a 4mb flash
; chip).
;
;
; Copyright (c) Altera Corporation 2001.
; All rights reserved.
;
;***************************************************************************
GET stripe.s
IMPORT Reset_Handler
IMPORT CIrqHandler
IMPORT CFiqHandler
IMPORT CPabtHandler
IMPORT CDabtHandler
IMPORT CSwiHandler
IMPORT CUdefHandler
IMPORT |Image$$Read_Only$$Limit| ;-Symbol is used for find the end of
;application code. Section Read_Only
;is defined in the scatter.link file
AREA bootloader, CODE, READONLY
;***************************************************************************
; Vector Table
;
; This section acts as the processor's interrupt vector table. When
; booting is complete, this table will reside at address 0, the fixed
; interrupt vectors taken by the ARM922T microprocessor
;
;***************************************************************************
b START
b UDEFHND
b SWIHND
b PABTHND
b DABTHND
b UNEXPECTED
b IRQHND
b FIQHND
START
;***************************************************************************
; Read IDCODE
;
; This section reads the IDCODE register ad address (base + 0x8) and
; compares it to the XA10 IDCODE, 0x090010DD. An error vector is taken if
; they do not match.
;***************************************************************************
ldr r0, =(EXC_REGISTERS_BASE + 0x8) ;-Load address of IDCODE
ldr r1, [r0] ;-Load value of IDCODE
ldr r2, =0x090010DD ;-IDCODE for EPXA10
cmp r1,r2 ;-Compare IDCODE's
bne ID_Error ;Should branch somewhere else ;-Take error vector if
; they do not match
;***************************************************************************
; Setup PLLs
;
; The PLL setup section configures AHB1 clock to run at 120MH.
; CLK_OUT = ((CLK_REF * (M / N)) / K). With a CLK_REF
; of 25MHz, the values of PLL1 and PLL2 will be set to:
; PLL1 N=5
; M=96
; K=2
; CLK_OUT value is divided by 2 to yield the final clock frequency of AHB1
;
; After the PLL is set up, it is started by writing
; the recommended value to CTRL, and a logic 1 to the P bit of the
; registers CLK_PLL1_CTRL and CLK_PLL2_CTRL. The bypass bits are cleared
; for both PLLs, then we wait for them to lock. The final step is to clear
; the "lock change" bit after the PLL is locked. Since this is an
; expected change in lock status (we just started the PLL), we dont want
; to take the interrupt that these bits cause.
;
;***************************************************************************
; Load the M, N, and K counters for PLL1 and PLL2.
ldr r0, =(EXC_REGISTERS_BASE + 0x300) ;-Load address of CLK_PLL1_NCNT
ldr r1, =0x40000 ;-N=5
str r1, [r0] ;-Load CLK_PLL1_NCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x304) ;-Load address of CLK_PLL1_MCNT
ldr r1, =0x20505 ;-M=96
str r1, [r0] ;-Load CLK_PLL1_MCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x308) ;-Load address of CLK_PLL1_KCNT
ldr r1, =0x20101 ;-K=2
str r1, [r0] ;-Load CLK_PLL1_KCNT
; Set CTRL field in PLL control registers and start the PLL. The value written to
; CLK_PLLx_CTRL is dependent upon the frequencies involved.
ldr r0, =(EXC_REGISTERS_BASE + 0x30C) ;-Load address of CLK_PLL1_CTRL
ldr r1, =0x01055
str r1, [r0] ;-Start PLL1
; Clear both PLLs' bypass bits
ldr r0, =(EXC_REGISTERS_BASE + 0x320) ;-Load address of CLK_DERIVE
ldr r1, =0x2010 ;-Write 0x10 to it
str r1, [r0] ; to clear bits 12, 13
; Wait for PLLs to lock
ldr r0, =(EXC_REGISTERS_BASE + 0x324) ;-Load address of CLK_STATUS
PLL_CHECK
ldr r1, [r0] ;-Load value of CLK_STATUS
cmp r1, #0x17 ;-Check that we have lock
bne PLL_CHECK ;-Loop until they are
; Since the lock change bits just went high, we need to clear them to prevent
; a resulting interrupt. r0 should still contain the address of CLK_STATUS.
ldr r1, =0xC ;-Write '1's to bits 2, 3
str r1, [r0] ; of CLK_STATUS
;***************************************************************************
; Disable Previous Memory Map
;
; Because the previous image setup a memory map, that memory map has to be
; disabled. If it is not, then you run the risk of having overlapping memory
; regions. Care also has to be taken as we are not running out of EBI1 and
; therefore can not disable the decoding of the location were we are running
; code from.
;***************************************************************************
DISABLE_PREV_MEM_MAP
DISABLE_MAP_EBI0
ldr r0, =(EXC_REGISTERS_BASE + 0xC0) ;-Map EBI0
ldr r1, =0x0 ; by loading register
str r1, [r0] ; MMAP_EBI0
DISABLE_MAP_SDRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0xB0) ;-Map SDRAM0
ldr r1, =0x0
str r1, [r0] ; MMAP_SDRAM0
DISABLE_MAP_SRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0x90) ;-Map SRAM0
ldr r1, =0x0
str r1, [r0] ; MMAP_SRAM0
DISABLE_MAP_SRAM1
ldr r0, =(EXC_REGISTERS_BASE + 0x94) ;-Map SRAM1
ldr r1, =0x0 ; by loading register
str r1, [r0] ; MMAP_SRAM1
;***************************************************************************
; Setup Memory Map
;
; In this section, we setup the system memory map. This section performs
; the following steps.
;
; -- Maps EBI0, EBI1, SRAM0(should be 0x0), SRAM1
; to the locations configured in the megawizard.
; -- Turn off default boot mapping as we no longer need an alias of EBI0
; at address 0x0
;***************************************************************************
SETUP_MEM_MAP
MAP_EBI0
ldr r0, =(EXC_REGISTERS_BASE + 0xC0) ;-Map EBI0
ldr r1, =(EXC_EBI_BLOCK0_BASE +0xA83) ; by loading register
str r1, [r0] ; MMAP_EBI0
EBI_BLOCK0
ldr r0, =(EXC_REGISTERS_BASE + 0x390) ;-Set options for EBI Block0
ldr r1, =0x01E ; by loading register
str r1, [r0] ; EBI_block0
EBI_CR
ldr r0, =(EXC_REGISTERS_BASE + 0x380) ;-Set Global options for EBI
ldr r1, =0x048 ; by loading register
str r1, [r0] ; EBI_CR
MAP_PLD0
ldr r0, =(EXC_REGISTERS_BASE + 0xD0) ;-Map PLD0
ldr r1, =(EXC_PLD_BLOCK0_BASE + 0x683) ; by loading register
str r1, [r0] ; MMAP_PLD0
MAP_DPRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0xA0) ;-Map DPRAM0
ldr r1, =(EXC_DPSRAM_BLOCK0_BASE + 0x881) ; by loading register
str r1, [r0] ; MMAP_DPRAM0
MAP_DPRAM0_LCR
ldr r0, =(EXC_REGISTERS_BASE + 0x34) ;-Map DPRAM0
ldr r1, =0x0 ; by loading register
str r1, [r0] ; MMAP_DPRAM0
MAP_SRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0x90) ;-Map SRAM0
ldr r1, =(EXC_SPSRAM_BLOCK0_BASE + 0x801) ; by loading register
str r1, [r0] ; MMAP_SRAM0
MAP_SRAM1
ldr r0, =(EXC_REGISTERS_BASE + 0x94) ;-Map SRAM1
ldr r1, =(EXC_SPSRAM_BLOCK1_BASE + 0x801) ; by loading register
str r1, [r0] ; MMAP_SRAM1
COPY_CODE_TO_SRAM0
ldr r9, =EXC_SPSRAM_BLOCK0_BASE ;-Load address of SRAM0
ldr r10, =EXC_EBI_BLOCK1_BASE ;-Load address of EBI1
ldr r11,=|Image$$Read_Only$$Limit| ; This will leave put us at half
add r11, r11, r9 ; of the flash chip
COPY_8_WORDS
ldmia r10!, {r0-r7} ;-Load 8 words from flash
stmia r9!, {r0-r7} ;-Store 8 words to SRAM0
cmp r9, r11 ;-Repeat until SRAM0 is
blo COPY_8_WORDS ; full
BRANCH_TO_SRAM1
ldr r0, =EXC_SPSRAM_BLOCK0_BASE ;-Branch to SRAM0 where
ldr r1, =EXC_EBI_BLOCK1_BASE ; boot code was copied
sub r0, r1, r0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -