This article mainly analyzes the assembly code CPU/PXA/start. s related to the U-boot startup process. The target platform uses PXA270 as an example.
Cpu_init_crit:
/* Mask all irqs */
LDR r0, ic_base/* R0 <-interrupt-controller base address */
MoV R1, #0x00
STR R1, [r0, # icmr_offset]/* The ICMR registers are cleared to shield all interrupts */
/*
* Before relocating, We Have To Setup RAM Timing
* Because memory timing is board-dependend, you will
* Find A lowlevel_init.s in your board directory.
*/
BL lowlevel_init/* jump to lowlevel_init to execute SDRAM-related initialization. For details, refer to the analysis of lowlevel_init.s */
# If defined (cfg_cpuspeed)
/*
* The system frequency is calculated as follows:
* Turbo-mode frequency (t) = 13-mhz processor-Oscillator frequency * l * n
* Run-mode frequency (R) = 13-mhz processor-Oscillator frequency * l
* System-bus frequency = 13-mhz processor-Oscillator frequency * L/B,
* Where B = 1 (when in fast-bus mode) or B = 2 (when not in fast-bus mode)
* For CCCR [a] = 0:
* Memory-controller frequency = 13-mhz processor-Oscillator frequency * L/m,
* Where m = 1 (L = 2-10), m = 2 (L = 11-20), or M = 4 (L = 21-31)
* LCD frequency = 13-mhz processor-Oscillator frequency * l/K,
* Where k = 1 (L = 2-7), k = 2 (L = 8-16), or K = 4 (L = 17-31)
* For clkcfg [B] = 0 and CCCR [a] = 1:
* Memory-controller frequency = 13-mhz processor-Oscillator frequency * l/2
* LCD frequency = 13-mhz processor-Oscillator frequency * l/K,
* Where k = 1 (L = 2-7), k = 2 (L = 8-16), or K = 4 (L = 17-31)
* For clkcfg [B] = 1 and CCCR [a] = 1:
* Memory-controller frequency = 13-mhz processor-Oscillator frequency * l
* LCD frequency = 13-mhz processor-Oscillator frequency * l/K,
* Where k = 1 (L = 2-7), k = 2 (L = 8-16), or K = 4 (L = 17-31)
*/
/* Set clock speed */
LDR r0, = cc_base
LDR R1, cpuspeed
STR R1, [r0, # cccr_offset]/* Core clock configuration register */
LDR R1, [r0, # cccr_offset]/* read back to make sure write action completed */
MoV IP, LR/* temporary register <-link register */
BL xlli_freq_change/* jump to the label xlli_freq_change and execute */
MoV LR, IP
/* Before enabling fast bus mode, must make sure memory controller is configured properly */
# If defined (config_sysbus_208)
MoV r0, # 0x0b/* fast bus | freq. Change | Turbo mode */
# Else
MoV r0, #0x03 /*~ Fast bus | freq. Change | Turbo mode */
# Endif
MCR P14, 0, R0, C6, C0, 0/* write cclkcfg */
# If defined (config_memc_bs)/* Memory Controller buffer strength control */
LDR r0, = memc_base
LDR R1, = rj_bscntr0_val
STR R1, [r0, # bscntr0_offset]
LDR R1, = rj_bscntr1_val
STR R1, [r0, # bscntr1_offset]
LDR R1, = rj_bscntr2_val
STR R1, [r0, # bscntr2_offset]
LDR R1, = rj_bscntr3_val
STR R1, [r0, # bscntr3_offset]
LDR R1, [r0, # bscntr3_offset]/* Make sure value is written */
# Endif
Setspeed_done:
# Endif
. Global normal_boot
Normal_boot:
/* Memory interfaces are working. Disable MMU and enable I-Cache .*/
LDR r0, = 0x2001/* enable access to all coproc .*/
MCR P15, 0, R0, C15, C1, 0/* enable access to cp13 cp0 */
Cpwait/* Wait For effect */
MCR P15, 0, R0, C7, C10, 4/* drain the write & fill buffers */
Cpwait
MCR P15, 0, R0, C7, C7, 0/* flush icache, dcache and BTB */
Cpwait
MCR P15, 0, R0, C8, C7, 0/* flush instuction and data tlbs */
Cpwait
/* Enable the icache */
MRC P15, 0, R0, C1, C0, 0
ORR r0, R0, #0x1800/* Instruction Cache enable, Branch Target Buffer enable */
MCR P15, 0, R0, C1, C0, 0
Cpwait
@ Mov PC, LR
B cpu_init_done/* Call return back */
/* Frequency change sequence from blob */
Xlli_freq_change:
MRC P14, 0, R0, C6, C0, 0/* Get present status (preserve Turbo and fast bus bits )*/
ORR r0, R0, #2/* set the f bit, frequency change, a change sequence is initiated when F is set .*/
MCR P14, 0, R0, C6, C0, 0/* initiate the frequency change sequence */
/*
* If the clock frequency is chaged, The mdrefr register must be rewritten, even
* If it's the same value. This will result in a refresh being stored med and
* Refresh counter being reset to the reset interval. (Section 13.10.3, pg 13-17 of EAS)
*/
LDR R4, = memc_base/* Get memory controller base address */
LDR R1, [R4, # mdrefr_offset]/* Get the current state of mdrefr */
STR R1, [R4, # mdrefr_offset]/* re-write this value */
MoV PC, LR/* return to calling routine */
/* RS :??? */
. Macro cpwait/* canonical method to wait for CP15 update */
MRC P15, 0, R0, C2, C0, 0/* arbitrary read of CP15 */
MoV r0, R0/* NOP, wait for it */
Sub PC, PC, #4/* branch to next instruction */
/* At this point, any previous CP15 writes are guaranteed to have taken effect .*/
. Endm
Cpu_init_done:
# Ifndef config_skip_relocate_uboot
Relocate:/* relocate U-boot to Ram */
ADR r0, _ start/* R0 <-current position of code */
LDR R1, _ text_base/* test if we run from flash or Ram */
CMP r0, R1/* Don't reloc during debug */
Beq stack_setup
LDR R2, _ armboot_start
LDR R3, _ bss_start
Sub R2, R3, R2/* R2 <-size of armboot */
Add R2, R0, R2/* R2 <-source end address */
Copy_loop:
Ldmia R0 !, {R3-r10}/* copy from Source Address [R0] */
Stmia R1 !, {R3-r10}/* Copy to target address [R1] */
CMP r0, R2/* Until source end addreee [R2] */
Ble copy_loop
# Endif/* config_skip_relocate_uboot */
/* Set up the stack */
Stack_setup:
LDR r0, _ text_base/* upper 128 kib: relocated uboot */
Sub r0, R0, # maid/* malloc area */
Sub r0, R0, # cfg_gbl_data_size/* bdinfo */
# Ifdef config_use_irq
Sub r0, R0, # (config_stacksize_irq + config_stacksize_fiq)
# Endif
Sub sp, R0, #12/* Leave 3 words for abort-stack, sp -- Stack pointer register */
Clear_bss:
LDR r0, _ bss_start/* Find start of BSS segment */
LDR R1, _ bss_end/* Stop here */
MoV R2. #0x00000000/* clear */
Clbss_l: Str R2, [R0]/* clear loop ...*/
Add r0, R0, #4
CMP r0, r1
Ble clbss_l