📄 loader.s
字号:
/***************************************** Copyright (c) 2002-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* Minimized from MAMBiOs by Ho Lee 01/14/2003*/#define __ASSEMBLY__#include "config.h"#include "hardware.h"#include "memcfg.h"// #define DEBUG#define Mode_USR 0x10#define Mode_FIQ 0x11#define Mode_IRQ 0x12#define Mode_SVC 0x13#define Mode_ABT 0x17#define Mode_UNDEF 0x1B#define Mode_SYS 0x1F // available on ARM Arch 4 and later#define I_Bit 0x80 // when I bit is set, IRQ is disabled#define F_Bit 0x40 // when F bit is set, FIQ is disabled .text .code 32 .align 0@@ ARM vector table@ only process RESET, IRQ, FIQ@ .global startvectors: ldr pc, RESET_jump @ offset 0x00 : reset ldr pc, UNDEF_jump @ offset 0x04 : undefined error ldr pc, SWI_jump @ offset 0x08 : software interrupt ldr pc, I_ABORT_jump @ offset 0x0c : prefetch fault ldr pc, D_ABORT_jump @ offset 0x10 : data fault ldr pc, RSV_jump @ offset 0x14 : reserved ldr pc, IRQ_jump @ offset 0x18 : interrupt request ldr pc, FIQ_jump @ offset 0x1c : fast interrupt requestRESET_jump : @ offset 0x20 .word RESET_handlerUNDEF_jump : @ offset 0x24 .word UNDEF_handlerSWI_jump : @ offset 0x28 .word SWI_handlerI_ABORT_jump : @ offset 0x2c .word I_ABORT_handlerD_ABORT_jump : @ offset 0x30 .word D_ABORT_handlerRSV_jump : @ offset 0x34 .word RSV_handlerIRQ_jump : @ offset 0x38 .word IRQ_handlerFIQ_jump : @ offset 0x3c .word FIQ_handler@@ Configuration area@data_config_valid : @ offset 0x40 .long LOADER_CONFIGBOOTVALIDdata_config : @ offset 0x44 - 0x9f : configuration from stage 0 boot loader .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000data_reserved : @ offset 0xa0 - 0xff .space 0x60data_kernelparam : @ offset 0x100 - 0x1ff .space 0x100#ifdef SECONDARY_LOADER@ offset 0x200 (this is where the value of CFG_2NDBOOT in config.h comes from)data_stage2_signature: .long LOADER_CONFIGSIGNdata_loader_drambase: .long LOADER_DRAMBASE data_stage2_image_size: .long STAGE2_IMAGE_SIZEdata_loader_entry: .long LOADER_DRAMBASE #endif@@ LOADER public data@main_address: .long entry @ Pointer to entry C routine@@ debugging@#ifdef DEBUG .macro uart_putc, ch, reg1, reg2#if 01: ldr \reg1, =(REG_BASE_CPU + CPU_uart0_linestat) ldr \reg1, [\reg1] and \reg1, \reg1, #0x20 beq 1b#endif ldr \reg1, =(REG_BASE_CPU + CPU_uart0_txd) mov \reg2, \ch str \reg2, [\reg1] .endm .macro uart_putc_io, ch, regio, reg2 mov \reg2, \ch str \reg2, [\regio] .endm#else .macro uart_putc, ch, reg1, reg2 .endm .macro uart_putc_io, ch, regio, reg2 .endm#endifRESET_handler: @ offset 0x20 : b startUNDEF_handler: @ offset 0x24 :SWI_handler:I_ABORT_handler:D_ABORT_handler:RSV_handler:unhandled_handler: b unhandled_handler@@ loader entry point@start: uart_putc #'2', r10, r11@ --- Initialise stack pointer registers and cache@ Enter IRQ mode and set up the IRQ stack pointer ldr r0, =(DRAM0_BASE + FM_IRQHANDLER_STACKTOP_IRQ) msr CPSR_c, #(Mode_IRQ | I_Bit | F_Bit) @ No interrupts mov sp, r0@ Enter FIQ mode and set up the FIQ stack pointer ldr r0, =(DRAM0_BASE + FM_IRQHANDLER_STACKTOP_FIQ) msr CPSR_c, #(Mode_FIQ | I_Bit | F_Bit) @ No interrupts mov sp, r0@ Enter SYS mode and set up the USR stack pointer ldr r0, =(DRAM0_BASE + FM_IRQHANDLER_STACKTOP_USR) msr CPSR_c, #(Mode_SYS | I_Bit | F_Bit) @ No interrupts mov sp, r0 @ Enter UNDEF mode and set up the stack pointer ldr r0, =(DRAM0_BASE + FM_IRQHANDLER_STACKTOP_USR) msr CPSR_c, #(Mode_UNDEF | I_Bit | F_Bit) @ No interrupts mov sp, r0 @ Now change to SVC mode again and setup SVC mode stack ldr r0, =(DRAM0_BASE + FM_STACKTOP_SVC) msr CPSR_c, #(Mode_SVC | I_Bit | F_Bit) @ No interrupts mov sp, r0@ Enable instruction and data cache mov r4, #0x0 mcr p15, 0x0, r4, c7, c5, 0 @ Invalidate Instruction Cache (all) mcr p15, 0x0, r4, c7, c6, 0 @ Invalidate Data Cache (all)#ifdef CONFIG_ENABLE_CACHE mov r4, #0x1c @ 512 MB regions (0x20000000) orr r4, r4, r4, lsl #8 @ Instruction and Data region size @ 0:7 = DRSIZE (Data Cache region size) @ 8:15 = IRSIZE (Instruction Cache region size) mcr p15, 0x0, r4, c6, c0, 0 @ Region Size register (CP15-6) mov r4, #0xf000 @ Enable Instruction Cache for regions over 2GB (4, 5, 6, 7) orr r4, r4, #0x00f0 @ Enable Data Cache for regions over 2GB (4, 5, 6, 7) mcr p15, 0x0, r4, c2, c0, 0 @ Cacheability Control register (CP15-2) mov r4, #0xf0 @ Enable Writeback for regions over 2GB (4, 5, 6, 7) mcr p15, 0x0, r4, c3, c0, 0 @ Writeback Control register (CP15-3) ldr r4, =0xffff @ Read/write access in any mode mcr p15, 0x0, r4, c4, c0, 0 @ Instruction Space Protection register (CP15-4) ldr r4, =0xffff @ Read/write access in any mode mcr p15, 0x0, r4, c5, c0, 0 @ Data Space Protection register (CP15-5) mov r4, #0x00 @ (little-endian) orr r4, r4, #0x1000 @ Instruction Cache Enable orr r4, r4, #0x0004 @ Data Cache Enable orr r4, r4, #0x0002 @ Writeback orr r4, r4, #0x0001 @ Protection Enable @ When set, this bit enables caches, protection, @ and write buffering. When cleared, all are disabled @ regardless of other bits. mcr p15, 0x0, r4, c1, c0, 0 @ Configuration register (CP15-1)#else mcr p15, 0x0, r4, c1, c0, 0 @ disable all cache#endif @ nop cycles for stability (not necessary) mov r0, r0 mov r0, r0 mov r0, r0 mov r0, r0@ Now enter the C code ldr r0, =main_address ldr pc, [r0] .global do_boot_prog @ r0 = addressdo_boot_prog:#ifdef CONFIG_ENABLE_CACHE/* @ flush data cache mov r4, #0x0 mcr p15, 0x0, r4, c7, c10, 0 @ clean data cache mcr p15, 0x0, r4, c7, c10, 0 @ invalidate data cache @ disable data cache mrc p15, 0x0, r4, c1, c0, 0 @ read current configuration bic r4, r4, #0x0004 @ Data Cache Disable bic r4, r4, #0x0002 @ Write Buffer Disable mcr p15, 0x0, r4, c1, c0, 0 @ Configuration register (CP15-1)*/#endif mov r4, r0 mov r0, #0 @ r0 = 0 mov r1, #186 @ r1 = architecture type of EM86XX : 186#ifdef CONFIG_SD_PRESERVE_FIQ msr CPSR_c, #(Mode_SVC | I_Bit) @ No interrupts except FIQ#else msr CPSR_c, #(Mode_SVC | I_Bit | F_Bit) @ No interrupts#endif mov pc, r4IRQ_handler: stmdb sp!, { r0 - r12, lr } @ save r0 - r12, lr bl em86xx_irq_handler @ call handler ldmia sp!, { r0 - r12, lr } @ restore r0 - r12, lr subs pc, lr, #4 @ returnFIQ_handler: stmdb sp!, { r0 - r7, lr } @ save r0 - r7 bl em86xx_fiq_handler @ call handler ldmia sp!, { r0 - r7, lr } @ restore r0 - r7, lr subs pc, lr, #4 @ return#ifdef CONFIG_ENABLE_FULLFUNCTION .global profile_instprofile_inst: @ set clock to 0 mov r0, #0 mov r1, #0x10000 add r1, r1, #0x40 str r0, [r1] @ run some instructions ldr r0, [r1] @ read clock ldr r0, [r1] @ return mov pc, lr#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -