1 /*
  2  * Setup common bits before finally enabling the MMU.  Essentially
  3  * this is just loading the page table pointer and domain access
  4  * registers.
  5  *
  6  *  r0  = cp#15 control register
  7  *  r1  = machine ID
  8  *  r2  = atags or dtb pointer
  9  *  r4  = page table pointer
 10  *  r9  = processor ID
 11  *  r13 = *virtual* address to jump to upon completion
 12  */
 13 __enable_mmu:
 14 #if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
 15     orr    r0, r0, #CR_A
 16 #else
 17     bic    r0, r0, #CR_A
 18 #endif
 19 #ifdef CONFIG_CPU_DCACHE_DISABLE
 20     bic    r0, r0, #CR_C
 21 #endif
 22 #ifdef CONFIG_CPU_BPREDICT_DISABLE
 23     bic    r0, r0, #CR_Z
 24 #endif
 25 #ifdef CONFIG_CPU_ICACHE_DISABLE
 26     bic    r0, r0, #CR_I
 27 #endif
 28 #ifdef CONFIG_ARM_LPAE
 29     mov    r5, #0
 30     mcrr    p15, 0, r4, r5, c2                              @ load TTBR0
 31 #else
 32     mov    r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
 33               domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 34               domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 35               domain_val(DOMAIN_IO, DOMAIN_CLIENT))
 36     mcr    p15, 0, r5, c3, c0, 0                            @ domain0(DOMAIN_MANAGER):DOMAIN_KERNEL,DOMAIN_TABLE
 37                                                             @ domain1(DOMAIN_MANAGER):DOMAIN_USER
 38                                                             @ domain2(DOMAIN_CLIENT):DOMAIN_IO
 39     mcr    p15, 0, r4, c2, c0, 0                            @ r4=0x40004000(设置页目录表的起始地址,为开启mmu做准备)
 40 #endif
 41     b    __turn_mmu_on
 42 ENDPROC(__enable_mmu)
 43 
 44 /*
 45  * Enable the MMU.  This completely changes the structure of the visible
 46  * memory space.  You will not be able to trace execution through this.
 47  * If you have an enquiry about this, *please* check the linux-arm-kernel
 48  * mailing list archives BEFORE sending another post to the list.
 49  *
 50  *  r0  = cp#15 control register
 51  *  r1  = machine ID
 52  *  r2  = atags or dtb pointer
 53  *  r9  = processor ID
 54  *  r13 = *virtual* address to jump to upon completion
 55  *
 56  * other registers depend on the function called upon completion
 57  */
 58     .align    5
 59     .pushsection    .idmap.text, "ax"
 60 ENTRY(__turn_mmu_on)
 61     mov    r0, r0
 62     instr_sync
 63             @\
 64             @======================================================
 65             @/*
 66             @ * Instruction barrier(内存屏障)
 67             @ */
 68             @    .macro    instr_sync
 69             @#if __LINUX_ARM_ARCH__ >= 7
 70             @    isb
 71             @#elif __LINUX_ARM_ARCH__ == 6
 72             @    mcr    p15, 0, r0, c7, c5, 4         @ 清空预取缓冲区
 73             @#endif
 74             @    .endm
 75             @======================================================
 76     mcr    p15, 0, r0, c1, c0, 0                      @ 写 control 寄存器
 77     mrc    p15, 0, r3, c0, c0, 0                      @ 读 main id 寄存器
 78     instr_sync
 79     mov    r3, r3
 80     mov    r3, r13                                    @ 这里就是在1 head.S中提到的用到事先存放的r13的地方
 81     mov    pc, r3                                     @ 进行跳转到 __mmap_switched,请参考下面下方内容(*)
 82 __turn_mmu_on_end:
 83 ENDPROC(__turn_mmu_on)
 84     .popsection
 85 
 86 @ (*) 从这里到末尾部分是mov pc, r3以后的代码
 87 @==============================================================================================================
 88 /*
 89  * The following fragment of code is executed with the MMU on in MMU mode,
 90  * and uses absolute addresses; this is not position independent.
 91  *
 92  *  r0  = cp#15 control register
 93  *  r1  = machine ID
 94  *  r2  = atags/dtb pointer
 95  *  r9  = processor ID
 96  */
 97     __INIT
 98 __mmap_switched:
 99     adr    r3, __mmap_switched_data                    @ r3=__mmap_switched_data(phys)
100 
101     ldmia    r3!, {r4, r5, r6, r7}                     @ r4=__data_loc r5=_sdata r6=__bss_start r7=_end
102                                                        @ ex: r4=0xc02ce000 r5=0xc02ce000 r6=0xc02e6000 r7=0xc10a8c38
103     cmp    r4, r5                                      @ copy data segment if needed
104 1:    cmpne    r5, r6
105     ldrne    fp, [r4], #4
106     strne    fp, [r5], #4
107     bne    1b
108 
109     mov    fp, #0                                      @ clear BSS (and zero fp)
110 1:    cmp    r6, r7
111     strcc    fp, [r6],#4
112     bcc    1b
113 
114  ARM(    ldmia    r3, {r4, r5, r6, r7, sp})            @ 依次装载.long中的各种地址,准备存放各类值
115  THUMB(    ldmia    r3, {r4, r5, r6, r7}    )
116  THUMB(    ldr    sp, [r3, #16]        )
117     str    r9, [r4]                                    @ Save processor ID
118     str    r1, [r5]                                    @ Save machine type
119     str    r2, [r6]                                    @ Save atags pointer
120     bic    r4, r0, #CR_A                               @ Clear 'A' bit
121     stmia    r7, {r0, r4}                              @ Save control register values
122     b    start_kernel                                  @ 跳到第一个c函数,进入第二阶段,具体参考"2 start_kernel"
123 ENDPROC(__mmap_switched)
124 
125     .align    2
126     .type    __mmap_switched_data, %object
127 __mmap_switched_data:
128     .long    __data_loc                                @ r4
129     .long    _sdata                                    @ r5
130     .long    __bss_start                               @ r6
131     .long    _end                                      @ r7
132     .long    processor_id                              @ r4
133     .long    __machine_arch_type                       @ r5
134     .long    __atags_pointer                           @ r6
135     .long    cr_alignment                              @ r7
136     .long    init_thread_union + THREAD_START_SP       @ sp
137     .size    __mmap_switched_data, . - __mmap_switched_data
138 @==============================================================================================================

 

posted on 2013-08-27 21:40  choi87  阅读(1243)  评论(0)    收藏  举报