📄 401x.c
字号:
/************************************************************* * File: 401x.c * Purpose: provide 401x-specific routines for SerialICE drivers * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970218 Created using code from d4010.c * 970218 Tested icache and dcache display commands. * 970219 Added code for ilock. Not working yet. * 970226 Gated printfs with verbose flag. * 970305 wrbpt cmd works - sets ilock bpt. * 970305 this doesn't look right - dsoftflush restore * 970310 moved brkInstall and brkRemove here from iceif.c and * rewrote them. * 970310 Created ilockReq, hwibReq, and hwdbReq. * 970311 Removed write_target from method_ram * 970312 Merged icache and dcache cmds. * 980312 Switched to unified scheme for dll and imon. * 980323 Ignore flush_cache requests if target is running. * 980421 Added cache_size to cache_cmd * 980803 Added isset=0 to brkRemove * 980812 Added return if cache_size == 0. Also setFlushneeded(). * 981222 Changed dwriteback to use dcache_size and cache_line_size. */#ifndef LR4010#define LR4010#endif#include <imon.h>#include <mips.h>#include "iceif.h"#include "defs.h"#define ONLY_FLUSH_WHEN_NEEDED /* optimize the flushes */#define OP_FLUSH_ICACHE 0xbc010000#define OP_FLUSH_DCACHE 0xbc020000#define WB_DCACHE(a) (0xbc040000|((a)<<21))#define VALID_BIT (1<<1)int ilock_active;/************************************************************** void flush_target_401x(mode)* Flush the designated cache in the target.*/void flush_target_401x(mode)int mode;{Ulong ccc,tmpcfg;/* emit code to flush the caches *//* we are already in an isr with ints disabled *//* the instr buffer is in kseg1 */if (!target_stopped) return; /* 980323 */if (need_initial_flush) { printDiag(1,"performing initial flush 401x\n"); need_initial_flush = 0; flush_target(DCACHEI); flush_target(ICACHEI); }switch (mode) { case ICACHEI : printDiag(1,"hard iflush 401x\n"); if (icache_size == 0) { iflush_needed = 0; return; } send_buffer(); /* flush */ send_instr(OP_FLUSH_ICACHE); readA0(); iflush_needed = 0; break; case ICACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED if (!iflush_needed) return;#endif printDiag(1,"soft iflush 401x\n"); if (icache_size == 0) { iflush_needed = 0; return; } send_buffer(); /* we don't want to flush any sets that have been switched * to scratchpad mode. */ tmpcfg = ccc = read_target(XT_CP0,C0_CCC,0); if (ccc&CCC_ISR1) { printf("skipping is1 flush\n"); /* isr1 is set, so clear ie1 */ tmpcfg &= ~CCC_IE1; write_target(XT_CP0,C0_CCC,tmpcfg,0); send_buffer(); } /* flush */ send_instr(OP_FLUSH_ICACHE); readA0();#if 0 /* 970305 must always restore ccc */ if (cfg&CCC_ISR1) { write_target(XT_CP0,C0_CCC,tmpcfg,0); send_buffer(); }#else write_target(XT_CP0,C0_CCC,ccc,0); send_buffer();#endif iflush_needed = 0; break; case DCACHEI : printDiag(1,"hard dflush 401x\n"); if (dcache_size == 0) { dflush_needed = 0; return; } send_buffer(); send_instr(OP_FLUSH_DCACHE); readA0(); dflush_needed = 0; break; case DCACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED if (!dflush_needed) return;#endif printDiag(1,"soft dflush 401x\n"); if (dcache_size == 0) { dflush_needed = 0; return; } send_buffer(); /* we don't want to flush any sets that have been switched * to scratchpad mode. */#if 0 tmpcfg = ccc = read_target(XT_CP0,C0_CCC,0); if (ccc&CCC_SR0) { /* sr0 is set, so clear de0 */ tmpcfg &= ~CCC_DE0; } if (ccc&CCC_SR1) { /* sr1 is set, so clear de1 */ tmpcfg &= ~CCC_DE1; } write_target(XT_CP0,C0_CCC,tmpcfg,0); send_buffer();#endif /* actual cache code */ /* first we want to write-back the Dcache */ writeGpr(9,K0BASE); writeGpr(8,K0BASE+dcache_size); /* flush loop */ send_instr(WB_DCACHE(9)); /* writes 8 words */ send_instr(ADDIU(9,9,cache_line_size)); send_instr(BNE(8,9,-3)); readA0(); /* now flush the Dcache */ send_instr(OP_FLUSH_DCACHE); readA0();#if 0 /* this doesn't look right 970305 */ /* restore the ccc reg */ if (ccc&CCC_SR0 || ccc&CCC_SR1) { write_target(XT_CP0,C0_CCC,tmpcfg,0); send_buffer(); }#endif dflush_needed = 0; break; }}/************************************************************** Ulong readCache_401x(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 readCache_401x(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; }writeGpr(9,addr);writeGpr(8,tmpcfg);send_instr(MTC0(8,C0_CCC)); /* 3 nops before ld or st */send_instr(0);send_instr(0);send_instr(0);/* read the cache */send_instr(LW(4,0,9));send_instr(0);/* restore CCC */writeGpr(8,ccc);send_instr(MTC0(8,C0_CCC));tag = readA0();return(tag);}/************************************************************** writeCache(set,what,addr,tag)* UNTESTED*/static void writeCache(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 0 /* old */write_target(XT_CP0,C0_CCC,tmpcfg,0);send_buffer();write_target(XT_MEM,addr,tag,4);/* restore cfg reg */write_target(XT_CP0,C0_CCC,ccc,0);send_buffer();#else /* new */writeGpr(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}#ifdef PMCC/**************************************************************/Optdesc cache_opts_401x[] = { {"[-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}};void cache_cmd_401x(ac,av)int ac;char *av[];{int n,i,j,set,vflag,iflag;int cacheram,cachetag,cache_size;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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -