|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
@CPU初始化
; o8 y" e' a4 t5 D: y/ t6 ]2 [7 {' f% N
@在“relocate: ”之前被调用
+ d, X' T( R2 C: P' p, S% w* l, ~! P) D$ r7 N8 j- v# g
#ifndef CONFIG_SKIP_LOWLEVEL_INIT$ L6 u, X; l1 N3 s! p7 ]
cpu_init_crit:
# t2 R% d% p* e& g+ ^" r" ]% v* s# I+ O) c, A+ X% D
@初始化CACHES
6 J: H7 {9 F2 T' S+ pmov r0, #0
9 C) Z5 P0 n- `+ s# U& H+ amcr p15, 0, r0, c7, c7, 0 - ]: O3 l! U5 g, O3 j+ ]9 n
mcr p15, 0, r0, c8, c7, 0. x# h" F, Y: e
+ ]7 ~ }3 c T. R% g; z, c& ?
8 i! A% q7 p, M6 N( N2 h0 b9 h" w0 g) i
: A' w: u8 @0 B0 |& O@关闭MMU和CACHES- @, u( d8 W6 l- b/ L% T8 o
mrc p15, 0, r0, c1, c0, 0; ]* Y* {6 y) E, p6 h
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
3 Q5 M7 p/ x# v. M) @* e! @7 F3 cbic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)7 l0 J& I+ M4 y! W& e& v; B" D+ m
orr r0, r0, #0x00000002 @ set bit 2 (A) Align* ^; `7 W: Z6 K6 l5 Z( C- y
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache6 u8 r- ~/ C% z5 ^3 X7 R
mcr p15, 0, r0, c1, c0, 01 R( E6 Z4 Q1 D
@对协处理器的操作还是看不懂,暂时先不管吧,有时间研究一下ARM技术手册的协处理器部分。: k* X, W4 }+ y: r) [. Y' V
4 m' t, Z% G. q- y
5 i- b2 u+ {. {/ H# m; Q8 S" {0 W* J$ j2 M. e. W
2 L, x. }) x% t T a9 l
@初始化RAM时钟,因为内存是跟开发板密切相关的,所以这部分在/开发板目录/lowlevel_init.S中实现
& s' ^2 b3 R R: z5 W/ A; Fmov ip, lr
7 B! p" O: m* {' e. W7 L@保存LR,以便正常返回,注意前面是通过BL跳到cpu_init_crit来的。
3 |) v9 k W7 e. }9 Q; J@(ARM9有37个寄存器,ARM7有27个)4 A$ H; A& Q8 X; \; R2 S
37个寄存器=7个未分组寄存器(R0~R7)+ 2×(5个分组寄存器R8~R12)+6×2(R13=SP,R14=lr 分组寄存器) + 1(R15=PC) +1(CPSR) + 5(SPSR)
. V, T. o& E3 n. h# c- ?- @用途和访问权限:
, ]% a! H7 J) wR0~R7:USR(用户模式)、fiq(快速中断模式)、irq(中断模式)、svc(超级用法模式)、abt、und, {/ e5 V9 X7 C1 Q/ A; ]9 C8 R
R8~R12:R8_usr~R12_usr(usr,irq,svc,abt,und), I6 C5 A$ ~$ B* @& q' j+ V" w# F
R8_fiq~R12_fiq(fiq) . }8 I- c4 a8 D& u. H
R11=fp/ S( y. m" B5 P7 z
R12=IP(从反汇编上看,fp和ip一般用于存放SP的值)
" p3 ?; b W( s, p, d# WR13~R14:R13_usr R14_usr(每种模式都有自己的寄存器)
( o3 p' L5 G8 P# o8 W6 ^SP ~lr :R13_fiq R14_fiq( E# v' i: S6 W$ q5 r, q
R13_irq R14_irq+ F' ]. I# P8 W# `
R13_svc R14_svc
, O8 b9 G7 L5 FR13_abt R14_abt
& A! p. ^: S* F+ ~% }5 xR13_und R14_und
6 a1 i# n M- Y- Q; UR15(PC):都可以访问(即PC的值为当前指令的地址值加8个字节)
( f% K' o; n: h6 oR16 :((Current Program Status Register,当前程序状态寄存器))
; H1 }( Z* Y1 K0 P$ `% WSPSR _fiq,SPSR_irq,SPSR_abt,SPSR_und(USR模式没有)
& u5 d7 n& D7 y" U4 ^3 y! l* |% x; [! ], \4 W* S
9 X# U$ Q& _. g' N: j3 o& `0 ~
: S% i8 L$ Z) s7 U2 d* C#if defined(CONFIG_AT91RM9200EK)
, U8 ]) |! L- n, g
! ?* v$ f, g3 t$ V7 D' b2 j0 Y
" z3 [; j# H4 @- Z, R& I9 m D
5 I" P$ x9 ]- w3 P1 e1 E#else0 f& G; e' Q6 l' R4 W8 I# l% x
bl lowlevel_init
! U& r- D9 n# r [! J3 X1 Q6 [" e5 ]6 f
@在重定向代码之前,必须初始化内存时序,因为重定向时需要将@flash中的代码复制到内存中lowlevel_init在@/board/smdk2410/lowlevel_init.S中。
7 }7 b* u4 b: j- l& i* H% @; F
- d1 k3 C, a; m5 u* r
) n) y* C, r6 U3 L8 y5 k. p5 H$ k p5 Z/ M: L! Q
#endif
4 P" z) \$ C$ O5 Gmov lr, ip
) j9 K. p. M# x) W( d% A2 I* w3 ~; nmov pc, lr" ^3 d6 E5 q% c) w N% \7 X0 d: O7 P
@返回到主程序
2 K- Q. s. y; j1 ]4 t
" r! m) w+ e& l/ m U4 D- x1 \
0 T; E7 {+ g2 u# J% @4 b* k; N' _0 |
#endif) |% u1 A2 I; l6 `4 A& e
/ x5 w2 i' q: V
8 s- f. e5 N- f/ t: N& L N
# R d, P- [% X0 m0 Z
. G" Z' D4 X s. R@这段没有看明白,不过好像跟移植关系不是很大,先放一放。
( a/ Y! n" V+ T/ O+ A h@
1 A4 \+ S3 W. T) f( W/ \@ IRQ stack frame." }' y* ]% r' u+ L1 [% P& i. U
@6 L* N$ s( U' t* j) J
#define S_FRAME_SIZE 72* `6 G9 d" { L# o. |
- V4 d/ Y, Z& f. S
7 n4 c$ W+ [3 ^6 t* {" c4 d) m. Y# \3 V6 U2 n& z2 I& @
#define S_OLD_R0 68
( p! m2 Y9 p. g4 Z0 T; v* ?8 p#define S_PSR 643 j5 J1 }% j9 A7 R3 w. E- o! u3 o
#define S_PC 60
$ y# q9 L+ M2 j+ Y) s" q#define S_LR 56. {! E/ e3 A/ d6 y, m2 ^
#define S_SP 52
8 v6 _; o% d: J
) {% d: }$ }( H- j. K2 e4 ^ & p. z2 v, G' c6 ~4 u) O# ?
, A' o1 B5 W! _" e# w7 k
#define S_IP 48
1 B+ D. n5 |1 Q/ {#define S_FP 44
2 _- d2 ~. E) [0 y9 |7 \& K; r#define S_R10 40. v+ _$ w2 w7 u' K) B$ b3 p
#define S_R9 36
5 e' H% ]1 N- d8 F* h0 f2 P#define S_R8 32
$ ~6 T3 Q3 J) o1 y% Z0 ~#define S_R7 28
1 T' M2 Y E1 ]& v! c#define S_R6 240 M. ]. ^ F, N' E7 s3 ^& o
#define S_R5 20$ d' t0 [+ @. ?( n! {* D: ]
#define S_R4 169 S5 H' n1 N/ p4 t4 B/ s ], C
#define S_R3 12
. R& A- N! C# i: |6 g1 D#define S_R2 8! z- q2 C1 n6 v/ P7 _! ^1 V4 m
#define S_R1 4
; G8 |# n) t4 ]! o; g0 i#define S_R0 0& S' p% Z8 _: X; Q* ]( C
- e5 Z z6 L) k$ i5 O; n) A+ g9 i
3 y0 ~) t' e7 ?- S" o7 w6 k7 w, i% k; D! l& s( s
#define MODE_SVC 0x130 Q2 |2 `/ v0 h2 O
#define I_BIT 0x80
* a: w- E! k1 j" o) H; b
8 o: _% a2 S) e G# j- o# |$ y
. P5 s; L2 N* K: a3 q0 W! d
. h: ^7 W4 \7 j" \3 P 3 m5 |5 \4 v7 X- m
2 Z: A9 _8 [% D
/ \: L" ?# ^1 Y' \
% U2 |1 k5 H8 r$ c
.macro bad_save_user_regs. J" M- m0 k6 O4 A( m! H- N
sub sp, sp, #S_FRAME_SIZE
8 u* ]( Y5 v) x1 r6 Sstmia sp, {r0 - r12} @ Calling r0-r12
% p3 F7 w3 u+ F! sldr r2, _armboot_start* [8 {5 b( E7 i" e+ s. _" }1 w
sub r2, r2, #(CONFIG_STACKSIZE)4 P+ y+ Z8 B' T0 k/ A
sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)9 y" N- _. w' N% k% l5 _$ Q" a
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
: Z: y( m2 t7 j5 ^ Kldmia r2, {r2 - r3} @ get pc, cpsr
: ?5 B# W- n7 X% Y" L, Qadd r0, sp, #S_FRAME_SIZE @ restore sp_SVC
6 r4 X' J# N _" u" S
( {/ t1 k$ k- i9 r1 A2 q* [ : x) \; e& @. O& [9 a# A' l
5 A' k# x* }4 }: Z4 R; g/ }add r5, sp, #S_SP. _3 f& ^, D7 y0 H" C7 c. g p
mov r1, lr
6 d9 U1 ?) N* ]+ }) } Q0 Ostmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr6 ]. L" t# y# k. L8 y, l
mov r0, sp$ V6 c+ \+ a2 ^% u0 W* U
.endm4 l( [0 X% f3 ^+ N6 s5 f+ \
% Y3 Z& R* E5 K$ U
5 `! W5 x$ [8 d) ?; X0 f
) E/ Z. w8 H- [; o0 O$ ?; S/ b.macro irq_save_user_regs
, y0 U7 ]) g. F6 W' S/ Lsub sp, sp, #S_FRAME_SIZE
2 _3 q. u: v2 j* ~& m! n9 Vstmia sp, {r0 - r12} @ Calling r0-r125 @) b# s+ c) \# W# k; C
add r7, sp, #S_PC
a; \% g+ c8 mstmdb r7, {sp, lr}^ @ Calling SP, LR
' q$ V$ F- M K/ k- d9 ^, q8 Lstr lr, [r7, #0] @ Save calling PC2 x4 i: Q! C( ?1 n& `- u
mrs r6, spsr
5 D' }, N0 Y, ?" hstr r6, [r7, #4] @ Save CPSR3 ]( S6 ~- }* x5 j* v
str r0, [r7, #8] @ Save OLD_R0
0 |- J1 M9 ?# W/ R1 t: \: V/ I+ imov r0, sp5 Q, ^# p' A" t
.endm* t: J, M5 J+ Y% z0 x: C3 w0 D0 }+ e
/ ?9 E2 v i- C6 l* E$ a7 Y8 L- \! U
+ k! d+ Q' s3 z0 I' I
3 b! r6 U" U) G
.macro irq_restore_user_regs
* V t7 O3 P* [8 x6 S- gldmia sp, {r0 - lr}^ @ Calling r0 - lr: B" p2 C% u* |9 z' h' \
mov r0, r0
5 ~4 h; O$ C6 b) F! Oldr lr, [sp, #S_PC] @ Get PC5 e b( T) f( ^& P0 m
add sp, sp, #S_FRAME_SIZE
) J: u! f$ l: C; Msubs pc, lr, #4 @ return & move spsr_svc into cpsr
/ d/ w, V. k0 T, M3 B% G6 c# P4 m.endm8 J \+ ~; K$ _: i. Z8 ^
1 J2 p! i9 F/ w# z; d
5 {7 a5 W; ?" I5 ?7 ]+ n$ E
4 k0 @2 r' x. I& u r.macro get_bad_stack
% X1 m2 n% s5 @' T+ a+ fldr r13, _armboot_start @ setup our mode stack
7 U$ o f3 I6 e1 m5 w' x4 [5 {sub r13, r13, #(CONFIG_STACKSIZE)
- I/ i1 R( y& E: Vsub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
+ {* X$ Q4 c0 Ksub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack: S. {+ d( L, b9 n3 k, e+ D1 k
% G( v$ U5 K5 u \' ?
, K' C# N3 b9 \) w5 w( _2 y" `+ W. R
$ c. O; |$ y% p9 Hstr lr, [r13] @ save caller lr / spsr+ s8 a. F. Q/ C5 e
mrs lr, spsr0 l4 w7 h& W% L" C* h2 Q
str lr, [r13, #4]# i* f, h/ ]. |
8 f8 u5 U, k6 x8 [9 j
2 R- L4 F, W! x) R( D5 n0 F! `; W2 s! ~. j5 J' k+ r/ ]
mov r13, #MODE_SVC @ prepare SVC-Mode
8 t$ Q. ~2 n! ^2 e, ]: H+ Q" h@ msr spsr_c, r13
, e' ~& L; W+ B: i. V" E% k4 [msr spsr, r139 V& J- x1 }; r
mov lr, pc$ A3 L/ f) H, N
movs pc, lr# p: s" y9 }0 m7 v3 k" m7 g+ _2 z
.endm
, L6 a- `8 Y3 ?9 U M+ _2 h$ o; o; o6 z2 H$ |0 l0 `
! y: m4 u! ^% h( `" }+ O
& K2 M. `+ E8 N+ e% ~1 t. W
.macro get_irq_stack @ setup IRQ stack
# J* |! e4 }6 J! c8 Rldr sp, IRQ_STACK_START
% n& A1 R0 S: A( q3 ?.endm% ?6 C% m1 v; |- ~7 S
1 ?( X1 \8 p& H* B& T
% X: x+ C" H2 i- s, X
+ ]2 u5 z0 C. U7 o: K.macro get_fiq_stack @ setup FIQ stack
& Q- x+ a4 A6 J" Jldr sp, FIQ_STACK_START
7 ^5 P' A2 q$ d! s1 p" G5 X( u.endm1 V) t* u, c, s1 s- s1 N( i$ s; I0 n
* ^9 a2 g9 z5 |/ _0 p
/ S3 h+ P4 H7 k
# \/ C/ G( M* l& A; ?+ \- t) `/ b8 e8 w' p/ W7 f8 v. I2 i. n9 n
@异常向量处理
8 e1 c- w' @# r3 e: f. y@每一个异常向量处其实只放了一条跳转指令(因为每个异常向量只 @有4个字节不能放太多的程序),跳到相应的异常处理程序中。& y+ P. j- g! G, S/ Q: Q- A1 }- c
.align 5
6 K8 t, q( D' z1 b R" z. g* Q/ x4 Lundefined_instruction:5 R" E, q. X1 W
get_bad_stack- _1 M1 y, r$ O+ m* \2 ?$ D
bad_save_user_regs2 q& ~$ x1 O- F# O$ A6 x
bl do_undefined_instruction
. y2 P7 e9 x8 H+ g. `. [. N) j
- N% I' X2 R' a# z# Q) l+ m+ ~( w ; G2 I Q/ {$ ^
- ?) v2 b) ^! Q# I, u# n' x& X
.align 5
( w! a# O) D3 q' h. Lsoftware_interrupt:
1 X4 W- Y' i2 }3 O+ F* U( \( `get_bad_stack1 a, T% W7 z: v1 c2 ^ U( y7 z
bad_save_user_regs
8 v9 W9 ^1 v- h1 bbl do_software_interrupt
2 h6 H. r" R; B, L+ u* Z. @. R' a! [& ]" F
' l: y) l' R; n- `1 I6 D
# {+ L7 x5 }/ g( n1 f" a.align 5- i9 o* x7 G( J2 _( K, v: o: c6 F
prefetch_abort:
5 V5 j4 ?; G" R0 e3 A# i+ kget_bad_stack
) p6 Z5 I7 U& |bad_save_user_regs
8 P. O( y1 N$ i* `bl do_prefetch_abort2 O3 T# o2 S9 x, r
5 E4 y$ V: x9 C& @; b& k& x B * V4 i, r' `7 U G& d- u2 B
9 i9 v2 e9 V" y% z3 s1 ~: h.align 5
5 Q% U9 Q4 Q5 P& Ldata_abort:
. W- a/ b: }+ P/ R+ Fget_bad_stack: x5 d* ^, G, M2 Z- u: N7 h0 B
bad_save_user_regs
1 K/ r$ W! u% {: k* Dbl do_data_abort
) K/ ]4 S* K3 a5 R9 v
7 O6 |" o/ F9 l$ B* M - Z5 x2 I. a2 M. v3 b) r0 \
7 n5 N2 i+ Q0 C.align 59 O+ O0 I0 t) ]- x9 E4 N) Q
not_used:- F0 v: D( x- T" n, m/ [7 {
get_bad_stack
1 O+ p5 {/ G3 u8 I, {bad_save_user_regs% A, R8 Q) j0 e; V' o/ _
bl do_not_used
: G" g) n) C' u0 ~) F$ ?1 x( u- ~4 s! ]8 h1 I& a8 _' `
7 J: L: j# [+ ~- o+ A' E* E7 ~; r: J" P
% Z5 {1 f# P# g, P#ifdef CONFIG_USE_IRQ+ E+ y6 l+ c/ h, t7 \; a% t0 H0 h0 y- n
) Q' K/ Z0 ]* X9 ?4 I1 k3 y
# V& `" U8 M0 p, f
$ H# Q) G, w, Q$ h' _.align 5! m. _2 m' m+ I& y
irq:
}! L9 l# ? Q1 l: p. q iget_irq_stack- [5 O* Z$ ]7 Q' S
irq_save_user_regs+ f$ T0 h. o2 E3 L+ ^. o
bl do_irq3 A/ T3 R7 l2 Z0 d% ]9 W0 T
irq_restore_user_regs
# O% g$ g5 C: V: m6 P, T# l* I/ F2 n8 s
c) g' R' Q O# ~
, l/ y! b+ p- f' t# V) T. S.align 5 @2 B8 l: D" ]. x" V2 p
fiq:, H: k0 o. F( a2 R# ?3 J1 ~
get_fiq_stack
) \# z: N% j- f9 L( x1 a
) ?- a" ~8 @* _ ]& T& hirq_save_user_regs/ A8 R+ T$ [( f$ @
bl do_fiq$ Q$ m- \6 Q. |5 B4 |
irq_restore_user_regs+ c5 D w# y, C2 N t
. h. P+ @0 ~; k" c& D: T/ A% l
) D( u7 p) f3 x, _: }5 a5 a8 D) D/ d: Y
#else
; d( D- ]: y/ p! [& K& H. H: e
! K% a3 e4 Y) ^! l9 q
2 B" @- I7 Q4 G( X/ R: `+ a& B6 p( W$ T3 Z
.align 5
/ |. C; ?) H& z7 g$ Yirq:& m2 r$ o0 r H4 l* E9 b9 \ d
get_bad_stack' l M' C& x0 _
bad_save_user_regs, M7 H8 V: Y+ I& p. I5 v
bl do_irq
# D" B& l7 @! U, I( e* W
# a* n4 v1 C8 I. Y% N6 H 7 c: W8 N: z, ]% a
) y# N- E P7 {$ P7 Z; p
.align 5+ m, S: O: ]! c# i+ [
fiq:# h r; \ L0 w- D, I; e: a6 [
get_bad_stack
8 i. D& t2 m) j$ _) ?% _bad_save_user_regs# T I, w- s! m' }' Y
bl do_fiq
, L( A8 Z3 R$ W) Z6 R
) U/ r: \. R! v3 H& Y
- g1 o8 f, ^( v" [" Z( g, c
, w. b4 ?" ^) _, R, D2 ]$ W1 R#endif 8 j$ d+ Z( m5 m: \" v \
@可知start.S的流程为:异常向量——上电复位后进入复位异常向量——跳到启动代码处——设置处理器进入管理模式——关闭看门狗——关闭中断——设置时钟分频——关闭MMU和CACHE——进入lowlever_init.S——检查当前代码所处的位置,如果在FLASH中就将代码搬移到RAM中 |
|