📄 mmu.c
字号:
jtlb[Random].v1=(Entrylo1>>1)&(0x00000001);
itlb[0].v=0;
itlb[1].v=0;
itlb[2].v=0;
dtlb[0].v=0;
dtlb[1].v=0;
dtlb[2].v=0;
//printf("Entryhi=%08x Random=%08x\n",Entryhi,Random);
//printf("jtlb[Index].vpn2=%x Index=%08x jtlb[Index].asid=%x\n",jtlb[Index].vpn2,Index,jtlb[Index].asid);
break;
default: printf("tlb instruction type in mmu error!\n");
}
/*
if(ERL == 0){
//jtlb 0x40000000 to 0xc0000000
}else if(ERL == 1){
//jtlb 0x00000000 to 0x80000000
}else{
printf("ERL=%d, The value is error!\n",ERL);
}
*/
}
unsigned long addr_translate(unsigned long virtual_addr,unsigned instr_data_flag){
auto char temp_end;
unsigned long physical_address;
if(tlb_fm_flag == 0){
physical_address=tlb_addr_translate(virtual_addr,instr_data_flag);
}else if(tlb_fm_flag == 1){
physical_address=fm_addr_translate( virtual_addr);
}else{
printf("tlb_fm_flag=%d The value is error!\n",tlb_fm_flag);
scanf("%c",&temp_end);
if(temp_end){
exit(0);
}
}
return(physical_address);
}
unsigned long tlb_addr_translate(unsigned long virtual_addr,unsigned instr_data_flag){
auto char end;
unsigned long physical_addr;
unsigned long current_asid;
int tlb_hit,i;
tlb_dirty_bit_flag=0;
tlb_hit=0;
current_asid=Entryhi&(0x000000ff);
if(virtual_addr >= ((unsigned long)0xc0000000)){
physical_addr=virtual_addr;
}else if((virtual_addr >= ((unsigned long)0x80000000)) && (virtual_addr < ((unsigned long)0xa0000000))){
physical_addr=virtual_addr - (unsigned long)0x80000000;
}else if((virtual_addr >= ((unsigned long)0xa0000000)) && (virtual_addr < ((unsigned long)0xc0000000))){
// printf("addr_translate 0x%08x \n",virtual_addr);
physical_addr=virtual_addr - (unsigned long)0xa0000000;
}else{
//find in tlb
physical_addr=virtual_addr;
if(instr_data_flag == 0){
//find in itlb
for(i=0;i<3;i++){
if((itlb[i].v == 1)&&(itlb[i].vpn == ((virtual_addr>>12)&(0x000fffff)))&&((itlb[i].g == 1)||(itlb[i].asid == current_asid))){
physical_addr=itlb[i].pfn;
physical_addr=physical_addr<<12;
physical_addr=(physical_addr&(0xffff000))|(virtual_addr&(0x00000fff));
tlb_hit=1;
break;
}
}
if(tlb_hit == 0){
//itlb miss , find in jtlb
for(i=0;i<16;i++){
if((jtlb[i].vpn2 == ((virtual_addr>>13)&(0x0007ffff)))&&((jtlb[i].g == 1)||(jtlb[i].asid == current_asid))){
if(jtlb[i].v == 0){
exception_flag_ip=29; //tlbl general exception tlb invalid
}
physical_addr=(((virtual_addr>>12)&(0x00000001))== 0)? jtlb[i].pfn0 : jtlb[i].pfn1;
physical_addr=physical_addr<<12;
physical_addr=(physical_addr&(0xffff000))|(virtual_addr&(0x00000fff));
tlb_hit=1;
//refill to itlb
itlb[i%3].vpn=(virtual_addr>>12)&(0x000fffff);
itlb[i%3].g=jtlb[i].g;
itlb[i%3].asid=jtlb[i].asid;
itlb[i%3].pfn=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].pfn0 : jtlb[i].pfn1;
itlb[i%3].c_n=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].c0 :jtlb[i].c1;
itlb[i%3].d=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].d0 :jtlb[i].d1;
itlb[i%3].v=1;
break;
}
}
}
if(tlb_hit == 0){
//jtlb refill exception I step
if((Status&(0x00000002)) == 0){
Entryhi=Entryhi&(0x00001fff);
Entryhi=Entryhi|(virtual_addr&(0xffffe000));
Badvaddr=virtual_addr;
CPR[10]=Entryhi;
CPR[8]=Badvaddr;
exception_flag_ip=12;
ErrorEPC=pc_address_ip;
EPC=pc_address_ip;
CPR[30]=pc_address_ip;
CPR[14]=pc_address_ip;
}else{
exception_flag_ip=exception_flag_ip;
// exception_flag_ip=0;
/* printf("Jtlb refill exception!please input Enter key to exit:");
scanf("%c",&end);
if(end){
exit(0);
}*/
}
}
}else if(instr_data_flag == 1){
//find in dtlb
for(i=0;i<3;i++){
if((dtlb[i].v == 1)&&(dtlb[i].vpn == ((virtual_addr>>12)&(0x000fffff)))&&((dtlb[i].g == 1)||(dtlb[i].asid == current_asid))){
physical_addr=dtlb[i].pfn;
physical_addr=physical_addr<<12;
physical_addr=(physical_addr&(0xffff000))|(virtual_addr&(0x00000fff));
tlb_hit=1;
break;
}
}
if(tlb_hit == 0){
//dtlb miss , find in jtlb
for(i=0;i<16;i++){
if((jtlb[i].vpn2 == ((virtual_addr>>13)&(0x0007ffff)))&&((jtlb[i].g == 1)||(jtlb[i].asid == current_asid))){
if(jtlb[i].v == 0){
exception_flag_mp=30; //tlbs general exception tlb invalid
if(branch_flag_wp == 1){
ErrorEPC=pc_address_wp;
EPC=pc_address_wp;
CPR[30]=pc_address_wp;
CPR[14]=pc_address_wp;
}else{
ErrorEPC=pc_address_mp;
EPC=pc_address_mp;
CPR[30]=pc_address_mp;
CPR[14]=pc_address_mp;
}
}
physical_addr=(((virtual_addr>>12)&(0x00000001))== 0)? jtlb[i].pfn0 : jtlb[i].pfn1;
physical_addr=physical_addr<<12;
physical_addr=(physical_addr&(0xffff000))|(virtual_addr&(0x00000fff));
tlb_hit=1;
//refill to itlb
dtlb[i%3].vpn=(virtual_addr>>12)&(0x000fffff);
dtlb[i%3].g=jtlb[i].g;
dtlb[i%3].asid=jtlb[i].asid;
dtlb[i%3].pfn=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].pfn0 : jtlb[i].pfn1;
dtlb[i%3].c_n=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].c0 :jtlb[i].c1;
dtlb[i%3].d=((virtual_addr>>12)&(0x00000001) == 0)? jtlb[i].d0 :jtlb[i].d1;
dtlb[i%3].v=1;
if(dtlb[i%3].d == 0){
tlb_dirty_bit_flag=1;
}
break;
}
}
}
if(tlb_hit == 0){
//jtlb refill exception m step
if((Status&(0x00000002)) == 0){
Entryhi=Entryhi&(0x00001fff);
Entryhi=Entryhi|(virtual_addr&(0xffffe000));
Badvaddr=virtual_addr;
CPR[10]=Entryhi;
CPR[8]=Badvaddr;
exception_flag_mp=25;
printf("5555555555555555555555555555555\n");
if(branch_flag_wp == 1){
ErrorEPC=pc_address_wp;
EPC=pc_address_wp;
CPR[30]=pc_address_wp;
CPR[14]=pc_address_wp;
}else{
ErrorEPC=pc_address_mp;
EPC=pc_address_mp;
CPR[30]=pc_address_mp;
CPR[14]=pc_address_mp;
}
}else{
exception_flag_mp=0;
/* printf("Jtlb refill exception!please input Enter key to exit:");
scanf("%c",&end);
if(end){
exit(0);
}*/
}
}
}else{
printf("instr_data_flag=%d,The value is error!",instr_data_flag);
printf("please input Enter key to exit:");
scanf("%c",&end);
if(end){
exit(0);
}
}
}
return(physical_addr);
}
unsigned long fm_addr_translate(unsigned long virtual_addr){
unsigned long physical_addr;
auto char end;
unsigned long temp_flag;
temp_flag=(virtual_addr>>28)&(0x0000000f);
ERL=(Status>>2)&(0x00000001);
if(ERL == 0){
switch(temp_flag)
{case 0 : physical_addr=virtual_addr + 0x40000000; break;
case 1 : physical_addr=virtual_addr + 0x40000000; break;
case 2 : physical_addr=virtual_addr + 0x40000000; break;
case 3 : physical_addr=virtual_addr + 0x40000000; break;
case 4 : physical_addr=virtual_addr + 0x40000000; break;
case 5 : physical_addr=virtual_addr + 0x40000000; break;
case 6 : physical_addr=virtual_addr + 0x40000000; break;
case 7 : physical_addr=virtual_addr + 0x40000000; break;
case 8 : physical_addr=virtual_addr - 0x80000000; break;
case 9 : physical_addr=virtual_addr - 0x80000000; break;
case 10 : physical_addr=virtual_addr - 0xa0000000; break;
case 11 : physical_addr=virtual_addr - 0xa0000000; break;
case 12 : physical_addr=virtual_addr; break;
case 13 : physical_addr=virtual_addr; break;
case 14 : physical_addr=virtual_addr; break;
case 15 : physical_addr=virtual_addr; break;
default: printf("There is error when translating virtual address to physical address in fixed table!"); break;
}
}else if(ERL == 1){
switch(temp_flag)
{case 0 : physical_addr=virtual_addr; break;
case 1 : physical_addr=virtual_addr; break;
case 2 : physical_addr=virtual_addr; break;
case 3 : physical_addr=virtual_addr; break;
case 4 : physical_addr=virtual_addr; break;
case 5 : physical_addr=virtual_addr; break;
case 6 : physical_addr=virtual_addr; break;
case 7 : physical_addr=virtual_addr; break;
case 8 : physical_addr=virtual_addr - 0x80000000; break;
case 9 : physical_addr=virtual_addr - 0x80000000; break;
case 10 : physical_addr=virtual_addr - 0xa0000000; break;
case 11 : physical_addr=virtual_addr - 0xa0000000; break;
case 12 : physical_addr=virtual_addr; break;
case 13 : physical_addr=virtual_addr; break;
case 14 : physical_addr=virtual_addr; break;
case 15 : physical_addr=virtual_addr; break;
default: printf("There is error when translating virtual address to physical address in fixed table!"); break;
}
}else{
printf("ERL=%d The value is error! Please input enter key to exit:",ERL);
scanf("%c",&end);
if(end){
exit(0);
}
}
return(physical_addr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -