13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * mipsim.h 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include "/mips/include/ureg.h" 53e12c5d1SDavid du Colombier #define USERADDR 0xC0000000 63e12c5d1SDavid du Colombier #define UREGADDR (USERADDR+BY2PG-4-0xA0) 73e12c5d1SDavid du Colombier #define USER_REG(x) (UREGADDR+(ulong)(x)) 83e12c5d1SDavid du Colombier #define REGOFF(x) (USER_REG(&((struct Ureg *) 0)->x)) 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier typedef struct Registers Registers; 113e12c5d1SDavid du Colombier typedef struct Segment Segment; 123e12c5d1SDavid du Colombier typedef struct Memory Memory; 133e12c5d1SDavid du Colombier typedef struct Mul Mul; 143e12c5d1SDavid du Colombier typedef struct Mulu Mulu; 153e12c5d1SDavid du Colombier typedef struct Inst Inst; 163e12c5d1SDavid du Colombier typedef struct Icache Icache; 173e12c5d1SDavid du Colombier typedef struct Tlb Tlb; 183e12c5d1SDavid du Colombier typedef struct Breakpoint Breakpoint; 193e12c5d1SDavid du Colombier 203e12c5d1SDavid du Colombier enum 213e12c5d1SDavid du Colombier { 223e12c5d1SDavid du Colombier Instruction = 1, 233e12c5d1SDavid du Colombier Read = 2, 243e12c5d1SDavid du Colombier Write = 4, 253e12c5d1SDavid du Colombier Access = 2|4, 263e12c5d1SDavid du Colombier Equal = 4|8, 273e12c5d1SDavid du Colombier }; 283e12c5d1SDavid du Colombier 293e12c5d1SDavid du Colombier struct Breakpoint 303e12c5d1SDavid du Colombier { 313e12c5d1SDavid du Colombier int type; /* Instruction/Read/Access/Write/Equal */ 323e12c5d1SDavid du Colombier ulong addr; /* Place at address */ 333e12c5d1SDavid du Colombier int count; /* To execute count times or value */ 343e12c5d1SDavid du Colombier int done; /* How many times passed through */ 353e12c5d1SDavid du Colombier Breakpoint *next; /* Link to next one */ 363e12c5d1SDavid du Colombier }; 373e12c5d1SDavid du Colombier 383e12c5d1SDavid du Colombier enum 393e12c5d1SDavid du Colombier { 403e12c5d1SDavid du Colombier Iload, 413e12c5d1SDavid du Colombier Istore, 423e12c5d1SDavid du Colombier Iarith, 433e12c5d1SDavid du Colombier Ibranch, 443e12c5d1SDavid du Colombier Ireg, 453e12c5d1SDavid du Colombier Isyscall, 463e12c5d1SDavid du Colombier Ifloat, 473e12c5d1SDavid du Colombier }; 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier enum 503e12c5d1SDavid du Colombier { 513e12c5d1SDavid du Colombier Nmaxtlb = 64, 523e12c5d1SDavid du Colombier }; 533e12c5d1SDavid du Colombier 543e12c5d1SDavid du Colombier struct Tlb 553e12c5d1SDavid du Colombier { 563e12c5d1SDavid du Colombier int on; /* Being updated */ 573e12c5d1SDavid du Colombier int tlbsize; /* Number of entries */ 583e12c5d1SDavid du Colombier ulong tlbent[Nmaxtlb]; /* Virtual address tags */ 593e12c5d1SDavid du Colombier int hit; /* Number of successful tag matches */ 603e12c5d1SDavid du Colombier int miss; /* Number of failed tag matches */ 613e12c5d1SDavid du Colombier }; 623e12c5d1SDavid du Colombier 633e12c5d1SDavid du Colombier struct Icache 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier int on; /* Turned on */ 663e12c5d1SDavid du Colombier int linesize; /* Line size in bytes */ 673e12c5d1SDavid du Colombier int stall; /* Cache stalls */ 683e12c5d1SDavid du Colombier int *lines; /* Tag array */ 693e12c5d1SDavid du Colombier int* (*hash)(ulong); /* Hash function */ 703e12c5d1SDavid du Colombier char *hashtext; /* What the function looks like */ 713e12c5d1SDavid du Colombier }; 723e12c5d1SDavid du Colombier 733e12c5d1SDavid du Colombier struct Inst 743e12c5d1SDavid du Colombier { 753e12c5d1SDavid du Colombier void (*func)(ulong); 763e12c5d1SDavid du Colombier char *name; 773e12c5d1SDavid du Colombier int type; 783e12c5d1SDavid du Colombier int count; 793e12c5d1SDavid du Colombier int taken; 803e12c5d1SDavid du Colombier int useddelay; 813e12c5d1SDavid du Colombier }; 823e12c5d1SDavid du Colombier 833e12c5d1SDavid du Colombier struct Registers 843e12c5d1SDavid du Colombier { 853e12c5d1SDavid du Colombier ulong pc; 863e12c5d1SDavid du Colombier ulong ir; 873e12c5d1SDavid du Colombier Inst *ip; 883e12c5d1SDavid du Colombier long r[32]; 893e12c5d1SDavid du Colombier ulong mhi; 903e12c5d1SDavid du Colombier ulong mlo; 913e12c5d1SDavid du Colombier 923e12c5d1SDavid du Colombier ulong fpsr; 933e12c5d1SDavid du Colombier union { 943e12c5d1SDavid du Colombier double fd[16]; 953e12c5d1SDavid du Colombier float fl[32]; 963e12c5d1SDavid du Colombier ulong di[32]; 973e12c5d1SDavid du Colombier }; 983e12c5d1SDavid du Colombier char ft[32]; 993e12c5d1SDavid du Colombier }; 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier enum 1023e12c5d1SDavid du Colombier { 1033e12c5d1SDavid du Colombier FPd = 0, 1043e12c5d1SDavid du Colombier FPs, 1053e12c5d1SDavid du Colombier FPmemory, 1063e12c5d1SDavid du Colombier }; 1073e12c5d1SDavid du Colombier #define dreg(r) ((r)>>1) 1083e12c5d1SDavid du Colombier 1093e12c5d1SDavid du Colombier struct Mulu 1103e12c5d1SDavid du Colombier { 1113e12c5d1SDavid du Colombier ulong lo; 1123e12c5d1SDavid du Colombier ulong hi; 1133e12c5d1SDavid du Colombier }; 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier struct Mul 1163e12c5d1SDavid du Colombier { 1173e12c5d1SDavid du Colombier long lo; 1183e12c5d1SDavid du Colombier long hi; 1193e12c5d1SDavid du Colombier }; 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier enum 1223e12c5d1SDavid du Colombier { 1233e12c5d1SDavid du Colombier MemRead, 1243e12c5d1SDavid du Colombier MemReadstring, 1253e12c5d1SDavid du Colombier MemWrite, 1263e12c5d1SDavid du Colombier }; 1273e12c5d1SDavid du Colombier 1283e12c5d1SDavid du Colombier enum 1293e12c5d1SDavid du Colombier { 1303e12c5d1SDavid du Colombier Stack, 1313e12c5d1SDavid du Colombier Text, 1323e12c5d1SDavid du Colombier Data, 1333e12c5d1SDavid du Colombier Bss, 1343e12c5d1SDavid du Colombier Nseg, 1353e12c5d1SDavid du Colombier }; 1363e12c5d1SDavid du Colombier 1373e12c5d1SDavid du Colombier struct Segment 1383e12c5d1SDavid du Colombier { 1393e12c5d1SDavid du Colombier short type; 1403e12c5d1SDavid du Colombier ulong base; 1413e12c5d1SDavid du Colombier ulong end; 1423e12c5d1SDavid du Colombier ulong fileoff; 1433e12c5d1SDavid du Colombier ulong fileend; 1443e12c5d1SDavid du Colombier int rss; 1453e12c5d1SDavid du Colombier int refs; 1463e12c5d1SDavid du Colombier uchar **table; 1473e12c5d1SDavid du Colombier }; 1483e12c5d1SDavid du Colombier 1493e12c5d1SDavid du Colombier struct Memory 1503e12c5d1SDavid du Colombier { 1513e12c5d1SDavid du Colombier Segment seg[Nseg]; 1523e12c5d1SDavid du Colombier }; 1533e12c5d1SDavid du Colombier 1543e12c5d1SDavid du Colombier void fatal(int, char*, ...); 1553e12c5d1SDavid du Colombier void run(void); 1563e12c5d1SDavid du Colombier void undef(ulong); 1573e12c5d1SDavid du Colombier void dumpreg(void); 1583e12c5d1SDavid du Colombier void dumpfreg(void); 1593e12c5d1SDavid du Colombier void dumpdreg(void); 1603e12c5d1SDavid du Colombier void* emalloc(ulong); 1613e12c5d1SDavid du Colombier void* erealloc(void*, ulong, ulong); 1623e12c5d1SDavid du Colombier void* vaddr(ulong); 1637dd7cddfSDavid du Colombier int badvaddr(ulong, int); 1643e12c5d1SDavid du Colombier void itrace(char *, ...); 1653e12c5d1SDavid du Colombier void segsum(void); 1663e12c5d1SDavid du Colombier void Ssyscall(ulong); 1673e12c5d1SDavid du Colombier char* memio(char*, ulong, int, int); 1683e12c5d1SDavid du Colombier ulong ifetch(ulong); 1693e12c5d1SDavid du Colombier ulong getmem_w(ulong); 1703e12c5d1SDavid du Colombier ushort getmem_h(ulong); 1713e12c5d1SDavid du Colombier void putmem_w(ulong, ulong); 1723e12c5d1SDavid du Colombier uchar getmem_b(ulong); 1733e12c5d1SDavid du Colombier void putmem_b(ulong, uchar); 1743e12c5d1SDavid du Colombier ulong getmem_4(ulong); 1753e12c5d1SDavid du Colombier ulong getmem_2(ulong); 1763e12c5d1SDavid du Colombier void putmem_h(ulong, short); 1773e12c5d1SDavid du Colombier Mul mul(long, long); 1783e12c5d1SDavid du Colombier Mulu mulu(ulong, ulong); 1793e12c5d1SDavid du Colombier void isum(void); 1803e12c5d1SDavid du Colombier void initicache(void); 1813e12c5d1SDavid du Colombier void updateicache(ulong addr); 1823e12c5d1SDavid du Colombier void tlbsum(void); 1833e12c5d1SDavid du Colombier long lnrand(long); 1843e12c5d1SDavid du Colombier void randseed(long, long); 1853e12c5d1SDavid du Colombier void cmd(void); 1863e12c5d1SDavid du Colombier void brkchk(ulong, int); 1873e12c5d1SDavid du Colombier void delbpt(char*); 1883e12c5d1SDavid du Colombier void breakpoint(char*, char*); 1893e12c5d1SDavid du Colombier char* nextc(char*); 1903e12c5d1SDavid du Colombier ulong expr(char*); 191219b2ee8SDavid du Colombier void initmap(void); 192219b2ee8SDavid du Colombier void inithdr(int); 193219b2ee8SDavid du Colombier void initstk(int, char**); 1943e12c5d1SDavid du Colombier void reset(void); 1953e12c5d1SDavid du Colombier void dobplist(void); 1964de34a7eSDavid du Colombier int _mipscoinst(Map*, uvlong, char*, int); 1973e12c5d1SDavid du Colombier void procinit(int); 1983e12c5d1SDavid du Colombier void printsource(long); 1993e12c5d1SDavid du Colombier void printparams(Symbol *, ulong); 2003e12c5d1SDavid du Colombier void printlocals(Symbol *, ulong); 2013e12c5d1SDavid du Colombier void stktrace(int); 2023e12c5d1SDavid du Colombier void iprofile(void); 2033e12c5d1SDavid du Colombier 2043e12c5d1SDavid du Colombier /* Globals */ 2053e12c5d1SDavid du Colombier Extern Registers reg; 2063e12c5d1SDavid du Colombier Extern Memory memory; 2073e12c5d1SDavid du Colombier Extern int text; 2083e12c5d1SDavid du Colombier Extern int trace; 2093e12c5d1SDavid du Colombier Extern int sysdbg; 2103e12c5d1SDavid du Colombier Extern int calltree; 2113e12c5d1SDavid du Colombier Extern Inst itab[]; 2123e12c5d1SDavid du Colombier Extern Inst ispec[]; 2133e12c5d1SDavid du Colombier Extern Icache icache; 2143e12c5d1SDavid du Colombier Extern Tlb tlb; 2153e12c5d1SDavid du Colombier Extern int count; 2163e12c5d1SDavid du Colombier Extern jmp_buf errjmp; 2173e12c5d1SDavid du Colombier Extern Breakpoint *bplist; 2183e12c5d1SDavid du Colombier Extern int atbpt; 2193e12c5d1SDavid du Colombier Extern int membpt; 2203e12c5d1SDavid du Colombier Extern int cmdcount; 2213e12c5d1SDavid du Colombier Extern int nopcount; 2223e12c5d1SDavid du Colombier Extern ulong dot; 2233e12c5d1SDavid du Colombier extern char *file; 2243e12c5d1SDavid du Colombier Extern Biobuf *bioout; 2253e12c5d1SDavid du Colombier Extern Biobuf *bin; 2263e12c5d1SDavid du Colombier Extern ulong *iprof; 2273e12c5d1SDavid du Colombier extern int datasize; 228219b2ee8SDavid du Colombier Extern Map *symmap; 2297dd7cddfSDavid du Colombier Extern int rtrace; 2303e12c5d1SDavid du Colombier 2313e12c5d1SDavid du Colombier /* Plan9 Kernel constants */ 232*426f2a32SDavid du Colombier #define BY2PG (16*1024) 2333e12c5d1SDavid du Colombier #define BY2WD 4 2343e12c5d1SDavid du Colombier #define UTZERO 0x1000 2353e12c5d1SDavid du Colombier #define STACKTOP 0x80000000 2363e12c5d1SDavid du Colombier #define STACKSIZE 0x10000 2373e12c5d1SDavid du Colombier 2383e12c5d1SDavid du Colombier #define PROFGRAN 4 2393e12c5d1SDavid du Colombier /* Opcode decoders */ 2403e12c5d1SDavid du Colombier #define Getrsrt(s,t,i) s = (i>>21)&0x1f; t = (i>>16)&0x1f; 2413e12c5d1SDavid du Colombier #define Getrbrt(b,t,i) b = (i>>21)&0x1f; t = (i>>16)&0x1f; 2423e12c5d1SDavid du Colombier #define Get3(s, t, d, i) s = (i>>21)&0x1f; t = (i>>16)&0x1f; d = (i>>11)&0x1f; 2433e12c5d1SDavid du Colombier #define Getf3(s, t, d, i) s = (i>>11)&0x1f; t = (i>>16)&0x1f; d = (i>>6)&0x1f; 2443e12c5d1SDavid du Colombier #define Getf2(s, d, i) s = (i>>11)&0x1f; d = (i>>6)&0x1f; 2453e12c5d1SDavid du Colombier #define SpecialGetrtrd(t, d, i) t = (i>>16)&0x1f; d = (i>>11)&0x1f; 2463e12c5d1SDavid du Colombier 2473e12c5d1SDavid du Colombier #define INOPINST "nor" 2483e12c5d1SDavid du Colombier #define INOP 0x00000027 /* Instruction used as nop */ 2493e12c5d1SDavid du Colombier #define SIGNBIT 0x80000000 2503e12c5d1SDavid du Colombier #define Iexec(ir) {Inst *i; i = &itab[(ir)>>26]; reg.ip = i; i->count++; (*i->func)(ir); } 2513e12c5d1SDavid du Colombier #define Statbra() reg.ip->taken++; if(reg.ir != INOP) reg.ip->useddelay++; 2523e12c5d1SDavid du Colombier 2533e12c5d1SDavid du Colombier #define FP_U 3 2543e12c5d1SDavid du Colombier #define FP_L 1 2553e12c5d1SDavid du Colombier #define FP_G 2 2563e12c5d1SDavid du Colombier #define FP_E 0 2573e12c5d1SDavid du Colombier #define FP_CBIT (1<<23) 258