Uboot分析(四)

@board/samsung/smdkc100/lowlevel_init.S

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

/*
 * Register usages:
 *
 * r5 has zero always
 */

_TEXT_BASE:
 .word TEXT_BASE

 .globl lowlevel_init
lowlevel_init:
 mov r9, lr

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

 ldr r8, =S5PC100_GPIO_BASE

 /* Disable Watchdog */    @关看门狗
 ldr r0, =S5PC100_WATCHDOG_BASE  @0xEA200000    Watchdog Timer  WTCON地址
 orr r0, r0, #0x0
 str r5, [r0]    @看门狗控制器的最低位为0时,看门狗不输出复位信号

@向看门狗控制寄存器写入0,关闭看门狗。否则在U-Boot启动过程中,CPU将不断重启

#ifndef CONFIG_ONENAND_IPL
 /* setting SRAM */
 ldr r0, =S5PC100_SROMC_BASE
 ldr r1, =0x9
 str r1, [r0]
#endif

 /* S5PC100 has 3 groups of interrupt sources */
 ldr r0, =S5PC100_VIC0_BASE   @0xE4000000
 ldr r1, =S5PC100_VIC1_BASE   @0xE4100000
 ldr r2, =S5PC100_VIC2_BASE   @0xE4200000

 /* Disable all interrupts (VIC0, VIC1 and VIC2) */
 mvn r3, #0x0
 str r3, [r0, #0x14]    @INTENCLEAR    Interrupt Enable Clear Register中断使能清除寄存器
 str r3, [r1, #0x14]    @INTENCLEAR
 str r3, [r2, #0x14]    @INTENCLEAR

#ifndef CONFIG_ONENAND_IPL
 /* Set all interrupts as IRQ */
 str r5, [r0, #0xc]    @INTSELECT    Interrupt Select Register中断选择寄存器
 str r5, [r1, #0xc]    @INTSELECT
 str r5, [r2, #0xc]    @INTSELECT

 /* Pending Interrupt Clear */
 str r5, [r0, #0xf00]   @INTADDRESS    Vector Address Register向量地址寄存器
 str r5, [r1, #0xf00]   @INTADDRESS
 str r5, [r2, #0xf00]   @INTADDRESS
#endif

#ifndef CONFIG_ONENAND_IPL
 /* for UART */
 bl uart_asm_init

 /* for TZPC */
 bl tzpc_asm_init
#endif

#ifdef CONFIG_ONENAND_IPL
 /* init system clock */
 bl system_clock_init

 bl mem_ctrl_asm_init

 /* Wakeup support. Don't know if it's going to be used, untested. */
 ldr r0, =S5PC100_RST_STAT
 ldr r1, [r0]
 bic r1, r1, #0xfffffff7
 cmp r1, #0x8
 beq wakeup_reset
#endif

1:
 mov lr, r9
 mov pc, lr

#ifdef CONFIG_ONENAND_IPL
wakeup_reset:

 /* Clear wakeup status register */
 ldr r0, =S5PC100_WAKEUP_STAT
 ldr r1, [r0]
 str r1, [r0]

 /* Load return address and jump to kernel */
 ldr r0, =S5PC100_INFORM0

 /* r1 = physical address of s5pc100_cpu_resume function */
 ldr r1, [r0]

 /* Jump to kernel (sleep.S) */
 mov pc, r1
 nop
 nop    @NOP指令为单周期指令,延时很短

@nop指令的作用:
1)就是通过nop指令的填充(nop指令一个字节),使指令按字对齐,从而减少取指令时的内存访问次数。(一般用来内存地址偶数对齐,比如有一条指令,占3字节,这时候使用nop指令,cpu 就可以从第四个字节处读取指令了。)
2)通过nop指令产生一定的延迟,但是对于快速的CPU来说效果不明显,可以使用rep前缀,多延迟几个时钟;-->具体应该说是占用了3个时钟脉冲!
3)i/o传输时,也会用一下 nop,等待缓冲区清空,总线恢复;
4)清除由上一个算术逻辑指令设置的flag位;
#endif

/*
 * system_clock_init: Initialize core clock and bus clock.
 * void system_clock_init(void)
 */
system_clock_init:
 ldr r8, =S5PC1XX_CLOCK_BASE  @ 0xE0100000

 /* Set Clock divider */    设置时钟分频值
 ldr r1, =0x00011110
 str r1, [r8, #0x304]    @Set clock divider ratio 1 (Main D1 domain)
 ldr r1, =0x1
 str r1, [r8, #0x308]    @Set clock divider ratio 2 (Connectivity)
 ldr r1, =0x00011301
 str r1, [r8, #0x300]    @Set clock divider ratio 0 (Main D0 domain)

 /* Set Lock Time */
 ldr r1, =0xe10   @ Locktime : 0xe10 = 3600
 str r1, [r8, #0x000]  @ APLL_LOCK    Control PLL masking period for APLL
 str r1, [r8, #0x004]  @ MPLL_LOCK
 str r1, [r8, #0x008]  @ EPLL_LOCK
 str r1, [r8, #0x00C]  @ HPLL_LOCK

 /* APLL_CON */
 ldr r1, =0x81bc0400  @ SDIV 0, PDIV 4, MDIV 444 (1332MHz)

@FOUT = MDIV X FIN / (PDIV X 2SDIV)

@FOUT = 444 * 12MHz / 4 = 1332MHz 

/*

The output frequency is calculated by the following equation:
FOUT = MDIV X FIN / (PDIV X 2SDIV)
where, MDIV, PDIV, SDIV for APLL and MPLL must meet the following conditions :
PDIV: 1 ≤ PDIV ≤ 63
MDIV: 64 ≤ MDIV ≤ 1023
SDIV: 0 ≤ SDIV ≤ 5
Fref (=FIN / PDIV): 3MHz ≤ Fref ≤ 6MHz
FVCO (=MDIV X FIN / PDIV): 1000MHz ≤ FVCO ≤ 2000MHz
FOUT: 50MHz ≤ FVCO ≤ 2000MHz

*/
 str r1, [r8, #0x100]
 /* MPLL_CON */
 ldr r1, =0x80590201  @ SDIV 1, PDIV 2, MDIV 89 (267MHz)
 str r1, [r8, #0x104]
 /* EPLL_CON */
 ldr r1, =0x80870303  @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz)
 str r1, [r8, #0x108]
 /* HPLL_CON */
 ldr r1, =0x80600603
 str r1, [r8, #0x10C]

 /* Set Source Clock */
 ldr r1, =0x1111   @ A, M, E, HPLL Muxing
 str r1, [r8, #0x200]  @ CLK_SRC0

 ldr r1, =0x1000001   @ Uart Clock & CLK48M Muxing
 str r1, [r8, #0x204]  @ CLK_SRC1

 ldr r1, =0x9000   @ ARMCLK/4
 str r1, [r8, #0x400]  @ CLK_OUT

 /* wait at least 200us to stablize all clock */
 mov r2, #0x10000
1: subs r2, r2, #1
 bne 1b

 mov pc, lr

#ifndef CONFIG_ONENAND_IPL
/*
 * uart_asm_init: Initialize UART's pins
 */
uart_asm_init:
 mov r0, r8
 ldr r1, =0x22222222
 str r1, [r0, #0x0]   @ GPA0_CON    0xE030_0000    配置UART_0/UART_1
 ldr r1, =0x00022222
 str r1, [r0, #0x20]   @ GPA1_CON    配置UART_2/UART_3/UARTCLK

 mov pc, lr

/*
 * tzpc_asm_init: Initialize TZPC
 */
tzpc_asm_init:
 ldr r0, =0xE3800000    @TZPC0    SECURE RAM REGION SIZE REGISTER
 mov r1, #0x0
 str r1, [r0]
 mov r1, #0xff
 str r1, [r0, #0x804]
 str r1, [r0, #0x810]

 ldr r0, =0xE2800000    @TZPC1
 str r1, [r0, #0x804]
 str r1, [r0, #0x810]
 str r1, [r0, #0x81C]

 ldr r0, =0xE2900000    @TZPC2
 str r1, [r0, #0x804]
 str r1, [r0, #0x810]

 mov pc, lr
#endif

你可能感兴趣的:(Boot)