📄 cache.c
字号:
#include <stdio.h>
unsigned long load_instruction(unsigned long virtual_addr);
unsigned long addr_translate(unsigned long virtual_addr);
long load_align(unsigned long virtual_addr, long data_in, unsigned data_width);
long store_align(unsigned long virtual_addr,long data_store,long data_old,unsigned data_width);
long load_data(unsigned long virtual_addr,unsigned data_width);
long store_data(unsigned long virtual_addr,long data_in,unsigned data_width);
extern instr_out[10000];
extern instr_out_1[10000];
extern instr_out_2[10000];
extern mem_data[1000][2];
extern *mem_data_fp;
extern unsigned long sysad_addr;
extern long sysad_data[4];
extern long GPR[32],CPR[34];
extern FILE *lf_fp_code,*reg_trace_fp,*pc_trace_fp,*sysad_trace_fp;
extern unsigned long pc_address_ip,pc_address_dp,pc_address_ep,pc_address_mp,pc_address_wp;
extern int tlb_dirty_bit_flag;
//extern long Watchhi,Watchlo,Entryhi;
//extern long Index,Random,Entrylo0,Entrylo1,Context,Pagemask,Wired,Badvaddr,Count,Entryhi,Compare,Status,Cause,EPC,Processor_Identification,Config,Config1,Load_Linked_Address,Watchlo,Watchhi,Errctl,Taglo,Datalo,ErrorEPC,Desave;
extern long Index;
extern long Random;
extern long Entrylo0;
extern long Entrylo1;
extern long Context;
extern long Pagemask;
extern long Wired;
extern long Badvaddr;
extern long Count;
extern long Entryhi;
extern long Compare;
extern long Status;
extern long Cause;
extern long EPC;
extern long Processor_Identification;
extern long Config;
extern long Config1;
extern long Load_Linked_Address;
extern long Watchlo;
extern long Watchhi;
extern long Errctl;
extern long Taglo;
extern long Datalo;
extern long ErrorEPC;
extern long Desave;
extern int exception_flag_ip,exception_flag_mp;
void biu(unsigned long read_write_flag);
struct cache_data
{
unsigned pa : 20;
unsigned valid : 4;
unsigned l : 1;
unsigned lrf :1;
unsigned long word0;
unsigned long word1;
unsigned long word2;
unsigned long word3;
}icache_data[256],dcache_data[256];
unsigned long icache(unsigned long virtual_addr,unsigned read_invalidate_flag){
int i;
auto char except;
unsigned long load_instr,condition0,condition1;
if((virtual_addr&(0x00000003)) != 0){
exception_flag_ip=11;
Badvaddr=virtual_addr;
EPC=virtual_addr;
CPR[8]=Badvaddr;
CPR[14]=EPC;
ErrorEPC=virtual_addr;
CPR[30]=virtual_addr;
}
if(read_invalidate_flag == 0){
condition0=((Watchlo>>2)&(0x00000001)) && ((Watchhi>>30)&(0x00000001)) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
condition1=((Watchlo>>2)&(0x00000001)) && (((Watchhi>>30)&(0x00000001)) == 0) && (((Watchhi>>16)&(0x000000ff))==(Entryhi&(0x000000ff))) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
if(condition0 ||condition1){
if((Status&(0x00000006)) == 0){
//both EXL and ERL are zero ,Watch exception happen
exception_flag_ip=10;
ErrorEPC=virtual_addr;
EPC=virtual_addr;
CPR[30]=virtual_addr;
CPR[14]=virtual_addr;
}else{
Cause=Cause|(0x00400000);
}
}
if((virtual_addr >= 0xa0000000)&&(virtual_addr <= 0xbfffffff)){
//uncache address
sysad_addr=addr_translate(virtual_addr,0);
biu(0);
switch(((virtual_addr>>2)&(0x00000003)))
{
case 0 : load_instr=sysad_data[0]; break;
case 1 : load_instr=sysad_data[1]; break;
case 2 : load_instr=sysad_data[2]; break;
case 3 : load_instr=sysad_data[3]; break;
default : printf("icache word select error!\n");
}
return(load_instr);
}else{
//cache address
if((icache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].pa == ((addr_translate(virtual_addr,0)>>12)&(0x000fffff)))&&(icache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].valid == 15)){
#ifdef DEBUG
printf("icache hit! 0x%08x \n",virtual_addr);
#endif
return(load_instruction(virtual_addr));
}else{
#ifdef DEBUG
printf("icache miss! 0x%08x \n",virtual_addr);
#endif
sysad_addr=addr_translate(virtual_addr,0);
biu(0);
icache_data[(virtual_addr>>4)&(0x000000ff)].word0=sysad_data[0];
icache_data[(virtual_addr>>4)&(0x000000ff)].word1=sysad_data[1];
icache_data[(virtual_addr>>4)&(0x000000ff)].word2=sysad_data[2];
icache_data[(virtual_addr>>4)&(0x000000ff)].word3=sysad_data[3];
icache_data[(virtual_addr>>4)&(0x000000ff)].pa=((addr_translate(virtual_addr,0)>>12)&(0x000fffff));
icache_data[(virtual_addr>>4)&(0x000000ff)].valid=15;
return(load_instruction(virtual_addr));
}
}
}else if(read_invalidate_flag == 2){
//index invalidate icache
icache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].valid=0;
return((unsigned long)(virtual_addr>>4)&(0x000000ff));
}else if(read_invalidate_flag == 3){
//hit invalidate icache
if((icache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].pa == ((addr_translate(virtual_addr,0)>>12)&(0x000fffff)))){
icache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].valid=0;
return((unsigned long)(virtual_addr>>4)&(0x000000ff));
}else{
return(0);
}
}else{
printf("read_invalidate_flag error when call icache function!\n");
}
}
unsigned long load_instruction(unsigned long virtual_addr){
switch(((virtual_addr>>2)&(0x00000003)))
{
case 0 : return(icache_data[(virtual_addr>>4)&(0x000000ff)].word0); break;
case 1 : return(icache_data[(virtual_addr>>4)&(0x000000ff)].word1); break;
case 2 : return(icache_data[(virtual_addr>>4)&(0x000000ff)].word2); break;
case 3 : return(icache_data[(virtual_addr>>4)&(0x000000ff)].word3); break;
default : printf("icache word select error!\n");
}
}
long dcache(unsigned long virtual_addr,long data_in,unsigned data_width,unsigned read_write_flag){
auto char except;
unsigned long condition0,condition1;
if(read_write_flag == 0){
//load data from dcache
condition0=((Watchlo>>1)&(0x00000001)) && ((Watchhi>>30)&(0x00000001)) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
condition1=((Watchlo>>1)&(0x00000001)) && (((Watchhi>>30)&(0x00000001)) == 0) && (((Watchhi>>16)&(0x000000ff))==(Entryhi&(0x000000ff))) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
if(condition0 || condition1){
if((Status&(0x00000006)) == 0){
//both EXL and ERL are zero ,Watch exception happen
exception_flag_mp=21;
ErrorEPC=pc_address_mp;
EPC=pc_address_mp;
CPR[30]=pc_address_mp;
CPR[14]=pc_address_mp;
}else{
Cause=Cause|(0x00400000);
}
return(load_data(virtual_addr,data_width));
/* printf("Watch exception occur! Please input enter key to exit:");
scanf("%c",&except);
if(except){
exit(0);
}*/
}else{
return(load_data(virtual_addr,data_width));
}
}else if(read_write_flag == 1){
//store data to dcache
condition0=((Watchlo)&(0x00000001)) && ((Watchhi>>30)&(0x00000001)) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
condition1=((Watchlo)&(0x00000001)) && (((Watchhi>>30)&(0x00000001)) == 0) && (((Watchhi>>16)&(0x000000ff))==(Entryhi&(0x000000ff))) && (((Watchlo>>12)&(0x000fffff))==((virtual_addr>>12)&(0x000fffff))) && (((Watchhi>>3)&(0x00000001))||(((Watchlo>>3)&(0x00000001))==((virtual_addr>>3)&(0x00000001)))) && (((Watchhi>>4)&(0x00000001))||(((Watchlo>>4)&(0x00000001))==((virtual_addr>>4)&(0x00000001)))) && (((Watchhi>>5)&(0x00000001))||(((Watchlo>>5)&(0x00000001))==((virtual_addr>>5)&(0x00000001)))) && (((Watchhi>>6)&(0x00000001))||(((Watchlo>>6)&(0x00000001))==((virtual_addr>>6)&(0x00000001)))) && (((Watchhi>>7)&(0x00000001))||(((Watchlo>>7)&(0x00000001))==((virtual_addr>>7)&(0x00000001)))) && (((Watchhi>>8)&(0x00000001))||(((Watchlo>>8)&(0x00000001))==((virtual_addr>>8)&(0x00000001)))) && (((Watchhi>>9)&(0x00000001))||(((Watchlo>>9)&(0x00000001))==((virtual_addr>>9)&(0x00000001)))) && (((Watchhi>>10)&(0x00000001))||(((Watchlo>>10)&(0x00000001))==((virtual_addr>>10)&(0x00000001)))) && (((Watchhi>>11)&(0x00000001))||(((Watchlo>>11)&(0x00000001))==((virtual_addr>>11)&(0x00000001))));
if(condition0 || condition1){
if((Status&(0x00000006)) == 0){
//both EXL and ERL are zero ,Watch exception happen
exception_flag_mp=21;
ErrorEPC=pc_address_mp;
EPC=pc_address_mp;
CPR[30]=pc_address_mp;
CPR[14]=pc_address_mp;
}else{
Cause=Cause|(0x00400000);
}
return(0x00000000);
/* printf("Watch exception occur! Please input enter key to exit:");
scanf("%c",&except);
if(except){
exit(0);
}*/
}else{
return(store_data(virtual_addr,data_in,data_width));
}
}else if(read_write_flag == 2){
//index invalidate dcache
dcache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].valid=0;
return(0x00000000);
printf("dcache invalidate\n");
}else if(read_write_flag == 3){
//hit invalidate dcache
if((dcache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].pa == ((addr_translate(virtual_addr,1)>>12)&(0x000fffff)))){
dcache_data[(unsigned long)(virtual_addr>>4)&(0x000000ff)].valid=0;
}
return(0x00000000);
}else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -