📄 c4300.c
字号:
/************************************************************* * File: lib/c4300.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 980305 Created from c4011.c * 980615 Renamed re_sonic re_ether * 980616 Added "case 8" devinit. * 980730 Added F_MIPS for Crossview. * 980730 Fixed the HI reg #. * 980828 Applied outw fix to brkRemove. * 981107 Fixed typo for build when CLKFREQ is defined */#ifndef VR4300#define VR4000#endif#include "mips.h"#include <termio.h>#include <terms.h>#include <pmon.h>#define outw(a,v) (*((volatile Ulong *)(a))=(v))static measureFreq();static char *c0_regs[] = { "C0_INDEX", "C0_RAND", "C0_ENTRYLO0", "C0_ENTRYL01", "C0_CTEXT", "C0_PAGEMASK", "C0_WIRED", "$7", "C0_BADVADDR", "C0_COUNT", "C0_ENTRYHI", "C0_COMPARE", "C0_SR", "C0_CAUSE", "C0_EPC", "C0_PRID", "C0_CONFIG", "C0_LLADR", "C0_WATCHLO", "C0_WATCHHI", "C0_XCONTEXT", "$21", "$22", "C0_ROTATE", "C0_CMASK", "$25", "$26", "C0_CACHEERR", "C0_TAGLO", "C0_TAGHI", "C0_ERREPC", "$31" };static RegSpec mips4k_sr_def[] = { {4,28,"CU",2,0,0}, {1,27,"RP",2,0,0}, {1,26,"FR",2,0,0}, {1,25,"RE",2,0,0}, {1,22,"BEV",2,0,0}, {1,21,"SR",2,0,0}, {1,20,"SR",2,0,0}, {1,18,"CH",2,0,0}, {1,17,"CE",2,0,0}, {1,16,"DE",2,0,0}, {8,8,"IM&SW",2,0,0}, {1,7,"KX",2,0,0}, {1,6,"SX",2,0,0}, {1,5,"UX",2,0,0}, {2,3,"KSU",2,0,0}, {1,2,"ERL",2,0,0}, {1,1,"EXL",2,0,0}, {1,0,"IE",2,0,0}, {0}};static char *exccodes4k[] = { "Int","TLBmod","TLBL","TLBS","AdEL","AdES","IBE","DBE", "Sys", "Bp","RI","CpU","Ov","Tr","Resv","FPE", "Resv","Resv", "Resv","Resv","Resv","Resv","Resv", "WATCH", "Resv","Resv","Resv","Resv","Resv","Resv", "Resv","Resv", 0};static RegSpec mips4k_cause_def[] = { {1,31,"BD",2,0,1}, {2,28,"CE",2,0,1}, {8,8,"IP",2,0,1}, {5,2,"EXC",0,exccodes4k,1}, {0}};static RegSpec vr4300_config_def[] = { {3,28,"EC",2,0,0}, {4,24,"EP",2,0,0}, {1,15,"BE",2,0,0}, {1,3,"CU",2,0,0}, {3,0,"K0",2,0,0}, {0}};static RegRec reglist[] = { {mXpc,0,"PC","pc",14,(F_MIPS|F_CPU)}, {mXgpr,0,"HI","HI",32,(F_CPU|F_MIPS)}, {mXgpr,0,"LO","LO",33,(F_CPU|F_MIPS)}, /* ========== cp0 ========== */ {mXc0,mips4k_sr_def,"C0_SR","SR",12,(F_CP0|F_MIPS)}, {mXc0,mips4k_cause_def,"C0_CAUSE","CAUSE",13,(F_CP0|F_MIPS)}, {mXc0,mips_prid_def,"C0_PRID","PRID",15,(F_CP0|F_RO|F_MIPS)}, {mXc0,0,"C0_EPC","EPC",14,(F_CP0|F_MIPS)},/*--------- end of basic MIPS stuff ------------------------*/ {mXc0,vr4300_config_def,"C0_CONFIG","CONFIG",16,0}, {mXc0,0,"C0_INDEX","INDEX",0,0}, {mXc0,0,"C0_RANDOM","RANDOM",1,0}, {mXc0,0,"C0_ENTRYLO0","ENTRYLO",2,0}, {mXc0,0,"C0_ENTRYLO1","ENTRYLO",3,0}, {mXc0,0,"C0_CONTEXT","CONTEXT",4,0}, {mXc0,0,"C0_PAGEMASK","PAGEMASK",5,0}, {mXc0,0,"C0_WIRED","WIRED",6,0}, {mXc0,0,"C0_BADVADDR","BADVADDR",8,0}, {mXc0,0,"C0_COUNT","COUNT",9,0}, {mXc0,0,"C0_ENTRYHI","ENTRYHI",10,0}, {mXc0,0,"C0_COMPARE","COMPARE",11,0}, {mXc0,0,"C0_LLADR","LLADR",17,0}, {mXc0,0,"C0_WATCHLO","WATCHLO",18,0}, {mXc0,0,"C0_WATCHHI","WATCHHI",19,0}, {mXc0,0,"C0_XCONTEXT","XCONTEXT",20,0}, {mXc0,0,"C0_ROTATE","ROTATE",23,0}, {mXc0,0,"C0_CMASK","CMASK",24,0}, {mXc0,0,"C0_CACHEERR","CACHEERR",27,0}, {mXc0,0,"C0_TAGLO","TAGLO",28,0}, {mXc0,0,"C0_TAGHI","TAGHI",29,0}, {mXc0,0,"C0_ERREPC","ERREPC",30,0}, {0}};static int setbp_target(),brkInstall(),brkRemove();extern int iflush_needed,dflush_needed;extern int icache_size,dcache_size,cache_line_size;int p16c552();static struct p16c552info tty1dat = {(Uchar *)0xbe900000};/************************************************************** c4300init(type)*/c4300init(type)int type;{int i,cf;switch (type) { case 0 : /* hostInit(0) */ break; case 1 : /* */ break; case 2 : /* cpuInit(2) */ c0regNames = c0_regs; for (i=0;reglist[i].func;i++) addRegRec(®list[i]); icache_size = 16*1024; cache_line_size = 32; brkInstall_ptr = brkInstall; brkRemove_ptr = brkRemove; setbp_target_ptr = setbp_target; if ((cf=measureFreq())==0) cf = 33; /* default */ setdMonEnv("clkfreq",cf); break; case 3 : /* hostInit(3) extra memory */ break; case 4 : /* hostInit(4) */#ifdef NVRAM nvInfo.start = 0xbfc00000; nvInfo.width = 1; nvInfo.gap = 1; nvInfo.nvbase = 0; #endif break; case 7 : /* hostInit(7) */#ifdef NVRAM nvInfo.start = 0xbfd00000;#endif break; case 5 : /* hostInit(5) */#if defined(ETHERNET) && defined(MIPSEB) re_ether = 1;#endif break; case 8 : addDevice((Addr)&tty1dat,0,p16c552,1024,DEFBAUD); addDevice((Addr)&tty1dat,1,p16c552,1024,DEFBAUD); break; }}/************************************************************** measureFreq()**/static measureFreq(){#ifdef CLKFREQreturn CLKFREQ; /* 981107 */#endifreturn(0);}/************************************************************** static int setbp_target(n,type,addr,addr2,value)* type: 1=bpc 2=bda 3=itemp 4=sstep 5=nonrt* returns bp number, or -1 on error.* addr2 and value are only used for BPTYPE_DATA.* In the case of BPTYPE_DATA the access type (r/w) is encoded* in the 2nd nibble of 'type';*/static int setbp_target(n,type,addr,addr2,value)int n,type;Ulong addr,addr2,value;{int i,method,atype,code;long mask; /* must be signed */ #if 0printf("setbp_target(%d,%d,%08x,%08x,%08x)\n",n,type,addr,addr2,value);#endifatype = type>>4;type &= 0xf;code = 0;if (type == BPTYPE_NONRT) { printf("Warning: This breakpoint requires non real-time execution.\n"); }else if (type == BPTYPE_PC || type == BPTYPE_ITMP || type == BPTYPE_TRACE) { if (is_writeable_target(addr)) method = BRK_METHOD_RAM; else { printf("%08x: can't set bpt\n",addr); return(0-BP_E_ERR); } }if (n == -1) { for (i=0;i<MAX_BPT;i++) if (brkList[i].type == 0) break; if (i >= MAX_BPT) { printf("Fatal error: out of bpts\n"); return(0-BP_E_ERR); } n = i; }if (n < 0 || n >= MAX_BPT) { printf("%d: bad bpt number\n",n); return(0-BP_E_ERR); }brkList[n].type = type;brkList[n].addr = addr;brkList[n].method = method;brkList[n].mask = mask;brkList[n].isset = 0;return((code<<16)|n);}/************************************************************** brkInstall(type)* type=1 install regular+temp bpts* type=2 install trace bpts*/static brkInstall(type)int type;{int i,flag;Ulong tag,vmask,addr;if (verbose) printf("\nbrkInstall(%d)\n",type);flag = 0;for (i=0;i<MAX_BPT;i++) { /* first discard the entries we aren't going to handle */ if (brkList[i].type==0) continue; if (type == 1 && brkList[i].type == BPTYPE_TRACE) continue; if (type == 2 && brkList[i].type != BPTYPE_TRACE) continue; addr = brkList[i].addr; switch (brkList[i].method) { case BRK_METHOD_RAM : if (verbose) printf("installing ram bpt at %08x\n",addr); brkList[i].val = read_target(XT_MEM,addr,4); outw(addr,BPT_CODE); iflush_needed = dflush_needed = 1; flush_target(ICACHE); flush_target(DCACHE); brkList[i].isset = 1; break; default : printf("%d: error bad method\n",brkList[i].method); return(-1); } }}/************************************************************** int brkRemove(epc)* returns type: 0=none 1=bpc 2=bda 3=itemp 4=sstep*/static int brkRemove(epc)Ulong epc;{int i,type,flag;Ulong ccc;type = flag = 0;for (i=0;i<MAX_BPT;i++) { /* first discard the entries we aren't going to handle */ if (brkList[i].type==0) continue; if (brkList[i].isset==0) continue; if (epc == brkList[i].addr) type = brkList[i].type; switch (brkList[i].method) { case BRK_METHOD_RAM : outw(brkList[i].addr,brkList[i].val); iflush_needed = dflush_needed = 1; flush_target(ICACHE); flush_target(DCACHE); break; } if (brkList[i].type == BPTYPE_ITMP) brkList[i].type = 0; if (brkList[i].type == BPTYPE_TRACE) brkList[i].type = 0; }return(type);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -