?? boot_gnu.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.
//
//***************************************************************************
//***************************************************************************
#define EXC_REGISTERS_BASE (0x7fffc000) //-Stripe configuration
// register base
.section .text
//***************************************************************************
// 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -