|
|
1.1 root 1: /*
2: * Cisco 7200 (Predator) simulation platform.
3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
4: */
5:
6: #ifndef __MIPS_64_H__
7: #define __MIPS_64_H__
8:
9: #include <pthread.h>
10:
11: #include "utils.h"
12: #include "rbtree.h"
13:
14: /* MIPS General Purpose Registers */
15: #define MIPS_GPR_ZERO 0 /* zero */
16: #define MIPS_GPR_AT 1 /* at */
17: #define MIPS_GPR_V0 2 /* v0 */
18: #define MIPS_GPR_V1 3 /* v1 */
19: #define MIPS_GPR_A0 4 /* a0 */
20: #define MIPS_GPR_A1 5 /* a1 */
21: #define MIPS_GPR_A2 6 /* a2 */
22: #define MIPS_GPR_A3 7 /* a3 */
23: #define MIPS_GPR_T0 8 /* t0 */
24: #define MIPS_GPR_T1 9 /* t1 */
25: #define MIPS_GPR_T2 10 /* t2 */
26: #define MIPS_GPR_T3 11 /* t3 */
27: #define MIPS_GPR_T4 12 /* t4 */
28: #define MIPS_GPR_T5 13 /* t5 */
29: #define MIPS_GPR_T6 14 /* t6 */
30: #define MIPS_GPR_T7 15 /* t7 */
31: #define MIPS_GPR_S0 16 /* s0 */
32: #define MIPS_GPR_S1 17 /* s1 */
33: #define MIPS_GPR_S2 18 /* s2 */
34: #define MIPS_GPR_S3 19 /* s3 */
35: #define MIPS_GPR_S4 20 /* s4 */
36: #define MIPS_GPR_S5 21 /* s5 */
37: #define MIPS_GPR_S6 22 /* s6 */
38: #define MIPS_GPR_S7 23 /* s7 */
39: #define MIPS_GPR_T8 24 /* t8 */
40: #define MIPS_GPR_T9 25 /* t9 */
41: #define MIPS_GPR_K0 26 /* k0 */
42: #define MIPS_GPR_K1 27 /* k1 */
43: #define MIPS_GPR_GP 28 /* gp */
44: #define MIPS_GPR_SP 29 /* sp */
45: #define MIPS_GPR_FP 30 /* fp */
46: #define MIPS_GPR_RA 31 /* ra */
47:
48: /*
49: * Coprocessor 0 (System Coprocessor) Register definitions
50: */
51: #define MIPS_CP0_INDEX 0 /* TLB Index */
52: #define MIPS_CP0_RANDOM 1 /* TLB Random */
53: #define MIPS_CP0_TLB_LO_0 2 /* TLB Entry Lo0 */
54: #define MIPS_CP0_TLB_LO_1 3 /* TLB Entry Lo1 */
55: #define MIPS_CP0_CONTEXT 4 /* Kernel PTE pointer */
56: #define MIPS_CP0_PAGEMASK 5 /* TLB Page Mask */
57: #define MIPS_CP0_WIRED 6 /* TLB Wired */
58: #define MIPS_CP0_BADVADDR 8 /* Bad Virtual Address */
59: #define MIPS_CP0_COUNT 9 /* Count */
60: #define MIPS_CP0_TLB_HI 10 /* TLB Entry Hi */
61: #define MIPS_CP0_COMPARE 11 /* Timer Compare */
62: #define MIPS_CP0_STATUS 12 /* Status */
63: #define MIPS_CP0_CAUSE 13 /* Cause */
64: #define MIPS_CP0_EPC 14 /* Exception PC */
65: #define MIPS_CP0_PRID 15 /* Proc Rev ID */
66: #define MIPS_CP0_CONFIG 16 /* Configuration */
67: #define MIPS_CP0_LLADDR 17 /* Load/Link address */
68: #define MIPS_CP0_WATCHLO 18 /* Low Watch address */
69: #define MIPS_CP0_WATCHHI 19 /* High Watch address */
70: #define MIPS_CP0_XCONTEXT 20 /* Extended context */
71: #define MIPS_CP0_ECC 26 /* ECC and parity */
72: #define MIPS_CP0_CACHERR 27 /* Cache Err/Status */
73: #define MIPS_CP0_TAGLO 28 /* Cache Tag Lo */
74: #define MIPS_CP0_TAGHI 29 /* Cache Tag Hi */
75: #define MIPS_CP0_ERR_EPC 30 /* Error exception PC */
76:
77: /*
78: * CP0 Status Register
79: */
80: #define MIPS_CP0_STATUS_CU0 0x10000000
81: #define MIPS_CP0_STATUS_CU1 0x20000000
82: #define MIPS_CP0_STATUS_BEV 0x00400000
83: #define MIPS_CP0_STATUS_TS 0x00200000
84: #define MIPS_CP0_STATUS_SR 0x00100000
85: #define MIPS_CP0_STATUS_CH 0x00040000
86: #define MIPS_CP0_STATUS_CE 0x00020000
87: #define MIPS_CP0_STATUS_DE 0x00010000
88: #define MIPS_CP0_STATUS_RP 0x08000000
89: #define MIPS_CP0_STATUS_FR 0x04000000
90: #define MIPS_CP0_STATUS_RE 0x02000000
91: #define MIPS_CP0_STATUS_KX 0x00000080
92: #define MIPS_CP0_STATUS_SX 0x00000040
93: #define MIPS_CP0_STATUS_UX 0x00000020
94: #define MIPS_CP0_STATUS_KSU 0x00000018
95: #define MIPS_CP0_STATUS_ERL 0x00000004
96: #define MIPS_CP0_STATUS_EXL 0x00000002
97: #define MIPS_CP0_STATUS_IE 0x00000001
98: #define MIPS_CP0_STATUS_IMASK8 0x00000000
99: #define MIPS_CP0_STATUS_IMASK7 0x00008000
100: #define MIPS_CP0_STATUS_IMASK6 0x00004000
101: #define MIPS_CP0_STATUS_IMASK5 0x00002000
102: #define MIPS_CP0_STATUS_IMASK4 0x00001000
103: #define MIPS_CP0_STATUS_IMASK3 0x00000800
104: #define MIPS_CP0_STATUS_IMASK2 0x00000400
105: #define MIPS_CP0_STATUS_IMASK1 0x00000200
106: #define MIPS_CP0_STATUS_IMASK0 0x00000100
107:
108: #define MIPS_CP0_STATUS_DS_MASK 0x00770000
109: #define MIPS_CP0_STATUS_CU_MASK 0xF0000000
110: #define MIPS_CP0_STATUS_IMASK 0x0000FF00
111:
112: /* Addressing mode: Kernel, Supervisor and User */
113: #define MIPS_CP0_STATUS_KSU_SHIFT 0x03
114: #define MIPS_CP0_STATUS_KSU_MASK 0x03
115:
116: #define MIPS_CP0_STATUS_KM 0x00
117: #define MIPS_CP0_STATUS_SM 0x01
118: #define MIPS_CP0_STATUS_UM 0x10
119:
120:
121: /*
122: * CP0 Cause register
123: */
124: #define MIPS_CP0_CAUSE_BD_SLOT 0x80000000
125:
126: #define MIPS_CP0_CAUSE_MASK 0x0000007C
127: #define MIPS_CP0_CAUSE_CEMASK 0x30000000
128: #define MIPS_CP0_CAUSE_IMASK 0x0000FF00
129:
130: #define MIPS_CP0_CAUSE_SHIFT 2
131: #define MIPS_CP0_CAUSE_CESHIFT 28
132: #define MIPS_CP0_CAUSE_ISHIFT 8
133:
134: #define MIPS_CP0_CAUSE_INTERRUPT 0
135: #define MIPS_CP0_CAUSE_TLB_MOD 1
136: #define MIPS_CP0_CAUSE_TLB_LOAD 2
137: #define MIPS_CP0_CAUSE_TLB_SAVE 3
138: #define MIPS_CP0_CAUSE_ADDR_LOAD 4 /* ADEL */
139: #define MIPS_CP0_CAUSE_ADDR_SAVE 5 /* ADES */
140: #define MIPS_CP0_CAUSE_BUS_INSTR 6
141: #define MIPS_CP0_CAUSE_BUS_DATA 7
142: #define MIPS_CP0_CAUSE_SYSCALL 8
143: #define MIPS_CP0_CAUSE_BP 9
144: #define MIPS_CP0_CAUSE_ILLOP 10
145: #define MIPS_CP0_CAUSE_CP_UNUSABLE 11
146: #define MIPS_CP0_CAUSE_OVFLW 12
147: #define MIPS_CP0_CAUSE_TRAP 13
148: #define MIPS_CP0_CAUSE_VC_INSTR 14 /* Virtual Coherency */
149: #define MIPS_CP0_CAUSE_FPE 15
150: #define MIPS_CP0_CAUSE_WATCH 23
151: #define MIPS_CP0_CAUSE_VC_DATA 31 /* Virtual Coherency */
152:
153: #define MIPS_CP0_CAUSE_IBIT7 0x00008000
154: #define MIPS_CP0_CAUSE_IBIT6 0x00004000
155: #define MIPS_CP0_CAUSE_IBIT5 0x00002000
156: #define MIPS_CP0_CAUSE_IBIT4 0x00001000
157: #define MIPS_CP0_CAUSE_IBIT3 0x00000800
158: #define MIPS_CP0_CAUSE_IBIT2 0x00000400
159: #define MIPS_CP0_CAUSE_IBIT1 0x00000200
160: #define MIPS_CP0_CAUSE_IBIT0 0x00000100
161:
162:
163: /* TLB masks and shifts */
164: #define MIPS_TLB_PAGE_MASK 0x01ffe000
165: #define MIPS_TLB_PAGE_SHIFT 13
166: #define MIPS_TLB_VPN2_MASK 0xffffffffffffe000ULL
167: #define MIPS_TLB_PFN_MASK 0x3fffffc0
168: #define MIPS_TLB_ASID_MASK 0x000000ff /* "asid" in EntryHi */
169: #define MIPS_TLB_G_MASK 0x00001000 /* "Global" in EntryHi */
170: #define MIPS_TLB_V_MASK 0x2 /* "Valid" in EntryLo */
171: #define MIPS_TLB_D_MASK 0x4 /* "Dirty" in EntryLo */
172:
173: #define MIPS_CP0_LO_G_MASK 0x00000001 /* "Global" in Lo0/1 reg */
174: #define MIPS_CP0_HI_SAFE_MASK 0xffffe0ff /* Safety mask for Hi reg */
175: #define MIPS_CP0_LO_SAFE_MASK 0x7fffffff /* Safety mask for Lo reg */
176:
177: /* MIPS "jr ra" instruction */
178: #define MIPS_INSN_JR_RA 0x03e00008
179:
180: /* Minimum page size: 4 Kb */
181: #define MIPS_MIN_PAGE_SIZE (1 << 12)
182:
183: /* Addressing mode: Kernel, Supervisor and User */
184: #define MIPS_MODE_KERNEL 00
185:
186: /* Segments in 32-bit User mode */
187: #define MIPS_USEG_BASE 0x00000000
188: #define MIPS_USEG_SIZE 0x80000000
189:
190: /* Segments in 32-bit Supervisor mode */
191: #define MIPS_SUSEG_BASE 0x00000000
192: #define MIPS_SUSEG_SIZE 0x80000000
193: #define MIPS_SSEG_BASE 0xc0000000
194: #define MIPS_SSEG_SIZE 0x20000000
195:
196: /* Segments in 32-bit Kernel mode */
197: #define MIPS_KUSEG_BASE 0x00000000
198: #define MIPS_KUSEG_SIZE 0x80000000
199:
200: #define MIPS_KSEG0_BASE 0x80000000
201: #define MIPS_KSEG0_SIZE 0x20000000
202:
203: #define MIPS_KSEG1_BASE 0xa0000000
204: #define MIPS_KSEG1_SIZE 0x20000000
205:
206: #define MIPS_KSSEG_BASE 0xc0000000
207: #define MIPS_KSSEG_SIZE 0x20000000
208:
209: #define MIPS_KSEG3_BASE 0xe0000000
210: #define MIPS_KSEG3_SIZE 0x20000000
211:
212: /* Macros for CPU structure access */
213: #define REG_OFFSET(reg) (OFFSET(cpu_mips_t,gpr[(reg)]))
214: #define CP0_REG_OFFSET(c0reg) (OFFSET(cpu_mips_t,cp0.reg[(c0reg)]))
215: #define MEMOP_OFFSET(op) (OFFSET(cpu_mips_t,mem_op_fn[(op)]))
216:
217: /* Initial Program Counter and Stack pointer for ROM */
218: #define MIPS_ROM_PC 0xffffffffbfc00000ULL
219: #define MIPS_ROM_SP 0xffffffff80004000ULL
220:
221: /* Number of GPR (general purpose registers) */
222: #define MIPS64_GPR_NR 32
223:
224: /* Number of registers in CP0 */
225: #define MIPS64_CP0_REG_NR 32
226:
227: /* Number of registers in CP1 */
228: #define MIPS64_CP1_REG_NR 32
229:
230: /* Number of TLB entries */
231: #define MIPS64_TLB_ENTRIES 64
232: #define MIPS64_TLB_IDX_MASK 0x3f /* 6 bits */
233:
234: /* Virtual CPU states */
235: enum {
236: MIPS_CPU_RUNNING = 0,
237: MIPS_CPU_HALTED,
238: MIPS_CPU_SUSPENDED,
239: };
240:
241: /* Memory operations */
242: enum {
243: MIPS_MEMOP_LB = 0,
244: MIPS_MEMOP_LBU,
245: MIPS_MEMOP_LH,
246: MIPS_MEMOP_LHU,
247: MIPS_MEMOP_LW,
248: MIPS_MEMOP_LWU,
249: MIPS_MEMOP_LD,
250: MIPS_MEMOP_SB,
251: MIPS_MEMOP_SH,
252: MIPS_MEMOP_SW,
253: MIPS_MEMOP_SD,
254:
255: MIPS_MEMOP_LWL,
256: MIPS_MEMOP_LWR,
257: MIPS_MEMOP_LDL,
258: MIPS_MEMOP_LDR,
259: MIPS_MEMOP_SWL,
260: MIPS_MEMOP_SWR,
261: MIPS_MEMOP_SDL,
262: MIPS_MEMOP_SDR,
263:
264: MIPS_MEMOP_LL,
265: MIPS_MEMOP_SC,
266:
267: MIPS_MEMOP_LDC1,
268: MIPS_MEMOP_SDC1,
269:
270: MIPS_MEMOP_CACHE,
271:
272: MIPS_MEMOP_MAX,
273: };
274:
275: /* 6 bits are reserved for device ID (see the memory subsystem) */
276: #define MIPS64_DEVICE_MAX (1 << 6)
277:
278: /* Number of recorded memory accesses (power of two) */
279: #define MEMLOG_COUNT 16
280:
281: /* Maximum number of breakpoints */
282: #define MIPS64_MAX_BREAKPOINTS 8
283:
284: typedef struct memlog_access memlog_access_t;
285: struct memlog_access {
286: m_uint64_t pc;
287: m_uint64_t vaddr;
288: m_uint64_t data;
289: m_uint32_t data_valid;
290: m_uint32_t op_size;
291: m_uint32_t op_type;
292: };
293:
294: /* MIPS CPU type */
295: typedef struct cpu_mips cpu_mips_t;
296:
297: /* Memory operation function prototype */
298: typedef fastcall u_int (*mips_memop_fn)(cpu_mips_t *cpu,m_uint64_t vaddr,
299: u_int reg);
300:
301: /* TLB entry definition */
302: typedef struct {
303: m_uint64_t mask;
304: m_uint64_t hi;
305: m_uint64_t lo0;
306: m_uint64_t lo1;
307: }tlb_entry_t;
308:
309: /* System Coprocessor (CP0) definition */
310: typedef struct {
311: m_uint64_t reg[MIPS64_CP0_REG_NR];
312: tlb_entry_t tlb[MIPS64_TLB_ENTRIES];
313: }mips_cp0_t;
314:
315: /* FPU Coprocessor (CP1) definition */
316: typedef struct {
317: m_uint64_t reg[MIPS64_CP1_REG_NR];
318: }mips_cp1_t;
319:
320: /* CPU definition */
321: struct cpu_mips {
322: m_uint64_t gpr[MIPS64_GPR_NR];
323: m_uint64_t pc;
324: m_uint64_t lo,hi;
325: m_uint32_t irq_pending;
326:
327: /* Red-Black tree to locate PC */
328: rbtree_tree *insn_block_tree;
329:
330: /* MTS 1st level array */
331: void *mts_l1_ptr;
332:
333: /* MTS32 array free list */
334: void *mts32_l2_free_list;
335:
336: /* Memory lookup function (to load ELF image,...) */
337: void *(*mem_op_lookup)(cpu_mips_t *cpu,m_uint64_t vaddr);
338:
339: /* Memory access functions */
340: mips_memop_fn mem_op_fn[MIPS_MEMOP_MAX];
341:
342: /* LL/SC information */
343: u_int ll_bit;
344:
345: /* Virtual version of CP0 Compare Register */
346: m_uint32_t cp0_virt_cmp_reg;
347: m_uint32_t cp0_virt_cnt_reg;
348:
349: /* Address bus mask */
350: m_uint64_t addr_bus_mask;
351:
352: /* System coprocessor (CP0) */
353: mips_cp0_t cp0;
354:
355: /* FPU (CP1) */
356: mips_cp1_t fpu;
357:
358: /* CPU identifier for MP systems and CPU state */
359: u_int id,state;
360:
361: /* Next CPU in group */
362: cpu_mips_t *next;
363:
364: /* Memory mapped devices */
365: struct vdevice *dev_array[MIPS64_DEVICE_MAX];
366:
367: /* Thread running this CPU */
368: pthread_t cpu_thread;
369:
370: /* Memory access log for fault debugging */
371: u_int memlog_pos;
372: memlog_access_t memlog_array[MEMLOG_COUNT];
373:
374: /* Breakpoints */
375: m_uint64_t breakpoints[MIPS64_MAX_BREAKPOINTS];
376: u_int breakpoint_enabled;
377:
378: /* non-JIT mode instruction counter */
379: m_uint64_t insn_exec_count;
380: };
381:
382: /* Register names */
383: extern char *mips64_gpr_reg_names[];
384:
385: /* Initialize a MIPS64 processor */
386: void mips64_init(cpu_mips_t *cpu);
387:
388: /* Update the IRQ flag */
389: void mips64_update_irq_flag(cpu_mips_t *cpu);
390:
391: /* Generate an exception */
392: void mips64_trigger_exception(cpu_mips_t *cpu,u_int exc_code,int bd_slot);
393:
394: /*
395: * Increment count register and trigger the timer IRQ if value in compare
396: * register is the same.
397: */
398: fastcall void mips64_exec_inc_cp0_cnt(cpu_mips_t *cpu);
399:
400: /* Trigger the Timer IRQ */
401: fastcall void mips64_trigger_timer_irq(cpu_mips_t *cpu);
402:
403: /* Execute ERET instruction */
404: fastcall void mips64_exec_eret(cpu_mips_t *cpu);
405:
406: /* Execute SYSCALL instruction */
407: fastcall void mips64_exec_syscall(cpu_mips_t *cpu);
408:
409: /* Execute BREAK instruction */
410: fastcall void mips64_exec_break(cpu_mips_t *cpu,u_int code);
411:
412: /* Trigger a Trap Exception */
413: asmlinkage void mips64_trigger_trap_exception(cpu_mips_t *cpu);
414:
415: /* Trigger IRQs */
416: fastcall void mips64_trigger_irq(cpu_mips_t *cpu);
417:
418: /* Set an IRQ */
419: void mips64_set_irq(cpu_mips_t *cpu,u_int irq);
420:
421: /* Clear an IRQ */
422: void mips64_clear_irq(cpu_mips_t *cpu,u_int irq);
423:
424: /* DMFC1 */
425: fastcall void mips64_exec_dmfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg);
426:
427: /* DMTC1 */
428: fastcall void mips64_exec_dmtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg);
429:
430: /* MFC1 */
431: fastcall void mips64_exec_mfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg);
432:
433: /* MTC1 */
434: fastcall void mips64_exec_mtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg);
435:
436: /* Virtual breakpoint */
437: fastcall void mips64_run_breakpoint(cpu_mips_t *cpu);
438:
439: /* Dump registers of a MIPS64 processor */
440: void mips64_dump_regs(cpu_mips_t *cpu);
441:
442: /* Dump a memory block */
443: void mips64_dump_memory(cpu_mips_t *cpu,m_uint64_t vaddr,u_int count);
444:
445: /* Dump the stack */
446: void mips64_dump_stack(cpu_mips_t *cpu,u_int count);
447:
448: /* Save the CPU state into a file */
449: int mips64_save_state(cpu_mips_t *cpu,char *filename);
450:
451: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.