/[gxemul]/upstream/0.3.7/src/include/cpu_mips.h
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.7/src/include/cpu_mips.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show annotations)
Mon Oct 8 16:19:28 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 14085 byte(s)
0.3.7
1 #ifndef CPU_MIPS_H
2 #define CPU_MIPS_H
3
4 /*
5 * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
6 *
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 * $Id: cpu_mips.h,v 1.21 2005/08/28 20:16:24 debug Exp $
32 */
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 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 };
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 #define NOT_DELAYED 0
161 #define DELAYED 1
162 #define TO_BE_DELAYED 2
163
164 #define N_HI6 64
165 #define N_SPECIAL 64
166 #define N_REGIMM 32
167
168 /* Number of "tiny" translation cache entries: */
169 #define N_TRANSLATION_CACHE_INSTR 5
170 #define N_TRANSLATION_CACHE_DATA 5
171
172 struct translation_cache_entry {
173 int wf;
174 uint64_t vaddr_pfn;
175 uint64_t paddr;
176 };
177
178 /* This should be a value which the program counter
179 can "never" have: */
180 #define PC_LAST_PAGE_IMPOSSIBLE_VALUE 3
181
182 /* An "impossible" paddr: */
183 #define IMPOSSIBLE_PADDR 0x1212343456566767ULL
184
185 #define DEFAULT_PCACHE_SIZE 15 /* 32 KB */
186 #define DEFAULT_PCACHE_LINESIZE 5 /* 32 bytes */
187
188 struct r3000_cache_line {
189 uint32_t tag_paddr;
190 int tag_valid;
191 };
192 #define R3000_TAG_VALID 1
193 #define R3000_TAG_DIRTY 2
194
195 struct r4000_cache_line {
196 char dummy;
197 };
198
199 #define BINTRANS_DONT_RUN_NEXT 0x1000000
200 #define BINTRANS_N_MASK 0x0ffffff
201
202 #define N_SAFE_BINTRANS_LIMIT_SHIFT 14
203 #define N_SAFE_BINTRANS_LIMIT ((1 << (N_SAFE_BINTRANS_LIMIT_SHIFT - 1)) - 1)
204
205 #define N_BINTRANS_VADDR_TO_HOST 20
206
207 /* Virtual to host address translation tables: */
208 struct vth32_table {
209 void *haddr_entry[1024 * 2];
210 uint32_t paddr_entry[1024];
211 uint32_t *bintrans_chunks[1024];
212 struct vth32_table *next_free;
213 int refcount;
214 };
215
216 struct mips_cpu {
217 struct mips_cpu_type_def cpu_type;
218
219 struct mips_coproc *coproc[N_MIPS_COPROCS];
220
221 int compare_register_set;
222
223 /* Special purpose registers: */
224 uint64_t pc_last; /* PC of last instruction */
225 uint64_t hi;
226 uint64_t lo;
227
228 /* General purpose registers: */
229 uint64_t gpr[N_MIPS_GPRS];
230
231 /*
232 * The translation_cached stuff is used to speed up the
233 * most recent lookups into the TLB. Whenever the TLB is
234 * written to, translation_cached[] must be filled with zeros.
235 */
236 #ifdef USE_TINY_CACHE
237 struct translation_cache_entry
238 translation_cache_instr[N_TRANSLATION_CACHE_INSTR];
239 struct translation_cache_entry
240 translation_cache_data[N_TRANSLATION_CACHE_DATA];
241 #endif
242
243 /*
244 * For faster memory lookup when running instructions:
245 *
246 * Reading memory to load instructions is a very common thing in the
247 * emulator, and an instruction is very often read from the address
248 * following the previously executed instruction. That means that we
249 * don't have to go through the TLB each time.
250 *
251 * We then get the vaddr -> paddr translation for free. There is an
252 * even better case when the paddr is a RAM address (as opposed to an
253 * address in a memory mapped device). Then we can figure out the
254 * address in the host's memory directly, and skip the paddr -> host
255 * address calculation as well.
256 *
257 * A modification to the TLB should set the virtual_page variable to
258 * an "impossible" value, so that there won't be a hit on the next
259 * instruction.
260 */
261 uint64_t pc_last_virtual_page;
262 uint64_t pc_last_physical_page;
263 unsigned char *pc_last_host_4k_page;
264
265 /* MIPS Bintrans: */
266 int dont_run_next_bintrans;
267 int bintrans_instructions_executed; /* set to the
268 number of bintranslated instructions executed
269 when running a bintrans codechunk */
270 int pc_bintrans_paddr_valid;
271 uint64_t pc_bintrans_paddr;
272 unsigned char *pc_bintrans_host_4kpage;
273
274 /* Chunk base address: */
275 unsigned char *chunk_base_address;
276
277 /* This should work for 32-bit MIPS emulation: */
278 struct vth32_table *vaddr_to_hostaddr_nulltable;
279 struct vth32_table *vaddr_to_hostaddr_r2k3k_icachetable;
280 struct vth32_table *vaddr_to_hostaddr_r2k3k_dcachetable;
281 struct vth32_table **vaddr_to_hostaddr_table0_kernel;
282 struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_i;
283 struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_d;
284 struct vth32_table **vaddr_to_hostaddr_table0_user;
285 struct vth32_table **vaddr_to_hostaddr_table0; /* should point to kernel or user */
286 struct vth32_table *next_free_vth_table;
287
288 /* Testing... */
289 unsigned char **host_load;
290 unsigned char **host_store;
291 unsigned char **host_load_orig;
292 unsigned char **host_store_orig;
293 unsigned char **huge_r2k3k_cache_table;
294
295 /* For 64-bit (generic) emulation: */
296 unsigned char *(*fast_vaddr_to_hostaddr)(struct cpu *cpu,
297 uint64_t vaddr, int writeflag);
298 int bintrans_next_index;
299 int bintrans_data_writable[N_BINTRANS_VADDR_TO_HOST];
300 uint64_t bintrans_data_vaddr[N_BINTRANS_VADDR_TO_HOST];
301 unsigned char *bintrans_data_hostpage[N_BINTRANS_VADDR_TO_HOST];
302
303 void (*bintrans_load_32bit)(struct cpu *); /* Note: incorrect args */
304 void (*bintrans_store_32bit)(struct cpu *); /* Note: incorrect args */
305 void (*bintrans_jump_to_32bit_pc)(struct cpu *);
306 void (*bintrans_simple_exception)(struct cpu *, int);
307 void (*bintrans_fast_rfe)(struct cpu *);
308 void (*bintrans_fast_eret)(struct cpu *);
309 void (*bintrans_fast_tlbwri)(struct cpu *, int);
310 void (*bintrans_fast_tlbpr)(struct cpu *, int);
311
312 #ifdef ENABLE_MIPS16
313 int mips16; /* non-zero if MIPS16 code is allowed */
314 uint16_t mips16_extend; /* set on 'extend' instructions to the entire 16-bit extend instruction */
315 #endif
316
317 #ifdef ENABLE_INSTRUCTION_DELAYS
318 int instruction_delay;
319 #endif
320
321 uint64_t delay_jmpaddr; /* only used if delay_slot > 0 */
322 int delay_slot;
323 int nullify_next; /* set to 1 if next instruction
324 is to be nullified */
325
326 /* This is set to non-zero, if it is possible at all that an
327 interrupt will occur. */
328 int cached_interrupt_is_possible;
329
330 int show_trace_delay; /* 0=normal, > 0 = delay until show_trace */
331 uint64_t show_trace_addr;
332
333 int last_was_jumptoself;
334 int jump_to_self_reg;
335
336 #ifdef MFHILO_DELAY
337 int mfhi_delay; /* instructions since last mfhi */
338 int mflo_delay; /* instructions since last mflo */
339 #endif
340
341 int rmw; /* Read-Modify-Write */
342 int rmw_len; /* Length of rmw modification */
343 uint64_t rmw_addr; /* Address of rmw modification */
344
345 /*
346 * TODO: The R5900 has 128-bit registers. I'm not really sure
347 * whether they are used a lot or not, at least with code produced
348 * with gcc they are not. An important case however is lq and sq
349 * (load and store of 128-bit values). These "upper halves" of R5900
350 * quadwords can be used in those cases.
351 *
352 * TODO: Generalize this.
353 */
354 uint64_t gpr_quadhi[N_MIPS_GPRS];
355
356
357 /*
358 * Statistics:
359 */
360 long stats_opcode[N_HI6];
361 long stats__special[N_SPECIAL];
362 long stats__regimm[N_REGIMM];
363 long stats__special2[N_SPECIAL];
364
365 /* Data and Instruction caches: */
366 unsigned char *cache[2];
367 void *cache_tags[2];
368 uint64_t cache_last_paddr[2];
369 int cache_size[2];
370 int cache_linesize[2];
371 int cache_mask[2];
372 int cache_miss_penalty[2];
373
374 /* Other stuff: */
375 uint64_t cop0_config_select1;
376 };
377
378
379 /* cpu_mips.c: */
380 void mips_cpu_show_full_statistics(struct machine *m);
381 void mips_cpu_tlbdump(struct machine *m, int x, int rawflag);
382 void mips_cpu_register_match(struct machine *m, char *name,
383 int writeflag, uint64_t *valuep, int *match_register);
384 void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs);
385 int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
386 int running, uint64_t addr, int bintrans);
387 int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr);
388 int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr);
389 void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
390 /* uint64_t pagemask, */ int coproc_nr, uint64_t vaddr_vpn2,
391 int vaddr_asid, int x_64);
392 void mips_cpu_cause_simple_exception(struct cpu *cpu, int exc_code);
393 int mips_cpu_run(struct emul *emul, struct machine *machine);
394 void mips_cpu_dumpinfo(struct cpu *cpu);
395 void mips_cpu_list_available_types(void);
396 int mips_cpu_family_init(struct cpu_family *);
397
398
399 /* cpu_mips_coproc.c: */
400 struct mips_coproc *mips_coproc_new(struct cpu *cpu, int coproc_nr);
401 void mips_coproc_tlb_set_entry(struct cpu *cpu, int entrynr, int size,
402 uint64_t vaddr, uint64_t paddr0, uint64_t paddr1,
403 int valid0, int valid1, int dirty0, int dirty1, int global, int asid,
404 int cachealgo0, int cachealgo1);
405 void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
406 unsigned char *host_page, int writeflag, uint64_t paddr_page);
407 void clear_all_chunks_from_all_tables(struct cpu *cpu);
408 void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t, int);
409 void coproc_register_read(struct cpu *cpu,
410 struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select);
411 void coproc_register_write(struct cpu *cpu,
412 struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int flag64,
413 int select);
414 void coproc_tlbpr(struct cpu *cpu, int readflag);
415 void coproc_tlbwri(struct cpu *cpu, int randomflag);
416 void coproc_rfe(struct cpu *cpu);
417 void coproc_eret(struct cpu *cpu);
418 void coproc_function(struct cpu *cpu, struct mips_coproc *cp, int cpnr,
419 uint32_t function, int unassemble_only, int running);
420
421
422 /* memory_mips.c: */
423 int memory_cache_R3000(struct cpu *cpu, int cache, uint64_t paddr,
424 int writeflag, size_t len, unsigned char *data);
425 int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
426 unsigned char *data, size_t len, int writeflag, int cache_flags);
427
428
429 /* mips16.c: */
430 int mips16_to_32(struct cpu *cpu, unsigned char *instr16, unsigned char *instr);
431
432
433 #endif /* CPU_MIPS_H */

  ViewVC Help
Powered by ViewVC 1.1.26