天天看点

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

这里我们来看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*/

继续阅读