⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmu.c

📁 32cpu的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	                  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 + -