歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android210 uboot 調試

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