?? boot_ads.s
字號:
;***************************************************************************
;***************************************************************************
;
; boot.s
;
; This assembly code file demonstrates the boot process of Altera
; ARM-based Excalibur devices. After executing this boot code, the
; Excalibur device will be fully configured and initialized for basic
; system operation.
;
; Note that the code in this file is not intended to be efficient nor is
; it intended to follow proper assembly coding style. The purpose of the
; code in this file is for demonstration and clarity of the procedures
; performed. Literal values are used in most cases in place of variables
; to allow easy correlation with register descriptions in the ARM-based
; Excalibur Hardware Reference Manual. The Excalibur Megawizard Plugin
; for the Quartus II software provides header files that contain much of
; the information presented here as literal values.
;
; Copyright (c) Altera Corporation 2001.
; All rights reserved.
;
;***************************************************************************
;***************************************************************************
EXC_REGISTERS_BASE EQU (0x7fffc000) ;-Stripe configuration
; register base
AREA init, 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 ;-Take error vector if
; they do not match
;***************************************************************************
; Setup PLLs
;
; The PLL setup section configures PLL1 and PLL2 to run at 125MHz and
; 100MHz, respectively. CLK_OUT = ((CLK_REF * (M / N)) / K). With a
; CLK_REF of 50MHz, the values of PLL1 will be set to N=1, M=10, K=4 to
; make its output 125MHz. Similarly, PLL2 will be set to N=1, M=12, M=3.
; Since we are using SDR SDRAM, PLL2 needs to be setup for twice our
; desired SDRAM frequency (See ARM-based Excalibur Hardware Reference
; Manual). After the PLLs are setup, they are both 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" bits after the PLLs are locked. Since this is an
; expected change in lock status (we just started the PLLs), 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=1
str r1, [r0] ;-Load CLK_PLL1_NCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x304) ;-Load address of CLK_PLL1_MCNT
ldr r1, =0x20505 ;-M=10
str r1, [r0] ;-Load CLK_PLL1_MCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x308) ;-Load address of CLK_PLL1_KCNT
ldr r1, =0x20101 ;-K=4
str r1, [r0] ;-Load CLK_PLL1_KCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x310) ;-Load address of CLK_PLL2_NCNT
ldr r1, =0x40000 ;-N=1
str r1, [r0] ;-Load CLK_PLL2_NCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x314) ;-Load address of CLK_PLL2_MCNT
ldr r1, =0x20606 ;-M=12
str r1, [r0] ;-Load CLK_PLL2_MCNT
ldr r0, =(EXC_REGISTERS_BASE + 0x318) ;-Load address of CLK_PLL2_KCNT
ldr r1, =0x10201 ;-K=3
str r1, [r0] ;-Load CLK_PLL2_KCNT
;Set CTRL field in PLL control registers and start the PLLs. 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, =0x01035
str r1, [r0] ;-Start PLL1
ldr r0, =(EXC_REGISTERS_BASE + 0x31C) ;-Load address of CLK_PLL2_CTRL
str r1, [r0] ;-Start PLL2
;Clear both PLLs' bypass bits
ldr r0, =(EXC_REGISTERS_BASE + 0x320) ;-Load address of CLK_DERIVE
ldr r1, =0x10 ;-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, #0x3F ;-Check low 7 bits are '1'
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
;***************************************************************************
; Setup Memory Map and Copy Code to SRAM
;
; In this section, we prepare the system to run software code out of SRAM.
; Upon entering this section, the boot code running is running out of Flash
; memory on EBI0. This section performs the following steps.
;
; -- Map EBI0 (Flash) to 0x40000000 with a size of 4MB
; -- Branch to newly mapped copy of EBI0 at 0x40000000
; -- Turn off default boot mapping as we no longer need an alias of EBI0
; at address 0x0
; -- Map SRAM0 to 0x0 with a size of 128KB
; -- Map SRAM1 to 0x20000 with a size of 128KB
; -- Copy code from Flash on EBI0 at 0x40000000 to SRAM0 at address 0x0.
; -- Note : This example copies 128K of data from Flash to SRAM0. This
; -- fills all of SRAM0 in an EPXA10 as this example is
; -- intended to be universal. Normally, only the amount of
; -- data that is needed would be copied.
; -- Branch to new copy of code residing in SRAM0
; -- Map SDRAM0 to 0x10000000 with a size of 128MB
;
; At the end of this section, code is running out of SRAM0.
;
;***************************************************************************
SETUP_MEM_MAP
MAP_EBI0
ldr r0, =(EXC_REGISTERS_BASE + 0xC0) ;-Map EBI0
ldr r1, =0x40000A83 ; by loading register
str r1, [r0] ; MMAP_EBI0
BRANCH_TO_EBI0
ldr r0, =0x40000000 ;-Branch to where EBI0
add pc, pc, r0 ; was just mapped.
nop ;-NOP is not executed as
; pipeline is flushed
; when pc is altered.
TURN_OFF_BOOT_MAP
ldr r0, =(EXC_REGISTERS_BASE + 0x0) ;-Turn off boot mapping
ldr r1, =0x1 ; by loading register
str r1, [r0] ; BOOT_CR
MAP_SRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0x90) ;-Map SRAM0
ldr r1, =0x20000803 ; by loading register
str r1, [r0] ; MMAP_SRAM0
MAP_SRAM1
ldr r0, =(EXC_REGISTERS_BASE + 0x94) ;-Map SRAM1
ldr r1, =0x20020803 ; by loading register
str r1, [r0] ; MMAP_SRAM1
COPY_CODE_TO_SRAM0
ldr r9, =0x20000000 ;-Load address of SRAM0
ldr r10, =0x40000000 ;-Load address of EBI0
add r11, r10, #0x20000 ;-Load address of last
; word in flash to copy
COPY_8_WORDS
ldmia r10!, {r0-r7} ;-Load 8 words from flash
stmia r9!, {r0-r7} ;-Store 8 words to SRAM0
cmp r10, r11 ;-Repeat until SRAM0 is
blo COPY_8_WORDS ; full
BRANCH_TO_SRAM0
ldr r0, =0x20000000 ;-Branch to SRAM0 where
ldr r1, =0x40000000 ; boot code was copied
sub r0, r1, r0
sub pc, pc, r0
nop ;-NOP is not executed as
; pipeline is flushed
; when pc is altered.
MAP_SDRAM0
ldr r0, =(EXC_REGISTERS_BASE + 0xB0) ;-Map SDRAM0
ldr r1, =0x00000D03 ; by loading register
str r1, [r0] ; MMAP_SDRAM0
;***************************************************************************
; Setup Stripe IO
;
; Much of the Embedded Stripe I/O is dual purpose, meaning if the Stripe
; does not need it, it can be used as regular PLD I/O. This section sets
; up the SDRAM and EBI pins for stripe use, and the UART and TRACE pins for
; PLD use.
;***************************************************************************
ldr r0, =(EXC_REGISTERS_BASE + 0x40) ;-Load register
ldr r1, =0x7 ; IOCR_SDRAM
str r1, [r0] ; Fast slew rate, LVTTL,
; Stripe use
ldr r0, =(EXC_REGISTERS_BASE + 0x44) ;-Load register
ldr r1, =0x3 ; IOCR_EBI
str r1, [r0] ; Slow slew rate, LVTTL,
; Stripe use
ldr r0, =(EXC_REGISTERS_BASE + 0x48) ;-Load register
ldr r1, =0x5 ; IOCR_UART
str r1, [r0] ; Fast slew rate, LVTTL,
; PLD use
ldr r0, =(EXC_REGISTERS_BASE + 0x4C) ;-Load register
ldr r1, =0x5 ; IOCR_TRACE
str r1, [r0] ; Fast slew rate, LVTTL,
; PLD use
;***************************************************************************
; Turn on Cache
;
; This section reads register 1 of the MMU, turns on the instruction cache
; enable and round robin bits, then writes it back. At the end of this
; section, the instruction cache is turned on and running in round-robin
; mode
;
;***************************************************************************
; CP# Cop1 Rd CRn CRm Cop2 ;-Operands of MCR inst.
mrc p15, 0, r0, c1, c0, 0 ;-Read register 1 of MMU
ldr r1, =0x1000 ;-ICache enable bit mask
ldr r2, =0x4000 ;-Round Robin bit mask
orr r0, r0, r1 ;-Set ICache enable bit
orr r0, r0, r2 ;-Set Round Robin bit
mcr p15, 0, r0, c1, c0, 0 ;-Write back register 1
;***************************************************************************
; Setup SDRAM Controller
;
; This section configures the SDRAM controller for SDR SDRAM.
; Specifically, the SDRAM controller is setup to interface with a Crucial
; CT16M72S4D75.9T 128MB DIMM. First we wait to assure that PLL2 has been
; locked for 100us. At this point we load the registers SDRAM_TIMING1,
; SDRAM_TIMING2, SDRAM_CONFIG, SDRAM_REFRESH, SDRAM_ADDR, and SDRAM_MODE0.
; These registers configure how the SDRAM controller will interface with
; the SDRAM devices. Descriptions of these registers can be found in the
; ARM-based Excalibur Hardware Reference Manual.
;
;***************************************************************************
;We must wait 100us after PLL2 is locked.
ldr r6, =(EXC_REGISTERS_BASE + 0x328) ;-Load address of AHB1-COUNT
ldr r9, =12500
bl WAIT_FUNCTION ;-Wait for 12500 AHB1 cycles
; (100us)
LOAD_SDRAM_REGS
ldr r0, =(EXC_REGISTERS_BASE + 0x400) ;-Load register
ldr r1, =0x4A92 ; SDRAM_TIMING1
str r1, [r0] ; RCD=2, RAS=5, RRD=2,
; RP=2, WR=2
ldr r0, =(EXC_REGISTERS_BASE + 0x404) ;-Load register
ldr r1, =0x7BB8 ; SDRAM_TIMING2
str r1, [r0] ; RC=7, CL=3, BL=8,
; RFC=7
ldr r0, =(EXC_REGISTERS_BASE + 0x408) ;-Load register
ldr r1, =0x0 ; SDRAM_CONFIG
str r1, [r0] ; Type=SDR
ldr r0, =(EXC_REGISTERS_BASE + 0x40C) ;-Load register
ldr r1, =0x5DC ; SDRAM_REFRESH
str r1, [r0] ; Refresh=15us
ldr r0, =(EXC_REGISTERS_BASE + 0x410) ;-Load register
ldr r1, =0xCA80 ; SDRAM_ADDR
str r1, [r0] ; ROW=12, COL=10
ldr r0, =(EXC_REGISTERS_BASE + 0x420) ;-Load register
ldr r1, =0x033 ; SDRAM_MODE0
str r1, [r0] ; CAS=3, sequential,
; burst length=8
;Register SDRAM_MODE1 is not used in SDR mode
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -