zoukankan      html  css  js  c++  java
  • uboot_smdkv210 分析二:启动代码start.s分析

    1.链接文件
    . = 0x00000000;

    . = ALIGN(4);
    .text      :
    {
      cpu/s5pc11x/start.o    (.text)
      cpu/s5pc11x/s5pc110/cpu_init.o  (.text)

    又链接文件可知,首先启动的是start.o,现在从start.s开始分析。

    2.启动阶段
    u-boot的启动分为两个阶段:
    stage1: 系统上电后执行的汇编代码,完成系统初始化、代码搬移等操作。
    stage2:搭建c环境,进入c语言执行。


    3.start.s

    #if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)    阶段启动相关配置
     .word 0x2000
     .word 0x0
     .word 0x0
     .word 0x0
    #endif


    .globl _start
    _start: b reset                                 复位入口,此处使用b指令为相对调整,不依赖运行地址
     ldr pc, _undefined_instruction            以下进入异常处理函数
     ldr pc, _software_interrupt
     ldr pc, _prefetch_abort
     ldr pc, _data_abort
     ldr pc, _not_used
     ldr pc, _irq
     ldr pc, _fiq

    _undefined_instruction:
     .word undefined_instruction                   定义异常处理函数地址
    _software_interrupt:
     .word software_interrupt
    _prefetch_abort:
     .word prefetch_abort
    _data_abort:
     .word data_abort
    _not_used:
     .word not_used
    _irq:
     .word irq
    _fiq:
     .word fiq
    _pad:
     .word 0x12345678 /* now 16*4=64 */           保证16字节对齐
    .global _end_vect
    _end_vect:

     .balignl 16,0xdeadbeef                       同样是保证16字节对齐,详见.align实验文章
    /*
     *************************************************************************
     *
     * Startup Code (reset vector)                       启动代码(复位向量)此处仅进行重要的初始化操作,搬移代码和建立堆栈
     *
     * do important init only if we don't start from memory!
     * setup Memory and board specific bits prior to relocation.
     * relocate armboot to ram
     * setup stack
     *
     *************************************************************************
     */

    _TEXT_BASE:
     .word TEXT_BASE                            TEST_BASE为根目录下Makefile传递进来的参数,具体为0xc3e00000

    /*
     * Below variable is very important because we use MMU in U-Boot.
     * Without it, we cannot run code correctly before MMU is ON.
     * by scsuh.                                        下面的代码非常重要,因为我们使用了MMU,没有这段代码,在MMC开启前我们将不能正确的运行代码
     */
    _TEXT_PHY_BASE:
     .word CFG_PHY_UBOOT_BASE                  由dram的物理地址0x20000000加上0x3e00000而得,即0x23e00000.这个地址为MMU开启前的物理地址

    .globl _armboot_start
    _armboot_start:
     .word _start                                复位地址,具体为0xc3e00010

    /*
     * These are defined in the board-specific linker script.
     */
    .globl _bss_start
    _bss_start:
     .word __bss_start                           __bss_start在链接脚本文件中的bss段开始,_end在bss段结尾,用于清零bss端,这两个值在链接时才确定

    .globl _bss_end
    _bss_end:
     .word _end

    #if defined(CONFIG_USE_IRQ)                         如果使用中断,定义中断栈地址
    /* IRQ stack memory (calculated at run-time) */
    .globl IRQ_STACK_START
    IRQ_STACK_START:
     .word 0x0badc0de

    /* IRQ stack memory (calculated at run-time) */
    .globl FIQ_STACK_START
    FIQ_STACK_START:
     .word 0x0badc0de
    #endif

    /*
     * the actual reset code
     */

    reset:
     /*
      * set the cpu to SVC32 mode and IRQ & FIQ disable
      */
     @;mrs r0,cpsr
     @;bic r0,r0,#0x1f
     @;orr r0,r0,#0xd3
     @;msr cpsr,r0
     msr cpsr_c, #0xd3  @ I & F disable, Mode: 0x13 - SVC  1.进入svc模式,中断禁止


    /*
     *************************************************************************
     *
     * CPU_init_critical registers
     *
     * setup important registers
     * setup memory timing
     *
     *************************************************************************
     */
             /*
             * we do sys-critical inits only at reboot, 仅在关键初始化时执行,而不是在从ram复位时执行
             * not when booting from ram!
             */
    cpu_init_crit:

    #ifndef CONFIG_EVT1
    #if 0 
     bl v7_flush_dcache_all
    #else
     bl disable_l2cache                  2.禁止l2cache

     mov r0, #0x0 @
     mov r1, #0x0 @ i 
     mov r3, #0x0
     mov r4, #0x0
    lp1:
     mov r2, #0x0 @ j
    lp2: 
     mov r3, r1, LSL #29  @ r3 = r1(i) <<29
     mov r4, r2, LSL #6  @ r4 = r2(j) <<6
     orr r4, r4, #0x2  @ r3 = (i<<29)|(j<<6)|(1<<1)
     orr r3, r3, r4
     mov r0, r3   @ r0 = r3
     bl CoInvalidateDCacheIndex                        3.清除数据缓存 8 * 1024
     add r2, #0x1  @ r2(j)++
     cmp r2, #1024  @ r2 < 1024
     bne lp2   @ jump to lp2
     add r1, #0x1  @ r1(i)++
     cmp r1, #8   @ r1(i) < 8
     bne lp1   @ jump to lp1

     bl set_l2cache_auxctrl                            4.锁定l2cache
     
     bl enable_l2cache                                 5.使能l2cache地址对齐
    #endif
    #endif
     
     bl disable_l2cache                                6.禁止l2cache

     bl set_l2cache_auxctrl_cycle                      7.锁定l2cache

     bl enable_l2cache                                 8.使能l2cache
     
           /*
            * Invalidate L1 I/D
            */
            mov r0, #0                  @ set up for MCR
            mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs      9.禁止TLB
            mcr p15, 0, r0, c7, c5, 0   @ invalidate icache    10.禁止指令缓存

           /*
            * disable MMU stuff and caches
            */
            mrc p15, 0, r0, c1, c0, 0
            bic r0, r0, #0x00002000     @ clear bits 13 (--V-)
            bic r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
            orr r0, r0, #0x00000002     @ set bit 1 (--A-) Align
            orr r0, r0, #0x00000800     @ set bit 12 (Z---) BTB
            mcr  p15, 0, r0, c1, c0, 0                         11.禁止MMC和cache


            /* Read booting information */
            ldr r0, =PRO_ID_BASE
            ldr r1, [r0,#OMR_OFFSET]
            bic r2, r1, #0xffffffc1                           12.读取启动信息

    #ifdef CONFIG_VOGUES
     /* PS_HOLD(GPH0_0) set to output high */
     ldr r0, =ELFIN_GPIO_BASE
     ldr r1, =0x00000001
     str r1, [r0, #GPH0CON_OFFSET]

     ldr r1, =0x5500
     str r1, [r0, #GPH0PUD_OFFSET]

     ldr r1, =0x01
     str r1, [r0, #GPH0DAT_OFFSET]
    #endif

     /* NAND BOOT */
     cmp r2, #0x0  @ 512B 4-cycle      13.识别各种启动方式,并将识别到的启动识别码写入R3中
     moveq r3, #BOOT_NAND

     cmp r2, #0x2  @ 2KB 5-cycle
     moveq r3, #BOOT_NAND

     cmp r2, #0x4  @ 4KB 5-cycle 8-bit ECC
     moveq r3, #BOOT_NAND

     cmp r2, #0x6  @ 4KB 5-cycle 16-bit ECC
     moveq r3, #BOOT_NAND

     cmp r2, #0x8  @ OneNAND Mux
     moveq r3, #BOOT_ONENAND

     /* SD/MMC BOOT */
     cmp     r2, #0xc
     moveq   r3, #BOOT_MMCSD 

     /* NOR BOOT */
     cmp     r2, #0x14
     moveq   r3, #BOOT_NOR 

    #if 0 /* Android C110 BSP uses OneNAND booting! */
     /* For second device booting */
     /* OneNAND BOOTONG failed */
     cmp     r2, #0x8
     moveq   r3, #BOOT_SEC_DEV
    #endif

     /* Uart BOOTONG failed */
     cmp     r2, #(0x1<<4)
     moveq   r3, #BOOT_SEC_DEV
     
     ldr r0, =INF_REG_BASE
     str r3, [r0, #INF_REG3_OFFSET]                                 14.将启动标识码写入INF_REG3中

     /*
      * Go setup Memory and board specific bits prior to relocation.    15.重定位前初始化存储器和板特殊位
      */

     ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */      16.分配给u-boot的sram的结尾 sram为0xd0020000-d003ffff 分配大小为90k
     sub sp, sp, #12 /* set stack */
     mov fp, #0
     
     bl lowlevel_init /* go setup pll,mux,memory */              17.调用lowlevel_init函数初始化pll memory等与板子相关的内容 函数位于board目录下
     /* To hold max8698 output before releasing power on switch,
      * set PS_HOLD signal to high
      */
     ldr r0, =0xE010E81C  /* PS_HOLD_CONTROL register */            18.PS_HOLD输出高电平,PS_HOLD使能。PMIC相关
     ldr r1, =0x00005301  /* PS_HOLD output high */
     str r1, [r0]

     /* get ready to call C functions */
     ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */     19.建立临时栈指针,内容为0x23e00000
     sub sp, sp, #12
     mov fp, #0   /* no previous frame, so fp=0 */

     /* when we already run in ram, we don't need to relocate U-Boot.
      * and actually, memory controller must be configured before U-Boot   20.如果程序已经在ram中运行,我们不需要重新定位u-boot。
      * is running in ram.                                                    实际上存储器一定在u-boot在ram中运行前被初始化了
      */
     ldr r0, =0xff000fff
     bic r1, pc, r0  /* r0 <- current base addr of code */  21.r1=当前PC
     ldr r2, _TEXT_BASE  /* r1 <- original base addr in ram */
     bic r2, r2, r0  /* r0 <- current base addr of code */  22.r2=定位后运行地址
     cmp     r1, r2                  /* compare r0, r1                  */
     beq     after_copy  /* r0 == r1 then skip flash copy   */  23.如果r1=r2,跳过复制部分

    #if defined(CONFIG_EVT1)
     /* If BL1 was copied from SD/MMC CH2 */
     ldr r0, =0xD0037488
     ldr r1, [r0]                          24.取0xd0037488地址的值
     ldr r2, =0xEB200000
     cmp r1, r2
     beq     mmcsd_boot                        25.如果等于0xEB200000,跳转到mmcsd_boot
    #endif

     ldr r0, =INF_REG_BASE                 26.读取存储的INF_REG3中的启动类型
     ldr r1, [r0, #INF_REG3_OFFSET]
     cmp r1, #BOOT_NAND  /* 0x0 => boot device is nand */
     beq nand_boot
     cmp r1, #BOOT_ONENAND /* 0x1 => boot device is onenand */
     beq onenand_boot
     cmp     r1, #BOOT_MMCSD
     beq     mmcsd_boot
     cmp     r1, #BOOT_NOR
     beq     nor_boot
     cmp     r1, #BOOT_SEC_DEV
     beq     mmcsd_boot

    nand_boot:
     mov r0, #0x1000                       27.以下函数实现代码的搬移
     bl copy_from_nand
     b after_copy

    onenand_boot:
     bl onenand_bl2_copy
     b after_copy

    mmcsd_boot:
    #if DELETE
     ldr     sp, _TEXT_PHY_BASE     
     sub     sp, sp, #12
     mov     fp, #0
    #endif
     bl      movi_bl2_copy
     b       after_copy

    nor_boot:
     bl      read_hword
     b       after_copy


    after_copy:

    #if defined(CONFIG_ENABLE_MMU)
    enable_mmu:
     /* enable domain access */
     ldr r5, =0x0000ffff                 28.定义使能域的访问权限
     mcr p15, 0, r5, c3, c0, 0  @load domain access register

     /* Set the TTB register */
     ldr r0, _mmu_table_base
     ldr r1, =CFG_PHY_UBOOT_BASE
     ldr r2, =0xfff00000
     bic r0, r0, r2
     orr r1, r0, r1
     mcr p15, 0, r1, c2, c0, 0           29.将MMU启用前的的mmu_table_base转成sdram中的地址,并写入cp15的c2中

     /* Enable the MMU */
    mmu_on:
     mrc p15, 0, r0, c1, c0, 0           30.启用mmu
     orr r0, r0, #1
     mcr p15, 0, r0, c1, c0, 0
     nop
     nop
     nop
     nop
    #endif

    skip_hw_init:
     /* Set up the stack          */
    stack_setup:
    #if defined(CONFIG_MEMORY_UPPER_CODE)
     ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
    #else
     ldr r0, _TEXT_BASE  /* upper 128 KiB: relocated uboot   */      0xc3e00000
     sub r0, r0, #CFG_MALLOC_LEN /* malloc area                      */      0x4000
     sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */      128
    #if defined(CONFIG_USE_IRQ)
     sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)                2*4*1024
    #endif
     sub sp, r0, #12  /* leave 3 words for abort-stack    */      31.为取址终止异常预留3个字空间

    #endif

    clear_bss:
     ldr r0, _bss_start  /* find start of bss segment        */
     ldr r1, _bss_end  /* stop here                        */
     mov  r2, #0x00000000  /* clear                            */

    clbss_l:
     str r2, [r0]  /* clear loop...                    */      32.清除bss端内存
     add r0, r0, #4
     cmp r0, r1
     ble clbss_l
     
     ldr pc, _start_armboot                                                  33.第一阶段结束,进入c程序阶段

    _start_armboot:
     .word start_armboot

    #if defined(CONFIG_ENABLE_MMU)
    _mmu_table_base:
     .word mmu_table
    #endif

    /*
     * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
     * r0: size to be compared
     * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
     */
     .globl copy_from_nand
    copy_from_nand:
     push {lr}  /* save return address */

     mov r9, r0
     
     mov r9, #0x100  /* Compare about 8KB */
     bl copy_uboot_to_ram                                 35.从nandflash中读取512k到0x23e00000中
     tst  r0, #0x0
     bne copy_failed

    #if defined(CONFIG_EVT1)
     ldr r0, =0xd0020000                                   36.iram的起始地址
    #else 
     ldr r0, =0xd0030000                                   37.iram的中间地址
    #endif
     ldr r1, _TEXT_PHY_BASE /* 0x23e00000 */

    #if !defined(CONFIG_SECURE_BOOT)
    1: ldr r3, [r0], #4                                      38.取r0+4地址的值到r3中
     ldr r4, [r1], #4                                      39.取r1+4地址的值到r4中
     teq r3, r4
     bne compare_failed /* not matched */                 40.如果r3和r4不相等,比较失败
     subs r9, r9, #4
     bne 1b
    #endif
     pop {pc}  /* all is OK */                   41.复制成功,返回

    copy_failed:
     nop   /* copy from nand failed */
     b copy_failed

    compare_failed:
     nop   /* compare failed */
     b compare_failed

    /*
     * we assume that cache operation is done before. (eg. cleanup_before_linux())
     * actually, we don't need to do anything about cache if not use d-cache in U-Boot
     * So, in this function we clean only MMU. by scsuh
     *
     * void theLastJump(void *kernel, int arch_num, uint boot_params);
     */
    #if defined(CONFIG_ENABLE_MMU)
     .globl theLastJump
    theLastJump:
     mov r9, r0                    保存内核地址
     ldr r3, =0xfff00000
     ldr r4, _TEXT_PHY_BASE
     adr r5, phy_last_jump
     bic r5, r5, r3
     orr r5, r5, r4
     mov pc, r5
    phy_last_jump:
     /*
      * disable MMU stuff             关闭MMU
      */
     mrc p15, 0, r0, c1, c0, 0
     bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
     bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
     orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
     orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
     mcr p15, 0, r0, c1, c0, 0

     mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

     mov r0, #0
     mov pc, r9                      跳转到内核地址
    #endif
    /*
     *************************************************************************
     *
     * Interrupt handling
     *
     *************************************************************************
     */
    @
    @ IRQ stack frame.
    @
    #define S_FRAME_SIZE 72

    #define S_OLD_R0 68
    #define S_PSR  64
    #define S_PC  60
    #define S_LR  56
    #define S_SP  52

    #define S_IP  48
    #define S_FP  44
    #define S_R10  40
    #define S_R9  36
    #define S_R8  32
    #define S_R7  28
    #define S_R6  24
    #define S_R5  20
    #define S_R4  16
    #define S_R3  12
    #define S_R2  8
    #define S_R1  4
    #define S_R0  0

    #define MODE_SVC 0x13
    #define I_BIT  0x80

    /*                                                     定义异常时保存寄存器的宏
     * use bad_save_user_regs for abort/prefetch/undef/swi ...
     * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
     */

     .macro bad_save_user_regs
     sub sp, sp, #S_FRAME_SIZE  @ carve out a frame on current user stack
     stmia sp, {r0 - r12}   @ Save user registers (now in svc mode) r0-r12

     ldr r2, _armboot_start
     sub r2, r2, #(CFG_MALLOC_LEN)
     sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
     ldmia r2, {r2 - r3}   @ get values for "aborted" pc and cpsr (into parm regs)
     add r0, sp, #S_FRAME_SIZE  @ grab pointer to old stack

     add r5, sp, #S_SP
     mov r1, lr
     stmia r5, {r0 - r3}   @ save sp_SVC, lr_SVC, pc, cpsr
     mov r0, sp    @ save current stack into r0 (param register)
     .endm

     .macro irq_save_user_regs
     sub sp, sp, #S_FRAME_SIZE
     stmia sp, {r0 - r12}   @ Calling r0-r12
     add r8, sp, #S_PC   @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
     stmdb r8, {sp, lr}^   @ Calling SP, LR
     str lr, [r8, #0]   @ Save calling PC
     mrs r6, spsr
     str r6, [r8, #4]   @ Save CPSR
     str r0, [r8, #8]   @ Save OLD_R0
     mov r0, sp
     .endm

     .macro irq_restore_user_regs
     ldmia sp, {r0 - lr}^   @ Calling r0 - lr
     mov r0, r0
     ldr lr, [sp, #S_PC]   @ Get PC
     add sp, sp, #S_FRAME_SIZE
     subs pc, lr, #4   @ return & move spsr_svc into cpsr
     .endm

     .macro get_bad_stack
     ldr r13, _armboot_start  @ setup our mode stack (enter in banked mode)
     sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool
     sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack

     str lr, [r13]   @ save caller lr in position 0 of saved stack
     mrs lr, spsr   @ get the spsr
     str lr, [r13, #4]   @ save spsr in position 1 of saved stack

     mov r13, #MODE_SVC   @ prepare SVC-Mode
     @ msr spsr_c, r13
     msr spsr, r13   @ switch modes, make sure moves will execute
     mov lr, pc    @ capture return pc
     movs pc, lr    @ jump to next instruction & switch modes.
     .endm

     .macro get_bad_stack_swi
     sub r13, r13, #4   @ space on current stack for scratch reg.
     str r0, [r13]   @ save R0's value.
     ldr r0, _armboot_start  @ get data regions start
     sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool
     sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
     str lr, [r0]   @ save caller lr in position 0 of saved stack
     mrs r0, spsr   @ get the spsr
     str lr, [r0, #4]   @ save spsr in position 1 of saved stack
     ldr r0, [r13]   @ restore r0
     add r13, r13, #4   @ pop stack entry
     .endm

     .macro get_irq_stack   @ setup IRQ stack
     ldr sp, IRQ_STACK_START
     .endm

     .macro get_fiq_stack   @ setup FIQ stack
     ldr sp, FIQ_STACK_START
     .endm

    /*
     * exception handlers                         异常处理句柄
     */
     .align 5
    undefined_instruction:
     get_bad_stack
     bad_save_user_regs
     bl do_undefined_instruction

     .align 5
    software_interrupt:
     get_bad_stack_swi
     bad_save_user_regs
     bl do_software_interrupt

     .align 5
    prefetch_abort:
     get_bad_stack
     bad_save_user_regs
     bl do_prefetch_abort

     .align 5
    data_abort:
     get_bad_stack
     bad_save_user_regs
     bl do_data_abort

     .align 5
    not_used:
     get_bad_stack
     bad_save_user_regs
     bl do_not_used

    #if defined(CONFIG_USE_IRQ)

     .align 5
    irq:
     get_irq_stack
     irq_save_user_regs
     bl do_irq
     irq_restore_user_regs

     .align 5
    fiq:
     get_fiq_stack
     /* someone ought to write a more effiction fiq_save_user_regs */
     irq_save_user_regs
     bl do_fiq
     irq_restore_user_regs

    #else

     .align 5
    irq:
     get_bad_stack
     bad_save_user_regs
     bl do_irq

     .align 5
    fiq:
     get_bad_stack
     bad_save_user_regs
     bl do_fiq

    #endif
     .align 5
    .global arm_cache_flush
    arm_cache_flush:
           mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
           mov     pc, lr                          @ back to caller

    /*
     *     v7_flush_dcache_all()
     *
     *     Flush the whole D-cache.
     *
     *     Corrupted registers: r0-r5, r7, r9-r11
     *
     *     - mm    - mm_struct describing address space
     */
           .align 5
    .global v7_flush_dcache_all
    v7_flush_dcache_all:

     ldr r0, =0xffffffff
     mrc p15, 1, r0, c0, c0, 1   @ Read CLIDR
     ands r3, r0, #0x7000000
     mov r3, r3, LSR #23         @ Cache level value (naturally aligned)
     beq  Finished
     mov r10, #0
    Loop1:        
     add r2, r10, r10, LSR #1    @ Work out 3xcachelevel
     mov r1, r0, LSR r2          @ bottom 3 bits are the Ctype for this level
     and r1, r1, #7              @ get those 3 bits alone
     cmp r1, #2
     blt Skip                     @ no cache or only instruction cache at this level
     mcr p15, 2, r10, c0, c0, 0   @ write the Cache Size selection register
     mov r1, #0
     mcr p15, 0, r1, c7, c5, 4   @ PrefetchFlush to sync the change to the CacheSizeID reg
     mrc p15, 1, r1, c0, c0, 0   @ reads current Cache Size ID register
     and r2, r1, #0x7             @ extract the line length field
     add r2, r2, #4              @ add 4 for the line length offset (log2 16 bytes)
     ldr r4, =0x3FF
     ands r4, r4, r1, LSR #3     @ R4 is the max number on the way size (right aligned)
     clz r5, r4                  @ R5 is the bit position of the way size increment
     ldr r7, =0x00007FFF
     ands r7, r7, r1, LSR #13    @ R7 is the max number of the index size (right aligned)
    Loop2:        
     mov r9, r4                       @ R9 working copy of the max way size (right aligned)
    Loop3:        
     orr r11, r10, r9, LSL r5         @ factor in the way number and cache number into R11
     orr r11, r11, r7, LSL r2         @ factor in the index number
     mcr p15, 0, r11, c7, c6, 2   @ invalidate by set/way
     subs r9, r9, #1                  @ decrement the way number
     bge Loop3
     subs r7, r7, #1                  @ decrement the index
     bge Loop2
    Skip:         
     add r10, r10, #2                 @ increment the cache number
     cmp r3, r10
     bgt Loop1
    Finished:
     mov pc, lr
     
           .align  5
    .global disable_l2cache
    disable_l2cache:
     mrc     p15, 0, r0, c1, c0, 1
     bic     r0, r0, #(1<<1)
     mcr     p15, 0, r0, c1, c0, 1
     mov pc, lr


           .align  5
    .global enable_l2cache
    enable_l2cache:
     mrc     p15, 0, r0, c1, c0, 1
     orr     r0, r0, #(1<<1)
     mcr     p15, 0, r0, c1, c0, 1
     mov     pc, lr

           .align  5
    .global set_l2cache_auxctrl
    set_l2cache_auxctrl:
     mov r0, #0x0
     mcr     p15, 1, r0, c9, c0, 2
     mov     pc, lr

           .align  5
    .global set_l2cache_auxctrl_cycle
    set_l2cache_auxctrl_cycle:
     mrc  p15, 1, r0, c9, c0, 2                   值0010_0000_0010_0000_0001_1100_0111?
     bic  r0, r0, #(0x1<<29)
     bic  r0, r0, #(0x1<<21)
     bic  r0, r0, #(0x7<<6)
     bic  r0, r0, #(0x7<<0)
     mcr  p15, 1, r0, c9, c0, 2
     mov     pc,lr

     .align 5
    CoInvalidateDCacheIndex:
     ;/* r0 = index */
     mcr     p15, 0, r0, c7, c6, 2
     mov     pc,lr


    #if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_CINTEGRATOR)
    /* Use the IntegratorCP function from board/integratorcp/platform.S */
    #elif defined(CONFIG_S5PC11X)
    /* For future usage of S3C64XX*/
    #else
     .align 5
    .globl reset_cpu
    reset_cpu:
     ldr r1, rstctl /* get addr for global reset reg */
     mov r3, #0x2 /* full reset pll+mpu */
     str r3, [r1] /* force reset */              复位CPU
     mov r0, r0
    _loop_forever:
     b _loop_forever
    rstctl:
     .word PM_RSTCTRL_WKUP

    #endif

  • 相关阅读:
    Shell基础
    不错的设计类网站
    win7旗舰版 OEM KEY
    js获取url参数值
    在ASP.Net中利用JS调用Aspx页面的输出
    Virtual Router – 为易用而生的虚拟WiFi热点 (虚拟路由器)
    php5.3.8安装体验
    WIN2003+IIS6+PHP5.3.8配置
    PHP环境一键安装包 ZkeysPHP
    诡异的apache RewriteCond %{REQUEST_FILENAME} !s问题
  • 原文地址:https://www.cnblogs.com/Efronc/p/2371662.html
Copyright © 2011-2022 走看看