#define COARSE_FLAGS (1 | (1 << 4) ) //bit(1,0) = 01 coarse page base,
#define SMALL_MEM_FLAGS (2 | (1 << 2) | ( 1 << 3)) //bit(1,0) = 10 4KB page, bit(3,2) = 11 write back cacheable
#define SMALL_IO_FLAGS (2 ) //bit(1,0) = 10 4KB page, bit(3,2) = 00 nocached nobuffered
(*printf)(char *, ...) = 0x33f95964;
/*
*前面0地址开始的4KB + 0x30000000开始的64MB
*
*1个一级页项表对应256个二级页表项
*
*1个二级页表项对应1个页帧
*
*1个页帧4KB
*
*/
#define TTB 0x32000000; //ttb基址,也是一级页目录表基址
#define TTB_L2 (0x32000000 + 0x4000) //二级页表基址, 给一级页表留足16KB
unsigned long *ttb = (void *)TTB;
unsigned long *ttb_l2 = (void *)TTB_L2;
void memset(char *dst, char ch, int size);
void _start(void)
{
unsigned long c1_flags;
unsigned long virt, phys, temp, addr;
int *p;
memset(ttb, 0x00, 4096 * 4);
c1_flags = 1 | (1 << 1) | (0xf << 3) | (0x3 << 30); //bit0 = 1 MMU enable,bit1 = 1 fault check, bit6..3 = 0xf write, bit31,30 = 0x3 async clock mode
/*第一个4KB, 第一页*/
ttb[0] = ((unsigned long)ttb_l2) | COARSE_FLAGS;
ttb_l2[0] = 0 | SMALL_MEM_FLAGS;
ttb_l2 = TTB_L2 + 256 * 4;
/*线性地址空间[0x30000000, 0x34000000] 映射到物理地址空间[0x30000000, 0x34000000]*/
for (addr = 0x30000000; addr < 0x34000000; ttb_l2 += 256) {
ttb[addr >> 20] = ((unsigned long )ttb_l2 & 0xfffffc00) | COARSE_FLAGS;
temp = addr + 0x100000; //限定处理1MB空间对应的页表
for (; addr < temp; addr += 0x1000) {
ttb_l2[(addr & 0xff000) >> 12] = (addr & 0xfffff000) | SMALL_MEM_FLAGS;
}
}
/*线性地址空间[0x48000000, 0x60000000] 映射到物理地址空间[0x48000000, 0x60000000]*/
for (addr = 0x48000000; addr < 0x60000000; ttb_l2 += 256) {
ttb[addr >> 20] = ((unsigned long)ttb_l2 & 0xfffffc00) | COARSE_FLAGS;
temp = addr + 0x100000; //限定处理1MB空间对应的页表
for (; addr < temp; addr += 0x1000) {
ttb_l2[(addr & 0xff000) >> 12] = (addr & 0xfffff000) | SMALL_IO_FLAGS;
}
}
/*线性地址空间[0xc0000000, 0xc4000000] 映射到物理地址空间[0x30000000, 0x34000000]*/
for (virt = 0xc0000000; virt < 0xc4000000; ttb_l2 += 256) {
ttb[virt >> 20] = ((unsigned long )ttb_l2 & 0xfffffc00) | COARSE_FLAGS;
temp = virt + 0x100000; //每一个一级页表项限定处理1MB空间对应的页表
for (; virt < temp; virt += 0x1000) {
phys = virt - 0xc0000000 + 0x30000000; //虚拟地址与物理地址之间的关系
ttb_l2[(virt & 0xff000) >> 12] = (phys & 0xfffff000) | SMALL_MEM_FLAGS;
}
}
//------------------------------------------
__asm__ __volatile__ (
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c7, 0\n" //清除I-cache和D-cache的内容:
"mcr p15, 0, r0, c8, c7, 0\n" //清除I & D TLB 的内容
"mvn r0, #0\n"
"mcr p15, 0, r0, c3, c0, 0\n" //clear Domain access control
//--------------------------------
"mcr p15, 0, %1, c2, c0, 0\n" //ttb写入c2
"mcr p15, 0, %0, c1, c0, 0\n" //c1_flags写入c1
:
: "r" (c1_flags), "r" (ttb)
: "r0"
);
/*先看初始值*/
virt = 0x30130000;
printf("0x30130000 = %x\n", *(int *)virt);
virt = 0xc0130000;
printf("0xc0130000 = %x\n", *(int *)virt);
/*修改0x30130000地址处的值, 再看0xc0130000处的值*/
virt = 0x30130000;
*(int *)virt = 0x2222;
virt = 0xc0130000;
printf("0xc0130000 = %x\n", *(int *)virt);
/*修改0x30130000地址处的值, 再看0xc0130000处的值*/
virt = 0x30130000;
*(int *)virt = 0x3333;
virt = 0xc0130000;
printf("0xc0130000 = %x\n", *(int *)virt);
}
void memset(char *dst, char ch, int size)
{
int i;
for (i = 0; i < size; i ++) {
dst[i] = ch;
}
}
|