1 |
dpavlin |
4 |
#ifndef CPU_MIPS_H |
2 |
|
|
#define CPU_MIPS_H |
3 |
|
|
|
4 |
|
|
/* |
5 |
dpavlin |
22 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
6 |
dpavlin |
4 |
* |
7 |
|
|
* Redistribution and use in source and binary forms, with or without |
8 |
|
|
* modification, are permitted provided that the following conditions are met: |
9 |
|
|
* |
10 |
|
|
* 1. Redistributions of source code must retain the above copyright |
11 |
|
|
* notice, this list of conditions and the following disclaimer. |
12 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
|
|
* notice, this list of conditions and the following disclaimer in the |
14 |
|
|
* documentation and/or other materials provided with the distribution. |
15 |
|
|
* 3. The name of the author may not be used to endorse or promote products |
16 |
|
|
* derived from this software without specific prior written permission. |
17 |
|
|
* |
18 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
19 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
21 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
22 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
24 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
26 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
28 |
|
|
* SUCH DAMAGE. |
29 |
|
|
* |
30 |
|
|
* |
31 |
dpavlin |
22 |
* $Id: cpu_mips.h,v 1.26 2006/02/13 04:23:25 debug Exp $ |
32 |
dpavlin |
4 |
*/ |
33 |
|
|
|
34 |
|
|
#include "misc.h" |
35 |
|
|
|
36 |
|
|
/* |
37 |
|
|
* ENABLE_MIPS16 should be defined on the cc commandline using -D, if you |
38 |
|
|
* want it. (This is done by ./configure --mips16) |
39 |
|
|
*/ |
40 |
|
|
/* #define MFHILO_DELAY */ |
41 |
|
|
|
42 |
|
|
struct cpu_family; |
43 |
|
|
struct emul; |
44 |
|
|
struct machine; |
45 |
|
|
|
46 |
|
|
/* |
47 |
|
|
* CPU type definitions: See mips_cpu_types.h. |
48 |
|
|
*/ |
49 |
|
|
|
50 |
|
|
struct mips_cpu_type_def { |
51 |
|
|
char *name; |
52 |
|
|
int rev; |
53 |
|
|
int sub; |
54 |
|
|
char flags; |
55 |
|
|
char exc_model; /* EXC3K or EXC4K */ |
56 |
|
|
char mmu_model; /* MMU3K or MMU4K */ |
57 |
|
|
char isa_level; /* 1, 2, 3, 4, 5, 32, 64 */ |
58 |
|
|
int nr_of_tlb_entries; /* 32, 48, 64, ... */ |
59 |
|
|
char instrs_per_cycle; /* simplified, 1, 2, or 4 */ |
60 |
dpavlin |
12 |
int picache; |
61 |
|
|
int pilinesize; |
62 |
|
|
int piways; |
63 |
|
|
int pdcache; |
64 |
|
|
int pdlinesize; |
65 |
|
|
int pdways; |
66 |
|
|
int scache; |
67 |
|
|
int slinesize; |
68 |
|
|
int sways; |
69 |
dpavlin |
4 |
}; |
70 |
|
|
|
71 |
|
|
#define INITIAL_PC 0xffffffffbfc00000ULL |
72 |
|
|
#define INITIAL_STACK_POINTER (0xffffffffa0008000ULL - 256) |
73 |
|
|
|
74 |
|
|
|
75 |
|
|
/* |
76 |
|
|
* Coproc 0: |
77 |
|
|
*/ |
78 |
|
|
#define N_MIPS_COPROC_REGS 32 |
79 |
|
|
struct mips_tlb { |
80 |
|
|
uint64_t hi; |
81 |
|
|
uint64_t lo0; |
82 |
|
|
uint64_t lo1; |
83 |
|
|
uint64_t mask; |
84 |
|
|
}; |
85 |
|
|
|
86 |
|
|
|
87 |
|
|
/* |
88 |
|
|
* Coproc 1: |
89 |
|
|
*/ |
90 |
|
|
#define N_MIPS_FCRS 32 |
91 |
|
|
|
92 |
|
|
struct mips_coproc { |
93 |
|
|
int coproc_nr; |
94 |
|
|
uint64_t reg[N_MIPS_COPROC_REGS]; |
95 |
|
|
|
96 |
|
|
/* Only for COP0: */ |
97 |
|
|
struct mips_tlb *tlbs; |
98 |
|
|
int nr_of_tlbs; |
99 |
|
|
|
100 |
|
|
/* Only for COP1: floating point control registers */ |
101 |
|
|
/* (Maybe also for COP0?) */ |
102 |
|
|
uint64_t fcr[N_MIPS_FCRS]; |
103 |
|
|
}; |
104 |
|
|
|
105 |
|
|
#define N_MIPS_COPROCS 4 |
106 |
|
|
|
107 |
|
|
#define N_MIPS_GPRS 32 /* General purpose registers */ |
108 |
|
|
#define N_MIPS_FPRS 32 /* Floating point registers */ |
109 |
|
|
|
110 |
|
|
/* |
111 |
|
|
* These should all be 2 characters wide: |
112 |
|
|
* |
113 |
|
|
* NOTE: These are for 32-bit ABIs. For the 64-bit ABI, registers 8..11 |
114 |
|
|
* are used to pass arguments and are then called "a4".."a7". |
115 |
|
|
* |
116 |
|
|
* TODO: Should there be two different variants of this? It's not really |
117 |
|
|
* possible to figure out in some easy way if the code running was |
118 |
|
|
* written for a 32-bit or 64-bit ABI. |
119 |
|
|
*/ |
120 |
|
|
#define MIPS_REGISTER_NAMES { \ |
121 |
|
|
"zr", "at", "v0", "v1", "a0", "a1", "a2", "a3", \ |
122 |
|
|
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \ |
123 |
|
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \ |
124 |
|
|
"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" } |
125 |
|
|
|
126 |
|
|
#define MIPS_GPR_ZERO 0 /* zero */ |
127 |
|
|
#define MIPS_GPR_AT 1 /* at */ |
128 |
|
|
#define MIPS_GPR_V0 2 /* v0 */ |
129 |
|
|
#define MIPS_GPR_V1 3 /* v1 */ |
130 |
|
|
#define MIPS_GPR_A0 4 /* a0 */ |
131 |
|
|
#define MIPS_GPR_A1 5 /* a1 */ |
132 |
|
|
#define MIPS_GPR_A2 6 /* a2 */ |
133 |
|
|
#define MIPS_GPR_A3 7 /* a3 */ |
134 |
|
|
#define MIPS_GPR_T0 8 /* t0 */ |
135 |
|
|
#define MIPS_GPR_T1 9 /* t1 */ |
136 |
|
|
#define MIPS_GPR_T2 10 /* t2 */ |
137 |
|
|
#define MIPS_GPR_T3 11 /* t3 */ |
138 |
|
|
#define MIPS_GPR_T4 12 /* t4 */ |
139 |
|
|
#define MIPS_GPR_T5 13 /* t5 */ |
140 |
|
|
#define MIPS_GPR_T6 14 /* t6 */ |
141 |
|
|
#define MIPS_GPR_T7 15 /* t7 */ |
142 |
|
|
#define MIPS_GPR_S0 16 /* s0 */ |
143 |
|
|
#define MIPS_GPR_S1 17 /* s1 */ |
144 |
|
|
#define MIPS_GPR_S2 18 /* s2 */ |
145 |
|
|
#define MIPS_GPR_S3 19 /* s3 */ |
146 |
|
|
#define MIPS_GPR_S4 20 /* s4 */ |
147 |
|
|
#define MIPS_GPR_S5 21 /* s5 */ |
148 |
|
|
#define MIPS_GPR_S6 22 /* s6 */ |
149 |
|
|
#define MIPS_GPR_S7 23 /* s7 */ |
150 |
|
|
#define MIPS_GPR_T8 24 /* t8 */ |
151 |
|
|
#define MIPS_GPR_T9 25 /* t9 */ |
152 |
|
|
#define MIPS_GPR_K0 26 /* k0 */ |
153 |
|
|
#define MIPS_GPR_K1 27 /* k1 */ |
154 |
|
|
#define MIPS_GPR_GP 28 /* gp */ |
155 |
|
|
#define MIPS_GPR_SP 29 /* sp */ |
156 |
|
|
#define MIPS_GPR_FP 30 /* fp */ |
157 |
|
|
#define MIPS_GPR_RA 31 /* ra */ |
158 |
|
|
|
159 |
|
|
/* Meaning of delay_slot: */ |
160 |
dpavlin |
22 |
#define NOT_DELAYED 0 |
161 |
|
|
#define DELAYED 1 |
162 |
|
|
#define TO_BE_DELAYED 2 |
163 |
|
|
#define EXCEPTION_IN_DELAY_SLOT 0x100 |
164 |
dpavlin |
4 |
|
165 |
|
|
#define N_HI6 64 |
166 |
|
|
#define N_SPECIAL 64 |
167 |
|
|
#define N_REGIMM 32 |
168 |
|
|
|
169 |
dpavlin |
22 |
/******************************* OLD: *****************************/ |
170 |
|
|
|
171 |
dpavlin |
4 |
/* Number of "tiny" translation cache entries: */ |
172 |
|
|
#define N_TRANSLATION_CACHE_INSTR 5 |
173 |
|
|
#define N_TRANSLATION_CACHE_DATA 5 |
174 |
|
|
|
175 |
|
|
struct translation_cache_entry { |
176 |
|
|
int wf; |
177 |
|
|
uint64_t vaddr_pfn; |
178 |
|
|
uint64_t paddr; |
179 |
|
|
}; |
180 |
|
|
|
181 |
|
|
/* This should be a value which the program counter |
182 |
|
|
can "never" have: */ |
183 |
|
|
#define PC_LAST_PAGE_IMPOSSIBLE_VALUE 3 |
184 |
|
|
|
185 |
|
|
/* An "impossible" paddr: */ |
186 |
|
|
#define IMPOSSIBLE_PADDR 0x1212343456566767ULL |
187 |
|
|
|
188 |
|
|
#define DEFAULT_PCACHE_SIZE 15 /* 32 KB */ |
189 |
|
|
#define DEFAULT_PCACHE_LINESIZE 5 /* 32 bytes */ |
190 |
|
|
|
191 |
|
|
struct r3000_cache_line { |
192 |
|
|
uint32_t tag_paddr; |
193 |
|
|
int tag_valid; |
194 |
|
|
}; |
195 |
|
|
#define R3000_TAG_VALID 1 |
196 |
|
|
#define R3000_TAG_DIRTY 2 |
197 |
|
|
|
198 |
|
|
struct r4000_cache_line { |
199 |
|
|
char dummy; |
200 |
|
|
}; |
201 |
|
|
|
202 |
dpavlin |
22 |
/********************************************************************/ |
203 |
|
|
|
204 |
|
|
#ifdef ONEKPAGE |
205 |
|
|
#define MIPS_IC_ENTRIES_SHIFT 8 |
206 |
|
|
#else |
207 |
|
|
#define MIPS_IC_ENTRIES_SHIFT 10 |
208 |
|
|
#endif |
209 |
|
|
|
210 |
|
|
#define MIPS_N_IC_ARGS 3 |
211 |
|
|
#define MIPS_INSTR_ALIGNMENT_SHIFT 2 |
212 |
|
|
#define MIPS_IC_ENTRIES_PER_PAGE (1 << MIPS_IC_ENTRIES_SHIFT) |
213 |
|
|
#define MIPS_PC_TO_IC_ENTRY(a) (((a)>>MIPS_INSTR_ALIGNMENT_SHIFT) \ |
214 |
|
|
& (MIPS_IC_ENTRIES_PER_PAGE-1)) |
215 |
|
|
#define MIPS_ADDR_TO_PAGENR(a) ((a) >> (MIPS_IC_ENTRIES_SHIFT \ |
216 |
|
|
+ MIPS_INSTR_ALIGNMENT_SHIFT)) |
217 |
|
|
|
218 |
|
|
struct mips_instr_call { |
219 |
|
|
void (*f)(struct cpu *, struct mips_instr_call *); |
220 |
|
|
size_t arg[MIPS_N_IC_ARGS]; |
221 |
|
|
}; |
222 |
|
|
|
223 |
|
|
/* Translation cache struct for each physical page: */ |
224 |
|
|
struct mips_tc_physpage { |
225 |
|
|
struct mips_instr_call ics[MIPS_IC_ENTRIES_PER_PAGE + 3]; |
226 |
|
|
uint32_t next_ofs; /* or 0 for end of chain */ |
227 |
|
|
int flags; |
228 |
|
|
uint64_t physaddr; |
229 |
|
|
}; |
230 |
|
|
|
231 |
|
|
#define MIPS_MAX_VPH_TLB_ENTRIES 128 |
232 |
|
|
struct mips_vpg_tlb_entry { |
233 |
|
|
uint8_t valid; |
234 |
|
|
uint8_t writeflag; |
235 |
|
|
unsigned char *host_page; |
236 |
|
|
int64_t timestamp; |
237 |
|
|
uint64_t vaddr_page; |
238 |
|
|
uint64_t paddr_page; |
239 |
|
|
}; |
240 |
|
|
|
241 |
|
|
|
242 |
|
|
/******************************* OLD: *****************************/ |
243 |
|
|
|
244 |
dpavlin |
4 |
#define BINTRANS_DONT_RUN_NEXT 0x1000000 |
245 |
|
|
#define BINTRANS_N_MASK 0x0ffffff |
246 |
|
|
|
247 |
|
|
#define N_SAFE_BINTRANS_LIMIT_SHIFT 14 |
248 |
|
|
#define N_SAFE_BINTRANS_LIMIT ((1 << (N_SAFE_BINTRANS_LIMIT_SHIFT - 1)) - 1) |
249 |
|
|
|
250 |
|
|
#define N_BINTRANS_VADDR_TO_HOST 20 |
251 |
|
|
|
252 |
|
|
/* Virtual to host address translation tables: */ |
253 |
|
|
struct vth32_table { |
254 |
dpavlin |
10 |
void *haddr_entry[1024 * 2]; |
255 |
dpavlin |
4 |
uint32_t paddr_entry[1024]; |
256 |
|
|
uint32_t *bintrans_chunks[1024]; |
257 |
|
|
struct vth32_table *next_free; |
258 |
|
|
int refcount; |
259 |
|
|
}; |
260 |
|
|
|
261 |
dpavlin |
22 |
/********************************************************************/ |
262 |
|
|
|
263 |
dpavlin |
4 |
struct mips_cpu { |
264 |
|
|
struct mips_cpu_type_def cpu_type; |
265 |
|
|
|
266 |
|
|
struct mips_coproc *coproc[N_MIPS_COPROCS]; |
267 |
|
|
|
268 |
|
|
int compare_register_set; |
269 |
|
|
|
270 |
|
|
/* Special purpose registers: */ |
271 |
|
|
uint64_t pc_last; /* PC of last instruction */ |
272 |
|
|
uint64_t hi; |
273 |
|
|
uint64_t lo; |
274 |
|
|
|
275 |
|
|
/* General purpose registers: */ |
276 |
|
|
uint64_t gpr[N_MIPS_GPRS]; |
277 |
|
|
|
278 |
|
|
/* |
279 |
|
|
* The translation_cached stuff is used to speed up the |
280 |
|
|
* most recent lookups into the TLB. Whenever the TLB is |
281 |
|
|
* written to, translation_cached[] must be filled with zeros. |
282 |
|
|
*/ |
283 |
|
|
#ifdef USE_TINY_CACHE |
284 |
|
|
struct translation_cache_entry |
285 |
|
|
translation_cache_instr[N_TRANSLATION_CACHE_INSTR]; |
286 |
|
|
struct translation_cache_entry |
287 |
|
|
translation_cache_data[N_TRANSLATION_CACHE_DATA]; |
288 |
|
|
#endif |
289 |
|
|
|
290 |
|
|
/* |
291 |
|
|
* For faster memory lookup when running instructions: |
292 |
|
|
* |
293 |
|
|
* Reading memory to load instructions is a very common thing in the |
294 |
|
|
* emulator, and an instruction is very often read from the address |
295 |
|
|
* following the previously executed instruction. That means that we |
296 |
|
|
* don't have to go through the TLB each time. |
297 |
|
|
* |
298 |
|
|
* We then get the vaddr -> paddr translation for free. There is an |
299 |
|
|
* even better case when the paddr is a RAM address (as opposed to an |
300 |
|
|
* address in a memory mapped device). Then we can figure out the |
301 |
|
|
* address in the host's memory directly, and skip the paddr -> host |
302 |
|
|
* address calculation as well. |
303 |
|
|
* |
304 |
|
|
* A modification to the TLB should set the virtual_page variable to |
305 |
|
|
* an "impossible" value, so that there won't be a hit on the next |
306 |
|
|
* instruction. |
307 |
|
|
*/ |
308 |
|
|
uint64_t pc_last_virtual_page; |
309 |
|
|
uint64_t pc_last_physical_page; |
310 |
|
|
unsigned char *pc_last_host_4k_page; |
311 |
|
|
|
312 |
dpavlin |
12 |
/* MIPS Bintrans: */ |
313 |
dpavlin |
4 |
int dont_run_next_bintrans; |
314 |
|
|
int bintrans_instructions_executed; /* set to the |
315 |
|
|
number of bintranslated instructions executed |
316 |
|
|
when running a bintrans codechunk */ |
317 |
|
|
int pc_bintrans_paddr_valid; |
318 |
|
|
uint64_t pc_bintrans_paddr; |
319 |
|
|
unsigned char *pc_bintrans_host_4kpage; |
320 |
|
|
|
321 |
|
|
/* Chunk base address: */ |
322 |
|
|
unsigned char *chunk_base_address; |
323 |
|
|
|
324 |
|
|
/* This should work for 32-bit MIPS emulation: */ |
325 |
|
|
struct vth32_table *vaddr_to_hostaddr_nulltable; |
326 |
|
|
struct vth32_table *vaddr_to_hostaddr_r2k3k_icachetable; |
327 |
|
|
struct vth32_table *vaddr_to_hostaddr_r2k3k_dcachetable; |
328 |
|
|
struct vth32_table **vaddr_to_hostaddr_table0_kernel; |
329 |
|
|
struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_i; |
330 |
|
|
struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_d; |
331 |
|
|
struct vth32_table **vaddr_to_hostaddr_table0_user; |
332 |
|
|
struct vth32_table **vaddr_to_hostaddr_table0; /* should point to kernel or user */ |
333 |
|
|
struct vth32_table *next_free_vth_table; |
334 |
|
|
|
335 |
dpavlin |
12 |
/* Testing... */ |
336 |
dpavlin |
22 |
unsigned char **host_OLD_load; |
337 |
|
|
unsigned char **host_OLD_store; |
338 |
dpavlin |
12 |
unsigned char **host_load_orig; |
339 |
|
|
unsigned char **host_store_orig; |
340 |
|
|
unsigned char **huge_r2k3k_cache_table; |
341 |
|
|
|
342 |
dpavlin |
4 |
/* For 64-bit (generic) emulation: */ |
343 |
|
|
unsigned char *(*fast_vaddr_to_hostaddr)(struct cpu *cpu, |
344 |
|
|
uint64_t vaddr, int writeflag); |
345 |
|
|
int bintrans_next_index; |
346 |
|
|
int bintrans_data_writable[N_BINTRANS_VADDR_TO_HOST]; |
347 |
|
|
uint64_t bintrans_data_vaddr[N_BINTRANS_VADDR_TO_HOST]; |
348 |
|
|
unsigned char *bintrans_data_hostpage[N_BINTRANS_VADDR_TO_HOST]; |
349 |
|
|
|
350 |
dpavlin |
10 |
void (*bintrans_load_32bit)(struct cpu *); /* Note: incorrect args */ |
351 |
|
|
void (*bintrans_store_32bit)(struct cpu *); /* Note: incorrect args */ |
352 |
dpavlin |
4 |
void (*bintrans_jump_to_32bit_pc)(struct cpu *); |
353 |
|
|
void (*bintrans_simple_exception)(struct cpu *, int); |
354 |
|
|
void (*bintrans_fast_rfe)(struct cpu *); |
355 |
|
|
void (*bintrans_fast_eret)(struct cpu *); |
356 |
|
|
void (*bintrans_fast_tlbwri)(struct cpu *, int); |
357 |
|
|
void (*bintrans_fast_tlbpr)(struct cpu *, int); |
358 |
|
|
|
359 |
|
|
#ifdef ENABLE_MIPS16 |
360 |
|
|
int mips16; /* non-zero if MIPS16 code is allowed */ |
361 |
|
|
uint16_t mips16_extend; /* set on 'extend' instructions to the entire 16-bit extend instruction */ |
362 |
|
|
#endif |
363 |
|
|
|
364 |
|
|
#ifdef ENABLE_INSTRUCTION_DELAYS |
365 |
|
|
int instruction_delay; |
366 |
|
|
#endif |
367 |
|
|
|
368 |
|
|
uint64_t delay_jmpaddr; /* only used if delay_slot > 0 */ |
369 |
|
|
int delay_slot; |
370 |
|
|
int nullify_next; /* set to 1 if next instruction |
371 |
|
|
is to be nullified */ |
372 |
|
|
|
373 |
|
|
/* This is set to non-zero, if it is possible at all that an |
374 |
|
|
interrupt will occur. */ |
375 |
|
|
int cached_interrupt_is_possible; |
376 |
|
|
|
377 |
|
|
int show_trace_delay; /* 0=normal, > 0 = delay until show_trace */ |
378 |
|
|
uint64_t show_trace_addr; |
379 |
|
|
|
380 |
|
|
int last_was_jumptoself; |
381 |
|
|
int jump_to_self_reg; |
382 |
|
|
|
383 |
|
|
#ifdef MFHILO_DELAY |
384 |
|
|
int mfhi_delay; /* instructions since last mfhi */ |
385 |
|
|
int mflo_delay; /* instructions since last mflo */ |
386 |
|
|
#endif |
387 |
|
|
|
388 |
|
|
int rmw; /* Read-Modify-Write */ |
389 |
|
|
int rmw_len; /* Length of rmw modification */ |
390 |
|
|
uint64_t rmw_addr; /* Address of rmw modification */ |
391 |
|
|
|
392 |
|
|
/* |
393 |
|
|
* TODO: The R5900 has 128-bit registers. I'm not really sure |
394 |
|
|
* whether they are used a lot or not, at least with code produced |
395 |
|
|
* with gcc they are not. An important case however is lq and sq |
396 |
|
|
* (load and store of 128-bit values). These "upper halves" of R5900 |
397 |
|
|
* quadwords can be used in those cases. |
398 |
|
|
* |
399 |
|
|
* TODO: Generalize this. |
400 |
|
|
*/ |
401 |
|
|
uint64_t gpr_quadhi[N_MIPS_GPRS]; |
402 |
|
|
|
403 |
|
|
|
404 |
|
|
/* |
405 |
|
|
* Statistics: |
406 |
|
|
*/ |
407 |
|
|
long stats_opcode[N_HI6]; |
408 |
|
|
long stats__special[N_SPECIAL]; |
409 |
|
|
long stats__regimm[N_REGIMM]; |
410 |
|
|
long stats__special2[N_SPECIAL]; |
411 |
|
|
|
412 |
|
|
/* Data and Instruction caches: */ |
413 |
|
|
unsigned char *cache[2]; |
414 |
|
|
void *cache_tags[2]; |
415 |
|
|
uint64_t cache_last_paddr[2]; |
416 |
|
|
int cache_size[2]; |
417 |
|
|
int cache_linesize[2]; |
418 |
|
|
int cache_mask[2]; |
419 |
|
|
int cache_miss_penalty[2]; |
420 |
dpavlin |
10 |
|
421 |
|
|
/* Other stuff: */ |
422 |
|
|
uint64_t cop0_config_select1; |
423 |
dpavlin |
22 |
|
424 |
|
|
|
425 |
|
|
/* NEW DYNTRANS: */ |
426 |
|
|
|
427 |
|
|
|
428 |
|
|
/* |
429 |
|
|
* Instruction translation cache and Virtual->Physical->Host |
430 |
|
|
* address translation: |
431 |
|
|
*/ |
432 |
|
|
DYNTRANS_ITC(mips) |
433 |
|
|
VPH_TLBS(mips,MIPS) |
434 |
|
|
VPH32(mips,MIPS,uint64_t,uint8_t) |
435 |
|
|
VPH64(mips,MIPS,uint8_t) |
436 |
dpavlin |
4 |
}; |
437 |
|
|
|
438 |
|
|
|
439 |
|
|
/* cpu_mips.c: */ |
440 |
|
|
void mips_cpu_show_full_statistics(struct machine *m); |
441 |
|
|
void mips_cpu_tlbdump(struct machine *m, int x, int rawflag); |
442 |
|
|
void mips_cpu_register_match(struct machine *m, char *name, |
443 |
|
|
int writeflag, uint64_t *valuep, int *match_register); |
444 |
|
|
void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs); |
445 |
|
|
int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr, |
446 |
|
|
int running, uint64_t addr, int bintrans); |
447 |
|
|
int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr); |
448 |
|
|
int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr); |
449 |
|
|
void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr, |
450 |
|
|
/* uint64_t pagemask, */ int coproc_nr, uint64_t vaddr_vpn2, |
451 |
|
|
int vaddr_asid, int x_64); |
452 |
|
|
void mips_cpu_cause_simple_exception(struct cpu *cpu, int exc_code); |
453 |
|
|
int mips_cpu_run(struct emul *emul, struct machine *machine); |
454 |
|
|
void mips_cpu_dumpinfo(struct cpu *cpu); |
455 |
|
|
void mips_cpu_list_available_types(void); |
456 |
|
|
int mips_cpu_family_init(struct cpu_family *); |
457 |
|
|
|
458 |
|
|
|
459 |
|
|
/* cpu_mips_coproc.c: */ |
460 |
|
|
struct mips_coproc *mips_coproc_new(struct cpu *cpu, int coproc_nr); |
461 |
|
|
void mips_coproc_tlb_set_entry(struct cpu *cpu, int entrynr, int size, |
462 |
|
|
uint64_t vaddr, uint64_t paddr0, uint64_t paddr1, |
463 |
|
|
int valid0, int valid1, int dirty0, int dirty1, int global, int asid, |
464 |
|
|
int cachealgo0, int cachealgo1); |
465 |
dpavlin |
22 |
void mips_OLD_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, |
466 |
dpavlin |
4 |
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
467 |
|
|
void clear_all_chunks_from_all_tables(struct cpu *cpu); |
468 |
dpavlin |
14 |
void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t, int); |
469 |
dpavlin |
4 |
void coproc_register_read(struct cpu *cpu, |
470 |
dpavlin |
10 |
struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select); |
471 |
dpavlin |
4 |
void coproc_register_write(struct cpu *cpu, |
472 |
dpavlin |
10 |
struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int flag64, |
473 |
|
|
int select); |
474 |
dpavlin |
4 |
void coproc_tlbpr(struct cpu *cpu, int readflag); |
475 |
|
|
void coproc_tlbwri(struct cpu *cpu, int randomflag); |
476 |
|
|
void coproc_rfe(struct cpu *cpu); |
477 |
|
|
void coproc_eret(struct cpu *cpu); |
478 |
|
|
void coproc_function(struct cpu *cpu, struct mips_coproc *cp, int cpnr, |
479 |
|
|
uint32_t function, int unassemble_only, int running); |
480 |
|
|
|
481 |
|
|
|
482 |
|
|
/* memory_mips.c: */ |
483 |
|
|
int memory_cache_R3000(struct cpu *cpu, int cache, uint64_t paddr, |
484 |
|
|
int writeflag, size_t len, unsigned char *data); |
485 |
|
|
int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, |
486 |
|
|
unsigned char *data, size_t len, int writeflag, int cache_flags); |
487 |
|
|
|
488 |
|
|
|
489 |
|
|
/* mips16.c: */ |
490 |
|
|
int mips16_to_32(struct cpu *cpu, unsigned char *instr16, unsigned char *instr); |
491 |
|
|
|
492 |
|
|
|
493 |
dpavlin |
22 |
/* NEW DYNTRANS: */ |
494 |
|
|
void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, |
495 |
|
|
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
496 |
|
|
void mips_invalidate_translation_caches(struct cpu *cpu, uint64_t, int); |
497 |
|
|
void mips_invalidate_code_translation(struct cpu *cpu, uint64_t, int); |
498 |
|
|
|
499 |
|
|
|
500 |
dpavlin |
4 |
#endif /* CPU_MIPS_H */ |