📄 400x.c
字号:
if ((addr&omsk) != (brkList[i].addr&omsk)) continue; /* not same line */ if ((addr&~tmsk) == (brkList[i].addr&~tmsk)) return(0); /* same tag */ }#endifreturn(1);}/************************************************************** void setFlushneeded_400x(Ulong addr,int size)*/void setFlushneeded_400x(Ulong addr,int size){if (IS_K0SEG(addr)) { printDiag(1,"iflush needed\n"); if (icache_size != 0) { iflush_needed += size; printDiag(3,"iflush_needed=%d\n",iflush_needed); } if (ejtag_mode && dcache_size != 0) { dflush_needed += size; /* 981216 */ printDiag(3,"dflush_needed=%d\n",dflush_needed); } /* prob was that because ejtag download is performed using dma, the * dcache needed updating. This is not a problem for SI. */ }else if ((addr&0xfff00000)==0xbff00000) ; /* 970225 */else if (is_ocm(addr)) ; /* 980225 */else { printDiag(1,"iflush & dflush needed\n"); if (icache_size != 0) { iflush_needed += size; printDiag(3,"iflush_needed=%d\n",iflush_needed); } if (dcache_size != 0) { dflush_needed += size; printDiag(3,"dflush_needed=%d\n",dflush_needed); } }}/**************************************************************/void setilockbpt_400x(Ulong addr,Ulong bptcode,int sz){Ulong cfg,tag,vmask;cfg = read_target(XT_MEM,M_CFG4001,4);if ((cfg&CFG_ISIZEMASK) == CFG_ISIZE_8) { /* handle the irefillsz=8 case */ setupcacheline_400x(addr); /* copy mem to cache */ }tag = readCache_400x(0,ICACHETAG,addr);vmask = 1<<((addr>>2)&3);if (!(tag&LCK_BIT)) { tag &= ~0xf; tag |= LCK_BIT; }tag |= vmask;writeCache(0,ICACHERAM,addr,bptcode,sz);writeCache(0,ICACHETAG,addr,tag,4);/* make sure that it is not in set1 */writeCache(1,ICACHETAG,addr,0,4); }/**************************************************************/void clrilockbpt_400x(Ulong addr){writeCache(0,ICACHETAG,addr,0,4);setFlushneeded(addr,4);}/************************************************************** void flush_target_400x_ejtag(mode)* Flush the designated cache in the target.* This version avoids loops. I flush the cache by sending* blocks of SW instructions terminated by a readA0.*/void flush_target_400x_ejtag(int mode){Ulong cfg,tmpcfg;int i,blksize,lines,n;int ibs = 64; /* instr buffer size. Should get this value from sah *//* need to allow space for code appended by ejtag.dll. The value alsoneed to be a multiple of cache_line_size. *//* flush_target_400x_ejtag: The gpr[10]s in this func were 26 (k0) *//* flush_target_400x_ejtag: The gpr[11]s in this func were 26 (k1) *//* 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 400x_ejtag\n"); need_initial_flush = 0; flush_target_400x_ejtag(DCACHEI); flush_target_400x_ejtag(ICACHEI); }switch (mode) { case ICACHEI : printDiag(1,"\niflush 400x_ejtag size=%d lnsize=%d\n", icache_size,cache_line_size); if (icache_size == 0) { iflush_needed = 0; return; } send_buffer(); cfg = read_target(XT_MEM,M_CFG4001,4); tmpcfg = cfg; tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK); tmpcfg |= (CFG_ICEN|CFG_DCEN|CFG_CMODE_ITEST); /* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */ writeGpr(8,tmpcfg); writeGpr(9,M_CFG4001); send_instr(SW(8,0,9)); send_instr(0); send_instr(0); send_instr(0); /* actual cache code */ writeGpr(9,K0BASE); blksize = ibs*cache_line_size; for (i=0;i<icache_size;i+=cache_line_size) { send_instr(SW(0,i,9)); if ((i%blksize)==(blksize-cache_line_size)) readA0(); if (dirty_icache_line) dirty_icache_line[i/cache_line_size]=0; } /* flush Icache set1 */ tmpcfg = cfg; tmpcfg &= ~(CFG_CMODEMASK|CFG_DSIZEMASK|CFG_ISIZEMASK); tmpcfg |= (CFG_ICEN|CFG_IS1EN|CFG_DCEN|CFG_CMODE_ITEST); /* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */ writeGpr(8,tmpcfg); writeGpr(9,M_CFG4001); send_instr(SW(8,0,9)); send_instr(0); send_instr(0); send_instr(0); /* actual cache code */ writeGpr(9,K0BASE); blksize = ibs*cache_line_size; for (i=0;i<icache_size;i+=cache_line_size) { send_instr(SW(0,i,9)); if ((i%blksize)==(blksize-cache_line_size)) readA0(); } iflush_needed = 0; break; case ICACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED if (!iflush_needed) return;#endif printDiag(1,"\nsoft iflush 400x_ejtag size=%d lnsize=%d\n", icache_size,cache_line_size); if (icache_size == 0) { iflush_needed = 0; return; } send_buffer(); cfg = read_target(XT_MEM,M_CFG4001,4); tmpcfg = cfg; tmpcfg &= ~(CFG_CMODEMASK|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK); tmpcfg |= (CFG_ICEN|CFG_DCEN|CFG_CMODE_ITEST); /* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */ writeGpr(8,tmpcfg); writeGpr(9,M_CFG4001); send_instr(SW(8,0,9)); send_instr(0); send_instr(0); send_instr(0); /* actual cache code */#ifdef USE_SINGLE_LINE_FLUSH printDiag(2,"iflush needed set0 cnt=%d\n",iflush_needed); lines = icache_size/cache_line_size; writeGpr(9,K0BASE); blksize = ibs/6; n = 0; for (i=0;i<lines;i++) { if (!dirty_icache_line || dirty_icache_line[i]) { send_instr(LW(10,i*cache_line_size,9)); send_instr(0); /* nop */ send_instr(SLLV(10,27)); send_instr(BLTZ(10,2)); send_instr(0); /* nop */ send_instr(SW(0,i*cache_line_size,9)); /* defer clearing the dirty bit until we flush set1 */ if ((i%blksize)==(blksize-1)) readA0(); n++; } } readA0(); printDiag(3,"%d $I0 lines flushed.\n",n);#else writeGpr(9,K0BASE); writeGpr(8,K0BASE+icache_size); /* flush loop */ /* only flush non-locked entries */ /* Note: only set0 is lockable */ send_instr(LW(10,0,9)); send_instr(0); /* nop */ send_instr(SLLV(10,27)); send_instr(BLTZ(10,2)); send_instr(0); /* nop */ send_instr(SW(0,0,9)); send_instr(ADDIU(9,9,cache_line_size)); send_instr(BNE(8,9,-8)); readA0();#endif /* flush Icache set1 */ tmpcfg = cfg; tmpcfg &= ~(CFG_CMODEMASK|CFG_DSIZEMASK|CFG_ISIZEMASK); tmpcfg |= (CFG_ICEN|CFG_IS1EN|CFG_DCEN|CFG_CMODE_ITEST); /* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */ writeGpr(8,tmpcfg); writeGpr(9,M_CFG4001); send_instr(SW(8,0,9)); send_instr(0); send_instr(0); send_instr(0); /* actual cache code */#ifdef USE_SINGLE_LINE_FLUSH printDiag(2,"iflush needed set1 cnt=%d\n",iflush_needed); lines = icache_size/cache_line_size; writeGpr(9,K0BASE); blksize = ibs; n = 0; for (i=0;i<lines;i++) { if (!dirty_icache_line || dirty_icache_line[i]) { send_instr(SW(0,i*cache_line_size,9)); if (dirty_icache_line) dirty_icache_line[i] = 0; if ((i%blksize)==(blksize-1)) readA0(); n++; } } printDiag(3,"%d $I1 lines flushed.\n",n);#else writeGpr(9,K0BASE); writeGpr(8,K0BASE+icache_size); /* flush loop */ send_instr(SW(0,0,9)); send_instr(ADDIU(9,9,cache_line_size)); send_instr(BNE(8,9,-3));#endif readA0(); iflush_needed = 0; break; case DCACHE :#ifdef ONLY_FLUSH_WHEN_NEEDED if (!dflush_needed) return;#endif case DCACHEI : printDiag(1,"\ndflush 400x_ejtag size=%d lnsize=%d\n", dcache_size,cache_line_size); if (dcache_size == 0) { dflush_needed = 0; return; } send_buffer(); /* flush Dcache set0 */ cfg = read_target(XT_MEM,M_CFG4001,4); tmpcfg = cfg; tmpcfg &= ~(CFG_CMODEMASK|CFG_ICEN|CFG_IS1EN|CFG_DSIZEMASK|CFG_ISIZEMASK); tmpcfg |= (CFG_DCEN|CFG_CMODE_DTEST); /* write_target(XT_MEM,M_CFG4001,tmpcfg,4); */ writeGpr(8,tmpcfg); writeGpr(9,M_CFG4001); send_instr(SW(8,0,9)); send_instr(0); send_instr(0); send_instr(0); /* actual cache code */#ifdef USE_SINGLE_LINE_FLUSH if (mode == DCACHE && dirty_dcache_line) { printDiag(2,"dflush needed cnt=%d\n",dflush_needed); lines = dcache_size/cache_line_size; writeGpr(9,K0BASE); blksize = ibs; n = 0; for (i=0;i<lines;i++) { if (dirty_dcache_line[i]) { send_instr(SW(0,i*cache_line_size,9)); dirty_dcache_line[i] = 0; if ((i%blksize)==(blksize-1)) readA0(); n++; } } printDiag(3,"%d $D lines flushed.\n",n); } else /* must be DCACHEI */ {#endif writeGpr(9,K0BASE); blksize = ibs*cache_line_size; for (i=0;i<dcache_size;i+=cache_line_size) { send_instr(SW(0,i,9)); if ((i%blksize)==(blksize-cache_line_size)) readA0(); if (dirty_dcache_line) dirty_dcache_line[i/cache_line_size]=0; }#ifdef USE_SINGLE_LINE_FLUSH }#endif dflush_needed = 0; break; }/* restore cfg reg *//* write_target(XT_MEM,M_CFG4001,cfg,4); */writeGpr(8,cfg);writeGpr(9,M_CFG4001);send_instr(SW(8,0,9));send_instr(0);readA0();}/**************************************************************/void markDcacheDirty(Ulong addr,int size){int shamt,msk,i,line;if (dcache_size == 0) return;if (!dirty_dcache_line) dirty_dcache_line = (char *)calloc(dcache_size/cache_line_size,1);for (shamt=0,msk=1;(cache_line_size&msk)==0;msk<<=1,shamt++) ;for (i=0;i<size;i++) { line = ((addr+i)&(dcache_size-1))>>shamt; dirty_dcache_line[line] = 1; }}/**************************************************************/void markIcacheDirty(Ulong addr,int size){int shamt,msk,i,line;if (icache_size == 0) return;if (!dirty_icache_line) dirty_icache_line = (char *)calloc(icache_size/cache_line_size,1);for (shamt=0,msk=1;(cache_line_size&msk)==0;msk<<=1,shamt++) ;for (i=0;i<size;i++) { line = ((addr+i)&(icache_size-1))>>shamt; dirty_icache_line[line] = 1; }}/************************************************************** void setFlushneeded_ejtag(Ulong addr,int size)*/void setFlushneeded_ejtag(Ulong addr,int size){if (IS_K0SEG(addr)) { if (icache_size != 0) { iflush_needed += size; markIcacheDirty(addr,size); printDiag(3,"iflush_needed=%d\n",iflush_needed); } if (ejtag_mode && dcache_size != 0) { dflush_needed += size; /* 981216 */ markDcacheDirty(addr,size); printDiag(3,"dflush_needed=%d\n",dflush_needed); } /* prob was that because ejtag download is performed using dma, the * dcache needed updating. This is not a problem for SI. */ }else if ((addr&0xfff00000)==0xbff00000) ; /* 970225 */else if (is_ocm(addr)) ; /* 980225 */else { if (icache_size != 0) { iflush_needed += size; markIcacheDirty(addr,size); printDiag(3,"iflush_needed=%d\n",iflush_needed); } if (dcache_size != 0) { dflush_needed += size; markDcacheDirty(addr,size); printDiag(3,"dflush_needed=%d\n",dflush_needed); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -