cortex A8处理器启动过程二引导代码BL1

BL1相当于u-boot的第一阶段代码,主要完成如下工作:1.初始化硬件:关看门狗、设置串口、SDRAM、初始化Flash;2.重定位,将代码重定位到SDRAM;3.引导u-boot第二阶段代码。其实如果它能引导内核,就相当于一个bootlaoder,这里先实现上面3个功能。代码有点多,我还是贴出来吧,懒得看,需要编译好的源码包留个邮箱我发你。

系统:ubuntu 10.04.4
单板:s5pc100(CES-C100)
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。

一、编写代码

文件start.S:

.global

_start:
	/*1. Disable Watchdog */
	/*1.关看门狗*/
	ldr	r0, =0xEA200000
	mov	r1, #0
	str	r1, [r0]

	bl	clock_init
	//bl	test
	bl	mp1_x_drive_strength_init
	bl	mem_ctrl_asm_init
	ldr	sp, =0xD0038000
	bl	init_uart
	bl	nand_init
	//bl	test
	ldr	r0, =0x0
	ldr	r1, =0x21000000
	ldr	r2, =bss_start
	sub	r2, r2, r1
	bl	copy_code_to_sdram
	//bl	test
	//b	main

clean_bss:
	ldr r0, =bss_start
	ldr r1, =bss_end
	mov r3, #0
	cmp r0, r1
	ldreq pc, =on_ddr
	
clean_loop:
	str r3, [r0], #4
	cmp r0, r1
	bne clean_loop
	ldr pc, =on_ddr

on_ddr:
	ldr sp, =0x21800000    /* ÖØгõÊŒ»¯Õ»£¬ÖžÏòÄÚŽæ */
	//bl  test
	ldr pc, =main

文件clock.S

.globl clock_init

clock_init:
	
	/* 1.设置LOCK_TIME */
	ldr r0, =0xe0100000  	//CLOCK_POWER_BASE
	mov r1, #0xe00
	orr r1, r1, #0x10
	str r1, [r0, #0x0]		/* APLL_LOCK */
	str r1, [r0, #0x4]	 /* MPLL_LOCK */
	str r1, [r0, #0x8]	 /* EPLL_LOCK */
	str r1, [r0, #0x0c]	//HPLL_LOCK

	
//#define OTHERS		0x7e00f900
//	@ set async mode  /* 当CPU时钟 != HCLK时,要设为异步模式 */
//	ldr r0, =OTHERS
//	ldr r1, [r0]
//	bic r1, r1, #0xc0	/* 1100,0000 */		
//	str r1, [r0]

//loop1:				/* 等待,直到CPU进入异步模式 */
//	ldr r0, =OTHERS
//	ldr r1, [r0]
//	and r1, r1, #0xf00					
//	cmp r1, #0
//	bne loop1		
	
	/* SYNC667 */
	/* MISC_CON[19] = 0 */

//#define ARM_RATIO    0   /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1)    */
//#define HCLKX2_RATIO 1   /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */
//#define HCLK_RATIO   1   /* HCLK = HCLKX2 / (HCLK_RATIO + 1)       */
//#define PCLK_RATIO   3   /* PCLK   = HCLKX2 / (PCLK_RATIO + 1)     */
//#define MPLL_RATIO   0   /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)     */
//	ldr r0, =0x7E00F020  /* CLK_DIV0 */
//	ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_//RATIO << 12)
//	str r1, [r0]
/* CLK_DIV0 */
#define APLL_RATIO	0
#define ARM_RATIO	4
#define D0_BUS_RATIO	8
#define PCLKD0_RATIO	12
#define SECSS_RATIO	16
	
	ldr r1, [r0, #0x300]	//CLK_DIV0 Clock divider
	ldr r2, =0x3fff
	bic r1, r1, r2

	ldr r2, =(1<<APLL_RATIO) | (0<<ARM_RATIO) | (4<<D0_BUS_RATIO) | (1<<PCLKD0_RATIO) | (1<<SECSS_RATIO)
	orr r1, r1, r2
	str r1, [r0, #0x300]	//CLK_DIV0

	ldr r2, =((1<<16) | (1<<12) | (1<<8) | (1<<4))
	orr r1 ,r1, r2
	str r1, [r0, #0x304]	//CLD_DIV1
	/* 2.配置时钟 */
	/* 2.1 配置APLL */
	/* 2.1.1 设置APLL
	 * 2.1.2 MUXAPLL
	 * 2.1.3 SYNC667
	 * 2.1.4 DIVAPLL
	 */
//#define APLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
//	ldr r0, =0x7E00F00C
//	ldr r1, =APLL_CON_VAL
//	str r1, [r0]		/* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */
#define APLL_VAL  ((1<<31) | (417 << 16) | (3 << 8) | (0))	
	//ldr r0, =0xe0100100	//APLL_CON
	ldr r1, =APLL_VAL
	str r1, [r0, #0x100]		/* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */
	/* 2.2 配置MPLL */
	/* 2.2.1 设置MPLL
	 * 2.2.2 MUXMPLL
	 * 2.2.3 SYNCMUX
	 * 2.2.4 SYNC667
	 * 2.2.5 HCLKX2_RATIO
	 * 2.2.6 PCLK_RATIO
	 */
//#define MPLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
//CONFIG_CLK_833_166_66
#define MPLL_VAL  ((1<<31) | (89 << 16) | (2 << 8) | (1))
#define EPLL_VAL  ((1<<31) | (135 << 16) | (3 << 8) | (3))
#define HPLL_VAL  ((1<<31) | (96 << 16) | (6 << 8) | (3))

	ldr r1, =MPLL_VAL
	str r1, [r0, #0x104]

	ldr r1, =EPLL_VAL
	str r1, [r0, #0x108]

	ldr r1, =HPLL_VAL
	str r1, [r0, #0x10c]
	
	/* 3.选择PLL的输出作为时钟源 */
	ldr r1, [r0, #0x200]	//CLK_SRC0 0xe0100200
	ldr r2, =0x1111
	orr r1, r1, r2
	str r1, [r0, #0x200]	//FOUT: APLL MPLL EPLL HPLL

	mov 	r1, #0x10000
1:	subs	r1, r1, #1
	bne	1b

	mov pc, lr

文件cpu_init.S

//#include "s5pc100.h"
/* Port Group MP1_X Drive Strength Control */
#define MP1_0DRV_OFFSET			0x03CC
#define MP1_1DRV_OFFSET			0x03EC
#define MP1_2DRV_OFFSET			0x040C
#define MP1_3DRV_OFFSET			0x042C
#define MP1_4DRV_OFFSET			0x044C
#define MP1_5DRV_OFFSET			0x046C
#define MP1_6DRV_OFFSET			0x048C
#define MP1_7DRV_OFFSET			0x04AC
#define MP1_8DRV_OFFSET			0x04CC

/*
 * Bus Matrix
 */
#define ELFIN_MEM_SYS_CFG		0x7e00f120

/*
 * Memory controller
 */
#define ELFIN_SROM_BASE			0xE7000000

#define SROM_BW_REG			__REG(ELFIN_SROM_BASE+0x0)
#define SROM_BC0_REG			__REG(ELFIN_SROM_BASE+0x4)
#define SROM_BC1_REG			__REG(ELFIN_SROM_BASE+0x8)
#define SROM_BC2_REG			__REG(ELFIN_SROM_BASE+0xC)
#define SROM_BC3_REG			__REG(ELFIN_SROM_BASE+0x10)
#define SROM_BC4_REG			__REG(ELFIN_SROM_BASE+0x14)
#define SROM_BC5_REG			__REG(ELFIN_SROM_BASE+0x18)

/*
 * SDRAM Controller
 */
#define APB_DMC_BASE			0xE6000000

#define	DMC_CONCONTROL			0x00
#define	DMC_MEMCONTROL			0x04
#define	DMC_MEMCONFIG0			0x08
#define	DMC_MEMCONFIG1			0x0C
#define	DMC_DIRECTCMD			0x10
#define	DMC_PRECHCONFIG			0x14
#define	DMC_PHYCONTROL0			0x18
#define	DMC_PHYCONTROL1			0x1C
#define	DMC_PHYCONTROL2			0x20
#define	DMC_PWRDNCONFIG 		0x28
#define	DMC_TIMINGAREF  		0x30
#define	DMC_TIMINGROW   		0x34
#define	DMC_TIMINGDATA  		0x38
#define	DMC_TIMINGPOWER 		0x3C
#define	DMC_PHYSTATUS0  		0x40
#define	DMC_PHYSTATUS1  		0x44
#define	DMC_CHIP0STATUS 		0x48
#define	DMC_CHIP1STATUS 		0x4C
#define	DMC_AREFSTATUS  		0x50
#define	DMC_MRSTATUS    		0x54
#define	DMC_PHYTEST0    		0x58
#define	DMC_PHYTEST1    		0x5C
#define	DMC_QOSCONTROL0 		0x60
#define	DMC_QOSCONFIG0  		0x64
#define	DMC_QOSCONTROL1 		0x68
#define	DMC_QOSCONFIG1  		0x6C
#define	DMC_QOSCONTROL2 		0x70
#define	DMC_QOSCONFIG2  		0x74
#define	DMC_DMC_QOSCONTROL3 		0x78
#define	DMC_QOSCONFIG3  		0x7C
#define	DMC_QOSCONTROL4 		0x80
#define	DMC_QOSCONFIG4  		0x84
#define	DMC_QOSCONTROL5 		0x88
#define	DMC_QOSCONFIG5  		0x8C
#define	DMC_QOSCONTROL6 		0x90
#define	DMC_QOSCONFIG6  		0x94
#define	DMC_QOSCONTROL7 		0x98
#define	DMC_QOSCONFIG7  		0x9C

/*
* Memory Chip direct command
*/
#define PRO_ID_BASE			0xE0000000
#define PRO_ID_OFFSET			0x00
#define OMR_OFFSET			0x04

/*
 * GPIO
 */
#define ELFIN_GPIO_BASE			0xE0300000


.globl	mp1_x_drive_strength_init
/*
 * Init MP1_X Driver Strength for SDRAM
 * void mp1_x_drive_strength_init(void)
 */
 mp1_x_drive_strength_init:
 
	ldr	r0, =ELFIN_GPIO_BASE
	ldr	r1, =0xaaaa
	str   	r1, [r0, #MP1_0DRV_OFFSET]
	str   	r1, [r0, #MP1_1DRV_OFFSET]
	str   	r1, [r0, #MP1_2DRV_OFFSET]
	str   	r1, [r0, #MP1_3DRV_OFFSET]
	str   	r1, [r0, #MP1_4DRV_OFFSET]
	str   	r1, [r0, #MP1_5DRV_OFFSET]
	str   	r1, [r0, #MP1_6DRV_OFFSET]	
	str   	r1, [r0, #MP1_7DRV_OFFSET]
	str   	r1, [r0, #MP1_8DRV_OFFSET]	
	
	mov pc, lr

	.globl mem_ctrl_asm_init
mem_ctrl_asm_init:

	ldr	r0, =APB_DMC_BASE			@APB_DMC_BASE 0xE6000000

	ldr	r1, =PRO_ID_BASE
	ldr	r2, [r1, #PRO_ID_OFFSET]
	bic	r2, #0xfffffdff
	mov	r2, r2, lsr #9
	cmp	r2, #0x1
	beq	onenand_pop

single:

/************ delay loop *************/

#if 0
	ldr		r1, =0x10000000
	mov 		r2, #0
loop1:

	cmp		r2, r1
	addne	r2, r2, #0x1
	bne loop1
#endif

/************ DLL initialization *************/
      
        ldr     r1, =0x6A101000				@ Phycontrol0 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL0]

        ldr     r1, =0x000084F4                       	 @Phycontrol1 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL1]

        ldr     r1, =0x00000000                        	 @Phycontrol2 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL2]

        ldr     r1, =0x6A101002			    	  @DLL on
        str     r1, [r0, #DMC_PHYCONTROL0]

        ldr     r1, =0x6A101003			  	@Dll start
        str     r1, [r0, #DMC_PHYCONTROL0]



	ldr	r2, = 0xE6000040		@DMC_PHYSTATUS0

loop1:

	ldr	r1, [r2]				@Check DLL lock
	ands	r1, r1, #4
	beq	loop1

	ldr	r1, [r2]
	mov	r1, r1,  LSR #(0x6)
	and	r1, r1, #(0xff)
	mov	r1, r1, LSL  #(0x18)
    ldr 	r2,  = 0xE6000018			@DMC_PHYCONTROL0
	ldr	r3, [r2]
	bic	r3,  r3, #(0xff000000)
	orr	r1, r3, r2
	str	r1, [r2]



        ldr     r1, =0x6A101003			@Force Value locking
        str     r1, [r0, #DMC_PHYCONTROL0]

        ldr     r1, =0x6A101009			@Dll off
        str     r1, [r0, #DMC_PHYCONTROL0]



#if 0
        ldr     r1, =0x6A101000				@ Phycontrol0 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL0]

        ldr     r1, =0x00008484                             @Phycontrol1 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL1]

        ldr     r1, =0x00000000                             @Phycontrol2 DLL parameter setting
        str     r1, [r0, #DMC_PHYCONTROL2]

#endif
/************ DLL initialization - END *************/




        ldr     r1, =0x0FF01010                         @auto refresh off
        str     r1, [r0, #DMC_CONCONTROL]

        ldr     r1, =0x00202400                         @ BL=4 , 1 chip , DDR2
        str     r1, [r0, #DMC_MEMCONTROL]

#if 1	// add xxs 256MB enable
        ldr     r1, =0x20F01323
        str     r1, [r0, #DMC_MEMCONFIG0]

        ldr     r1, =0x40F00323
        str     r1, [r0, #DMC_MEMCONFIG1]
#else	// 128MB enable
        ldr     r1, =0x20F81313						
        str     r1, [r0, #DMC_MEMCONFIG0]

        ldr     r1, =0x40F80313
        str     r1, [r0, #DMC_MEMCONFIG1]
#endif
  
        ldr     r1, =0x20000000		
        str     r1, [r0, #DMC_PRECHCONFIG]


 		ldr     r1, =0x00100004			@ PwrdnConfig
        str     r1, [r0, #DMC_PWRDNCONFIG]

#ifdef	CONFIG_HCLKD0_222
	ldr 	r1, =0x000006c3 						@7.8us*222MHz=0x6c3, 7.8us*166MHz=1294(0x50E)
       str     r1, [r0, #DMC_TIMINGAREF]
	/* T-rfc   127.5nS/5ns  64 */
       ldr     r1, =0x202332C8                         		@TimingRow      @222MHz
       str     r1, [r0, #DMC_TIMINGROW]

       ldr     r1, =0x24450304							@CL=5
       str     r1, [r0, #DMC_TIMINGDATA]

 #else


      	ldr     r1, =0x0000050E		
        str     r1, [r0, #DMC_TIMINGAREF]

		ldr	 r1, =0x16233297						 @TimingRow 	 @166MHz
        str     r1, [r0, #DMC_TIMINGROW]

@;		ldr	 r1, =0x24250304						 @CL=5
		ldr	 r1, =0x23230000						 @CL=3
        str     r1, [r0, #DMC_TIMINGDATA]
 #endif

        ldr     r1, =0x07c80232    	                   @ Timing Power
        str     r1, [r0, #DMC_TIMINGPOWER]

/* Direct Command for DDR2 */
        ldr     r1, =0x07000000                         @chip0 Deselect
        str     r1, [r0, #DMC_DIRECTCMD]

        ldr     r1, =0x01000000                        @chip0 PALL
        str     r1, [r0, #DMC_DIRECTCMD]

        ldr     r1, =0x00020000                         @chip0 EMRS2
        str     r1, [r0, #DMC_DIRECTCMD]

        ldr     r1, =0x00030000                         @chip0 EMRS3
        str     r1, [r0, #DMC_DIRECTCMD]

		ldr     r1, =0x00010400                         @chip0 EMRS1 (MEM DLL on = DQS# disable)
        str     r1, [r0, #DMC_DIRECTCMD]

@;		ldr     r1, =0x00000552                         @chip0 MRS (MEM DLL reset) CL=5, Burst Length=4
        ldr     r1, =0x00000532                         @chip0 MRS (MEM DLL reset) CL=3, Burst Length=4
        str     r1, [r0, #DMC_DIRECTCMD]

        ldr     r1, =0x01000000             
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值