📄 c401x.c
字号:
/************************************************************* * File: c401x.c * Purpose: provide 401x-specific routines for PMON * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970515 Created using code from bsps/401x.c */#ifndef LR4010#define LR4010#endif#include <pmon.h>#include <mips.h>#define ONLY_FLUSH_WHEN_NEEDED /* optimize the flushes */#define VALID_BIT (1<<1)#define BUGFIX /* needed for 4010 */int ilock_active;extern int iflush_needed;extern int dflush_needed;extern int verbose;extern int icache_size;extern int cache_line_size;/************************************************************** Ulong readCache401x(set,what,addr)* read one word from a cache* what: ICACHETAG DCACHETAG ICACHERAM DCACHERAM* Note that *all* LDs and STs go to the cache when ISC is set.*/Ulong readCache401x(set,what,addr)int set,what;Ulong addr;{Ulong ccc,tmpcfg,tag;/* we are already in an isr with ints disabled *//* the instr buffer is in kseg1 */tmpcfg = ccc = read_target(XT_CP0,C0_CCC,0);tmpcfg &= ~(CCC_IE1|CCC_IE0|CCC_DE0|CCC_DE1);tmpcfg |= CCC_ISC;if (what == ICACHETAG || what == DCACHETAG) tmpcfg |= CCC_TAG;if (what == ICACHETAG || what == ICACHERAM) { if (set) tmpcfg |= CCC_IE1; else tmpcfg |= CCC_IE0; }else if (what == DCACHETAG || what == DCACHERAM) { if (set) tmpcfg |= CCC_DE1; else tmpcfg |= CCC_DE0; }return specialRead401x(addr,tmpcfg);}/************************************************************** writeCache401x(set,what,addr,tag)* UNTESTED*/writeCache401x(set,what,addr,tag)int set,what;Ulong addr,tag;{Ulong ccc,tmpcfg;/* we are already in an isr with ints disabled *//* the instr buffer is in kseg1 */tmpcfg = ccc = read_target(XT_CP0,C0_CCC,0);tmpcfg &= ~(CCC_IE1|CCC_IE0|CCC_DE0|CCC_DE1);tmpcfg |= CCC_ISC;if (what == ICACHETAG || what == DCACHETAG) tmpcfg |= CCC_TAG;if (what == ICACHETAG || what == ICACHERAM) { if (set) tmpcfg |= CCC_IE1; else tmpcfg |= CCC_IE0; }else if (what == DCACHETAG || what == DCACHERAM) { if (set) tmpcfg |= CCC_DE1; else tmpcfg |= CCC_DE0; }#if 0writeGpr(8,tmpcfg);send_instr(MTC0(8,C0_CCC)); /* 3 nops before ld or st */send_instr(0);send_instr(0);send_instr(0);/* write the cache */writeGpr(8,tag);writeGpr(9,addr);send_instr(SW(8,0,9));send_instr(0);/* restore CCC */writeGpr(8,ccc);send_instr(MTC0(8,C0_CCC));readA0();#endif}/**************************************************************/Optdesc cache_opts401x[] = { {"[-idv][set [addr]]","display cache"}, {"set","select set (default 0)"}, {"addr","specify address"}, {"-i","display icache"}, {"-d","display dcache (default)"}, {"-v","display only valid entries"}, {0}};do_cache401x(ac,av)int ac;char *av[];{int n,i,j,set,vflag,iflag;int cacheram,cachetag;static Ulong next_adr;Ulong adr,tag,ccc;vflag = iflag = 0;for (n=0,i=1;i<ac;i++) { if (av[i][0] == '-') { if (strequ(av[i],"-v")) vflag = 1; else if (strequ(av[i],"-i")) iflag = 1; else if (strequ(av[i],"-d")) iflag = 0; else { printf("%s: unknown option\n",av[i]); return; } } else if (n==0) { if (!get_rsa(&set,av[i])) return; n++; } else if (n==1) { if (!get_rsa(&adr,av[i])) return; n++; } else { printf("%s: too many args\n",av[i]); return; } }if (n==0) set = 0;if (n<2) adr = next_adr;if (iflag) { cachetag = ICACHETAG; cacheram = ICACHERAM; }else { cachetag = DCACHETAG; cacheram = DCACHERAM; }/* cache lines always start on 32-byte boundaries */adr &= ~(cache_line_size-1); printf("Displaying %s set %d\n",(iflag)?"icache":"dcache",set);ccc = read_target(XT_CP0,C0_CCC,0);if ( (iflag && set == 1 && ccc&CCC_ISR1) || (!iflag && set == 0 && ccc&CCC_SR0) || (!iflag && set == 1 && ccc&CCC_SR1)) printf("This set is in scatchpad mode\n");for (n=j=0;j<8;adr += cache_line_size,n++) { if (n > icache_size/cache_line_size) break; tag = readCache401x(set,cachetag,adr); if (vflag && (tag&VALID_BIT)==0) continue; printf("%08x %08x ",adr,readCache401x(set,cacheram,adr)); printf("%08x ",readCache401x(set,cacheram,adr+4)); printf("%08x ",readCache401x(set,cacheram,adr+8)); printf("%08x\n ",readCache401x(set,cacheram,adr+12)); printf("%08x ",readCache401x(set,cacheram,adr+16)); printf("%08x ",readCache401x(set,cacheram,adr+20)); printf("%08x ",readCache401x(set,cacheram,adr+24)); printf("%08x ",readCache401x(set,cacheram,adr+28)); printf(" %08x\n",tag); j++; }next_adr = adr;}/************************************************************** ilockReq401x(addr)* verify that other ilock bpts don't conflict with this one* (ie. are a cachesize multiple apart).* Also verify that lock bit is not already set.*/ilockReq401x(addr)Ulong addr;{Ulong ccc,tmsk,omsk;int i;ccc = mfc0(C0_CCC);if (ccc&CCC_ISR1) return(0);tmsk = (icache_size)-1; /* tag mask */omsk = tmsk&~(cache_line_size-1); /* offset mask */for (i=0;i<MAX_BPT;i++) { if (brkList[i].type==0) continue; if (brkList[i].method != BRK_METHOD_ROM) continue; if ((addr&omsk) != (brkList[i].addr&omsk)) continue; /* not same line */ if ((addr&~tmsk) == (brkList[i].addr&~tmsk)) return(0); /* same tag */ }return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -