这个例子把dram以1M为单位进行平板映射,分3步:填充页表;无效cache和TLB;使能MMU。<br />(1)mem_mapping_linear()进行页表填充:<br />static inline void mem_mapping_linear(void)<br />{<br /> unsigned long pageoffset, sectionNumber;<br /><br /> putstr_hex('MMU table base address = 0x', (unsigned long)mmu_tlb_base);<br /> /* 4G, not cacacheable, not bufferable */<br /> for (sectionNumber = 0; sectionNumber < 4096; sectionNumber++) {<br /> pageoffset = (sectionNumber << 20);<br /> *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC;<br /> }<br /><br /> /* make dram cacheable */<br /> for (pageoffset = DRAM_BASE; pageoffset < (DRAM_BASE+DRAM_SIZE); pageoffset += SZ_1M) {<br /> /*DPRINTK(3, 'Make DRAM section cacheable: 0x%08lx<br />', pageoffset);*/<br /> *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC | MMU_CACHEABLE;<br /> } <br />} <br />(2)无效cache和TLB:<br />/*<br /> * cpu_arm920_cache_clean_invalidate_all()<br /> *<br /> * clean and invalidate all cache lines<br /> *<br /> */<br /><br />static inline void cpu_arm920_cache_clean_invalidate_all(void)<br />{<br />__asm__(<br /> ' mov r1, #0<br />'<br /> ' mov r1, #7 << 5<br />' /* 8 segments */<br /> '1: mov r3, #0<br />' /* added by lane 2004-06-15 */<br /> ' orr r3, r1,#63 << 26<br />' /* 64 entries */<br /> '2: mcr p15, 0, r3, c7, c14, 2<br />' /* clean & invalidate D index */<br /> ' subs r3, r3, #1 << 26<br />'<br /> ' bcs 2b<br />' /* entries 64 to 0 */<br /> ' subs r1, r1, #1 << 5<br />'<br /> ' bcs 1b<br />' /* segments 7 to 0 */<br /> ' mcr p15, 0, r1, c7, c5, 0<br />' /* invalidate I cache */<br /> ' mcr p15, 0, r1, c7, c10, 4<br />' /* drain WB */<br /> );<br />}<br /><br />void cache_clean_invalidate(void)<br />{<br /> cpu_arm920_cache_clean_invalidate_all();<br />}<br /><br />/*<br /> * cpu_arm920_tlb_invalidate_all()<br /> *<br /> * Invalidate all TLB entries<br /> */<br />static inline void cpu_arm920_tlb_invalidate_all(void)<br />{<br /> __asm__(<br /> 'mov r0, #0<br />'<br /> 'mcr p15, 0, r0, c7, c10, 4<br />' /* drain WB */<br /> 'mcr p15, 0, r0, c8, c7, 0<br />' /* invalidate I & D TLBs */<br /> );<br />}<br /><br />void tlb_invalidate(void)<br />{<br /> cpu_arm920_tlb_invalidate_all();<br />}<br />(3)使能MMU<br />static inline void arm920_setup(void)<br />{<br /> unsigned long ttb = MMU_TABLE_BASE;<br /><br />__asm__(<br /> /* Invalidate caches */<br /> 'mov r0, #0<br />'<br /> 'mcr p15, 0, r0, c7, c7, 0<br />' /* invalidate I,D caches on v4 */<br /> 'mcr p15, 0, r0, c7, c10, 4<br />' /* drain write buffer on v4 */<br /> 'mcr p15, 0, r0, c8, c7, 0<br />' /* invalidate I,D TLBs on v4 */<br /> /* Load page table pointer */<br /> 'mov r4, %0<br />'<br /> 'mcr p15, 0, r4, c2, c0, 0<br />' /* load page table pointer */<br /> /* Write domain id (cp15_r3) */<br /> 'mvn r0, #0<br />' /* Domains 0, 1 = client */<br /> 'mcr p15, 0, r0, c3, c0, 0<br />' /* load domain access register */<br /> /* Set control register v4 */<br /> 'mrc p15, 0, r0, c1, c0, 0<br />' /* get control register v4 */<br /> /* Clear out 'unwanted' bits (then put them in if we need them) */<br /> /* .RVI ..RS B... .CAM */<br /> 'bic r0, r0, #0x3000<br />' /* ..11 .... .... .... */<br /> 'bic r0, r0, #0x0300<br />' /* .... ..11 .... .... */<br /> 'bic r0, r0, #0x0087<br />' /* .... .... 1... .111 */<br /> /* Turn on what we want */<br /> /* Fault checking enabled */<br /> 'orr r0, r0, #0x0002<br />' /* .... .... .... ..1. */<br />#ifdef CONFIG_CPU_D_CACHE_ON<br /> 'orr r0, r0, #0x0004<br />' /* .... .... .... .1.. */<br />#endif<br />#ifdef CONFIG_CPU_I_CACHE_ON <br /> 'orr r0, r0, #0x1000<br />' /* ...1 .... .... .... */<br />#endif<br /> /* MMU enabled */<br /> 'orr r0, r0, #0x0001<br />' /* .... .... .... ...1 */<br /> 'mcr p15, 0, r0, c1, c0, 0<br />' /* write control register */<br /> : /* no outputs */<br /> : 'r' (ttb) );<br />}<br /> <br /> <br /> |
|