1 |
/* |
2 |
* Cisco router simulation platform. |
3 |
* Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) |
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 |
/* |
15 |
* MIPS General Purpose Registers |
16 |
*/ |
17 |
#define MIPS_GPR_ZERO 0 /* zero */ |
18 |
#define MIPS_GPR_AT 1 /* at */ |
19 |
#define MIPS_GPR_V0 2 /* v0 */ |
20 |
#define MIPS_GPR_V1 3 /* v1 */ |
21 |
#define MIPS_GPR_A0 4 /* a0 */ |
22 |
#define MIPS_GPR_A1 5 /* a1 */ |
23 |
#define MIPS_GPR_A2 6 /* a2 */ |
24 |
#define MIPS_GPR_A3 7 /* a3 */ |
25 |
#define MIPS_GPR_T0 8 /* t0 */ |
26 |
#define MIPS_GPR_T1 9 /* t1 */ |
27 |
#define MIPS_GPR_T2 10 /* t2 */ |
28 |
#define MIPS_GPR_T3 11 /* t3 */ |
29 |
#define MIPS_GPR_T4 12 /* t4 */ |
30 |
#define MIPS_GPR_T5 13 /* t5 */ |
31 |
#define MIPS_GPR_T6 14 /* t6 */ |
32 |
#define MIPS_GPR_T7 15 /* t7 */ |
33 |
#define MIPS_GPR_S0 16 /* s0 */ |
34 |
#define MIPS_GPR_S1 17 /* s1 */ |
35 |
#define MIPS_GPR_S2 18 /* s2 */ |
36 |
#define MIPS_GPR_S3 19 /* s3 */ |
37 |
#define MIPS_GPR_S4 20 /* s4 */ |
38 |
#define MIPS_GPR_S5 21 /* s5 */ |
39 |
#define MIPS_GPR_S6 22 /* s6 */ |
40 |
#define MIPS_GPR_S7 23 /* s7 */ |
41 |
#define MIPS_GPR_T8 24 /* t8 */ |
42 |
#define MIPS_GPR_T9 25 /* t9 */ |
43 |
#define MIPS_GPR_K0 26 /* k0 */ |
44 |
#define MIPS_GPR_K1 27 /* k1 */ |
45 |
#define MIPS_GPR_GP 28 /* gp */ |
46 |
#define MIPS_GPR_SP 29 /* sp */ |
47 |
#define MIPS_GPR_FP 30 /* fp */ |
48 |
#define MIPS_GPR_RA 31 /* ra */ |
49 |
|
50 |
/* |
51 |
* Coprocessor 0 (System Coprocessor) Register definitions |
52 |
*/ |
53 |
#define MIPS_CP0_INDEX 0 /* TLB Index */ |
54 |
#define MIPS_CP0_RANDOM 1 /* TLB Random */ |
55 |
#define MIPS_CP0_TLB_LO_0 2 /* TLB Entry Lo0 */ |
56 |
#define MIPS_CP0_TLB_LO_1 3 /* TLB Entry Lo1 */ |
57 |
#define MIPS_CP0_CONTEXT 4 /* Kernel PTE pointer */ |
58 |
#define MIPS_CP0_PAGEMASK 5 /* TLB Page Mask */ |
59 |
#define MIPS_CP0_WIRED 6 /* TLB Wired */ |
60 |
#define MIPS_CP0_INFO 7 /* Info (RM7000) */ |
61 |
#define MIPS_CP0_BADVADDR 8 /* Bad Virtual Address */ |
62 |
#define MIPS_CP0_COUNT 9 /* Count */ |
63 |
#define MIPS_CP0_TLB_HI 10 /* TLB Entry Hi */ |
64 |
#define MIPS_CP0_COMPARE 11 /* Timer Compare */ |
65 |
#define MIPS_CP0_STATUS 12 /* Status */ |
66 |
#define MIPS_CP0_CAUSE 13 /* Cause */ |
67 |
#define MIPS_CP0_EPC 14 /* Exception PC */ |
68 |
#define MIPS_CP0_PRID 15 /* Proc Rev ID */ |
69 |
#define MIPS_CP0_CONFIG 16 /* Configuration */ |
70 |
#define MIPS_CP0_LLADDR 17 /* Load/Link address */ |
71 |
#define MIPS_CP0_WATCHLO 18 /* Low Watch address */ |
72 |
#define MIPS_CP0_WATCHHI 19 /* High Watch address */ |
73 |
#define MIPS_CP0_XCONTEXT 20 /* Extended context */ |
74 |
#define MIPS_CP0_ECC 26 /* ECC and parity */ |
75 |
#define MIPS_CP0_CACHERR 27 /* Cache Err/Status */ |
76 |
#define MIPS_CP0_TAGLO 28 /* Cache Tag Lo */ |
77 |
#define MIPS_CP0_TAGHI 29 /* Cache Tag Hi */ |
78 |
#define MIPS_CP0_ERR_EPC 30 /* Error exception PC */ |
79 |
|
80 |
/* |
81 |
* CP0 Set 1 Registers (R7000) |
82 |
*/ |
83 |
#define MIPS_CP0_S1_CONFIG 16 /* Configuration Register */ |
84 |
#define MIPS_CP0_S1_IPLLO 18 /* Priority level for IRQ [7:0] */ |
85 |
#define MIPS_CP0_S1_IPLHI 19 /* Priority level for IRQ [15:8] */ |
86 |
#define MIPS_CP0_S1_INTCTL 20 /* Interrupt Control */ |
87 |
#define MIPS_CP0_S1_DERRADDR0 26 /* Imprecise Error Address */ |
88 |
#define MIPS_CP0_S1_DERRADDR1 27 /* Imprecise Error Address */ |
89 |
|
90 |
/* |
91 |
* CP0 Status Register |
92 |
*/ |
93 |
#define MIPS_CP0_STATUS_CU0 0x10000000 |
94 |
#define MIPS_CP0_STATUS_CU1 0x20000000 |
95 |
#define MIPS_CP0_STATUS_BEV 0x00400000 |
96 |
#define MIPS_CP0_STATUS_TS 0x00200000 |
97 |
#define MIPS_CP0_STATUS_SR 0x00100000 |
98 |
#define MIPS_CP0_STATUS_CH 0x00040000 |
99 |
#define MIPS_CP0_STATUS_CE 0x00020000 |
100 |
#define MIPS_CP0_STATUS_DE 0x00010000 |
101 |
#define MIPS_CP0_STATUS_RP 0x08000000 |
102 |
#define MIPS_CP0_STATUS_FR 0x04000000 |
103 |
#define MIPS_CP0_STATUS_RE 0x02000000 |
104 |
#define MIPS_CP0_STATUS_KX 0x00000080 |
105 |
#define MIPS_CP0_STATUS_SX 0x00000040 |
106 |
#define MIPS_CP0_STATUS_UX 0x00000020 |
107 |
#define MIPS_CP0_STATUS_KSU 0x00000018 |
108 |
#define MIPS_CP0_STATUS_ERL 0x00000004 |
109 |
#define MIPS_CP0_STATUS_EXL 0x00000002 |
110 |
#define MIPS_CP0_STATUS_IE 0x00000001 |
111 |
#define MIPS_CP0_STATUS_IMASK7 0x00008000 |
112 |
#define MIPS_CP0_STATUS_IMASK6 0x00004000 |
113 |
#define MIPS_CP0_STATUS_IMASK5 0x00002000 |
114 |
#define MIPS_CP0_STATUS_IMASK4 0x00001000 |
115 |
#define MIPS_CP0_STATUS_IMASK3 0x00000800 |
116 |
#define MIPS_CP0_STATUS_IMASK2 0x00000400 |
117 |
#define MIPS_CP0_STATUS_IMASK1 0x00000200 |
118 |
#define MIPS_CP0_STATUS_IMASK0 0x00000100 |
119 |
|
120 |
#define MIPS_CP0_STATUS_DS_MASK 0x00770000 |
121 |
#define MIPS_CP0_STATUS_CU_MASK 0xF0000000 |
122 |
#define MIPS_CP0_STATUS_IMASK 0x0000FF00 |
123 |
|
124 |
/* Addressing mode: Kernel, Supervisor and User */ |
125 |
#define MIPS_CP0_STATUS_KSU_SHIFT 0x03 |
126 |
#define MIPS_CP0_STATUS_KSU_MASK 0x03 |
127 |
|
128 |
#define MIPS_CP0_STATUS_KM 0x00 |
129 |
#define MIPS_CP0_STATUS_SM 0x01 |
130 |
#define MIPS_CP0_STATUS_UM 0x10 |
131 |
|
132 |
|
133 |
/* |
134 |
* CP0 Cause register |
135 |
*/ |
136 |
#define MIPS_CP0_CAUSE_BD_SLOT 0x80000000 |
137 |
|
138 |
#define MIPS_CP0_CAUSE_MASK 0x0000007C |
139 |
#define MIPS_CP0_CAUSE_CEMASK 0x30000000 |
140 |
#define MIPS_CP0_CAUSE_IMASK 0x0000FF00 |
141 |
|
142 |
#define MIPS_CP0_CAUSE_SHIFT 2 |
143 |
#define MIPS_CP0_CAUSE_CESHIFT 28 |
144 |
#define MIPS_CP0_CAUSE_ISHIFT 8 |
145 |
|
146 |
#define MIPS_CP0_CAUSE_INTERRUPT 0 |
147 |
#define MIPS_CP0_CAUSE_TLB_MOD 1 |
148 |
#define MIPS_CP0_CAUSE_TLB_LOAD 2 |
149 |
#define MIPS_CP0_CAUSE_TLB_SAVE 3 |
150 |
#define MIPS_CP0_CAUSE_ADDR_LOAD 4 /* ADEL */ |
151 |
#define MIPS_CP0_CAUSE_ADDR_SAVE 5 /* ADES */ |
152 |
#define MIPS_CP0_CAUSE_BUS_INSTR 6 |
153 |
#define MIPS_CP0_CAUSE_BUS_DATA 7 |
154 |
#define MIPS_CP0_CAUSE_SYSCALL 8 |
155 |
#define MIPS_CP0_CAUSE_BP 9 |
156 |
#define MIPS_CP0_CAUSE_ILLOP 10 |
157 |
#define MIPS_CP0_CAUSE_CP_UNUSABLE 11 |
158 |
#define MIPS_CP0_CAUSE_OVFLW 12 |
159 |
#define MIPS_CP0_CAUSE_TRAP 13 |
160 |
#define MIPS_CP0_CAUSE_VC_INSTR 14 /* Virtual Coherency */ |
161 |
#define MIPS_CP0_CAUSE_FPE 15 |
162 |
#define MIPS_CP0_CAUSE_WATCH 23 |
163 |
#define MIPS_CP0_CAUSE_VC_DATA 31 /* Virtual Coherency */ |
164 |
|
165 |
#define MIPS_CP0_CAUSE_IBIT7 0x00008000 |
166 |
#define MIPS_CP0_CAUSE_IBIT6 0x00004000 |
167 |
#define MIPS_CP0_CAUSE_IBIT5 0x00002000 |
168 |
#define MIPS_CP0_CAUSE_IBIT4 0x00001000 |
169 |
#define MIPS_CP0_CAUSE_IBIT3 0x00000800 |
170 |
#define MIPS_CP0_CAUSE_IBIT2 0x00000400 |
171 |
#define MIPS_CP0_CAUSE_IBIT1 0x00000200 |
172 |
#define MIPS_CP0_CAUSE_IBIT0 0x00000100 |
173 |
|
174 |
|
175 |
/* TLB masks and shifts */ |
176 |
#define MIPS_TLB_PAGE_MASK 0x01ffe000 |
177 |
#define MIPS_TLB_PAGE_SHIFT 13 |
178 |
#define MIPS_TLB_VPN2_MASK_32 0xffffe000ULL |
179 |
#define MIPS_TLB_VPN2_MASK_64 0xc00000ffffffe000ULL |
180 |
#define MIPS_TLB_PFN_MASK 0x3fffffc0 |
181 |
#define MIPS_TLB_ASID_MASK 0x000000ff /* "asid" in EntryHi */ |
182 |
#define MIPS_TLB_G_MASK 0x00001000 /* "Global" in EntryHi */ |
183 |
#define MIPS_TLB_V_MASK 0x2 /* "Valid" in EntryLo */ |
184 |
#define MIPS_TLB_D_MASK 0x4 /* "Dirty" in EntryLo */ |
185 |
#define MIPS_TLB_C_MASK 0x38 /* Page Coherency Attribute */ |
186 |
#define MIPS_TLB_C_SHIFT 3 |
187 |
|
188 |
#define MIPS_CP0_LO_G_MASK 0x00000001 /* "Global" in Lo0/1 reg */ |
189 |
#define MIPS_CP0_HI_SAFE_MASK 0xffffe0ff /* Safety mask for Hi reg */ |
190 |
#define MIPS_CP0_LO_SAFE_MASK 0x7fffffff /* Safety mask for Lo reg */ |
191 |
|
192 |
/* MIPS "jr ra" instruction */ |
193 |
#define MIPS_INSN_JR_RA 0x03e00008 |
194 |
|
195 |
/* Minimum page size: 4 Kb */ |
196 |
#define MIPS_MIN_PAGE_SHIFT 12 |
197 |
#define MIPS_MIN_PAGE_SIZE (1 << MIPS_MIN_PAGE_SHIFT) |
198 |
#define MIPS_MIN_PAGE_IMASK (MIPS_MIN_PAGE_SIZE - 1) |
199 |
#define MIPS_MIN_PAGE_MASK 0xfffffffffffff000ULL |
200 |
|
201 |
/* Addressing mode: Kernel, Supervisor and User */ |
202 |
#define MIPS_MODE_KERNEL 00 |
203 |
|
204 |
/* Segments in 32-bit User mode */ |
205 |
#define MIPS_USEG_BASE 0x00000000 |
206 |
#define MIPS_USEG_SIZE 0x80000000 |
207 |
|
208 |
/* Segments in 32-bit Supervisor mode */ |
209 |
#define MIPS_SUSEG_BASE 0x00000000 |
210 |
#define MIPS_SUSEG_SIZE 0x80000000 |
211 |
#define MIPS_SSEG_BASE 0xc0000000 |
212 |
#define MIPS_SSEG_SIZE 0x20000000 |
213 |
|
214 |
/* Segments in 32-bit Kernel mode */ |
215 |
#define MIPS_KUSEG_BASE 0x00000000 |
216 |
#define MIPS_KUSEG_SIZE 0x80000000 |
217 |
|
218 |
#define MIPS_KSEG0_BASE 0x80000000 |
219 |
#define MIPS_KSEG0_SIZE 0x20000000 |
220 |
|
221 |
#define MIPS_KSEG1_BASE 0xa0000000 |
222 |
#define MIPS_KSEG1_SIZE 0x20000000 |
223 |
|
224 |
#define MIPS_KSSEG_BASE 0xc0000000 |
225 |
#define MIPS_KSSEG_SIZE 0x20000000 |
226 |
|
227 |
#define MIPS_KSEG3_BASE 0xe0000000 |
228 |
#define MIPS_KSEG3_SIZE 0x20000000 |
229 |
|
230 |
/* xkphys mask (36-bit physical address) */ |
231 |
#define MIPS64_XKPHYS_ZONE_MASK 0xF800000000000000ULL |
232 |
#define MIPS64_XKPHYS_PHYS_SIZE (1ULL << 36) |
233 |
#define MIPS64_XKPHYS_PHYS_MASK (MIPS64_XKPHYS_PHYS_SIZE - 1) |
234 |
#define MIPS64_XKPHYS_CCA_SHIFT 59 |
235 |
|
236 |
/* Initial Program Counter and Stack pointer for ROM */ |
237 |
#define MIPS_ROM_PC 0xffffffffbfc00000ULL |
238 |
#define MIPS_ROM_SP 0xffffffff80004000ULL |
239 |
|
240 |
/* Number of GPR (general purpose registers) */ |
241 |
#define MIPS64_GPR_NR 32 |
242 |
|
243 |
/* Number of registers in CP0 */ |
244 |
#define MIPS64_CP0_REG_NR 32 |
245 |
|
246 |
/* Number of registers in CP1 */ |
247 |
#define MIPS64_CP1_REG_NR 32 |
248 |
|
249 |
/* Number of TLB entries */ |
250 |
#define MIPS64_TLB_STD_ENTRIES 48 |
251 |
#define MIPS64_TLB_MAX_ENTRIES 64 |
252 |
#define MIPS64_TLB_IDX_MASK 0x3f /* 6 bits */ |
253 |
|
254 |
/* Enable the 64 TLB entries for R7000 CPU */ |
255 |
#define MIPS64_R7000_TLB64_ENABLE 0x20000000 |
256 |
|
257 |
/* Number of instructions per page */ |
258 |
#define MIPS_INSN_PER_PAGE (MIPS_MIN_PAGE_SIZE/sizeof(mips_insn_t)) |
259 |
|
260 |
/* MIPS CPU Identifiers */ |
261 |
#define MIPS_PRID_R4600 0x00002012 |
262 |
#define MIPS_PRID_R4700 0x00002112 |
263 |
#define MIPS_PRID_R5000 0x00002312 |
264 |
#define MIPS_PRID_R7000 0x00002721 |
265 |
#define MIPS_PRID_R527x 0x00002812 |
266 |
#define MIPS_PRID_BCM1250 0x00040102 |
267 |
|
268 |
/* Memory operations */ |
269 |
enum { |
270 |
MIPS_MEMOP_LOOKUP = 0, |
271 |
|
272 |
MIPS_MEMOP_LB, |
273 |
MIPS_MEMOP_LBU, |
274 |
MIPS_MEMOP_LH, |
275 |
MIPS_MEMOP_LHU, |
276 |
MIPS_MEMOP_LW, |
277 |
MIPS_MEMOP_LWU, |
278 |
MIPS_MEMOP_LD, |
279 |
MIPS_MEMOP_SB, |
280 |
MIPS_MEMOP_SH, |
281 |
MIPS_MEMOP_SW, |
282 |
MIPS_MEMOP_SD, |
283 |
|
284 |
MIPS_MEMOP_LWL, |
285 |
MIPS_MEMOP_LWR, |
286 |
MIPS_MEMOP_LDL, |
287 |
MIPS_MEMOP_LDR, |
288 |
MIPS_MEMOP_SWL, |
289 |
MIPS_MEMOP_SWR, |
290 |
MIPS_MEMOP_SDL, |
291 |
MIPS_MEMOP_SDR, |
292 |
|
293 |
MIPS_MEMOP_LL, |
294 |
MIPS_MEMOP_SC, |
295 |
|
296 |
MIPS_MEMOP_LDC1, |
297 |
MIPS_MEMOP_SDC1, |
298 |
|
299 |
MIPS_MEMOP_CACHE, |
300 |
|
301 |
MIPS_MEMOP_MAX, |
302 |
}; |
303 |
|
304 |
/* Maximum number of breakpoints */ |
305 |
#define MIPS64_MAX_BREAKPOINTS 8 |
306 |
|
307 |
/* MIPS CPU type */ |
308 |
typedef struct cpu_mips cpu_mips_t; |
309 |
|
310 |
/* Memory operation function prototype */ |
311 |
typedef fastcall void (*mips_memop_fn)(cpu_mips_t *cpu,m_uint64_t vaddr, |
312 |
u_int reg); |
313 |
|
314 |
/* TLB entry definition */ |
315 |
typedef struct { |
316 |
m_uint64_t mask; |
317 |
m_uint64_t hi; |
318 |
m_uint64_t lo0; |
319 |
m_uint64_t lo1; |
320 |
}tlb_entry_t; |
321 |
|
322 |
/* System Coprocessor (CP0) definition */ |
323 |
typedef struct { |
324 |
m_uint64_t reg[MIPS64_CP0_REG_NR]; |
325 |
tlb_entry_t tlb[MIPS64_TLB_MAX_ENTRIES]; |
326 |
|
327 |
/* Number of TLB entries */ |
328 |
u_int tlb_entries; |
329 |
|
330 |
/* Extensions for R7000 CP0 Set1 */ |
331 |
m_uint32_t ipl_lo,ipl_hi,int_ctl; |
332 |
m_uint32_t derraddr0,derraddr1; |
333 |
}mips_cp0_t; |
334 |
|
335 |
/* FPU Coprocessor (CP1) definition */ |
336 |
typedef struct { |
337 |
m_uint64_t reg[MIPS64_CP1_REG_NR]; |
338 |
}mips_cp1_t; |
339 |
|
340 |
/* MIPS CPU definition */ |
341 |
struct cpu_mips { |
342 |
/* MTS32/MTS64 caches */ |
343 |
union { |
344 |
mts32_entry_t *mts32_cache; |
345 |
mts64_entry_t *mts64_cache; |
346 |
}mts_u; |
347 |
|
348 |
/* Virtual version of CP0 Compare Register */ |
349 |
m_uint32_t cp0_virt_cnt_reg,cp0_virt_cmp_reg; |
350 |
|
351 |
/* General Purpose Registers, Pointer Counter, LO/HI, IRQ */ |
352 |
m_uint32_t irq_pending,irq_cause,ll_bit; |
353 |
m_uint64_t pc,gpr[MIPS64_GPR_NR]; |
354 |
m_uint64_t lo,hi,ret_pc; |
355 |
|
356 |
/* Code page translation cache */ |
357 |
mips64_jit_tcb_t **exec_blk_map; |
358 |
|
359 |
/* Virtual address to physical page translation */ |
360 |
fastcall int (*translate)(cpu_mips_t *cpu,m_uint64_t vaddr, |
361 |
m_uint32_t *phys_page); |
362 |
|
363 |
/* Memory access functions */ |
364 |
mips_memop_fn mem_op_fn[MIPS_MEMOP_MAX]; |
365 |
|
366 |
/* Memory lookup function (to load ELF image,...) */ |
367 |
void *(*mem_op_lookup)(cpu_mips_t *cpu,m_uint64_t vaddr); |
368 |
|
369 |
/* System coprocessor (CP0) */ |
370 |
mips_cp0_t cp0; |
371 |
|
372 |
/* FPU (CP1) */ |
373 |
mips_cp1_t fpu; |
374 |
|
375 |
/* Address bus mask for physical addresses */ |
376 |
m_uint64_t addr_bus_mask; |
377 |
|
378 |
/* IRQ counters and cause */ |
379 |
m_uint64_t irq_count,timer_irq_count,irq_fp_count; |
380 |
pthread_mutex_t irq_lock; |
381 |
|
382 |
/* Current and free lists of translated code blocks */ |
383 |
mips64_jit_tcb_t *tcb_list,*tcb_last,*tcb_free_list; |
384 |
|
385 |
/* Executable page area */ |
386 |
void *exec_page_area; |
387 |
size_t exec_page_area_size; |
388 |
size_t exec_page_count,exec_page_alloc; |
389 |
insn_exec_page_t *exec_page_free_list; |
390 |
insn_exec_page_t *exec_page_array; |
391 |
|
392 |
/* Idle PC value */ |
393 |
volatile m_uint64_t idle_pc; |
394 |
|
395 |
/* Timer IRQs */ |
396 |
volatile u_int timer_irq_pending; |
397 |
u_int timer_irq_freq; |
398 |
u_int timer_irq_check_itv; |
399 |
u_int timer_drift; |
400 |
|
401 |
/* IRQ disable flag */ |
402 |
volatile u_int irq_disable; |
403 |
|
404 |
/* IRQ idling preemption */ |
405 |
u_int irq_idle_preempt[8]; |
406 |
|
407 |
/* Generic CPU instance pointer */ |
408 |
cpu_gen_t *gen; |
409 |
|
410 |
/* VM instance */ |
411 |
vm_instance_t *vm; |
412 |
|
413 |
/* non-JIT mode instruction counter */ |
414 |
m_uint64_t insn_exec_count; |
415 |
|
416 |
/* MTS map/unmap/rebuild operations */ |
417 |
void (*mts_map)(cpu_mips_t *cpu,m_uint64_t vaddr, |
418 |
m_uint64_t paddr,m_uint32_t len, |
419 |
int cache_access,int tlb_index); |
420 |
|
421 |
void (*mts_unmap)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint32_t len, |
422 |
m_uint32_t val,int tlb_index); |
423 |
|
424 |
void (*mts_shutdown)(cpu_mips_t *cpu); |
425 |
|
426 |
/* MTS cache statistics */ |
427 |
m_uint64_t mts_misses,mts_lookups; |
428 |
|
429 |
/* JIT flush method */ |
430 |
u_int jit_flush_method; |
431 |
|
432 |
/* Number of compiled pages */ |
433 |
u_int compiled_pages; |
434 |
|
435 |
/* Fast memory operations use */ |
436 |
u_int fast_memop; |
437 |
|
438 |
/* Direct block jump */ |
439 |
u_int exec_blk_direct_jump; |
440 |
|
441 |
/* Address mode (32 or 64 bits) */ |
442 |
u_int addr_mode; |
443 |
|
444 |
/* Current exec page (non-JIT) info */ |
445 |
m_uint64_t njm_exec_page; |
446 |
mips_insn_t *njm_exec_ptr; |
447 |
|
448 |
/* Performance counter (number of instructions executed by CPU) */ |
449 |
m_uint32_t perf_counter; |
450 |
|
451 |
/* Breakpoints */ |
452 |
m_uint64_t breakpoints[MIPS64_MAX_BREAKPOINTS]; |
453 |
u_int breakpoints_enabled; |
454 |
|
455 |
/* Symtrace */ |
456 |
int sym_trace; |
457 |
rbtree_tree *sym_tree; |
458 |
}; |
459 |
|
460 |
#define MIPS64_IRQ_LOCK(cpu) pthread_mutex_lock(&(cpu)->irq_lock) |
461 |
#define MIPS64_IRQ_UNLOCK(cpu) pthread_mutex_unlock(&(cpu)->irq_lock) |
462 |
|
463 |
/* Register names */ |
464 |
extern char *mips64_gpr_reg_names[]; |
465 |
|
466 |
/* Get cacheability info */ |
467 |
int mips64_cca_cached(m_uint8_t val); |
468 |
|
469 |
/* Reset a MIPS64 CPU */ |
470 |
int mips64_reset(cpu_mips_t *cpu); |
471 |
|
472 |
/* Initialize a MIPS64 processor */ |
473 |
int mips64_init(cpu_mips_t *cpu); |
474 |
|
475 |
/* Delete a MIPS64 processor */ |
476 |
void mips64_delete(cpu_mips_t *cpu); |
477 |
|
478 |
/* Set the CPU PRID register */ |
479 |
void mips64_set_prid(cpu_mips_t *cpu,m_uint32_t prid); |
480 |
|
481 |
/* Set idle PC value */ |
482 |
void mips64_set_idle_pc(cpu_gen_t *cpu,m_uint64_t addr); |
483 |
|
484 |
/* Timer IRQ */ |
485 |
void *mips64_timer_irq_run(cpu_mips_t *cpu); |
486 |
|
487 |
/* Determine an "idling" PC */ |
488 |
int mips64_get_idling_pc(cpu_gen_t *cpu); |
489 |
|
490 |
/* Set an IRQ (VM IRQ standard routing) */ |
491 |
void mips64_vm_set_irq(vm_instance_t *vm,u_int irq); |
492 |
|
493 |
/* Clear an IRQ (VM IRQ standard routing) */ |
494 |
void mips64_vm_clear_irq(vm_instance_t *vm,u_int irq); |
495 |
|
496 |
/* Update the IRQ flag */ |
497 |
void mips64_update_irq_flag(cpu_mips_t *cpu); |
498 |
|
499 |
/* Generate an exception */ |
500 |
void mips64_trigger_exception(cpu_mips_t *cpu,u_int exc_code,int bd_slot); |
501 |
|
502 |
/* |
503 |
* Increment count register and trigger the timer IRQ if value in compare |
504 |
* register is the same. |
505 |
*/ |
506 |
fastcall void mips64_exec_inc_cp0_cnt(cpu_mips_t *cpu); |
507 |
|
508 |
/* Trigger the Timer IRQ */ |
509 |
fastcall void mips64_trigger_timer_irq(cpu_mips_t *cpu); |
510 |
|
511 |
/* Execute ERET instruction */ |
512 |
fastcall void mips64_exec_eret(cpu_mips_t *cpu); |
513 |
|
514 |
/* Execute SYSCALL instruction */ |
515 |
fastcall void mips64_exec_syscall(cpu_mips_t *cpu); |
516 |
|
517 |
/* Execute BREAK instruction */ |
518 |
fastcall void mips64_exec_break(cpu_mips_t *cpu,u_int code); |
519 |
|
520 |
/* Trigger a Trap Exception */ |
521 |
fastcall void mips64_trigger_trap_exception(cpu_mips_t *cpu); |
522 |
|
523 |
/* Trigger IRQs */ |
524 |
fastcall void mips64_trigger_irq(cpu_mips_t *cpu); |
525 |
|
526 |
/* Set an IRQ */ |
527 |
void mips64_set_irq(cpu_mips_t *cpu,m_uint8_t irq); |
528 |
|
529 |
/* Clear an IRQ */ |
530 |
void mips64_clear_irq(cpu_mips_t *cpu,m_uint8_t irq); |
531 |
|
532 |
/* DMFC1 */ |
533 |
fastcall void mips64_exec_dmfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); |
534 |
|
535 |
/* DMTC1 */ |
536 |
fastcall void mips64_exec_dmtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); |
537 |
|
538 |
/* MFC1 */ |
539 |
fastcall void mips64_exec_mfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); |
540 |
|
541 |
/* MTC1 */ |
542 |
fastcall void mips64_exec_mtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); |
543 |
|
544 |
/* Virtual breakpoint */ |
545 |
fastcall void mips64_run_breakpoint(cpu_mips_t *cpu); |
546 |
|
547 |
/* Add a virtual breakpoint */ |
548 |
int mips64_add_breakpoint(cpu_gen_t *cpu,m_uint64_t pc); |
549 |
|
550 |
/* Remove a virtual breakpoint */ |
551 |
void mips64_remove_breakpoint(cpu_gen_t *cpu,m_uint64_t pc); |
552 |
|
553 |
/* Debugging for register-jump to address 0 */ |
554 |
fastcall void mips64_debug_jr0(cpu_mips_t *cpu); |
555 |
|
556 |
/* Set a register */ |
557 |
void mips64_reg_set(cpu_gen_t *cpu,u_int reg,m_uint64_t val); |
558 |
|
559 |
/* Dump registers of a MIPS64 processor */ |
560 |
void mips64_dump_regs(cpu_gen_t *cpu); |
561 |
|
562 |
/* Dump a memory block */ |
563 |
void mips64_dump_memory(cpu_mips_t *cpu,m_uint64_t vaddr,u_int count); |
564 |
|
565 |
/* Dump the stack */ |
566 |
void mips64_dump_stack(cpu_mips_t *cpu,u_int count); |
567 |
|
568 |
/* Save the CPU state into a file */ |
569 |
int mips64_save_state(cpu_mips_t *cpu,char *filename); |
570 |
|
571 |
/* Load a raw image into the simulated memory */ |
572 |
int mips64_load_raw_image(cpu_mips_t *cpu,char *filename,m_uint64_t vaddr); |
573 |
|
574 |
/* Load an ELF image into the simulated memory */ |
575 |
int mips64_load_elf_image(cpu_mips_t *cpu,char *filename,int skip_load, |
576 |
m_uint32_t *entry_point); |
577 |
|
578 |
/* Symbol lookup */ |
579 |
struct symbol *mips64_sym_lookup(cpu_mips_t *cpu,m_uint64_t addr); |
580 |
|
581 |
/* Insert a new symbol */ |
582 |
struct symbol *mips64_sym_insert(cpu_mips_t *cpu,char *name,m_uint64_t addr); |
583 |
|
584 |
/* Create the symbol tree */ |
585 |
int mips64_sym_create_tree(cpu_mips_t *cpu); |
586 |
|
587 |
/* Load a symbol file */ |
588 |
int mips64_sym_load_file(cpu_mips_t *cpu,char *filename); |
589 |
|
590 |
#endif |