uboot源码学习(4)cpu_init_crit

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_cp15
	bl	cpu_init_crit
#endif

执行完cpu_init_cp15后,跳转到cpu_init_crit执行。

ENTRY(cpu_init_crit)
	/*
	 * Jump to board specific initialization...
	 * The Mask ROM will have already initialized
	 * basic memory. Go here to bump up clock rate and handle
	 * wake up conditions.
	 */
	b	lowlevel_init		@ go setup pll,mux,memory
ENDPROC(cpu_init_crit)
#endif

最终跳转到lowlevel_init函数执行。此函数在**\u-boot-2012.10\board\samsung\goni\lowlevel_init.S**文件中。
25行到72行代码如下:

#include <config.h>
#include <version.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/power.h>

/*
 * Register usages:
 *
 * r5 has zero always
 * r7 has S5PC100 GPIO base, 0xE0300000
 * r8 has real GPIO base, 0xE0300000, 0xE0200000 at S5PC100, S5PC110 repectively
 * r9 has Mobile DDR size, 1 means 1GiB, 2 means 2GiB and so on
 */

_TEXT_BASE:
	.word	CONFIG_SYS_TEXT_BASE

	.globl lowlevel_init
lowlevel_init:
	mov	r11, lr

	/* r5 has always zero */
	mov	r5, #0

	ldr	r7, =S5PC100_GPIO_BASE
	ldr	r8, =S5PC100_GPIO_BASE
	/* Read CPU ID */
	ldr	r2, =S5PC110_PRO_ID
	ldr	r0, [r2]
	mov	r1, #0x00010000
	and	r0, r0, r1
	cmp	r0, r5
	beq	100f
	ldr	r8, =S5PC110_GPIO_BASE
100:
	/* Turn on KEY_LED_ON [GPJ4(1)] XMSMWEN */
	cmp	r7, r8
	beq	skip_check_didle			@ Support C110 only

	ldr	r0, =S5PC110_RST_STAT
	ldr	r1, [r0]
	and	r1, r1, #0x000D0000
	cmp	r1, #(0x1 << 19)			@ DEEPIDLE_WAKEUP
	beq	didle_wakeup
	cmp	r7, r8

一、

_TEXT_BASE:
	.word	CONFIG_SYS_TEXT_BASE

在标号_TEXT_BASE处定义了一个数CONFIG_SYS_TEXT_BASE,它具体的数值在\u-boot-2012.10\board\samsung\goni\lowlevel_init.S同级目录下的config.mk文件中。

CONFIG_SYS_TEXT_BASE = 0x34800000

在这里插入图片描述
如上图所示,即最后内核text段会被加载到CONFIG_SYS_TEXT_BASE = 0x34800000地址处。
二、
1、

.globl lowlevel_init
lowlevel_init:

.globl表示lowlevel_init是全局函数,在别的文件中可以调用。
2、

mov	r11, lr

将链接寄存器lr中的值存入r11。等函数返回的时候再把r11恢复到lr中。
3、

/* r5 has always zero */
	mov	r5, #0

r5中的值设置为0。
4、配置r7和r8寄存器

	ldr	r7, =S5PC100_GPIO_BASE
	ldr	r8, =S5PC100_GPIO_BASE

将r7,r8寄存器中的值都设为S5PC100_GPIO_BASE。它的值定义在#include <asm/arch/cpu.h>中。

#define S5PC100_GPIO_BASE	0xE0300000

表示的是GPIO的基地址。

#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/power.h>

这三个文件在\u-boot-2012.10\arch\arm\include\asm\arch-s5pc1xx路径下,它是绝对路径。而在#include <asm/arch/cpu.h>中是相对路径,这是因为在编译的时候,在Makefile中将\u-boot-2012.10\arch\arm\include\asm软链接到asm,此时#include <asm/arch/cpu.h>就能找到绝对路径下的cpu.h文件。
5、设置芯片号

/* Read CPU ID */
	ldr	r2, =S5PC110_PRO_ID

cpu.h文件:

#define S5PC100_PRO_ID		0xE0000000

表示将芯片的芯片号,放入r2寄存器,芯片是S5PV210或者S5PC110,它的芯片号是0x43110xxx。如果芯片是S5PC100,芯片号是0x43100xxx。这样可以判断目前运行的是哪个型号的芯片。
在这里插入图片描述
6、设置S5PC110 GPIO的基地址

	ldr	r0, [r2]
	mov	r1, #0x00010000
	and	r0, r0, r1
	cmp	r0, r5
	beq	100f
	ldr	r8, =S5PC110_GPIO_BASE

将0x43110xxx写入r0寄存器;
将0x00010000写入r1寄存器;
将r0和r1再与一下得到0x00010000,存入r0寄存器;
比较r5(#0)和r0(0x00010000),不等于;
将S5PC110_GPIO_BASE写入到r8寄存器,此时是110的GPIO基地址。

#define S5PC110_GPIO_BASE	0xE0200000

7、

100:
	/* Turn on KEY_LED_ON [GPJ4(1)] XMSMWEN */
	cmp	r7, r8
	beq	skip_check_didle			@ Support C110 only

r7不等于r8,所以跳过beq skip_check_didle @ Support C110 only

8、Reset Control Register

	ldr	r0, =S5PC110_RST_STAT
	ldr	r1, [r0]
	and	r1, r1, #0x000D0000
	cmp	r1, #(0x1 << 19)			@ DEEPIDLE_WAKEUP
	beq	didle_wakeup
	cmp	r7, r8

S5PC110_RST_STAT在power.h中定义:

#define S5PC110_RST_STAT		0xE010A000

在这里插入图片描述
此寄存器功能为从什么状态唤醒,如果第19位是1,则表示从DEEPIDLE_WAKEUP状态唤醒。

ldr	r1, [r0]
	and	r1, r1, #0x000D0000
	cmp	r1, #(0x1 << 19)			@ DEEPIDLE_WAKEUP

三句判断第19位是否为1。

beq	didle_wakeup

此句不运行。

cmp	r7, r8

比较r7和r8。

9、GPJ4

skip_check_didle:
	addeq	r0, r8, #0x280				@ S5PC100_GPIO_J4
	addne	r0, r8, #0x2C0				@ S5PC110_GPIO_J4

执行addne r0, r8, #0x2C0 @ S5PC110_GPIO_J4。此时r0=0xE020002C0。此地址为GPJ4的CON寄存器。
在这里插入图片描述

	ldr	r1, [r0, #0x0]				@ GPIO_CON_OFFSET
	bic	r1, r1, #(0xf << 4)			@ 1 * 4-bit
	orr	r1, r1, #(0x1 << 4)
	str	r1, [r0, #0x0]				@ GPIO_CON_OFFSET

	ldr	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET
	bic	r1, r1, #(1 << 1)
	str	r1, [r0, #0x4]				@ GPIO_DAT_OFFSET

此段代码为对GPJ4的配置。将GPJ4_1配置为output。并将GPJ4_1_DAT配置为0,低电平。
10、beq 100f跳过。
11、同步寄存器

ldr     r0, =0xe0f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xe1f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1800000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1900000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1a00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1b00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1c00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1d00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1e00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xf1f00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

	ldr     r0, =0xfaf00000
	ldr     r1, [r0]
	bic     r1, r1, #0x1
	str     r1, [r0]

此段代码设置同步寄存器。每个寄存器只有第0位有效,置0时为full状态,表示同步速率慢,但是平均出错率低。置1时为half状态,表示同步速率快,但是平均出错率高。此处全部设置为0.
在这里插入图片描述
在这里插入图片描述
注释中EVT0和EVT1表示次版本号。表示同型号不同批次的芯片。[7:0]可能会有差异。
在这里插入图片描述
12、ABB block

/*
	 * Diable ABB block to reduce sleep current at low temperature
	 * Note that it's hidden register setup don't modify it
	 */
	ldr	r0, =0xE010C300
	ldr	r1, =0x00800000
	str	r1, [r0]

0xE010C300,此寄存器是”hidden register“,所以在手册里查不到,照写就行。

13、S5PC110_OTHERS

100:
	/* IO retension release */
	ldreq	r0, =S5PC100_OTHERS			@ 0xE0108200
	ldrne	r0, =S5PC110_OTHERS			@ 0xE010E000
	ldr	r1, [r0]
	ldreq	r2, =(1 << 31)				@ IO_RET_REL
	ldrne	r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))
	orr	r1, r1, r2
	/* Do not release retention here for S5PC110 */
	streq	r1, [r0]

S5PC110_OTHERS 在power.h中定义。

#define S5PC110_OTHERS			0xE010E000

此句不执行。

ldreq	r2, =(1 << 31)				@ IO_RET_REL
ldrne	r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))

将r2最高4位都设置成1。

orr	r1, r1, r2

将r1和r2取或之后放入r1。

streq	r1, [r0]

此句也不执行。所以14这一大段代码没有实际用途。

S5PC110_OTHERS此寄存器的作用是休眠时候的保持状态。
在这里插入图片描述
14、Watchdog

/* Disable Watchdog */
	ldreq	r0, =S5PC100_WATCHDOG_BASE		@ 0xEA200000
	ldrne	r0, =S5PC110_WATCHDOG_BASE		@ 0xE2700000
	str	r5, [r0]

配置看门狗寄存器。将r5(#0)写入寄存器。
在这里插入图片描述
第0位:禁止看门狗复位功能;
第2位:禁止看门狗中断;
第[4:3]:时钟分频为16;
第5位:禁止看门狗定时器运行;
第[15:8]:预分频器的值。

15、SROM

/* setting SRAM */
	ldreq	r0, =S5PC100_SROMC_BASE
	ldrne	r0, =S5PC110_SROMC_BASE
	ldr	r1, =0x9
	str	r1, [r0]

此处应该是SROM,配置SROM寄存器的值为9。(1001)
在这里插入图片描述
在这里插入图片描述
第0位:数据总线的宽度为16位;
第1位:地址总线为半字宽度即16位。
第2位:禁止等待;
第3位:使用高半字还是低半字。

16、IRQ

/* S5PC100 has 3 groups of interrupt sources */
	ldreq	r0, =S5PC100_VIC0_BASE			@ 0xE4000000
	ldrne	r0, =S5PC110_VIC0_BASE			@ 0xF2000000
	add	r1, r0, #0x00100000
	add	r2, r0, #0x00200000

/* S5PC100 has 3 groups of interrupt sources */ ,S5PC110 有4个中断群组,注释中未标注。
将S5PC110_VIC0_BASE+#0x00100000放入r1寄存器;
将S5PC110_VIC0_BASE+#0x00200000放入2寄存器;

/* Disable all interrupts (VIC0, VIC1 and VIC2) */
	mvn	r3, #0x0
	str	r3, [r0, #0x14]				@ INTENCLEAR
	str	r3, [r1, #0x14]				@ INTENCLEAR
	str	r3, [r2, #0x14]				@ INTENCLEAR

将VIC0,VIC1,VIC2三个中断群组禁止。

mvn	r3, #0x0 

将#0赋给r3寄存器,并取反,即r3=0xffff;
再将0xfffff依次赋值给r0+14,r1+14,r2+14。
在这里插入图片描述
在这里插入图片描述

/* Set all interrupts as IRQ */
	str	r5, [r0, #0xc]				@ INTSELECT
	str	r5, [r1, #0xc]				@ INTSELECT
	str	r5, [r2, #0xc]				@ INTSELECT

将三个寄存器群组设为IRQ 模式。
在这里插入图片描述

/* Pending Interrupt Clear */
	str	r5, [r0, #0xf00]			@ INTADDRESS
	str	r5, [r1, #0xf00]			@ INTADDRESS
	str	r5, [r2, #0xf00]			@ INTADDRESS

将现在有中断信号的源全部清0;
在这里插入图片描述
17、跳转到uart_asm_init
开始配置串口。
/* for UART */
bl uart_asm_init

bl	internal_ram_init
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值