📄 mmu.c~
字号:
#include "s3c2410.h"#include "mmu.h"static unsigned long *mmu_tlb_base = (unsigned long *) MMU_TABLE_BASE;/***************************************************************************** 段页表项entry:[31:20]段基址,[11:10]为AP(控制访问权限),[8:5]域,* [3:2]=CP(decide cached&buffered),[1:0]=0b10-->页表项为段描述符* MMU_SECDESC:* AP=0b11* DOMAIN=0* [1:0]=0b10--->页表项为段描述符* MMU_CACHEABLE:* C=1(bit[3])*1. 将页表放在SDRAM 开始处,即:MMU_TABLE_BASE = 0x3000000(in mmu.h)*2. 对于64M SDRAM,其物理地址为0x30000000-0x33f00000,令其虚拟地址=物理地址*3. 对于SFR,其物理地址为0x48000000-0x60000000,令其虚拟地址等于物理地址(请参考数据手册P192)*4. exception vector:虚拟地址0xffff0000,物理地址0x33f000000*5. 进程号为PID的进程空间块的虚拟地址为:PID*0x02000000到PID*0x02000000+0x01ffffff*6. 进程0物理地址:0x30000000-0x300fffff*7. 进程1物理地址:0x30100000-0x301fffff*8. 进程2物理地址:0x30200000-0x302fffff*9. .... ....*10.进程62物理地址:0x33e00000-0x33efffff*******************************************************************************/void mmu_tlb_init(){ unsigned long entry_index; /*SDRAM*/ for(entry_index = SDRAM_BASE ; entry_index < SDRAM_BASE+SDRAM_SIZE; entry_index += 0x100000){ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+(entry_index>>20)) = entry_index |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; } /*SFR*/ for(entry_index = 0x48000000; entry_index < 0x60000000; entry_index += 0x100000){ /*section table's entry:AP=0b11,domain=0,NCNB*/ *(mmu_tlb_base+(entry_index>>20)) = entry_index |(0x03<<10)|(0<<5)|(1<<4)| 0x02; } /*进程1-23,25-35,48-62*/ for(entry_index = 1; entry_index < 24; entry_index++){ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+((entry_index*0x02000000)>>20)) = (entry_index*0x00100000+SDRAM_BASE) |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; } for(entry_index = 25; entry_index < 36; entry_index++){ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+((entry_index*0x02000000)>>20)) = (entry_index*0x00100000+SDRAM_BASE) |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; } for(entry_index = 48; entry_index < TASK_NR; entry_index++){ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+((entry_index*0x02000000)>>20)) = (entry_index*0x00100000+SDRAM_BASE) |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; } /*exception vector*/ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+(0xffff0000>>20)) = (VECTORS_PHY_BASE) |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; /*SDRAM_RAW_RW_VA_BASE开始的64M虚拟地址*/ /*大于32M,所以不需要经过PID转换即可访问物理内存*/ /*用于在不同进程中从nand flash中复制代码到内存,以及从其他进程访问另一个进程的空间*/ for(entry_index = SDRAM_RAW_RW_VA_BASE; entry_index < SDRAM_RAW_RW_VA_BASE + SDRAM_SIZE; entry_index += 0x100000){ /*section table's entry:AP=0b11,domain=0,Cached,write-through mode(WT)*/ *(mmu_tlb_base+((entry_index)>>20)) = (entry_index-SDRAM_RAW_RW_VA_BASE+SDRAM_BASE) |(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02; }}/**************************************************************************** 1.Invalidate I,D caches,drain write buffer,invalidate I,D TLBS* 2.Load page table pointer* 3.Write domain ID* 4.Set MMU control registers(read-modify-write):* a.read: mrc p15, 0, r0, c1, c0, 0* b.modify:* bit[13]=0,异常向量起始地址为0x00000000* bit[12]=0,Instruction cache disable* bit[9:8]=0b00,RS=0b00(因为页表中AP=0b11,所以RS的作用忽略)* bit[7]=0,Little-endian operation* bit[2]=0b000,Data cache disabel* bit[1:0]=0b11,Data alignment checking enable,MMU enable* c.write: mcr p15, 0, r0, c1, c0, 0***************************************************************************/void mmu_init(){ unsigned long ttb = MMU_TABLE_BASE;__asm__( "mov r0, #0\n" /* invalidate I,D caches on v4 */ "mcr p15, 0, r0, c7, c7, 0\n" /* drain write buffer on v4 */ "mcr p15, 0, r0, c7, c10, 4\n" /* invalidate I,D TLBs on v4 */ "mcr p15, 0, r0, c8, c7, 0\n" /* Load page table pointer */ "mov r4, %0\n" "mcr p15, 0, r4, c2, c0, 0\n" /* Write domain id (cp15_r3) */ "mvn r0, #0\n" /*0b11=Manager*/ "mcr p15, 0, r0, c3, c0, 0\n" /* Set control register v4 */ "mrc p15, 0, r0, c1, c0, 0\n" /* Clear out 'unwanted' bits (then put them in if we need them) */ "ldr r1, =0x1384\n" "bic r0, r0, r1\n" /* Turn on what we want */ /*Base location of exceptions = 0xffff0000*/ "orr r0, r0, #0x2000\n" /* Fault checking enabled */ "orr r0, r0, #0x0002\n"#ifdef CONFIG_CPU_D_CACHE_ON /*is not set*/ "orr r0, r0, #0x0004\n"#endif #ifdef CONFIG_CPU_I_CACHE_ON /*is not set*/ "orr r0, r0, #0x1000\n"#endif /* MMU enabled */ "orr r0, r0, #0x0001\n" /* write control register *//*write control register P545*/ "mcr p15, 0, r0, c1, c0, 0\n" : /* no outputs */ : "r" (ttb) ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -