这里我们来看xloader_entry中调用的第二个标号ddr_init处的代码,这部分代码的作用是对外部内存sdram进行初始化,在我 spearplus开发板中,使用的是ddr sdram。在调用ddr_init之前,外部内存是不能用的,因为外部内存的时钟以及控制寄存器都还没有初始化,因此此时只有芯片内部的sram以及在 sys_init的时候已经初始化了的serial flash、uart以及gmac是可用的。
而ddr_init的作用就是根据板子 使用的外部sdram来对外部内存进行初始化,针对不同的板子使用不同的sdram的,需要根据特定的sdram来定制这个初始化过程,这也是为什么要把 ddr_init单独放在一个文件中的原因,便于在不同的外部内存之间的代码移植。
在这里,我还有很多不明白的地方,我想是因为我对硬件 不过熟悉的缘故。所以很多代码只能够看到它的表面,真正代码想要完成的功能需要结合各个寄存器本身的作用以及对sdram初始化的整个过程的定义才能够看 清楚。但是,这需要阅读大量的芯片手册,这对于我来说,至少目前还不具备这种能力和条件,因此暂时先放一放,等到以后真正需要用到的时候再回过头来仔细研 究。在这里,我们只需要明白,这一段代码,是在对特定的外部内存进行初始化,初始化完成之后,外部内存就可以使用了,将来uboot以及linux kernel的代码都需要转移到外部内存之后才可以运行的。
对于我的代码来说,ddr_init位于xloader根目录下面的ddr/splus_mt47h128m8_3.266_c15_map_async.s中,完整的代码以及对代码的粗略分析如下:
1 #define mpmcbase 0xfc600000
2 #define num_of_mpmc_regs 100
3
4
5 /*****************************************************************************/
6
7 #define mpmcregsbase 0xfca80000
8 #define ddr_pll_reg mpmcregsbase + 0x0020
9 #define per1_clken mpmcregsbase + 0x002c
10 #define ddr_pad_reg mpmcregsbase + 0x00f0
11 #define ddr_1v8_reg mpmcregsbase + 0x00e4
12 #define ddr_2v5_reg mpmcregsbase + 0x00e8
13 #define ddr_3v3_reg mpmcregsbase + 0x00ec
14
15 #define mpmcbase 0xfc600000
16
17 #define denali_ctl_00 mpmcbase + 0x000
18 #define denali_ctl_01 mpmcbase + 0x004
19 #define denali_ctl_02 mpmcbase + 0x008
20 #define denali_ctl_03 mpmcbase + 0x00c
21 #define denali_ctl_04 mpmcbase + 0x010
22 #define denali_ctl_05 mpmcbase + 0x014
23 #define denali_ctl_06 mpmcbase + 0x018
24 #define denali_ctl_07 mpmcbase + 0x01c
25 #define denali_ctl_08 mpmcbase + 0x020
26 #define denali_ctl_09 mpmcbase + 0x024
27 #define denali_ctl_10 mpmcbase + 0x028
28 #define denali_ctl_11 mpmcbase + 0x02c
29 #define denali_ctl_12 mpmcbase + 0x030
30 #define denali_ctl_13 mpmcbase + 0x034
31 #define denali_ctl_14 mpmcbase + 0x038
32 #define denali_ctl_15 mpmcbase + 0x03c
33 #define denali_ctl_16 mpmcbase + 0x040
34 #define denali_ctl_17 mpmcbase + 0x044
35 #define denali_ctl_18 mpmcbase + 0x048
36 #define denali_ctl_19 mpmcbase + 0x04c
37 #define denali_ctl_20 mpmcbase + 0x050
38 #define denali_ctl_21 mpmcbase + 0x054
39 #define denali_ctl_22 mpmcbase + 0x058
40 #define denali_ctl_23 mpmcbase + 0x05c
41 #define denali_ctl_24 mpmcbase + 0x060
42 #define denali_ctl_25 mpmcbase + 0x064
43 #define denali_ctl_26 mpmcbase + 0x068
44 #define denali_ctl_27 mpmcbase + 0x06c
45 #define denali_ctl_28 mpmcbase + 0x070
46 #define denali_ctl_29 mpmcbase + 0x074
47 #define denali_ctl_30 mpmcbase + 0x078
48
49 /*;-----------------------------------------------------------------------------------*/
50 #define denali_ctl_31 mpmcbase + 0x07c
51 #define denali_ctl_32 mpmcbase + 0x080
52 #define denali_ctl_33 mpmcbase + 0x084
53 #define denali_ctl_34 mpmcbase + 0x088
54 #define denali_ctl_35 mpmcbase + 0x08c
55 #define denali_ctl_36 mpmcbase + 0x090
56 #define denali_ctl_37 mpmcbase + 0x094
57 #define denali_ctl_38 mpmcbase + 0x098
58 #define denali_ctl_39 mpmcbase + 0x09c
59 #define denali_ctl_40 mpmcbase + 0x0a0
60 #define denali_ctl_41 mpmcbase + 0x0a4
61 #define denali_ctl_42 mpmcbase + 0x0a8
62 #define denali_ctl_43 mpmcbase + 0x0ac
63 #define denali_ctl_44 mpmcbase + 0x0b0
64 #define denali_ctl_45 mpmcbase + 0x0b4
65 #define denali_ctl_46 mpmcbase + 0x0b8
66 #define denali_ctl_47 mpmcbase + 0x0bc
67 #define denali_ctl_48 mpmcbase + 0x0c0
68 #define denali_ctl_49 mpmcbase + 0x0c4
69 #define denali_ctl_50 mpmcbase + 0x0c8
70 #define denali_ctl_51 mpmcbase + 0x0cc
71 #define denali_ctl_52 mpmcbase + 0x0d0
72 #define denali_ctl_53 mpmcbase + 0x0d4
73 #define denali_ctl_54 mpmcbase + 0x0d8
74 #define denali_ctl_55 mpmcbase + 0x0dc
75 #define denali_ctl_56 mpmcbase + 0x0e0
76 #define denali_ctl_57 mpmcbase + 0x0e4
77 #define denali_ctl_58 mpmcbase + 0x0e8
78 #define denali_ctl_59 mpmcbase + 0x0ec
79 #define denali_ctl_60 mpmcbase + 0x0f0
80 #define denali_ctl_61 mpmcbase + 0x0f4
81 #define denali_ctl_62 mpmcbase + 0x0f8
82 #define denali_ctl_63 mpmcbase + 0x0fc
83 #define denali_ctl_64 mpmcbase + 0x100
84 #define denali_ctl_65 mpmcbase + 0x104
85 #define denali_ctl_66 mpmcbase + 0x108
86 #define denali_ctl_67 mpmcbase + 0x10c
87 #define denali_ctl_68 mpmcbase + 0x110
88 #define denali_ctl_69 mpmcbase + 0x114
89 #define denali_ctl_70 mpmcbase + 0x118
90 #define denali_ctl_71 mpmcbase + 0x11c
91 #define denali_ctl_72 mpmcbase + 0x120
92 #define denali_ctl_73 mpmcbase + 0x124
93 #define denali_ctl_74 mpmcbase + 0x128
94 #define denali_ctl_75 mpmcbase + 0x12c
95 #define denali_ctl_76 mpmcbase + 0x130
96 #define denali_ctl_77 mpmcbase + 0x134
97 #define denali_ctl_78 mpmcbase + 0x138
98 #define denali_ctl_79 mpmcbase + 0x13c
99 #define denali_ctl_80 mpmcbase + 0x140
100 #define denali_ctl_81 mpmcbase + 0x144
101 #define denali_ctl_82 mpmcbase + 0x148
102 #define denali_ctl_83 mpmcbase + 0x14c
103 #define denali_ctl_84 mpmcbase + 0x150
104 #define denali_ctl_85 mpmcbase + 0x154
105 #define denali_ctl_86 mpmcbase + 0x158
106 #define denali_ctl_87 mpmcbase + 0x15c
107 #define denali_ctl_88 mpmcbase + 0x160
108 #define denali_ctl_89 mpmcbase + 0x164
109 #define denali_ctl_90 mpmcbase + 0x168
110 #define denali_ctl_91 mpmcbase + 0x16c
111 #define denali_ctl_92 mpmcbase + 0x170
112 #define denali_ctl_93 mpmcbase + 0x174
113 #define denali_ctl_94 mpmcbase + 0x178
114 #define denali_ctl_95 mpmcbase + 0x17c
115 #define denali_ctl_96 mpmcbase + 0x180
116 #define denali_ctl_97 mpmcbase + 0x184
117 #define denali_ctl_98 mpmcbase + 0x188
118 #define denali_ctl_99 mpmcbase + 0x18c
119
120
121
122
123 /*;; export mpmc_init*/
124 /*;;mpmc_init rou*/
125
126 .global ddr_init
127 ddr_init:
128
/* 保存返回地址,用以返回xloader_entry */
129 mov v1, lr /* ; save lr*/
130
131 /*;;---------- ext regs config --------------*/
132 /*;;---------- ddrcore disable to switch core frequency -----*/
/* 从这里开始对ddr进行初始化设置,在设置ddr的频率之前,首先要disable ddr的时钟 */
133 ldr a1, = per1_clken /* per1_clken为外设时钟使能寄存器perip1_clk_enb的地址0xfca8002c */
134 ldr a2, [a1, #0] /* 载入perip1_clk_enb寄存器的当前值 */
135 ldr a3, =0x9fffffff /* a3作为掩码,用于对[0-31]位中的第29、30位清零 */
136 and a2,a2,a3 /* 将perip1_clk_enb寄存器的当前值的第29、30位清零,
* 根据手册第29位是ddr_core_enb,当该位为0时,disable ddr core clock
*/
137 ldr a3, =0x40000000 /* 根据芯片手册,perip1_clk_enb的第30位是reserved的,
* 因此这边将第30位置1以及上面的将第30位清零显得没有意义,
* 可能芯片手册不是最新的?
138 orr a2,a2,a3
139 str a2, [a1, #0] /* 将最新的设置保存至目标寄存器,但不知道为什么要保存两遍? */
140 str a2, [a1, #0]
141
142 /*;;---------- pll_reg (switch core frequency) ----------*/
/* 这里对外部内存ddr的时钟进行设定 */
143 ldr a1, = ddr_pll_reg /* ddr_pll_reg为pll_clk_cfg(pll clock config)寄存器的地址0xfca80020 */
144 ldr a2, [a1, #0] /* 载入pll_clk_cfg寄存器的当前值 */
145 ldr a3, =0x8fffffff /* a3作为掩码,用于对[0-31]位中的第28、29、30位清零 */
146 and a2,a2,a3 /* 将pll_clk_cfg寄存器的当前值的第28、29、30位清零,
* 根据手册可知,pll_clk_cfg的第[28-30]位定义了ddr时钟的工作模式
147 ldr a3, =0x30000000/* ;; vm :asynchronous mode :clock provided from pll2*/
/* 将pll_clk_cfg的第[28-30]位设置为'b011,查看手册可知,
* 此处将ddr的时钟设置成了异步模式,也就是使用由pll2提供过来的时钟。
148 orr a2,a2,a3 /* 设置并保存至ll_clk_cfg寄存器 */
149 str a2, [a1, #0]
150
151 /*;;---------- ddrcore enable after switch core frequency ----------*/
/* 此处所做的工作就是在设置完ddr时钟的工作模式后重新打开外设时钟使能寄存器中的ddr控制位 */
152 ldr a1, = per1_clken
153 ldr a2, [a1, #0]
154 ldr a3, =0xdfffffff /* 我觉得这里首先将ddr控制位(第29位)清零的做法是完全没有必要的 */
155 and a2,a2,a3 /* 因为反正下面马上就要将该位置1了,而且按理说在这里是不可能读到该位为1的 */
156 ldr a3, =0x20000000 /* 以下三句代码就是将perip1_clk_enb寄存器的第29位也就是ddr_core_enb置1 */
157 orr a2,a2,a3
158 str a2, [a1, #0] /* 然后保存到perip1_clk_enb寄存器中 */
159
160 /*;;------------------ pad_reg ----------------*/
/* 这里是设置sstlpad_cfg_ctr寄存器的低16位值,这个寄存器的每个位的功能比较复杂,
* 我还没有怎么看明白,具体可以参考芯片手册。
*/
161 ldr a1, = ddr_pad_reg
162 ldr a2, [a1, #0]
163 ldr a3, =0xffff0000
164 and a2,a2,a3
165 ldr a3, =0x0000eaab3
166 orr a2,a2,a3
167 str a2, [a1, #0]
168
169 /*;;------- comp3v3_reg -------*/
/* 配置compcor_3v3_cfg寄存器,具体每个位的功能参考芯片手册 */
170 ldr a1, = ddr_3v3_reg
171 ldr a2, [a1, #0]
172 ldr a3, =0x8080ffe0
173 and a2,a2,a3
174 ldr a3, =0x78000002
175 orr a2,a2,a3
176 str a2, [a1, #0]
177
178 /*;;---------- programmation sequence for sstl compensation --------------*/
179 /*;;---------- compensations reset configs (not required) --------------*/
180 /*;;------- comp1v8_reg (start)-------*/
/* 配置compsstl_1v8_cfg寄存器,具体每个位的功能参考芯片手册 */
181 ldr a1, = ddr_1v8_reg
182 ldr a2, [a1, #0]
183 ldr a3, =0x8080ffc0
184 and a2,a2,a3
185 ldr a3, =0x78000004
186 orr a2,a2,a3
187 str a2, [a1, #0]
188 /*;;------- comp2v5_reg (start) -------*/
/* 配置compsstl_2v5_cfg寄存器,具体每个位的功能参考芯片手册 */
189 ldr a1, = ddr_2v5_reg
190 ldr a2, [a1, #0]
191 ldr a3, =0x8080ffc0
192 and a2,a2,a3
193 ldr a3, =0x78000004
194 orr a2,a2,a3
195 str a2, [a1, #0]
196
197 /*;;---------- check selected ddr --------*/
/* 从sstlpad_cfg_ctr寄存器中读出第17、18两位,
* 如果两位都是1的话则跳转到sw_check标号处,否则跳转到hw_check标号处。
* 这在芯片手册上有说明
198 ldr a1, = ddr_pad_reg
199 /*;;--- check hw or sw selection*/
200 ldr a2, [a1, #0]
201 ldr a3, =0x00060000
202 and a2,a2,a3
203 cmp a2,a3
204 bne hw_check
205 b sw_check
206 /*;;--- 1v8 sw check*/
207 sw_check:
/* 如果是sw_check方式,则查看sstlpad_cfg_ctr寄存器的最低位,
* 若为0,则表示ddr1 dram interface(sstl2v5)
* 若为1,则表示ddr2 dram interface(sstl1v8)
208 ldr a2, [a1, #0]
209 ldr a3, =0x00000001
210 and a2,a2,a3
211 cmp a2,a3
212 bne sel_2v5
213 b sel_1v8
214 /* ;;--- 1v8 hw check*/
215 hw_check:
/* 如果是hw_check方式,则查看sstlpad_cfg_ctr寄存器的第15位,
216 ldr a2, [a1, #0]
217 ldr a3, =0x00008000
218 and a2,a2,a3
219 cmp a2,a3
220 bne sel_2v5
221 b sel_1v8
222
/* 以下分别是sel_1v8和sel_2v5两种方式,
* 这两种方式的唯一不同之处就是对两个寄存器compsstl_1v8_cfg和compsstl_2v5_cfg
* 的设置顺序以及设置的值不同,具体这些值代表什么意思以及这些寄存器的作用,
* 由于我对硬件的只是不够,所以看着还是一头雾水。。。
* 在设置完这两个寄存器的值以后,sel_1v8就等待直到compsstl_1v8_cfg的第4位为1
* 而sel_2v5则等待直到compsstl_2v5_cfg的第4位为1,
* 最后,都将跳转到end_comp处。
223 sel_1v8:
224 /*;;------- compensation 1v8 selected -------*/
225 /*;;------- comp2v5_reg (iddq) -------*/
226 ldr a1, = ddr_2v5_reg
227 ldr a2, [a1, #0]
228 ldr a3, =0x8080ffc0
229 and a2,a2,a3
230 ldr a3, =0x78000003
231 orr a2,a2,a3
232 str a2, [a1, #0]
233 /*;;------- comp1v8_reg (normal)-------*/
234 ldr a1, = ddr_1v8_reg
235 ldr a2, [a1, #0]
236 ldr a3, =0x8080ffc0
237 and a2,a2,a3
238 ldr a3, =0x78000010
239 orr a2,a2,a3
240 str a2, [a1, #0]
241 /* ;--- ok wait ---*/
242 ok_loop_1v8:
243 ldr a1, = ddr_1v8_reg
244 ldr a2, [a1, #0]
245 ldr a3, =0x00000010
246 and a2,a2,a3
247 cmp a2,a3
248 bne ok_loop_1v8
249 b end_comp
250
251
252 sel_2v5:
253 /*;;------- compensation 2v5 selected -------*/
254 /*;;------- comp1v8_reg (iddq)-------*/
255 ldr a1, = ddr_1v8_reg
256 ldr a2, [a1, #0]
257 ldr a3, =0x8080ffc0
258 and a2,a2,a3
259 ldr a3, =0x78000003
260 orr a2,a2,a3
261 str a2, [a1, #0]
262 /*;;------- comp2v5_reg (normal) -------*/
263 ldr a1, = ddr_2v5_reg
264 ldr a2, [a1, #0]
265 ldr a3, =0x8080ffc0
266 and a2,a2,a3
267 ldr a3, =0x78000010
268 orr a2,a2,a3
269 str a2, [a1, #0]
270 /* ;--- ok wait ---*/
271 ok_loop_2v5:
272 ldr a1, = ddr_2v5_reg
273 ldr a2, [a1, #0]
274 ldr a3, =0x00000010
275 and a2,a2,a3
276 cmp a2,a3
277 bne ok_loop_2v5
278 b end_comp
279
280 end_comp:
/* denali_ctl_00-denali_ctl_99分别代表寄存器mem0_ctl-mem99_ctl
* 这里根据每个寄存器的手册说明以及实际需求对这些内存控制寄存器进行了设置
* 由于时间以及能力所限,我无法对这里的每个寄存器的设置内容进行详细的说明
* 想要看得更加仔细,可以参考芯片手册。
* 我们的最终目的是了解整个引导的流程,所以在这里只需要知道对内存控制寄存器进行了设置即可。
281
282 /*;;---------- mpmc config --------------*/
283 ldr a2, =0x00000001
284 ldr a1, = denali_ctl_00
285 str a2, [a1, #0]
286
287 ldr a2, =0x00000000
288 ldr a1, = denali_ctl_01
289 str a2, [a1, #0]
290
291 ldr a2, =0x01000000
292 ldr a1, = denali_ctl_02
293 str a2, [a1, #0]
294
295 ldr a2, =0x00000101
296 ldr a1, = denali_ctl_03
297 str a2, [a1, #0]
298
299 ldr a2, =0x00000001
300 ldr a1, = denali_ctl_04
301 str a2, [a1, #0]
302
303 ldr a2, =0x01000000
304 ldr a1, = denali_ctl_05
305 str a2, [a1, #0]
306
307 ldr a2, =0x00010001
308 ldr a1, = denali_ctl_06
309 str a2, [a1, #0]
310
311 ldr a2, =0x00000100
312 ldr a1, = denali_ctl_07
313 str a2, [a1, #0]
314
315 ldr a2, =0x00010001
316 ldr a1, = denali_ctl_08
317 str a2, [a1, #0]
318
319 ldr a2, =0x00000003
320 ldr a1, = denali_ctl_09
321 str a2, [a1, #0]
322
323 ldr a2, =0x01000201
324 ldr a1, = denali_ctl_10
325 str a2, [a1, #0]
326
327 ldr a2, =0x03000202
328 ldr a1, = denali_ctl_11
329 str a2, [a1, #0]
330
331 ldr a2, =0x03030103
332 ldr a1, = denali_ctl_12
333 str a2, [a1, #0]
334
335 ldr a2, =0x03030302
336 ldr a1, = denali_ctl_13
337 str a2, [a1, #0]
338
339 ldr a2, =0x03040303
340 ldr a1, = denali_ctl_14
341 str a2, [a1, #0]
342
343 ldr a2, =0x03030503
344 ldr a1, = denali_ctl_15
345 str a2, [a1, #0]
346
347 #ifdef lcd
348 ldr a2, =0x02020206
349 #else
350 ldr a2, =0x02030306
351 #endif
352 ldr a1, = denali_ctl_16
353 str a2, [a1, #0]
354
355 ldr a2, =0x03000404
356 ldr a1, = denali_ctl_17
357 str a2, [a1, #0]
358
359 ldr a2, =0x02030202
360 ldr a1, = denali_ctl_18
361 str a2, [a1, #0]
362
363 ldr a2, =0x03000204
364 ldr a1, = denali_ctl_19
365 str a2, [a1, #0]
366
367 ldr a2, =0x0707073f
368 ldr a1, = denali_ctl_20
369 str a2, [a1, #0]
370
371 ldr a2, =0x07070707
372 ldr a1, = denali_ctl_21
373 str a2, [a1, #0]
374
375 ldr a2, =0x06060607
376 ldr a1, = denali_ctl_22
377 str a2, [a1, #0]
378
379 ldr a2, =0x06060606
380 ldr a1, = denali_ctl_23
381 str a2, [a1, #0]
382
383 ldr a2, =0x05050506
384 ldr a1, = denali_ctl_24
385 str a2, [a1, #0]
386
387 ldr a2, =0x05050505
388 ldr a1, = denali_ctl_25
389 str a2, [a1, #0]
390
391 ldr a2, =0x04040405
392 ldr a1, = denali_ctl_26
393 str a2, [a1, #0]
394
395 ldr a2, =0x04040404
396 ldr a1, = denali_ctl_27
397 str a2, [a1, #0]
398
399 ldr a2, =0x03030304
400 ldr a1, = denali_ctl_28
401 str a2, [a1, #0]
402
403 ldr a2, =0x03030303
404 ldr a1, = denali_ctl_29
405 str a2, [a1, #0]
406
407 ldr a2, =0x02020203
408 ldr a1, = denali_ctl_30
409 str a2, [a1, #0]
410
411 ldr a2, =0x02020202
412 ldr a1, = denali_ctl_31
413 str a2, [a1, #0]
414
415 ldr a2, =0x01010102
416 ldr a1, = denali_ctl_32
417 str a2, [a1, #0]
418
419 ldr a2, =0x01010101
420 ldr a1, = denali_ctl_33
421 str a2, [a1, #0]
422
423 ldr a2, =0x08080a01
424 ldr a1, = denali_ctl_34
425 str a2, [a1, #0]
426
427 ldr a2, =0x0000023f
428 ldr a1, = denali_ctl_35
429 str a2, [a1, #0]
430
431 ldr a2, =0x00040800
432 ldr a1, = denali_ctl_36
433 str a2, [a1, #0]
434
435 ldr a2, =0x00000000
436 ldr a1, = denali_ctl_37
437 str a2, [a1, #0]
438
439 ldr a2, =0x00000f02
440 ldr a1, = denali_ctl_38
441 str a2, [a1, #0]
442
443 ldr a2, =0x00001b1b
444 ldr a1, = denali_ctl_39
445 str a2, [a1, #0]
446
447 ldr a2, =0x7f000000
448 ldr a1, = denali_ctl_40
449 str a2, [a1, #0]
450
451 ldr a2, =0x005f0000
452 ldr a1, = denali_ctl_41
453 str a2, [a1, #0]
454
455 ldr a2, =0x1c040b6a
456 ldr a1, = denali_ctl_42
457 str a2, [a1, #0]
458
459 ldr a2, =0x00640064
460 ldr a1, = denali_ctl_43
461 str a2, [a1, #0]
462
463 ldr a2, =0x00640064
464 ldr a1, = denali_ctl_44
465 str a2, [a1, #0]
466
467 ldr a2, =0x00640064
468 ldr a1, = denali_ctl_45
469 str a2, [a1, #0]
470
471 ldr a2, =0x00000064
472 ldr a1, = denali_ctl_46
473 str a2, [a1, #0]
474
475 ldr a2, =0x00200020
476 ldr a1, = denali_ctl_47
477 str a2, [a1, #0]
478
479 ldr a2, =0x00200020
480 ldr a1, = denali_ctl_48
481 str a2, [a1, #0]
482
483 ldr a2, =0x00200020
484 ldr a1, = denali_ctl_49
485 str a2, [a1, #0]
486
487 ldr a2, =0x00200020
488 ldr a1, = denali_ctl_50
489 str a2, [a1, #0]
490
491 ldr a2, =0x00200020
492 ldr a1, = denali_ctl_51
493 str a2, [a1, #0]
494
495 ldr a2, =0x00200020
496 ldr a1, = denali_ctl_52
497 str a2, [a1, #0]
498
499 ldr a2, =0x00200020
500 ldr a1, = denali_ctl_53
501 str a2, [a1, #0]
502
503 ldr a2, =0x000007ff
504 ldr a1, = denali_ctl_54
505 str a2, [a1, #0]
506
507 ldr a2, =0x00000000
508 ldr a1, = denali_ctl_55
509 str a2, [a1, #0]
510
511 ldr a2, =0x47ec00c8
512 ldr a1, = denali_ctl_56
513 str a2, [a1, #0]
514
515 ldr a2, =0x00c8001f
516 ldr a1, = denali_ctl_57
517 str a2, [a1, #0]
518
519 ldr a2, =0x00000000
520 ldr a1, = denali_ctl_58
521 str a2, [a1, #0]
522
523 ldr a2, =0x0000cd98
524 ldr a1, = denali_ctl_59
525 str a2, [a1, #0]
526
527 ldr a2, =0x00000000
528 ldr a1, = denali_ctl_60
529 str a2, [a1, #0]
530
531 ldr a2, =0x03030100
532 ldr a1, = denali_ctl_61
533 str a2, [a1, #0]
534
535 ldr a2, =0x03030303
536 ldr a1, = denali_ctl_62
537 str a2, [a1, #0]
538
539 ldr a2, =0x03030303
540 ldr a1, = denali_ctl_63
541 str a2, [a1, #0]
542
543 ldr a2, =0x03030303
544 ldr a1, = denali_ctl_64
545 str a2, [a1, #0]
546
547 ldr a2, =0x00270000
548 ldr a1, = denali_ctl_65
549 str a2, [a1, #0]
550
551 ldr a2, =0x00250027
552 ldr a1, = denali_ctl_66
553 str a2, [a1, #0]
554
555 ldr a2, =0x00300000
556 ldr a1, = denali_ctl_67
557 str a2, [a1, #0]
558
559 ldr a2, =0x008900b7
560 ldr a1, = denali_ctl_68
561 str a2, [a1, #0]
562
563 ldr a2, =0x003fffff
564 ldr a1, = denali_ctl_69
565 str a2, [a1, #0]
566
567 ldr a2, =0x003fffff
568 ldr a1, = denali_ctl_70
569 str a2, [a1, #0]
570
571 ldr a2, =0x00000000
572 ldr a1, = denali_ctl_71
573 str a2, [a1, #0]
574
575 ldr a2, =0x00000000
576 ldr a1, = denali_ctl_72
577 str a2, [a1, #0]
578
579 ldr a2, =0x003fffff
580 ldr a1, = denali_ctl_73
581 str a2, [a1, #0]
582
583 ldr a2, =0x003fffff
584 ldr a1, = denali_ctl_74
585 str a2, [a1, #0]
586
587 ldr a2, =0x00000000
588 ldr a1, = denali_ctl_75
589 str a2, [a1, #0]
590
591 ldr a2, =0x00000000
592 ldr a1, = denali_ctl_76
593 str a2, [a1, #0]
594
595 ldr a2, =0x003fffff
596 ldr a1, = denali_ctl_77
597 str a2, [a1, #0]
598
599 ldr a2, =0x003fffff
600 ldr a1, = denali_ctl_78
601 str a2, [a1, #0]
602
603 ldr a2, =0x00000000
604 ldr a1, = denali_ctl_79
605 str a2, [a1, #0]
606
607 ldr a2, =0x00000000
608 ldr a1, = denali_ctl_80
609 str a2, [a1, #0]
610
611 ldr a2, =0x003fffff
612 ldr a1, = denali_ctl_81
613 str a2, [a1, #0]
614
615 ldr a2, =0x003fffff
616 ldr a1, = denali_ctl_82
617 str a2, [a1, #0]
618
619 ldr a2, =0x00000000
620 ldr a1, = denali_ctl_83
621 str a2, [a1, #0]
622
623 ldr a2, =0x00000000
624 ldr a1, = denali_ctl_84
625 str a2, [a1, #0]
626
627 ldr a2, =0x003fffff
628 ldr a1, = denali_ctl_85
629 str a2, [a1, #0]
630
631 ldr a2, =0x003fffff
632 ldr a1, = denali_ctl_86
633 str a2, [a1, #0]
634
635 ldr a2, =0x00000000
636 ldr a1, = denali_ctl_87
637 str a2, [a1, #0]
638
639 ldr a2, =0x00000000
640 ldr a1, = denali_ctl_88
641 str a2, [a1, #0]
642
643 ldr a2, =0x003fffff
644 ldr a1, = denali_ctl_89
645 str a2, [a1, #0]
646
647 ldr a2, =0x003fffff
648 ldr a1, = denali_ctl_90
649 str a2, [a1, #0]
650
651 ldr a2, =0x00000000
652 ldr a1, = denali_ctl_91
653 str a2, [a1, #0]
654
655 ldr a2, =0x00000000
656 ldr a1, = denali_ctl_92
657 str a2, [a1, #0]
658
659 ldr a2, =0x003fffff
660 ldr a1, = denali_ctl_93
661 str a2, [a1, #0]
662
663 ldr a2, =0x003fffff
664 ldr a1, = denali_ctl_94
665 str a2, [a1, #0]
666
667 ldr a2, =0x00000000
668 ldr a1, = denali_ctl_95
669 str a2, [a1, #0]
670
671 ldr a2, =0x00000000
672 ldr a1, = denali_ctl_96
673 str a2, [a1, #0]
674
675 ldr a2, =0x00000000
676 ldr a1, = denali_ctl_97
677 str a2, [a1, #0]
678
679 ldr a2, =0x00000000
680 ldr a1, = denali_ctl_98
681 str a2, [a1, #0]
682
683 ldr a2, =0x00000000
684 ldr a1, = denali_ctl_99
685 str a2, [a1, #0]
686
687 /*;;---------- mpmc start ---------------*/
688
689 ldr a2, =0x01000100
690 ldr a1, = denali_ctl_07
691 str a2, [a1, #0]
692
/* 最后,将开头保存的返回地址给pc,返回到xloader_entry中
* 返回之后,外部内存sdram就可以使用了。
693 mov pc, v1 /* ; restore lr*/