嵌入式Linux引导过程之1.4——Xloader的ddr_init

2019-07-13 05:05发布


--by FeCen

这里我们来看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位,
     * 若为0,则表示DDR1 dram interface(SSTL2V5)
     * 若为1,则表示DDR2 dram interface(SSTL1V8)
     */
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*/