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  

相关内容