歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android210 uboot 調試

Android210 uboot 調試

日期:2017/3/1 10:13:41   编辑:Linux編程

1.編譯配置

編譯前先進行配置:make smdkv210single_config

其中,Makefile中make smdkv210single_config為:

  1. smdkv210single_config : unconfig
  2. @$(MKCONFIG) $(@:_config=) arm s5pc11x smdkc110 samsung s5pc110
  3. @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/smdkc110/config.mk

這裡使用了Makefile中的替換引用規則,類似常看到的例子 obj=$(srcfiles:%.c=%.o): 由.c得到對應的.o文件.

這裡是一樣的道理: $(@:_config=) ,@代表的是target smdkv210single_config, 那麼$(@:_config=)就是將smdkv210single_config中的_config替換為空,

即得到smdkv210single。

這裡$(@:_config=) arm s5pc11x smdkc110 samsung s5pc110都是mkconfig(即@$(MKCONFIG))的參數,mkconfig即根目錄下的腳本文件。

執行這句命令後,在include/下生成config.mk和config.h。並且Makefile包含這個config.mk。

config.mk文件:

  1. ARCH = arm
  2. CPU = s5pc11x
  3. BOARD = smdkc110
  4. VENDOR = samsung
  5. SOC = s5pc110

它指定裡CPU架構,CPU型號,板子型號,CPU廠商,SOC??(母雞啦)

可以根據上面的這個信息找到對應的代碼。比如說CPU代碼在cpu/s5pc11x下,板子代碼在board/smdkc110下。

2.CPU

根據config.mk中CPU的信息,找到對應的cpu目錄為cpu/s5pc11x。首先看cpu/s5pc11x/start.S:

代碼解釋:

  1. /*
  2. * armboot - Startup Code for S5PC110/ARM-Cortex CPU-core
  3. *
  4. * Copyright (c) 2009 Samsung Electronics
  5. *
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. *
  25. * Base codes by scsuh (sc.suh)
  26. */
  27. #include <config.h>
  28. #include <version.h>
  29. #if defined(CONFIG_ENABLE_MMU)
  30. #include <asm/proc/domain.h>
  31. #endif
  32. #include <regs.h>
  33. #ifndef CONFIG_ENABLE_MMU
  34. #ifndef CFG_PHY_UBOOT_BASE
  35. #define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE
  36. #endif
  37. #endif
  38. /*
  39. *************************************************************************
  40. *
  41. * Jump vector table as in table 3.1 in [1]
  42. *
  43. *************************************************************************
  44. */
  45. #if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED) //階段啟動相關配置
  46. .word 0x2000
  47. .word 0x0
  48. .word 0x0
  49. .word 0x0
  50. #endif
  51. .globl _start
  52. _start: b reset //復位入口,此處使用b指令為相對調整,不依賴運行地址
  53. ldr pc, _undefined_instruction //以下進入異常處理函數
  54. ldr pc, _software_interrupt
  55. ldr pc, _prefetch_abort
  56. ldr pc, _data_abort
  57. ldr pc, _not_used
  58. ldr pc, _irq
  59. ldr pc, _fiq
  60. _undefined_instruction: //定義異常處理函數地址
  61. .word undefined_instruction
  62. _software_interrupt:
  63. .word software_interrupt
  64. _prefetch_abort:
  65. .word prefetch_abort
  66. _data_abort:
  67. .word data_abort
  68. _not_used:
  69. .word not_used
  70. _irq:
  71. .word irq
  72. _fiq:
  73. .word fiq
  74. _pad:
  75. .word 0x12345678 /* now 16*4=64 */ //保證16字節對齊
  76. .global _end_vect
  77. _end_vect:
  78. .balignl 16,0xdeadbeef //同樣是保證16字節對齊,詳見.align實驗文章
  79. /*
  80. *************************************************************************
  81. *
  82. * Startup Code (reset vector) 啟動代碼(復位向量)此處僅進行重要的初始化操作,搬移代碼和建立堆棧
  83. *
  84. * do important init only if we don't start from memory!
  85. * setup Memory and board specific bits prior to relocation.
  86. * relocate armboot to ram
  87. * setup stack
  88. *
  89. *************************************************************************
  90. */
  91. _TEXT_BASE:
  92. .word TEXT_BASE //TEST_BASE為根目錄下Makefile傳遞進來的參數,具體為0xc3e00000
  93. /*
  94. * Below variable is very important because we use MMU in U-Boot.
  95. * Without it, we cannot run code correctly before MMU is ON.
  96. * by scsuh. //下面的代碼非常重要,因為我們使用了MMU,沒有這段代碼,在MMC開啟前我們將不能正確的運行代碼
  97. */
  98. _TEXT_PHY_BASE:
  99. .word CFG_PHY_UBOOT_BASE //由dram的物理地址0x20000000加上0x3e00000而得,即0x23e00000.這個地址為MMU開啟前的物理地址
  100. .globl _armboot_start
  101. _armboot_start:
  102. .word _start //復位地址,具體為0xc3e00010
  103. /*
  104. * These are defined in the board-specific linker script.
  105. */
  106. .globl _bss_start
  107. _bss_start:
  108. .word __bss_start //__bss_start在鏈接腳本文件中的bss段開始,_end在bss段結尾,用於清零bss端,這兩個值在鏈接時才確定
  109. .globl _bss_end
  110. _bss_end:
  111. .word _end
  112. #if defined(CONFIG_USE_IRQ) //如果使用中斷,定義中斷棧地址
  113. /* IRQ stack memory (calculated at run-time) */
  114. .globl IRQ_STACK_START
  115. IRQ_STACK_START:
  116. .word 0x0badc0de
  117. /* IRQ stack memory (calculated at run-time) */
  118. .globl FIQ_STACK_START
  119. FIQ_STACK_START:
  120. .word 0x0badc0de
  121. #endif
  122. /*
  123. * the actual reset code
  124. */
  125. reset:
  126. /*
  127. * set the cpu to SVC32 mode and IRQ & FIQ disable
  128. */
  129. @;mrs r0,cpsr
  130. @;bic r0,r0,#0x1f
  131. @;orr r0,r0,#0xd3
  132. @;msr cpsr,r0
  133. msr cpsr_c, #0xd3 @ I & F disable, Mode: 0x13 - SVC //進入svc模式,中斷禁止
  134. /*
  135. *************************************************************************
  136. *
  137. * CPU_init_critical registers
  138. *
  139. * setup important registers
  140. * setup memory timing
  141. *
  142. *************************************************************************
  143. */
  144. /*
  145. * we do sys-critical inits only at reboot, //僅在關鍵初始化時執行,而不是在從ram復位時執行
  146. * not when booting from ram!
  147. */
  148. cpu_init_crit:
  149. #ifndef CONFIG_EVT1
  150. #if 0
  151. bl v7_flush_dcache_all
  152. #else
  153. bl disable_l2cache //禁止l2cache
  154. mov r0, #0x0 @
  155. mov r1, #0x0 @ i
  156. mov r3, #0x0
  157. mov r4, #0x0
  158. lp1:
  159. mov r2, #0x0 @ j
  160. lp2:
  161. mov r3, r1, LSL #29 @ r3 = r1(i) <<29
  162. mov r4, r2, LSL #6 @ r4 = r2(j) <<6
  163. orr r4, r4, #0x2 @ r3 = (i<<29)|(j<<6)|(1<<1)
  164. orr r3, r3, r4
  165. mov r0, r3 @ r0 = r3
  166. bl CoInvalidateDCacheIndex //清除數據緩存 8 * 1024
  167. add r2, #0x1 @ r2(j)++
  168. cmp r2, #1024 @ r2 < 1024
  169. bne lp2 @ jump to lp2
  170. add r1, #0x1 @ r1(i)++
  171. cmp r1, #8 @ r1(i) < 8
  172. bne lp1 @ jump to lp1
  173. bl set_l2cache_auxctrl //鎖定l2cache
  174. bl enable_l2cache //使能l2cache地址對齊
  175. #endif
  176. #endif
  177. bl disable_l2cache //禁止l2cache
  178. bl set_l2cache_auxctrl_cycle //鎖定l2cache
  179. bl enable_l2cache //使能l2cache
  180. /*
  181. * Invalidate L1 I/D
  182. */
  183. mov r0, #0 @ set up for MCR
  184. mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs //禁止TLB
  185. mcr p15, 0, r0, c7, c5, 0 @ invalidate icache //禁止指令緩存
  186. /*
  187. * disable MMU stuff and caches
  188. */
  189. mrc p15, 0, r0, c1, c0, 0
  190. bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
  191. bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
  192. orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
  193. orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
  194. mcr p15, 0, r0, c1, c0, 0 //禁止MMC和cache
  195. /* Read booting information */
  196. ldr r0, =PRO_ID_BASE
  197. ldr r1, [r0,#OMR_OFFSET]
  198. bic r2, r1, #0xffffffc1 //讀取啟動信息
  199. #ifdef CONFIG_VOGUES
  200. /* PS_HOLD(GPH0_0) set to output high */
  201. ldr r0, =ELFIN_GPIO_BASE
  202. ldr r1, =0x00000001
  203. str r1, [r0, #GPH0CON_OFFSET]
  204. ldr r1, =0x5500
  205. str r1, [r0, #GPH0PUD_OFFSET]
  206. ldr r1, =0x01
  207. str r1, [r0, #GPH0DAT_OFFSET]
  208. #endif
  209. /* NAND BOOT */
  210. cmp r2, #0x0 @ 512B 4-cycle //識別各種啟動方式,並將識別到的啟動識別碼寫入R3中
  211. moveq r3, #BOOT_NAND
  212. cmp r2, #0x2 @ 2KB 5-cycle
  213. moveq r3, #BOOT_NAND
  214. cmp r2, #0x4 @ 4KB 5-cycle 8-bit ECC
  215. moveq r3, #BOOT_NAND
  216. cmp r2, #0x6 @ 4KB 5-cycle 16-bit ECC
  217. moveq r3, #BOOT_NAND
  218. cmp r2, #0x8 @ OneNAND Mux
  219. moveq r3, #BOOT_ONENAND
  220. /* SD/MMC BOOT */
  221. cmp r2, #0xc
  222. moveq r3, #BOOT_MMCSD
  223. /* NOR BOOT */
  224. cmp r2, #0x14
  225. moveq r3, #BOOT_NOR
  226. #if 0 /* Android C110 BSP uses OneNAND booting! */
  227. /* For second device booting */
  228. /* OneNAND BOOTONG failed */
  229. cmp r2, #0x8
  230. moveq r3, #BOOT_SEC_DEV
  231. #endif
  232. /* Uart BOOTONG failed */
  233. cmp r2, #(0x1<<4)
  234. moveq r3, #BOOT_SEC_DEV
  235. ldr r0, =INF_REG_BASE
  236. str r3, [r0, #INF_REG3_OFFSET] //將啟動標識碼寫入INF_REG3中
  237. /*
  238. * Go setup Memory and board specific bits prior to relocation. //重定位前初始化存儲器和板特殊位
  239. */
  240. ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */ //分配給u-boot的sram的結尾 sram為0xd0020000-d003ffff 分配大小為90k
  241. sub sp, sp, #12 /* set stack */
  242. mov fp, #0
  243. bl lowlevel_init /* go setup pll,mux,memory */ //調用lowlevel_init函數初始化pll memory等與板子相關的內容 函數位於board目錄下
  244. /* To hold max8698 output before releasing power on switch,
  245. * set PS_HOLD signal to high
  246. */
  247. ldr r0, =0xE010E81C /* PS_HOLD_CONTROL register */ //PS_HOLD輸出高電平,PS_HOLD使能。PMIC相關
  248. ldr r1, =0x00005301 /* PS_HOLD output high */
  249. str r1, [r0]
  250. /* get ready to call C functions */
  251. ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */ //建立臨時棧指針,內容為0x23e00000
  252. sub sp, sp, #12
  253. mov fp, #0 /* no previous frame, so fp=0 */
  254. /* when we already run in ram, we don't need to relocate U-Boot.
  255. * and actually, memory controller must be configured before U-Boot //如果程序已經在ram中運行,我們不需要重新定位u-boot。
  256. * is running in ram. //實際上存儲器一定在u-boot在ram中運行前被初始化了
  257. */
  258. ldr r0, =0xff000fff
  259. bic r1, pc, r0 /* r0 <- current base addr of code */ //r1=當前PC
  260. ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */
  261. bic r2, r2, r0 /* r0 <- current base addr of code */ //r2=定位後運行地址
  262. cmp r1, r2 /* compare r0, r1 */
  263. beq after_copy /* r0 == r1 then skip flash copy */ //如果r1=r2,跳過復制部分
  264. #if defined(CONFIG_EVT1)
  265. /* If BL1 was copied from SD/MMC CH2 */
  266. ldr r0, =0xD0037488
  267. ldr r1, [r0] //取0xd0037488地址的值
  268. ldr r2, =0xEB200000
  269. cmp r1, r2
  270. beq mmcsd_boot //如果等於0xEB200000,跳轉到mmcsd_boot
  271. #endif
  272. ldr r0, =INF_REG_BASE //讀取存儲的INF_REG3中的啟動類型
  273. ldr r1, [r0, #INF_REG3_OFFSET]
  274. cmp r1, #BOOT_NAND /* 0x0 => boot device is nand */
  275. beq nand_boot
  276. cmp r1, #BOOT_ONENAND /* 0x1 => boot device is onenand */
  277. beq onenand_boot
  278. cmp r1, #BOOT_MMCSD
  279. beq mmcsd_boot
  280. cmp r1, #BOOT_NOR
  281. beq nor_boot
  282. cmp r1, #BOOT_SEC_DEV
  283. beq mmcsd_boot
  284. nand_boot:
  285. mov r0, #0x1000 //以下函數實現代碼的搬移
  286. bl copy_from_nand
  287. b after_copy
  288. onenand_boot:
  289. bl onenand_bl2_copy
  290. b after_copy
  291. mmcsd_boot:
  292. #if DELETE
  293. ldr sp, _TEXT_PHY_BASE
  294. sub sp, sp, #12
  295. mov fp, #0
  296. #endif
  297. bl movi_bl2_copy
  298. b after_copy
  299. nor_boot:
  300. bl read_hword
  301. b after_copy
  302. after_copy:
  303. #if defined(CONFIG_ENABLE_MMU)
  304. enable_mmu:
  305. /* enable domain access */
  306. ldr r5, =0x0000ffff //定義使能域的訪問權限
  307. mcr p15, 0, r5, c3, c0, 0 @load domain access register
  308. /* Set the TTB register */
  309. ldr r0, _mmu_table_base
  310. ldr r1, =CFG_PHY_UBOOT_BASE
  311. ldr r2, =0xfff00000
  312. bic r0, r0, r2
  313. orr r1, r0, r1
  314. mcr p15, 0, r1, c2, c0, 0 //將MMU啟用前的的mmu_table_base轉成sdram中的地址,並寫入cp15的c2中
  315. /* Enable the MMU */
  316. mmu_on:
  317. mrc p15, 0, r0, c1, c0, 0 //啟用mmu
  318. orr r0, r0, #1
  319. mcr p15, 0, r0, c1, c0, 0
  320. nop
  321. nop
  322. nop
  323. nop
  324. #endif
  325. skip_hw_init:
  326. /* Set up the stack */
  327. stack_setup:
  328. #if defined(CONFIG_MEMORY_UPPER_CODE)
  329. ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
  330. #else
  331. ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
  332. sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
  333. sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
  334. #if defined(CONFIG_USE_IRQ)
  335. sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
  336. #endif
  337. sub sp, r0, #12 /* leave 3 words for abort-stack */ //為取址終止異常預留3個字空間
  338. #endif
  339. clear_bss:
  340. ldr r0, _bss_start /* find start of bss segment */
  341. ldr r1, _bss_end /* stop here */
  342. mov r2, #0x00000000 /* clear */
  343. clbss_l:
  344. str r2, [r0] /* clear loop... */ //清除bss端內存
  345. add r0, r0, #4
  346. cmp r0, r1
  347. ble clbss_l
  348. ldr pc, _start_armboot
  349. _start_armboot: //第一階段結束,進入c程序階段
  350. .word start_armboot
  351. #if defined(CONFIG_ENABLE_MMU)
  352. _mmu_table_base:
  353. .word mmu_table
  354. #endif
  355. /*
  356. * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
  357. * r0: size to be compared
  358. * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
  359. */
  360. .globl copy_from_nand
  361. copy_from_nand:
  362. push {lr} /* save return address */
  363. mov r9, r0
  364. mov r9, #0x100 /* Compare about 8KB */
  365. bl copy_uboot_to_ram //從nandflash中讀取512k到0x23e00000中
  366. tst r0, #0x0
  367. bne copy_failed
  368. #if defined(CONFIG_EVT1)
  369. ldr r0, =0xd0020000 //iram的起始地址
  370. #else
  371. ldr r0, =0xd0030000 //iram的中間地址
  372. #endif
  373. ldr r1, _TEXT_PHY_BASE /* 0x23e00000 */
  374. 1: ldr r3, [r0], #4 //取r0+4地址的值到r3中
  375. ldr r4, [r1], #4 //取r1+4地址的值到r4中
  376. teq r3, r4
  377. bne compare_failed /* not matched */ //如果r3和r4不相等,比較失敗
  378. subs r9, r9, #4
  379. bne 1b
  380. pop {pc} /* all is OK */ //復制成功,返回
  381. copy_failed:
  382. nop /* copy from nand failed */
  383. b copy_failed
  384. compare_failed:
  385. nop /* compare failed */
  386. b compare_failed
  387. /*
  388. * we assume that cache operation is done before. (eg. cleanup_before_linux())
  389. * actually, we don't need to do anything about cache if not use d-cache in U-Boot
  390. * So, in this function we clean only MMU. by scsuh
  391. *
  392. * void theLastJump(void *kernel, int arch_num, uint boot_params);
  393. */
  394. #if defined(CONFIG_ENABLE_MMU)
  395. .globl theLastJump
  396. theLastJump:
  397. mov r9, r0 //保存內核地址
  398. ldr r3, =0xfff00000
  399. ldr r4, _TEXT_PHY_BASE
  400. adr r5, phy_last_jump
  401. bic r5, r5, r3
  402. orr r5, r5, r4
  403. mov pc, r5
  404. phy_last_jump:
  405. /*
  406. * disable MMU stuff //關閉MMU
  407. */
  408. mrc p15, 0, r0, c1, c0, 0
  409. bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
  410. bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
  411. orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
  412. orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
  413. mcr p15, 0, r0, c1, c0, 0
  414. mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
  415. mov r0, #0
  416. mov pc, r9 //跳轉到內核地址
  417. #endif
  418. /*
  419. *************************************************************************
  420. *
  421. * Interrupt handling
  422. *
  423. *************************************************************************
  424. */
  425. @
  426. @ IRQ stack frame.
  427. @
  428. #define S_FRAME_SIZE 72
  429. #define S_OLD_R0 68
  430. #define S_PSR 64
  431. #define S_PC 60
  432. #define S_LR 56
  433. #define S_SP 52
  434. #define S_IP 48
  435. #define S_FP 44
  436. #define S_R10 40
  437. #define S_R9 36
  438. #define S_R8 32
  439. #define S_R7 28
  440. #define S_R6 24
  441. #define S_R5 20
  442. #define S_R4 16
  443. #define S_R3 12
  444. #define S_R2 8
  445. #define S_R1 4
  446. #define S_R0 0
  447. #define MODE_SVC 0x13
  448. #define I_BIT 0x80
  449. /* //定義異常時保存寄存器的宏
  450. * use bad_save_user_regs for abort/prefetch/undef/swi ...
  451. * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
  452. */
  453. .macro bad_save_user_regs
  454. sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
  455. stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
  456. ldr r2, _armboot_start
  457. sub r2, r2, #(CFG_MALLOC_LEN)
  458. sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
  459. ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
  460. add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
  461. add r5, sp, #S_SP
  462. mov r1, lr
  463. stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
  464. mov r0, sp @ save current stack into r0 (param register)
  465. .endm
  466. .macro irq_save_user_regs
  467. sub sp, sp, #S_FRAME_SIZE
  468. stmia sp, {r0 - r12} @ Calling r0-r12
  469. add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
  470. stmdb r8, {sp, lr}^ @ Calling SP, LR
  471. str lr, [r8, #0] @ Save calling PC
  472. mrs r6, spsr
  473. str r6, [r8, #4] @ Save CPSR
  474. str r0, [r8, #8] @ Save OLD_R0
  475. mov r0, sp
  476. .endm
  477. .macro irq_restore_user_regs
  478. ldmia sp, {r0 - lr}^ @ Calling r0 - lr
  479. mov r0, r0
  480. ldr lr, [sp, #S_PC] @ Get PC
  481. add sp, sp, #S_FRAME_SIZE
  482. subs pc, lr, #4 @ return & move spsr_svc into cpsr
  483. .endm
  484. .macro get_bad_stack
  485. ldr r13, _armboot_start @ setup our mode stack (enter in banked mode)
  486. sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool
  487. sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
  488. str lr, [r13] @ save caller lr in position 0 of saved stack
  489. mrs lr, spsr @ get the spsr
  490. str lr, [r13, #4] @ save spsr in position 1 of saved stack
  491. mov r13, #MODE_SVC @ prepare SVC-Mode
  492. @ msr spsr_c, r13
  493. msr spsr, r13 @ switch modes, make sure moves will execute
  494. mov lr, pc @ capture return pc
  495. movs pc, lr @ jump to next instruction & switch modes.
  496. .endm
  497. .macro get_bad_stack_swi
  498. sub r13, r13, #4 @ space on current stack for scratch reg.
  499. str r0, [r13] @ save R0's value.
  500. ldr r0, _armboot_start @ get data regions start
  501. sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool
  502. sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
  503. str lr, [r0] @ save caller lr in position 0 of saved stack
  504. mrs r0, spsr @ get the spsr
  505. str lr, [r0, #4] @ save spsr in position 1 of saved stack
  506. ldr r0, [r13] @ restore r0
  507. add r13, r13, #4 @ pop stack entry
  508. .endm
  509. .macro get_irq_stack @ setup IRQ stack
  510. ldr sp, IRQ_STACK_START
  511. .endm
  512. .macro get_fiq_stack @ setup FIQ stack
  513. ldr sp, FIQ_STACK_START
  514. .endm
  515. /*
  516. * exception handlers //異常處理句柄
  517. */
  518. .align 5
  519. undefined_instruction:
  520. get_bad_stack
  521. bad_save_user_regs
  522. bl do_undefined_instruction
  523. .align 5
  524. software_interrupt:
  525. get_bad_stack_swi
  526. bad_save_user_regs
  527. bl do_software_interrupt
  528. .align 5
  529. prefetch_abort:
  530. get_bad_stack
  531. bad_save_user_regs
  532. bl do_prefetch_abort
  533. .align 5
  534. data_abort:
  535. get_bad_stack
  536. bad_save_user_regs
  537. bl do_data_abort
  538. .align 5
  539. not_used:
  540. get_bad_stack
  541. bad_save_user_regs
  542. bl do_not_used
  543. #if defined(CONFIG_USE_IRQ)
  544. .align 5
  545. irq:
  546. get_irq_stack
  547. irq_save_user_regs
  548. bl do_irq
  549. irq_restore_user_regs
  550. .align 5
  551. fiq:
  552. get_fiq_stack
  553. /* someone ought to write a more effiction fiq_save_user_regs */
  554. irq_save_user_regs
  555. bl do_fiq
  556. irq_restore_user_regs
  557. #else
  558. .align 5
  559. irq:
  560. get_bad_stack
  561. bad_save_user_regs
  562. bl do_irq
  563. .align 5
  564. fiq:
  565. get_bad_stack
  566. bad_save_user_regs
  567. bl do_fiq
  568. #endif
  569. .align 5
  570. .global arm_cache_flush
  571. arm_cache_flush:
  572. mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
  573. mov pc, lr @ back to caller
  574. /*
  575. * v7_flush_dcache_all()
  576. *
  577. * Flush the whole D-cache.
  578. *
  579. * Corrupted registers: r0-r5, r7, r9-r11
  580. *
  581. * - mm - mm_struct describing address space
  582. */
  583. .align 5
  584. .global v7_flush_dcache_all
  585. v7_flush_dcache_all:
  586. ldr r0, =0xffffffff
  587. mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
  588. ands r3, r0, #0x7000000
  589. mov r3, r3, LSR #23 @ Cache level value (naturally aligned)
  590. beq Finished
  591. mov r10, #0
  592. Loop1:
  593. add r2, r10, r10, LSR #1 @ Work out 3xcachelevel
  594. mov r1, r0, LSR r2 @ bottom 3 bits are the Ctype for this level
  595. and r1, r1, #7 @ get those 3 bits alone
  596. cmp r1, #2
  597. blt Skip @ no cache or only instruction cache at this level
  598. mcr p15, 2, r10, c0, c0, 0 @ write the Cache Size selection register
  599. mov r1, #0
  600. mcr p15, 0, r1, c7, c5, 4 @ PrefetchFlush to sync the change to the CacheSizeID reg
  601. mrc p15, 1, r1, c0, c0, 0 @ reads current Cache Size ID register
  602. and r2, r1, #0x7 @ extract the line length field
  603. add r2, r2, #4 @ add 4 for the line length offset (log2 16 bytes)
  604. ldr r4, =0x3FF
  605. ands r4, r4, r1, LSR #3 @ R4 is the max number on the way size (right aligned)
  606. clz r5, r4 @ R5 is the bit position of the way size increment
  607. ldr r7, =0x00007FFF
  608. ands r7, r7, r1, LSR #13 @ R7 is the max number of the index size (right aligned)
  609. Loop2:
  610. mov r9, r4 @ R9 working copy of the max way size (right aligned)
  611. Loop3:
  612. orr r11, r10, r9, LSL r5 @ factor in the way number and cache number into R11
  613. orr r11, r11, r7, LSL r2 @ factor in the index number
  614. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  615. subs r9, r9, #1 @ decrement the way number
  616. bge Loop3
  617. subs r7, r7, #1 @ decrement the index
  618. bge Loop2
  619. Skip:
  620. add r10, r10, #2 @ increment the cache number
  621. cmp r3, r10
  622. bgt Loop1
  623. Finished:
  624. mov pc, lr
  625. .align 5
  626. .global disable_l2cache
  627. disable_l2cache:
  628. mrc p15, 0, r0, c1, c0, 1
  629. bic r0, r0, #(1<<1)
  630. mcr p15, 0, r0, c1, c0, 1
  631. mov pc, lr
  632. .align 5
  633. .global enable_l2cache
  634. enable_l2cache:
  635. mrc p15, 0, r0, c1, c0, 1
  636. orr r0, r0, #(1<<1)
  637. mcr p15, 0, r0, c1, c0, 1
  638. mov pc, lr
  639. .align 5
  640. .global set_l2cache_auxctrl
  641. set_l2cache_auxctrl:
  642. mov r0, #0x0
  643. mcr p15, 1, r0, c9, c0, 2
  644. mov pc, lr
  645. .align 5
  646. .global set_l2cache_auxctrl_cycle
  647. set_l2cache_auxctrl_cycle:
  648. mrc p15, 1, r0, c9, c0, 2
  649. bic r0, r0, #(0x1<<29)
  650. bic r0, r0, #(0x1<<21)
  651. bic r0, r0, #(0x7<<6)
  652. bic r0, r0, #(0x7<<0)
  653. mcr p15, 1, r0, c9, c0, 2
  654. mov pc,lr
  655. .align 5
  656. CoInvalidateDCacheIndex:
  657. ;/* r0 = index */
  658. mcr p15, 0, r0, c7, c6, 2
  659. mov pc,lr
  660. #if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_CINTEGRATOR)
  661. /* Use the IntegratorCP function from board/integratorcp/platform.S */
  662. #elif defined(CONFIG_S5PC11X)
  663. /* For future usage of S3C64XX*/
  664. #else
  665. .align 5
  666. .globl reset_cpu
  667. reset_cpu:
  668. ldr r1, rstctl /* get addr for global reset reg */
  669. mov r3, #0x2 /* full reset pll+mpu */
  670. str r3, [r1] /* force reset */
  671. mov r0, r0
  672. _loop_forever:
  673. b _loop_forever
  674. rstctl:
  675. .word PM_RSTCTRL_WKUP
  676. #endif
Copyright © Linux教程網 All Rights Reserved