|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
@CPU初始化
5 ^4 V5 [$ Q. X4 E4 D+ |6 Q% G5 Z, [
@在“relocate: ”之前被调用
$ c0 [6 x! T4 @: U
( y; y1 W5 g) D' q, k#ifndef CONFIG_SKIP_LOWLEVEL_INIT
4 p3 c G3 r5 _; z6 C; z. v! L# v; zcpu_init_crit:
& s/ _5 {, Y9 n; N6 |1 X4 w3 F
( n8 k A8 b* G" l@初始化CACHES7 s0 X% i# P% g' S: Q
mov r0, #0
) I: R" }: b! Cmcr p15, 0, r0, c7, c7, 0 * C/ r5 r$ \/ e1 A& j
mcr p15, 0, r0, c8, c7, 0* `8 N5 x) T1 ?: N4 U# Y" t
! p- @7 V' N7 x" q& v( N9 S
2 ^8 D c# @, }* p# e" Q( |% E
( `5 V& e" T6 |+ v/ H' a4 a+ k. z7 W' y c: A% `0 A+ l
@关闭MMU和CACHES
' f7 ?+ |% X6 t; d3 u$ {- X% S1 Dmrc p15, 0, r0, c1, c0, 0) c; O3 H" |8 o
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)5 }3 B1 b5 X) b6 t+ R- Y. ~. [
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)5 n- P, S1 h# U9 S* ^# K$ s3 [6 |) v
orr r0, r0, #0x00000002 @ set bit 2 (A) Align, p' d- l6 d% P b% q
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache: V9 W/ E1 S$ T' y0 c: B
mcr p15, 0, r0, c1, c0, 0; S# K$ `. b# L7 P* B/ m, `
@对协处理器的操作还是看不懂,暂时先不管吧,有时间研究一下ARM技术手册的协处理器部分。" ]& k2 D# B6 U. W5 U8 }% e2 f
4 W' Y% Z L: x, G2 h/ T
, q4 E0 n& x, l, } A3 ~& p
/ @' ~( z3 C; r, l3 ]
g# u" D4 e# J# l( \
@初始化RAM时钟,因为内存是跟开发板密切相关的,所以这部分在/开发板目录/lowlevel_init.S中实现 % P; m, K& t. J A
mov ip, lr
) [6 s( U9 C3 |, O7 `0 O( {@保存LR,以便正常返回,注意前面是通过BL跳到cpu_init_crit来的。- ]& Z% s; N4 S
@(ARM9有37个寄存器,ARM7有27个)
5 \2 W" Z* F' H. i3 @9 w37个寄存器=7个未分组寄存器(R0~R7)+ 2×(5个分组寄存器R8~R12)+6×2(R13=SP,R14=lr 分组寄存器) + 1(R15=PC) +1(CPSR) + 5(SPSR)
/ p# \* ~. H$ ]$ ?用途和访问权限:5 Y1 i$ p3 o9 G* r7 T
R0~R7:USR(用户模式)、fiq(快速中断模式)、irq(中断模式)、svc(超级用法模式)、abt、und
: I! i# \ M9 KR8~R12:R8_usr~R12_usr(usr,irq,svc,abt,und). P8 n. e2 Q K3 W/ @" S
R8_fiq~R12_fiq(fiq)
1 R5 `+ @: y$ o8 H/ LR11=fp) \' |$ w. @9 @4 {2 X. C+ p
R12=IP(从反汇编上看,fp和ip一般用于存放SP的值)
+ v- J0 B6 ?0 C2 o( Q0 WR13~R14:R13_usr R14_usr(每种模式都有自己的寄存器)2 c6 O8 x- P4 f, y+ H7 N
SP ~lr :R13_fiq R14_fiq
, ?4 E! A7 f$ `7 l) zR13_irq R14_irq
3 H C+ J5 Q; n; E, R ?$ PR13_svc R14_svc1 y; D3 K- e; f
R13_abt R14_abt
6 G5 [* K+ n! K+ rR13_und R14_und2 f: [0 l. n |: n" h3 Y
R15(PC):都可以访问(即PC的值为当前指令的地址值加8个字节)
/ @( s# T* a0 c- ~" qR16 :((Current Program Status Register,当前程序状态寄存器))2 D/ E |7 I( W" C2 H9 Y
SPSR _fiq,SPSR_irq,SPSR_abt,SPSR_und(USR模式没有)
, ?# r$ E$ r( D( ~! a, F: z, N8 t* j& J4 \1 C
6 t6 w& {. H6 u5 f: _5 p8 r
/ v7 \! V; M# }5 X#if defined(CONFIG_AT91RM9200EK)
4 ?8 W5 w, Y7 Z: I6 A3 I+ U. O
; g; m! C$ t' o' n
) y% k' [9 h1 T# T! x
4 o; R+ @9 m" G#else
* \3 W3 t ?$ Pbl lowlevel_init
: e4 V( P! M6 k7 G8 O0 K: l* f
% g1 S5 t U3 a8 G# f F9 T@在重定向代码之前,必须初始化内存时序,因为重定向时需要将@flash中的代码复制到内存中lowlevel_init在@/board/smdk2410/lowlevel_init.S中。8 B! [9 h6 e$ y" t. u# F
+ F9 k' h0 a1 A/ R+ B
8 J, d7 \1 g" Q8 e0 x# ^
" |0 x! n- X/ _8 R5 r
#endif
7 P" o8 p6 r% S4 q$ m$ x$ X7 F# Pmov lr, ip
* @$ A3 h* {4 w6 E" vmov pc, lr- c/ `5 ~( F n
@返回到主程序9 W$ w6 h3 I2 ]- m. i, H
) | v& C) e Q
. D$ W& J2 j) _8 k9 T! A! v% D; M6 W8 j
#endif+ c- _- }; u! F8 P9 f3 H5 O
" [8 l# E$ v6 a/ W; [: c8 u
5 \1 r8 {, ^9 }% w4 O3 } Z- E! R$ X- Q7 Z( z$ h+ X
0 n8 h8 l0 }1 T5 |% J; w' H/ _@这段没有看明白,不过好像跟移植关系不是很大,先放一放。- y5 L" ~( l( ^+ P
@- u* n' ~- r$ W1 d& N
@ IRQ stack frame.' K+ A- ~8 C! A& A( N! m6 g
@
. N4 Z4 R; O* L$ _#define S_FRAME_SIZE 72
% }+ y9 S+ x' u
D; n% V( P5 E3 g1 `" F# _1 D5 g
4 l# P$ M; E/ a' X
s% \- c% v- H% i#define S_OLD_R0 68/ s2 U, }- x! g! d; Y& U6 w
#define S_PSR 64 f. }1 t% r! h, n/ B% e+ I
#define S_PC 60
* p% B6 k" r0 {" E5 V8 w. \#define S_LR 56* j; k# U$ q7 `4 U# Z
#define S_SP 52; z' C% E" h. a$ {1 l
7 F1 r. m0 [$ i) T
! T' j( b/ S7 a0 `
0 A1 t; q. i- i: U#define S_IP 48
, S. m" P, m0 d3 @#define S_FP 44
$ B; `" L, N8 x4 X$ p$ P#define S_R10 40" x& s& i g4 h4 K h
#define S_R9 366 G# N" y& F# V' `# M) l
#define S_R8 32
@) s5 O9 n S5 {& _/ E) `. P#define S_R7 28
) i0 L6 u/ a0 u2 a7 y4 @#define S_R6 24
3 L5 T" ]4 l, S" m e#define S_R5 20
! |1 |1 F! e8 Z- _#define S_R4 16
a3 `* k5 r* c1 g8 b* @1 O#define S_R3 12
) v1 ?. o6 \2 g5 ~0 m$ Q0 X#define S_R2 89 }8 \0 @( S5 x4 S: v
#define S_R1 4
0 t, B( N. ~3 P6 h- h, D8 K$ J#define S_R0 0- U, t7 m5 e, F7 i. z& x; a
9 a' Y/ ]" O& {3 | & Y, l# o o* A) a6 W0 V3 v; _' {
, V* S8 c* ]2 \( X0 `
#define MODE_SVC 0x13
0 p& T% P5 P; x5 Y2 A5 }$ N! U#define I_BIT 0x80
3 }0 b& l6 S; i' ^2 A" A$ A: A: r$ u c
( f+ k1 f% _) b$ u
0 a# D( Q7 r" J0 P
% M" B1 s* u& u& N. H1 C& R- P8 S6 @* M8 d" ^$ {' Q; y) \
1 s0 u/ C+ N: w$ H* d5 X3 A7 x
# ]. m/ s! @7 J* Z3 C" z
.macro bad_save_user_regs
) F2 | p' F1 rsub sp, sp, #S_FRAME_SIZE0 {$ Q- J E! M
stmia sp, {r0 - r12} @ Calling r0-r125 q. o1 w; v0 z& L- p" ?/ |6 l
ldr r2, _armboot_start5 n# {! H" E1 Z' ^5 D
sub r2, r2, #(CONFIG_STACKSIZE)
; Z! u N2 }6 G, }6 G3 ~" g1 asub r2, r2, #(CONFIG_SYS_MALLOC_LEN)9 v ` \- k# f7 j5 Y& Y1 y* B
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
5 R% ^/ Y! H( f+ Z5 q9 p9 \ F9 ?ldmia r2, {r2 - r3} @ get pc, cpsr' E( p5 N! s1 S5 |9 }
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
" U8 ]4 \/ v7 `: }7 ~9 ~: n, L5 l4 E# x" n/ }
9 T. C+ }$ A" p5 x( G" Q6 F/ \
+ I7 N1 p$ m" H# c( F: s& L& h; s5 S
add r5, sp, #S_SP9 _, _9 P# Q% e& c4 w; Q
mov r1, lr
' v% e# M2 R/ p u. q( C" I2 jstmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr1 Z M# J1 D S8 D' @9 s4 F; j
mov r0, sp
( W Y; Q ?/ v2 a' F3 G |.endm
9 I/ u! ^3 U5 P" Y+ m2 @0 E
* E+ I, o! l( b* R/ ] 8 @# ?0 ^( W+ d, X
/ a9 ?' U% L0 u$ c {' i4 M' t.macro irq_save_user_regs
/ w) E4 q Q8 O8 v$ o: tsub sp, sp, #S_FRAME_SIZE
4 M) _/ ?: h- s# S% istmia sp, {r0 - r12} @ Calling r0-r12
/ r8 ^+ [2 H8 W+ d! U. f# \add r7, sp, #S_PC& Q0 _1 s/ i5 c# x' p! b5 { p
stmdb r7, {sp, lr}^ @ Calling SP, LR1 d0 C( Y- c- s; `" M! y5 t
str lr, [r7, #0] @ Save calling PC
% Q# q( q+ M4 q5 C% v/ Xmrs r6, spsr5 w+ d( o7 P$ N" D- x% z8 w
str r6, [r7, #4] @ Save CPSR
0 ?$ `/ y4 h5 W# U6 R+ g5 |str r0, [r7, #8] @ Save OLD_R0
5 b# ?! x5 U% J: v+ Imov r0, sp" z% d- r9 r, _! |+ l- ^
.endm
4 }2 U0 z1 {$ X. T) q& U6 x, W+ A5 h5 l( J# p- Y
+ D/ E& P/ p! a7 J: T: r
9 m3 t9 ?0 N1 Q
.macro irq_restore_user_regs6 {. s/ k: f/ u. e6 O. `$ k
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
, k- m) I0 y1 Y2 Z" S3 omov r0, r0
4 F# z0 J s, |8 m" r7 y+ dldr lr, [sp, #S_PC] @ Get PC: c$ b$ |! q# `4 c: g& y9 E! E
add sp, sp, #S_FRAME_SIZE
- i3 j# f5 t8 Z2 b# t! v fsubs pc, lr, #4 @ return & move spsr_svc into cpsr
B b6 r5 D2 g5 U+ P# f3 @& p: W.endm q* N+ x! r! |$ H% y, H/ i+ Z
( y* i! p" @5 x: P
$ {) W2 V6 p) j+ V/ }/ C' I/ Q/ r& @* J6 w2 D
.macro get_bad_stack
2 m( O" o: `. Z- Y) Eldr r13, _armboot_start @ setup our mode stack
+ E! }9 C0 G1 w- _$ L8 I, K4 Esub r13, r13, #(CONFIG_STACKSIZE): d( I9 H6 p0 Q3 K$ L5 C
sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
# z% t2 z! c: J# Y1 gsub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
' V0 m% G0 K% F. `- u8 C u+ x5 z' P# S) G4 e! l
* k2 c4 m# D' s$ p1 v
/ I6 Z4 H: i+ ~ O. A
str lr, [r13] @ save caller lr / spsr6 y8 l( G& B9 s
mrs lr, spsr
# p f2 p, D6 j% @* C8 Bstr lr, [r13, #4]( ]; q$ T, f8 `7 O8 Y1 _1 A+ ~, }
h0 c, t9 o) {! v+ F# X+ J
' S' N$ M; d/ [0 G8 K2 m+ k
& |7 M+ j2 T% o) o+ T/ Y5 A- o
mov r13, #MODE_SVC @ prepare SVC-Mode
1 J9 _ M2 \8 j6 t@ msr spsr_c, r13
6 z0 Q8 M' b$ c+ N* y$ |4 W( B8 dmsr spsr, r13
1 I E8 R U; z- U# d9 a0 `0 j" hmov lr, pc7 h" H9 _4 T% F
movs pc, lr
! P7 ?( @7 u ?# {1 d+ F.endm
6 A0 c. `# F! b% K$ d5 R2 C' L+ C$ p) d- I; {
5 N+ u4 d& q: X; o' {0 T& V( X+ c
; k: ^# J; i. X3 \
.macro get_irq_stack @ setup IRQ stack9 z l0 q' b v$ Z, b
ldr sp, IRQ_STACK_START
# Q" l- P! g; U. A J.endm
, z( o% H" j/ l/ O' ]: |, Y. N. V
# v; C/ Z1 s! r$ G% Q* ]& l 9 F' K3 D: N- l* y' A+ S
u* R& J3 w2 W5 r7 K8 u: H$ v
.macro get_fiq_stack @ setup FIQ stack
+ d- V p. D1 Y. I T& u# V* ]ldr sp, FIQ_STACK_START
; p' c; M3 a! P3 v.endm
* p Q, z& |4 c6 f2 W0 j$ [. Y7 b
* v( S+ g) Y$ F0 C( E# ~6 X
. w" B" G' m2 a, ~1 n; @, o h. m
$ l, a6 j( Q" y# R6 l/ Z d+ S8 l% h* V$ `/ O6 x' n
@异常向量处理* d: x" @! N7 S$ s) e4 s9 g& T
@每一个异常向量处其实只放了一条跳转指令(因为每个异常向量只 @有4个字节不能放太多的程序),跳到相应的异常处理程序中。
+ \5 g6 j" x' u. n0 C.align 51 d& |8 d. }# _
undefined_instruction:
% o( k9 D7 G8 D; P; F3 jget_bad_stack& @, m6 n8 \; Q1 d
bad_save_user_regs
$ q% U5 O2 A2 {/ t1 E5 r: s3 {8 mbl do_undefined_instruction0 v7 Q! Y9 P! }# E. I( a
+ ]/ `9 v5 M: j( E
' E7 M& j F; p' d5 [ l0 B _, y; G! n1 M j6 C; |7 r
.align 51 O3 d7 A1 V( a0 W1 `4 @8 q
software_interrupt:
9 G' C' t7 ~7 qget_bad_stack# z& f; Q" |2 R/ ^' E
bad_save_user_regs
$ q' o. i" H) o* p1 {2 z+ lbl do_software_interrupt
9 q9 V- ^; q! Q" v8 E8 {4 `7 ~! K) Z; Y( F7 y8 F8 g' ^
( J$ X- {7 ?, }5 ~) r2 i! s
3 f3 S' A; |: y) u6 R2 `
.align 52 \; v s4 {( G7 N$ t
prefetch_abort:
3 ~" Z1 z+ O5 Y3 H. F8 eget_bad_stack6 a4 Q6 M, S. _2 B% n- W. P* z
bad_save_user_regs
+ f: k! T7 J9 K, ^bl do_prefetch_abort" c3 V( y- t8 ]9 n6 n
( i0 f5 S) ?8 R5 P % O. `! t# [; ~7 x8 ?1 K
n% b( V( A* k6 F6 f# C.align 5
; A. n( g: j- ~, x& M* b6 Pdata_abort:$ X9 J/ G6 K7 ?1 }
get_bad_stack# B3 \) u; b# \6 I- E& [6 c
bad_save_user_regs5 k; [6 v( L$ n' y! @/ G- @5 \' x
bl do_data_abort. Z1 ^% K s' W5 F, {
7 o/ C2 N. O# M6 `# |
. k+ F; ~1 J+ ], M+ _
% s4 ]3 U1 K4 a& a4 @3 P1 Y, R0 b" o.align 5
, O! L4 _0 Z+ ~$ {. S: h; _& Bnot_used:
% }% m' Z" D6 r+ s. J' V8 [1 X3 yget_bad_stack
4 b5 e, X. B; B% Gbad_save_user_regs
% w& S0 X% S3 }+ ]9 x7 y& b1 z N: ^: ^bl do_not_used
. t* H: ?/ z8 a) L) `/ W+ V
( k' B. p8 K Y C* N% r2 u " d4 I/ A+ a5 M" f0 d
* B# z9 `" \' {" x: W- c8 B4 Q0 ?# M#ifdef CONFIG_USE_IRQ
2 n; `6 a. T+ ^% V) _" r4 M2 Z/ p* ^2 H" ?
) V# ^5 _6 a! L0 _7 f+ e9 V" g) }* ?2 ^! m+ y" G8 g
.align 5
1 d1 h; F$ H$ o& C: E. lirq:
" S8 t4 H# {0 L4 jget_irq_stack
; y3 I# q0 i5 P3 _) t1 r: tirq_save_user_regs R0 d2 J' r8 Y+ ~% E, S
bl do_irq/ _- K: v5 J8 B. J8 b
irq_restore_user_regs
# b. Z0 S5 n& s! i, y o& g7 C3 n
; Q j/ A, k7 }! j( | f0 K `
+ A: v/ V3 R( B ?9 f% M: {
4 Q9 U" T( f2 U6 @" f.align 59 w9 k8 g/ O# Y' t4 T& p, K
fiq:3 A8 ]- R& b P
get_fiq_stack! Q' D% V0 G' H5 d
8 l6 D# A( {, c; ?5 birq_save_user_regs
( Z t, Y6 l. ~3 f) J G' Nbl do_fiq1 s9 [5 `/ U$ J& a
irq_restore_user_regs0 h! h+ I; |, S# K
% P1 n8 b3 w% ]5 }. ?
# t- d k, O8 p( c0 l
+ [: B: ^) r3 D% K7 N7 r#else; b) ?9 P9 }& |2 x6 l7 B
/ ~" b( d2 D# l3 u+ S 8 G- l" l' }/ n" U1 S5 g' {2 ]
+ B9 l$ j! T* {: Z) s
.align 5
" Y, M4 [/ O0 L9 \6 B2 W; mirq:$ Y; C9 P4 b/ O" D1 t( x
get_bad_stack4 n- G% _( S! S' O
bad_save_user_regs
+ W4 v( |% h+ ]( |3 \9 v6 ?bl do_irq
* T. |. k/ }# x% H( q$ }: T) W' ^2 a% Z! ?& l j8 M* T' |
$ D' S7 |; F' Y# N4 U0 M3 C9 b
+ p) h' l" @. v1 ?( _% e! p9 S
.align 5) \0 @% J8 ] X4 s$ @
fiq:. Z4 a% [! y6 a& `6 A
get_bad_stack7 l! x0 q, m- P& `
bad_save_user_regs) I6 @5 ^% D: c# Q" c
bl do_fiq. I: o4 J( e3 `) J4 P6 ?+ j
1 m) v1 \0 w6 }
4 Q" `' {: e+ L7 `3 B+ ~1 o) X# N) t) w1 B5 i$ B
#endif 0 \' A, w/ X1 N8 K; b3 w8 f
@可知start.S的流程为:异常向量——上电复位后进入复位异常向量——跳到启动代码处——设置处理器进入管理模式——关闭看门狗——关闭中断——设置时钟分频——关闭MMU和CACHE——进入lowlever_init.S——检查当前代码所处的位置,如果在FLASH中就将代码搬移到RAM中 |
|