;---------------------------------------------------- ;Copyright (C) 2005-2008 lst. ;版权所有 (C) 2005-2008 lst. ;所属模块: CPU初始化 ;作者: lst ;版本: V1.1.0 ;文件描述: CPU初始化必须用汇编语言实现的部分 ;其他说明: 无 ;修订历史: ;2. 日期: 2009-10-30 ; 作者: lst ; 新版本号:V1.1.0 ; 修改说明: 把内存和时钟用C语言初始化 ;1. 日期: 2009-03-10 ; 作者: lst ; 新版本号:V1.0.0 ; 修改说明: s3c2440的原始版本 ;------------------------------------------------------ USERMODE EQU 0x10 SYSMODE EQU 0x1f FIQMODE EQU 0x11 IRQMODE EQU 0x12 SVCMODE EQU 0x13 ABORTMODE EQU 0x17 UNDEFMODE EQU 0x1b MODEMASK EQU 0x1f NOINT EQU 0xc0 WTCON EQU 0x53000000 ; Watch-dog timer mode EXPORT _start IMPORT init_cpu_clk ;初始化cpu时钟 IMPORT init_mem_bus ;初始化内存总线 IMPORT start_int ; 在ints.s中定义 IMPORT |Image$$usr_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 IMPORT |Image$$svc_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 IMPORT |Image$$irq_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 IMPORT |Image$$fiq_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 IMPORT |Image$$undef_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 IMPORT |Image$$abort_stack$$ZI$$Limit| ;栈顶地址,在脚本中定义 PRESERVE8 AREA RESET, CODE, READONLY ENTRY _start b reset_start ; handlerReset b except_undef ; handlerUndef b except_swi ; SWI interrupt handler b except_pabort ; handlerPAbort b except_dabort ; handlerDAbort b . ; handlerReserved b start_int ; handlerIRQ b . ; fiq no use except_undef ; 未定义指令异常 b . except_swi ; SWI异常 b . except_pabort ; 取址异常 b . except_dabort ; 取数据异常 b . reset_start ;复位向量地址 mrs r0,cpsr ;取CPSR bic r0,r0,#MODEMASK ;清模式位 orr r1,r0,#SVCMODE|NOINT ;设置为管理态,并禁止中断 msr cpsr_cxsf,r1 ;切换到管理态,可防止意外返回0地址时出错. ldr r0,=WTCON ;禁止看门狗 ldr r1,=0x0 str r1,[r0] mrc p15,0,r0,c1,c0,0 orr r0,r0,#0xc0000000 ;2410特有的控制位,设置cpu工作在异步时钟 bic r0,r0,#0x1000 ;禁止Icache bic r0,r0,#0x1 ;禁止mmu bic r0,r0,#0x4 ;禁止Dcache mcr p15,0,r0,c1,c0,0 ;初始化栈指针 mrs r0, cpsr bic r0, r0, #MODEMASK orr r1, r0, #UNDEFMODE|NOINT msr cpsr_cxsf, r1 ; UndefMode ldr sp, =|Image$$undef_stack$$ZI$$Limit| orr r1, r0, #ABORTMODE|NOINT msr cpsr_cxsf, r1 ; AbortMode ldr sp, =|Image$$abort_stack$$ZI$$Limit| orr r1, r0, #IRQMODE|NOINT msr cpsr_cxsf, r1 ; IRQMode ldr sp, =|Image$$irq_stack$$ZI$$Limit| orr r1, r0, #FIQMODE|NOINT msr cpsr_cxsf, r1 ; FIQMode ldr sp, =|Image$$fiq_stack$$ZI$$Limit| orr r1, r0, #SVCMODE|NOINT msr cpsr_cxsf, r1 ; SVCMode ldr sp, =|Image$$svc_stack$$ZI$$Limit| orr r1, r0, #SYSMODE|NOINT msr cpsr_cxsf, r1 ; userMode ldr sp, =|Image$$usr_stack$$ZI$$Limit| bl init_cpu_clk bl init_mem_bus ;Set processor and MMU to known state as follows (we may have not ;been entered from a reset). We must do this before setting the CPU ;mode as we must set PROG32/DATA32. ; ;MMU Control Register layout. ; ;bit ; 0 M 0 MMU disabled ; 1 A 0 Address alignment fault disabled initially ; 2 C 0 Data cache disabled ; 3 W 0 Write Buffer disabled ; 4 P 1 PROG32 ; 5 D 1 DATA32 ; 6 L 1 Should Be One (Late abort on earlier CPUs) ; 7 B ? Endianness (1 => big) ; 8 S 0 System bit to zero } Modifies MMU protections not really ; 9 R 1 ROM bit to one } relevant until MMU switched on later. ;10 F 0 Should Be Zero ;11 Z 0 Should Be Zero (Branch prediction control on 810) ;12 I 0 Instruction cache control ;以下初始化L1页表,平板式全映射 ldr r0, =0x30000000 ;L1页表地址 mov r1, #0 ldr r3, =0xc12 ;不开cache loopnommu mov r2, r1, lsl #20 ;目标段编号写入L1条目的高12位 add r2, r2, r3 str r2, [r0], #4 add r1, r1, #1 cmp r1, #0x300 ;0~2fffffff不cache,不开写缓冲 bne loopnommu ldr r3, =0xc1e ;开cache loopmmu mov r2, r1, lsl #20 ;目标段编号写入L1条目的高12位 add r2, r2, r3 str r2, [r0], #4 add r1, r1, #1 cmp r1, #0x340 ;64M sdram区 bne loopmmu ldr r3, =0xc12 ;不开cache loopnommu1 mov r2, r1, lsl #20 ;目标段编号写入L1条目的高12位 add r2, r2, r3 str r2, [r0], #4 add r1, r1, #1 cmp r1, #0x1000 ;高端地址,不开cache bne loopnommu1 ldr r0, =0x30000000 mcr p15, 0, r0, c2, c0, 0 ;页表基地址 ldr r0, =0xffffffff ;全部域具有管理者权限 mcr p15, 0, r0, c3, c0, 0 ;写域寄存器 ;以下打开cache 使能mmu. mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0xc0000000 ;2410/2440特有的控制位,设置cpu工作在异步时钟 orr r0, r0, #0x1000 ;允许Icache orr r0, r0, #0x1 ;允许mmu orr r0, r0, #0x4 ;允许Dcache mcr p15, 0, r0, c1, c0, 0 IF :DEF:boot ldr r0,=0x3000405c mov pc,r0 ELSE IMPORT load_preload ; 加载程序,在C中定义 bl load_preload ENDIF ALIGN END