/[gxemul]/trunk/src/cpus/cpu_mips.c
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 /trunk/src/cpus/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations)
Mon Oct 8 16:20:26 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 56915 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1298 2006/07/22 11:27:46 debug Exp $
20060626	Continuing on SPARC emulation (beginning on the 'save'
		instruction, register windows, etc).
20060629	Planning statistics gathering (new -s command line option),
		and renaming speed_tricks to allow_instruction_combinations.
20060630	Some minor manual page updates.
		Various cleanups.
		Implementing the -s command line option.
20060701	FINALLY found the bug which prevented Linux and Ultrix from
		running without the ugly hack in the R2000/R3000 cache isol
		code; it was the phystranslation hint array which was buggy.
		Removing the phystranslation hint code completely, for now.
20060702	Minor dyntrans cleanups; invalidation of physpages now only
		invalidate those parts of a page that have actually been
		translated. (32 parts per page.)
		Some MIPS non-R3000 speed fixes.
		Experimenting with MIPS instruction combination for some
		addiu+bne+sw loops, and sw+sw+sw.
		Adding support (again) for larger-than-4KB pages in MIPS tlbw*.
		Continuing on SPARC emulation: adding load/store instructions.
20060704	Fixing a virtual vs physical page shift bug in the new tlbw*
		implementation. Problem noticed by Jakub Jermar. (Many thanks.)
		Moving rfe and eret to cpu_mips_instr.c, since that is the
		only place that uses them nowadays.
20060705	Removing the BSD license from the "testmachine" include files,
		placing them in the public domain instead; this enables the
		testmachine stuff to be used from projects which are
		incompatible with the BSD license for some reason.
20060707	Adding instruction combinations for the R2000/R3000 L1
		I-cache invalidation code used by NetBSD/pmax 3.0, lui+addiu,
		various branches followed by addiu or nop, and jr ra followed
		by addiu. The time it takes to perform a full NetBSD/pmax R3000
		install on the laptop has dropped from 573 seconds to 539. :-)
20060708	Adding a framebuffer controller device (dev_fbctrl), which so
		far can be used to change the fb resolution during runtime, but
		in the future will also be useful for accelerated block fill/
		copy, and possibly also simplified character output.
		Adding an instruction combination for NetBSD/pmax' strlen.
20060709	Minor fixes: reading raw files in src/file.c wasn't memblock
		aligned, removing buggy multi_sw MIPS instruction combination,
		etc.
20060711	Adding a machine_qemu.c, which contains a "qemu_mips" machine.
		(It mimics QEMU's MIPS machine mode, so that a test kernel
		made for QEMU_MIPS also can run in GXemul... at least to some
		extent.)  Adding a short section about how to run this mode to
		doc/guestoses.html.
20060714	Misc. minor code cleanups.
20060715	Applying a patch which adds getchar() to promemul/yamon.c
		(from Oleksandr Tymoshenko).
		Adding yamon.h from NetBSD, and rewriting yamon.c to use it
		(instead of ugly hardcoded numbers) + some cleanup.
20060716	Found and fixed the bug which broke single-stepping of 64-bit
		programs between 0.4.0 and 0.4.0.1 (caused by too quick
		refactoring and no testing). Hopefully this fix will not
		break too many other things.
20060718	Continuing on the 8253 PIT; it now works with Linux/QEMU_MIPS.
		Re-adding the sw+sw+sw instr comb (the problem was that I had
		ignored endian issues); however, it doesn't seem to give any
		big performance gain.
20060720	Adding a dummy Transputer mode (T414, T800 etc) skeleton (only
		the 'j' and 'ldc' instructions are implemented so far). :-}
20060721	Adding gtreg.h from NetBSD, updating dev_gt.c to use it, plus
		misc. other updates to get Linux 2.6 for evbmips/malta working
		(thanks to Alec Voropay for the details).
		FINALLY found and fixed the bug which made tlbw* for non-R3000
		buggy; it was a reference count problem in the dyntrans core.
20060722	Testing stuff; things seem stable enough for a new release.

==============  RELEASE 0.4.1  ==============


1 /*
2 * Copyright (C) 2003-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_mips.c,v 1.61 2006/07/16 13:32:26 debug Exp $
29 *
30 * MIPS core CPU emulation.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/types.h>
37 #include <ctype.h>
38
39 #include "../../config.h"
40
41 #include "arcbios.h"
42 #include "cop0.h"
43 #include "cpu.h"
44 #include "cpu_mips.h"
45 #include "debugger.h"
46 #include "devices.h"
47 #include "emul.h"
48 #include "machine.h"
49 #include "memory.h"
50 #include "mips_cpu_types.h"
51 #include "opcodes_mips.h"
52 #include "symbol.h"
53
54
55 extern volatile int single_step;
56
57 static char *exception_names[] = EXCEPTION_NAMES;
58
59 static char *hi6_names[] = HI6_NAMES;
60 static char *regimm_names[] = REGIMM_NAMES;
61 static char *special_names[] = SPECIAL_NAMES;
62 static char *special2_names[] = SPECIAL2_NAMES;
63 static char *mmi_names[] = MMI_NAMES;
64 static char *mmi0_names[] = MMI0_NAMES;
65 static char *mmi1_names[] = MMI1_NAMES;
66 static char *mmi2_names[] = MMI2_NAMES;
67 static char *mmi3_names[] = MMI3_NAMES;
68 static char *special3_names[] = SPECIAL3_NAMES;
69
70 static char *regnames[] = MIPS_REGISTER_NAMES;
71 static char *cop0_names[] = COP0_NAMES;
72
73
74 #define DYNTRANS_DUALMODE_32
75 #define DYNTRANS_DELAYSLOT
76 #include "tmp_mips_head.c"
77
78 void mips_pc_to_pointers(struct cpu *);
79 void mips32_pc_to_pointers(struct cpu *);
80
81
82 /*
83 * regname():
84 *
85 * Convert a register number into either 'r0', 'r31' etc, or a symbolic
86 * name, depending on machine->show_symbolic_register_names.
87 *
88 * NOTE: _NOT_ reentrant.
89 */
90 static char *regname(struct machine *machine, int r)
91 {
92 static char ch[4];
93 ch[3] = ch[2] = '\0';
94
95 if (r<0 || r>=32)
96 strlcpy(ch, "xx", sizeof(ch));
97 else if (machine->show_symbolic_register_names)
98 strlcpy(ch, regnames[r], sizeof(ch));
99 else
100 snprintf(ch, sizeof(ch), "r%i", r);
101
102 return ch;
103 }
104
105
106 /*
107 * mips_cpu_new():
108 *
109 * Create a new MIPS cpu object.
110 *
111 * Returns 1 on success, 0 if there was no valid MIPS processor with
112 * a matching name.
113 */
114 int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
115 int cpu_id, char *cpu_type_name)
116 {
117 int i, found, j, tags_size, n_cache_lines, size_per_cache_line;
118 struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
119 int64_t secondary_cache_size;
120 int x, linesize;
121
122 /* Scan the cpu_type_defs list for this cpu type: */
123 i = 0;
124 found = -1;
125 while (i >= 0 && cpu_type_defs[i].name != NULL) {
126 if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
127 found = i;
128 break;
129 }
130 i++;
131 }
132
133 if (found == -1)
134 return 0;
135
136 cpu->memory_rw = mips_memory_rw;
137 cpu->cd.mips.cpu_type = cpu_type_defs[found];
138 cpu->name = cpu->cd.mips.cpu_type.name;
139 cpu->byte_order = EMUL_LITTLE_ENDIAN;
140 cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER;
141
142 if (cpu->cd.mips.cpu_type.isa_level <= 2 ||
143 cpu->cd.mips.cpu_type.isa_level == 32)
144 cpu->is_32bit = 1;
145
146 if (cpu->is_32bit) {
147 cpu->run_instr = mips32_run_instr;
148 cpu->update_translation_table = mips32_update_translation_table;
149 cpu->invalidate_translation_caches =
150 mips32_invalidate_translation_caches;
151 cpu->invalidate_code_translation =
152 mips32_invalidate_code_translation;
153 } else {
154 cpu->run_instr = mips_run_instr;
155 cpu->update_translation_table = mips_update_translation_table;
156 cpu->invalidate_translation_caches =
157 mips_invalidate_translation_caches;
158 cpu->invalidate_code_translation =
159 mips_invalidate_code_translation;
160 }
161
162 cpu->instruction_has_delayslot = mips_cpu_instruction_has_delayslot;
163
164 if (cpu_id == 0)
165 debug("%s", cpu->cd.mips.cpu_type.name);
166
167 /*
168 * CACHES:
169 *
170 * 1) Use DEFAULT_PCACHE_SIZE and DEFAULT_PCACHE_LINESIZE etc.
171 * 2) If there are specific values defined for this type of cpu,
172 * in its cpu_type substruct, then let's use those.
173 * 3) Values in the emul struct override both of the above.
174 *
175 * Once we've decided which values to use, they are stored in
176 * the emul struct so they can be used from src/machine.c etc.
177 */
178
179 x = DEFAULT_PCACHE_SIZE;
180 if (cpu->cd.mips.cpu_type.pdcache)
181 x = cpu->cd.mips.cpu_type.pdcache;
182 if (machine->cache_pdcache == 0)
183 machine->cache_pdcache = x;
184
185 x = DEFAULT_PCACHE_SIZE;
186 if (cpu->cd.mips.cpu_type.picache)
187 x = cpu->cd.mips.cpu_type.picache;
188 if (machine->cache_picache == 0)
189 machine->cache_picache = x;
190
191 if (machine->cache_secondary == 0)
192 machine->cache_secondary = cpu->cd.mips.cpu_type.scache;
193
194 linesize = DEFAULT_PCACHE_LINESIZE;
195 if (cpu->cd.mips.cpu_type.pdlinesize)
196 linesize = cpu->cd.mips.cpu_type.pdlinesize;
197 if (machine->cache_pdcache_linesize == 0)
198 machine->cache_pdcache_linesize = linesize;
199
200 linesize = DEFAULT_PCACHE_LINESIZE;
201 if (cpu->cd.mips.cpu_type.pilinesize)
202 linesize = cpu->cd.mips.cpu_type.pilinesize;
203 if (machine->cache_picache_linesize == 0)
204 machine->cache_picache_linesize = linesize;
205
206 linesize = 0;
207 if (cpu->cd.mips.cpu_type.slinesize)
208 linesize = cpu->cd.mips.cpu_type.slinesize;
209 if (machine->cache_secondary_linesize == 0)
210 machine->cache_secondary_linesize = linesize;
211
212
213 /*
214 * Primary Data and Instruction caches:
215 */
216 for (i=CACHE_DATA; i<=CACHE_INSTRUCTION; i++) {
217 switch (i) {
218 case CACHE_DATA:
219 x = 1 << machine->cache_pdcache;
220 linesize = 1 << machine->cache_pdcache_linesize;
221 break;
222 case CACHE_INSTRUCTION:
223 x = 1 << machine->cache_picache;
224 linesize = 1 << machine->cache_picache_linesize;
225 break;
226 }
227
228 /* Primary cache size and linesize: */
229 cpu->cd.mips.cache_size[i] = x;
230 cpu->cd.mips.cache_linesize[i] = linesize;
231
232 switch (cpu->cd.mips.cpu_type.rev) {
233 case MIPS_R2000:
234 case MIPS_R3000:
235 size_per_cache_line = sizeof(struct r3000_cache_line);
236 break;
237 default:
238 size_per_cache_line = sizeof(struct r4000_cache_line);
239 }
240
241 cpu->cd.mips.cache_mask[i] = cpu->cd.mips.cache_size[i] - 1;
242 cpu->cd.mips.cache_miss_penalty[i] = 10; /* TODO ? */
243
244 cpu->cd.mips.cache[i] = malloc(cpu->cd.mips.cache_size[i]);
245 if (cpu->cd.mips.cache[i] == NULL) {
246 fprintf(stderr, "out of memory\n");
247 }
248
249 n_cache_lines = cpu->cd.mips.cache_size[i] /
250 cpu->cd.mips.cache_linesize[i];
251 tags_size = n_cache_lines * size_per_cache_line;
252
253 cpu->cd.mips.cache_tags[i] = malloc(tags_size);
254 if (cpu->cd.mips.cache_tags[i] == NULL) {
255 fprintf(stderr, "out of memory\n");
256 }
257
258 /* Initialize the cache tags: */
259 switch (cpu->cd.mips.cpu_type.rev) {
260 case MIPS_R2000:
261 case MIPS_R3000:
262 for (j=0; j<n_cache_lines; j++) {
263 struct r3000_cache_line *rp;
264 rp = (struct r3000_cache_line *)
265 cpu->cd.mips.cache_tags[i];
266 rp[j].tag_paddr = 0;
267 rp[j].tag_valid = 0;
268 }
269 break;
270 default:
271 ;
272 }
273
274 /* Set cache_last_paddr to something "impossible": */
275 cpu->cd.mips.cache_last_paddr[i] = IMPOSSIBLE_PADDR;
276 }
277
278 /*
279 * Secondary cache:
280 */
281 secondary_cache_size = 0;
282 if (machine->cache_secondary)
283 secondary_cache_size = 1 << machine->cache_secondary;
284 /* TODO: linesize... */
285
286 if (cpu_id == 0) {
287 debug(" (I+D = %i+%i KB",
288 (int)(cpu->cd.mips.cache_size[CACHE_INSTRUCTION] / 1024),
289 (int)(cpu->cd.mips.cache_size[CACHE_DATA] / 1024));
290
291 if (secondary_cache_size != 0) {
292 debug(", L2 = ");
293 if (secondary_cache_size >= 1048576)
294 debug("%i MB", (int)
295 (secondary_cache_size / 1048576));
296 else
297 debug("%i KB", (int)
298 (secondary_cache_size / 1024));
299 }
300
301 debug(")");
302 }
303
304 /* System coprocessor (0), and FPU (1): */
305 cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);
306 cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);
307
308 switch (cpu->cd.mips.cpu_type.mmu_model) {
309 case MMU3K:
310 cpu->translate_v2p = translate_v2p_mmu3k;
311 break;
312 case MMU8K:
313 cpu->translate_v2p = translate_v2p_mmu8k;
314 break;
315 case MMU10K:
316 cpu->translate_v2p = translate_v2p_mmu10k;
317 break;
318 default:
319 if (cpu->cd.mips.cpu_type.rev == MIPS_R4100)
320 cpu->translate_v2p = translate_v2p_mmu4100;
321 else
322 cpu->translate_v2p = translate_v2p_generic;
323 }
324
325 return 1;
326 }
327
328
329 /*
330 * mips_cpu_dumpinfo():
331 *
332 * Debug dump of MIPS-specific CPU data for specific CPU.
333 */
334 void mips_cpu_dumpinfo(struct cpu *cpu)
335 {
336 int iadd = DEBUG_INDENTATION;
337 struct mips_cpu_type_def *ct = &cpu->cd.mips.cpu_type;
338
339 debug_indentation(iadd);
340
341 debug("\n%i-bit %s-endian (MIPS",
342 cpu->is_32bit? 32 : 64,
343 cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
344
345 switch (ct->isa_level) {
346 case 1: debug(" ISA I"); break;
347 case 2: debug(" ISA II"); break;
348 case 3: debug(" ISA III"); break;
349 case 4: debug(" ISA IV"); break;
350 case 5: debug(" ISA V"); break;
351 case 32:
352 case 64:debug("%i, revision %i", ct->isa_level, ct->isa_revision);
353 break;
354 default:debug(" ISA level %i", ct->isa_level);
355 }
356
357 debug("), ");
358 if (ct->nr_of_tlb_entries)
359 debug("%i TLB entries", ct->nr_of_tlb_entries);
360 else
361 debug("no TLB");
362 debug("\n");
363
364 if (ct->picache) {
365 debug("L1 I-cache: %i KB", (1 << ct->picache) / 1024);
366 if (ct->pilinesize)
367 debug(", %i bytes per line", 1 << ct->pilinesize);
368 if (ct->piways > 1)
369 debug(", %i-way", ct->piways);
370 else
371 debug(", direct-mapped");
372 debug("\n");
373 }
374
375 if (ct->pdcache) {
376 debug("L1 D-cache: %i KB", (1 << ct->pdcache) / 1024);
377 if (ct->pdlinesize)
378 debug(", %i bytes per line", 1 << ct->pdlinesize);
379 if (ct->pdways > 1)
380 debug(", %i-way", ct->pdways);
381 else
382 debug(", direct-mapped");
383 debug("\n");
384 }
385
386 if (ct->scache) {
387 int kb = (1 << ct->scache) / 1024;
388 debug("L2 cache: %i %s",
389 kb >= 1024? kb / 1024 : kb, kb >= 1024? "MB":"KB");
390 if (ct->slinesize)
391 debug(", %i bytes per line", 1 << ct->slinesize);
392 if (ct->sways > 1)
393 debug(", %i-way", ct->sways);
394 else
395 debug(", direct-mapped");
396 debug("\n");
397 }
398
399 debug_indentation(-iadd);
400 }
401
402
403 /*
404 * mips_cpu_list_available_types():
405 *
406 * Print a list of available MIPS CPU types.
407 */
408 void mips_cpu_list_available_types(void)
409 {
410 int i, j;
411 struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
412
413 i = 0;
414 while (cpu_type_defs[i].name != NULL) {
415 debug("%s", cpu_type_defs[i].name);
416 for (j=10 - strlen(cpu_type_defs[i].name); j>0; j--)
417 debug(" ");
418 i++;
419 if ((i % 6) == 0 || cpu_type_defs[i].name == NULL)
420 debug("\n");
421 }
422 }
423
424
425 /*
426 * mips_cpu_instruction_has_delayslot():
427 *
428 * Return 1 if an opcode is a branch, 0 otherwise.
429 */
430 int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
431 {
432 uint32_t iword = *((uint32_t *)&ib[0]);
433
434 if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
435 iword = LE32_TO_HOST(iword);
436 else
437 iword = BE32_TO_HOST(iword);
438
439 switch (iword >> 26) {
440 case HI6_SPECIAL:
441 switch (iword & 0x3f) {
442 case SPECIAL_JR:
443 case SPECIAL_JALR:
444 return 1;
445 }
446 break;
447 case HI6_REGIMM:
448 switch ((iword >> 16) & 0x1f) {
449 case REGIMM_BLTZ:
450 case REGIMM_BGEZ:
451 case REGIMM_BLTZL:
452 case REGIMM_BGEZL:
453 case REGIMM_BLTZAL:
454 case REGIMM_BLTZALL:
455 case REGIMM_BGEZAL:
456 case REGIMM_BGEZALL:
457 return 1;
458 }
459 break;
460 case HI6_BEQ:
461 case HI6_BEQL:
462 case HI6_BNE:
463 case HI6_BNEL:
464 case HI6_BGTZ:
465 case HI6_BGTZL:
466 case HI6_BLEZ:
467 case HI6_BLEZL:
468 case HI6_J:
469 case HI6_JAL:
470 return 1;
471 }
472
473 return 0;
474 }
475
476
477 /*
478 * mips_cpu_tlbdump():
479 *
480 * Called from the debugger to dump the TLB in a readable format.
481 * x is the cpu number to dump, or -1 to dump all CPUs.
482 *
483 * If rawflag is nonzero, then the TLB contents isn't formated nicely,
484 * just dumped.
485 */
486 void mips_cpu_tlbdump(struct machine *m, int x, int rawflag)
487 {
488 int i, j;
489
490 /* Raw output: */
491 if (rawflag) {
492 for (i=0; i<m->ncpus; i++) {
493 if (x >= 0 && i != x)
494 continue;
495
496 /* Print index, random, and wired: */
497 printf("cpu%i: (", i);
498
499 if (m->cpus[i]->is_32bit)
500 printf("index=0x%08x random=0x%08x", (int)m->
501 cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],
502 (int)m->cpus[i]->cd.mips.coproc[0]->reg
503 [COP0_RANDOM]);
504 else
505 printf("index=0x%016"PRIx64
506 " random=0x%016"PRIx64,
507 (uint64_t)m->cpus[i]->cd.mips.coproc[0]->
508 reg[COP0_INDEX], (uint64_t)m->cpus[i]->
509 cd.mips.coproc[0]->reg[COP0_RANDOM]);
510
511 if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
512 printf(" wired=0x%"PRIx64, (uint64_t) m->cpus
513 [i]->cd.mips.coproc[0]->reg[COP0_WIRED]);
514
515 printf(")\n");
516
517 for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
518 nr_of_tlb_entries; j++) {
519 if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
520 MMU3K)
521 printf("%3i: hi=0x%08x lo=0x%08x\n", j,
522 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
523 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);
524 else if (m->cpus[i]->is_32bit)
525 printf("%3i: hi=0x%08x mask=0x%08x "
526 "lo0=0x%08x lo1=0x%08x\n", j,
527 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
528 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
529 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
530 (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
531 else
532 printf("%3i: hi=0x%016"PRIx64" mask=0x%016"PRIx64" "
533 "lo0=0x%016"PRIx64" lo1=0x%016"PRIx64"\n", j,
534 (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
535 (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
536 (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
537 (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
538 }
539 }
540 return;
541 }
542
543 /* Nicely formatted output: */
544 for (i=0; i<m->ncpus; i++) {
545 int pageshift = 12;
546
547 if (x >= 0 && i != x)
548 continue;
549
550 if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
551 pageshift = 10;
552
553 /* Print index, random, and wired: */
554 printf("cpu%i: (", i);
555 switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
556 case 1:
557 case 2: printf("index=0x%x random=0x%x",
558 (int) ((m->cpus[i]->cd.mips.coproc[0]->
559 reg[COP0_INDEX] & R2K3K_INDEX_MASK)
560 >> R2K3K_INDEX_SHIFT),
561 (int) ((m->cpus[i]->cd.mips.coproc[0]->
562 reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
563 >> R2K3K_RANDOM_SHIFT));
564 break;
565 default:printf("index=0x%x random=0x%x",
566 (int) (m->cpus[i]->cd.mips.coproc[0]->
567 reg[COP0_INDEX] & INDEX_MASK),
568 (int) (m->cpus[i]->cd.mips.coproc[0]->
569 reg[COP0_RANDOM] & RANDOM_MASK));
570 printf(" wired=0x%"PRIx64, (uint64_t)
571 m->cpus[i]->cd.mips.coproc[0]->reg[COP0_WIRED]);
572 }
573
574 printf(")\n");
575
576 for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
577 nr_of_tlb_entries; j++) {
578 uint64_t hi,lo0,lo1,mask;
579 hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;
580 lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;
581 lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;
582 mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;
583
584 printf("%3i: ", j);
585 switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
586 case MMU3K:
587 if (!(lo0 & R2K3K_ENTRYLO_V)) {
588 printf("(invalid)\n");
589 continue;
590 }
591 printf("vaddr=0x%08x ",
592 (int) (hi&R2K3K_ENTRYHI_VPN_MASK));
593 if (lo0 & R2K3K_ENTRYLO_G)
594 printf("(global), ");
595 else
596 printf("(asid %02x),", (int) ((hi &
597 R2K3K_ENTRYHI_ASID_MASK)
598 >> R2K3K_ENTRYHI_ASID_SHIFT));
599 printf(" paddr=0x%08x ",
600 (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));
601 if (lo0 & R2K3K_ENTRYLO_N)
602 printf("N");
603 if (lo0 & R2K3K_ENTRYLO_D)
604 printf("D");
605 printf("\n");
606 break;
607 default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
608 case MMU10K:
609 printf("vaddr=0x%1x..%011"PRIx64" ",
610 (int) (hi >> 60), (uint64_t)
611 (hi&ENTRYHI_VPN2_MASK_R10K));
612 break;
613 case MMU32:
614 printf("vaddr=0x%08"PRIx32" ",
615 (uint32_t)(hi&ENTRYHI_VPN2_MASK));
616 break;
617 default:/* R4000 etc. */
618 printf("vaddr=0x%1x..%010"PRIx64" ",
619 (int) (hi >> 60),
620 (uint64_t) (hi&ENTRYHI_VPN2_MASK));
621 }
622 if (hi & TLB_G)
623 printf("(global): ");
624 else
625 printf("(asid %02x):",
626 (int) (hi & ENTRYHI_ASID));
627
628 /* TODO: Coherency bits */
629
630 if (!(lo0 & ENTRYLO_V))
631 printf(" p0=(invalid) ");
632 else
633 printf(" p0=0x%09"PRIx64" ", (uint64_t)
634 (((lo0&ENTRYLO_PFN_MASK) >>
635 ENTRYLO_PFN_SHIFT) << pageshift));
636 printf(lo0 & ENTRYLO_D? "D" : " ");
637
638 if (!(lo1 & ENTRYLO_V))
639 printf(" p1=(invalid) ");
640 else
641 printf(" p1=0x%09"PRIx64" ", (uint64_t)
642 (((lo1&ENTRYLO_PFN_MASK) >>
643 ENTRYLO_PFN_SHIFT) << pageshift));
644 printf(lo1 & ENTRYLO_D? "D" : " ");
645 mask |= (1 << (pageshift+1)) - 1;
646 switch (mask) {
647 case 0x7ff: printf(" (1KB)"); break;
648 case 0x1fff: printf(" (4KB)"); break;
649 case 0x7fff: printf(" (16KB)"); break;
650 case 0x1ffff: printf(" (64KB)"); break;
651 case 0x7ffff: printf(" (256KB)"); break;
652 case 0x1fffff: printf(" (1MB)"); break;
653 case 0x7fffff: printf(" (4MB)"); break;
654 case 0x1ffffff: printf(" (16MB)"); break;
655 case 0x7ffffff: printf(" (64MB)"); break;
656 default:printf(" (mask=%08x?)", (int)mask);
657 }
658 printf("\n");
659 }
660 }
661 }
662 }
663
664
665 /*
666 * mips_cpu_register_match():
667 */
668 void mips_cpu_register_match(struct machine *m, char *name,
669 int writeflag, uint64_t *valuep, int *match_register)
670 {
671 int cpunr = 0;
672
673 /* CPU number: */
674
675 /* TODO */
676
677 /* Register name: */
678 if (strcasecmp(name, "pc") == 0) {
679 if (writeflag) {
680 m->cpus[cpunr]->pc = *valuep;
681 if (m->cpus[cpunr]->delay_slot) {
682 printf("NOTE: Clearing the delay slot"
683 " flag! (It was set before.)\n");
684 m->cpus[cpunr]->delay_slot = 0;
685 }
686 if (m->cpus[cpunr]->cd.mips.nullify_next) {
687 printf("NOTE: Clearing the nullify-ne"
688 "xt flag! (It was set before.)\n");
689 m->cpus[cpunr]->cd.mips.nullify_next = 0;
690 }
691 } else
692 *valuep = m->cpus[cpunr]->pc;
693 *match_register = 1;
694 } else if (strcasecmp(name, "hi") == 0) {
695 if (writeflag)
696 m->cpus[cpunr]->cd.mips.hi = *valuep;
697 else
698 *valuep = m->cpus[cpunr]->cd.mips.hi;
699 *match_register = 1;
700 } else if (strcasecmp(name, "lo") == 0) {
701 if (writeflag)
702 m->cpus[cpunr]->cd.mips.lo = *valuep;
703 else
704 *valuep = m->cpus[cpunr]->cd.mips.lo;
705 *match_register = 1;
706 } else if (name[0] == 'r' && isdigit((int)name[1])) {
707 int nr = atoi(name + 1);
708 if (nr >= 0 && nr < N_MIPS_GPRS) {
709 if (writeflag) {
710 if (nr != 0)
711 m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;
712 else
713 printf("WARNING: Attempt to modify r0.\n");
714 } else
715 *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];
716 *match_register = 1;
717 }
718 } else {
719 /* Check for a symbolic name such as "t6" or "at": */
720 int nr;
721 for (nr=0; nr<N_MIPS_GPRS; nr++)
722 if (strcmp(name, regnames[nr]) == 0) {
723 if (writeflag) {
724 if (nr != 0)
725 m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;
726 else
727 printf("WARNING: Attempt to modify r0.\n");
728 } else
729 *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];
730 *match_register = 1;
731 }
732 }
733
734 if (!(*match_register)) {
735 /* Check for a symbolic coproc0 name: */
736 int nr;
737 for (nr=0; nr<32; nr++)
738 if (strcmp(name, cop0_names[nr]) == 0) {
739 if (writeflag) {
740 coproc_register_write(m->cpus[cpunr],
741 m->cpus[cpunr]->cd.mips.coproc[0], nr,
742 valuep, 1, 0);
743 } else {
744 /* TODO: Use coproc_register_read instead? */
745 *valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr];
746 }
747 *match_register = 1;
748 }
749 }
750
751 /* TODO: Coprocessor 1,2,3 registers. */
752
753 /* Only return lowest 32 bits when doing 32-bit emulation: */
754 if (!writeflag && m->cpus[cpunr]->is_32bit)
755 *valuep = (uint32_t) (*valuep);
756 }
757
758
759 /*
760 * cpu_flags():
761 *
762 * Returns a pointer to a string containing "(d)" "(j)" "(dj)" or "",
763 * depending on the cpu's current delay_slot and last_was_jumptoself
764 * flags.
765 */
766 static const char *cpu_flags(struct cpu *cpu)
767 {
768 if (cpu->delay_slot) {
769 if (cpu->cd.mips.last_was_jumptoself)
770 return " (dj)";
771 else
772 return " (d)";
773 } else {
774 if (cpu->cd.mips.last_was_jumptoself)
775 return " (j)";
776 else
777 return "";
778 }
779 }
780
781
782 /*
783 * mips_cpu_disassemble_instr():
784 *
785 * Convert an instruction word into human readable format, for instruction
786 * tracing.
787 *
788 * If running is 1, cpu->pc should be the address of the instruction.
789 *
790 * If running is 0, things that depend on the runtime environment (eg.
791 * register contents) will not be shown, and addr will be used instead of
792 * cpu->pc for relative addresses.
793 *
794 * NOTE 2: coprocessor instructions are not decoded nicely yet (TODO)
795 */
796 int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
797 int running, uint64_t dumpaddr)
798 {
799 int hi6, special6, regimm5;
800 int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
801 uint64_t addr, offset;
802 uint32_t instrword;
803 unsigned char instr[4];
804 char *symbol;
805
806 if (running)
807 dumpaddr = cpu->pc;
808
809 if ((dumpaddr & 3) != 0)
810 printf("WARNING: Unaligned address!\n");
811
812 symbol = get_symbol_name(&cpu->machine->symbol_context,
813 dumpaddr, &offset);
814 if (symbol != NULL && offset==0)
815 debug("<%s>\n", symbol);
816
817 if (cpu->machine->ncpus > 1 && running)
818 debug("cpu%i: ", cpu->cpu_id);
819
820 if (cpu->is_32bit)
821 debug("%08"PRIx32, (uint32_t)dumpaddr);
822 else
823 debug("%016"PRIx64, (uint64_t)dumpaddr);
824
825 *((uint32_t *)&instr[0]) = *((uint32_t *)&originstr[0]);
826
827 /*
828 * The rest of the code is written for little endian,
829 * so swap if necessary:
830 */
831 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
832 int tmp = instr[0]; instr[0] = instr[3];
833 instr[3] = tmp;
834 tmp = instr[1]; instr[1] = instr[2];
835 instr[2] = tmp;
836 }
837
838 debug(": %02x%02x%02x%02x",
839 instr[3], instr[2], instr[1], instr[0]);
840
841 if (running)
842 debug("%s", cpu_flags(cpu));
843
844 debug("\t");
845
846 /*
847 * Decode the instruction:
848 */
849
850 if (cpu->cd.mips.nullify_next && running) {
851 debug("(nullified)");
852 goto disasm_ret;
853 }
854
855 hi6 = (instr[3] >> 2) & 0x3f;
856
857 switch (hi6) {
858 case HI6_SPECIAL:
859 special6 = instr[0] & 0x3f;
860 switch (special6) {
861 case SPECIAL_SLL:
862 case SPECIAL_SRL:
863 case SPECIAL_SRA:
864 case SPECIAL_DSLL:
865 case SPECIAL_DSRL:
866 case SPECIAL_DSRA:
867 case SPECIAL_DSLL32:
868 case SPECIAL_DSRL32:
869 case SPECIAL_DSRA32:
870 rt = instr[2] & 31;
871 rd = (instr[1] >> 3) & 31;
872 sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
873
874 if (rd == 0 && special6 == SPECIAL_SLL) {
875 if (sa == 0)
876 debug("nop");
877 else if (sa == 1)
878 debug("ssnop");
879 else if (sa == 3)
880 debug("ehb");
881 else
882 debug("nop (weird, sa=%i)", sa);
883 goto disasm_ret;
884 } else
885 debug("%s\t%s,",
886 special_names[special6],
887 regname(cpu->machine, rd));
888 debug("%s,%i", regname(cpu->machine, rt), sa);
889 break;
890 case SPECIAL_DSRLV:
891 case SPECIAL_DSRAV:
892 case SPECIAL_DSLLV:
893 case SPECIAL_SLLV:
894 case SPECIAL_SRAV:
895 case SPECIAL_SRLV:
896 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
897 rt = instr[2] & 31;
898 rd = (instr[1] >> 3) & 31;
899 debug("%s\t%s",
900 special_names[special6], regname(cpu->machine, rd));
901 debug(",%s", regname(cpu->machine, rt));
902 debug(",%s", regname(cpu->machine, rs));
903 break;
904 case SPECIAL_JR:
905 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
906 symbol = get_symbol_name(&cpu->machine->symbol_context,
907 cpu->cd.mips.gpr[rs], &offset);
908 debug("jr\t%s", regname(cpu->machine, rs));
909 if (running && symbol != NULL)
910 debug("\t<%s>", symbol);
911 break;
912 case SPECIAL_JALR:
913 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
914 rd = (instr[1] >> 3) & 31;
915 symbol = get_symbol_name(&cpu->machine->symbol_context,
916 cpu->cd.mips.gpr[rs], &offset);
917 debug("jalr\t%s", regname(cpu->machine, rd));
918 debug(",%s", regname(cpu->machine, rs));
919 if (running && symbol != NULL)
920 debug("\t<%s>", symbol);
921 break;
922 case SPECIAL_MFHI:
923 case SPECIAL_MFLO:
924 rd = (instr[1] >> 3) & 31;
925 debug("%s\t%s", special_names[special6],
926 regname(cpu->machine, rd));
927 break;
928 case SPECIAL_MTLO:
929 case SPECIAL_MTHI:
930 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
931 debug("%s\t%s", special_names[special6],
932 regname(cpu->machine, rs));
933 break;
934 case SPECIAL_ADD:
935 case SPECIAL_ADDU:
936 case SPECIAL_SUB:
937 case SPECIAL_SUBU:
938 case SPECIAL_AND:
939 case SPECIAL_OR:
940 case SPECIAL_XOR:
941 case SPECIAL_NOR:
942 case SPECIAL_SLT:
943 case SPECIAL_SLTU:
944 case SPECIAL_DADD:
945 case SPECIAL_DADDU:
946 case SPECIAL_DSUB:
947 case SPECIAL_DSUBU:
948 case SPECIAL_MOVZ:
949 case SPECIAL_MOVN:
950 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
951 rt = instr[2] & 31;
952 rd = (instr[1] >> 3) & 31;
953 if (cpu->is_32bit && (special6 == SPECIAL_ADDU ||
954 special6 == SPECIAL_SUBU) && rt == 0) {
955 /* Special case 1: addu/subu with
956 rt = the zero register ==> move */
957 debug("move\t%s", regname(cpu->machine, rd));
958 debug(",%s", regname(cpu->machine, rs));
959 } else if (special6 == SPECIAL_ADDU && cpu->is_32bit
960 && rs == 0) {
961 /* Special case 2: addu with
962 rs = the zero register ==> move */
963 debug("move\t%s", regname(cpu->machine, rd));
964 debug(",%s", regname(cpu->machine, rt));
965 } else {
966 debug("%s\t%s", special_names[special6],
967 regname(cpu->machine, rd));
968 debug(",%s", regname(cpu->machine, rs));
969 debug(",%s", regname(cpu->machine, rt));
970 }
971 break;
972 case SPECIAL_MULT:
973 case SPECIAL_MULTU:
974 case SPECIAL_DMULT:
975 case SPECIAL_DMULTU:
976 case SPECIAL_DIV:
977 case SPECIAL_DIVU:
978 case SPECIAL_DDIV:
979 case SPECIAL_DDIVU:
980 case SPECIAL_TGE:
981 case SPECIAL_TGEU:
982 case SPECIAL_TLT:
983 case SPECIAL_TLTU:
984 case SPECIAL_TEQ:
985 case SPECIAL_TNE:
986 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
987 rt = instr[2] & 31;
988 rd = (instr[1] >> 3) & 31;
989 debug("%s\t", special_names[special6]);
990 if (rd != 0) {
991 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
992 if (special6 == SPECIAL_MULT ||
993 special6 == SPECIAL_MULTU)
994 debug("%s,",
995 regname(cpu->machine, rd));
996 else
997 debug("WEIRD_R5900_RD,");
998 } else {
999 debug("WEIRD_RD_NONZERO,");
1000 }
1001 }
1002 debug("%s", regname(cpu->machine, rs));
1003 debug(",%s", regname(cpu->machine, rt));
1004 break;
1005 case SPECIAL_SYNC:
1006 imm = ((instr[1] & 7) << 2) + (instr[0] >> 6);
1007 debug("sync\t0x%02x", imm);
1008 break;
1009 case SPECIAL_SYSCALL:
1010 imm = (((instr[3] << 24) + (instr[2] << 16) +
1011 (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
1012 if (imm != 0)
1013 debug("syscall\t0x%05x", imm);
1014 else
1015 debug("syscall");
1016 break;
1017 case SPECIAL_BREAK:
1018 imm = (((instr[3] << 24) + (instr[2] << 16) +
1019 (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
1020 if (imm != 0)
1021 debug("break\t0x%05x", imm);
1022 else
1023 debug("break");
1024 break;
1025 case SPECIAL_MFSA:
1026 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1027 rd = (instr[1] >> 3) & 31;
1028 debug("mfsa\t%s", regname(cpu->machine, rd));
1029 } else {
1030 debug("unimplemented special 0x28");
1031 }
1032 break;
1033 case SPECIAL_MTSA:
1034 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1035 rs = ((instr[3] & 3) << 3) +
1036 ((instr[2] >> 5) & 7);
1037 debug("mtsa\t%s", regname(cpu->machine, rs));
1038 } else {
1039 debug("unimplemented special 0x29");
1040 }
1041 break;
1042 default:
1043 debug("%s\t= UNIMPLEMENTED", special_names[special6]);
1044 }
1045 break;
1046 case HI6_BEQ:
1047 case HI6_BEQL:
1048 case HI6_BNE:
1049 case HI6_BNEL:
1050 case HI6_BGTZ:
1051 case HI6_BGTZL:
1052 case HI6_BLEZ:
1053 case HI6_BLEZL:
1054 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1055 rt = instr[2] & 31;
1056 imm = (instr[1] << 8) + instr[0];
1057 if (imm >= 32768)
1058 imm -= 65536;
1059 addr = (dumpaddr + 4) + (imm << 2);
1060
1061 if (hi6 == HI6_BEQ && rt == MIPS_GPR_ZERO &&
1062 rs == MIPS_GPR_ZERO)
1063 debug("b\t");
1064 else {
1065 debug("%s\t", hi6_names[hi6]);
1066 switch (hi6) {
1067 case HI6_BEQ:
1068 case HI6_BEQL:
1069 case HI6_BNE:
1070 case HI6_BNEL:
1071 debug("%s,", regname(cpu->machine, rt));
1072 }
1073 debug("%s,", regname(cpu->machine, rs));
1074 }
1075
1076 if (cpu->is_32bit)
1077 debug("0x%08"PRIx32, (uint32_t)addr);
1078 else
1079 debug("0x%016"PRIx64, (uint64_t)addr);
1080
1081 symbol = get_symbol_name(&cpu->machine->symbol_context,
1082 addr, &offset);
1083 if (symbol != NULL && offset != addr)
1084 debug("\t<%s>", symbol);
1085 break;
1086 case HI6_ADDI:
1087 case HI6_ADDIU:
1088 case HI6_DADDI:
1089 case HI6_DADDIU:
1090 case HI6_SLTI:
1091 case HI6_SLTIU:
1092 case HI6_ANDI:
1093 case HI6_ORI:
1094 case HI6_XORI:
1095 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1096 rt = instr[2] & 31;
1097 imm = (instr[1] << 8) + instr[0];
1098 if (imm >= 32768)
1099 imm -= 65536;
1100 debug("%s\t%s,", hi6_names[hi6], regname(cpu->machine, rt));
1101 debug("%s,", regname(cpu->machine, rs));
1102 if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI)
1103 debug("0x%04x", imm & 0xffff);
1104 else
1105 debug("%i", imm);
1106 break;
1107 case HI6_LUI:
1108 rt = instr[2] & 31;
1109 imm = (instr[1] << 8) + instr[0];
1110 debug("lui\t%s,0x%x", regname(cpu->machine, rt), imm);
1111 break;
1112 case HI6_LB:
1113 case HI6_LBU:
1114 case HI6_LH:
1115 case HI6_LHU:
1116 case HI6_LW:
1117 case HI6_LWU:
1118 case HI6_LD:
1119 case HI6_LQ_MDMX:
1120 case HI6_LWC1:
1121 case HI6_LWC2:
1122 case HI6_LWC3:
1123 case HI6_LDC1:
1124 case HI6_LDC2:
1125 case HI6_LL:
1126 case HI6_LLD:
1127 case HI6_SB:
1128 case HI6_SH:
1129 case HI6_SW:
1130 case HI6_SD:
1131 case HI6_SQ_SPECIAL3:
1132 case HI6_SC:
1133 case HI6_SCD:
1134 case HI6_SWC1:
1135 case HI6_SWC2:
1136 case HI6_SWC3:
1137 case HI6_SDC1:
1138 case HI6_SDC2:
1139 case HI6_LWL:
1140 case HI6_LWR:
1141 case HI6_LDL:
1142 case HI6_LDR:
1143 case HI6_SWL:
1144 case HI6_SWR:
1145 case HI6_SDL:
1146 case HI6_SDR:
1147 if (hi6 == HI6_LQ_MDMX &&
1148 cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1149 debug("mdmx\t(UNIMPLEMENTED)");
1150 break;
1151 }
1152 if (hi6 == HI6_SQ_SPECIAL3 &&
1153 cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1154 special6 = instr[0] & 0x3f;
1155 debug("%s", special3_names[special6]);
1156 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1157 rt = instr[2] & 31;
1158 rd = (instr[1] >> 3) & 31;
1159
1160 switch (special6) {
1161
1162 case SPECIAL3_RDHWR:
1163 debug("\t%s", regname(cpu->machine, rt));
1164 debug(",hwr%i", rd);
1165 break;
1166
1167 default:
1168 debug("\t(UNIMPLEMENTED)");
1169 }
1170 break;
1171 }
1172
1173 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1174 rt = instr[2] & 31;
1175 imm = (instr[1] << 8) + instr[0];
1176 if (imm >= 32768)
1177 imm -= 65536;
1178 symbol = get_symbol_name(&cpu->machine->symbol_context,
1179 cpu->cd.mips.gpr[rs] + imm, &offset);
1180
1181 /* LWC3 is PREF in the newer ISA levels: */
1182 /* TODO: Which ISAs? IV? V? 32? 64? */
1183 if (cpu->cd.mips.cpu_type.isa_level >= 4 && hi6 == HI6_LWC3) {
1184 debug("pref\t0x%x,%i(%s)",
1185 rt, imm, regname(cpu->machine, rs));
1186
1187 if (running) {
1188 debug("\t[0x%016"PRIx64" = %s]",
1189 (uint64_t)(cpu->cd.mips.gpr[rs] + imm));
1190 if (symbol != NULL)
1191 debug(" = %s", symbol);
1192 debug("]");
1193 }
1194 goto disasm_ret;
1195 }
1196
1197 debug("%s\t", hi6_names[hi6]);
1198
1199 if (hi6 == HI6_SWC1 || hi6 == HI6_SWC2 || hi6 == HI6_SWC3 ||
1200 hi6 == HI6_SDC1 || hi6 == HI6_SDC2 ||
1201 hi6 == HI6_LWC1 || hi6 == HI6_LWC2 || hi6 == HI6_LWC3 ||
1202 hi6 == HI6_LDC1 || hi6 == HI6_LDC2)
1203 debug("r%i", rt);
1204 else
1205 debug("%s", regname(cpu->machine, rt));
1206
1207 debug(",%i(%s)", imm, regname(cpu->machine, rs));
1208
1209 if (running) {
1210 debug("\t[");
1211
1212 if (cpu->is_32bit)
1213 debug("0x%08"PRIx32,
1214 (uint32_t) (cpu->cd.mips.gpr[rs] + imm));
1215 else
1216 debug("0x%016"PRIx64,
1217 (uint64_t) (cpu->cd.mips.gpr[rs] + imm));
1218
1219 if (symbol != NULL)
1220 debug(" = %s", symbol);
1221
1222 /* TODO: In some cases, it is possible to peek into
1223 memory, and display that data here, like for the
1224 other emulation modes. */
1225
1226 debug("]");
1227 }
1228 break;
1229
1230 case HI6_J:
1231 case HI6_JAL:
1232 imm = (((instr[3] & 3) << 24) + (instr[2] << 16) +
1233 (instr[1] << 8) + instr[0]) << 2;
1234 addr = (dumpaddr + 4) & ~((1 << 28) - 1);
1235 addr |= imm;
1236 symbol = get_symbol_name(&cpu->machine->symbol_context,
1237 addr, &offset);
1238 debug("%s\t0x", hi6_names[hi6]);
1239 if (cpu->is_32bit)
1240 debug("%08"PRIx32, (uint32_t) addr);
1241 else
1242 debug("%016"PRIx64, (uint64_t) addr);
1243 if (symbol != NULL)
1244 debug("\t<%s>", symbol);
1245 break;
1246
1247 case HI6_COP0:
1248 case HI6_COP1:
1249 case HI6_COP2:
1250 case HI6_COP3:
1251 imm = (instr[3] << 24) + (instr[2] << 16) +
1252 (instr[1] << 8) + instr[0];
1253 imm &= ((1 << 26) - 1);
1254
1255 /* Call coproc_function(), but ONLY disassembly, no exec: */
1256 coproc_function(cpu, cpu->cd.mips.coproc[hi6 - HI6_COP0],
1257 hi6 - HI6_COP0, imm, 1, running);
1258 return sizeof(instrword);
1259
1260 case HI6_CACHE:
1261 rt = ((instr[3] & 3) << 3) + (instr[2] >> 5); /* base */
1262 copz = instr[2] & 31;
1263 imm = (instr[1] << 8) + instr[0];
1264 cache_op = copz >> 2;
1265 which_cache = copz & 3;
1266 showtag = 0;
1267 debug("cache\t0x%02x,0x%04x(%s)", copz, imm,
1268 regname(cpu->machine, rt));
1269 if (which_cache==0) debug(" [ primary I-cache");
1270 if (which_cache==1) debug(" [ primary D-cache");
1271 if (which_cache==2) debug(" [ secondary I-cache");
1272 if (which_cache==3) debug(" [ secondary D-cache");
1273 debug(", ");
1274 if (cache_op==0) debug("index invalidate");
1275 if (cache_op==1) debug("index load tag");
1276 if (cache_op==2) debug("index store tag"), showtag=1;
1277 if (cache_op==3) debug("create dirty exclusive");
1278 if (cache_op==4) debug("hit invalidate");
1279 if (cache_op==5) debug("fill OR hit writeback invalidate");
1280 if (cache_op==6) debug("hit writeback");
1281 if (cache_op==7) debug("hit set virtual");
1282 if (running)
1283 debug(", addr 0x%016"PRIx64,
1284 (uint64_t)(cpu->cd.mips.gpr[rt] + imm));
1285 if (showtag)
1286 debug(", taghi=%08lx lo=%08lx",
1287 (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_HI],
1288 (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_LO]);
1289 debug(" ]");
1290 break;
1291
1292 case HI6_SPECIAL2:
1293 special6 = instr[0] & 0x3f;
1294 instrword = (instr[3] << 24) + (instr[2] << 16) +
1295 (instr[1] << 8) + instr[0];
1296 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1297 rt = instr[2] & 31;
1298 rd = (instr[1] >> 3) & 31;
1299
1300 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1301 int c790mmifunc = (instrword >> 6) & 0x1f;
1302 if (special6 != MMI_MMI0 && special6 != MMI_MMI1 &&
1303 special6 != MMI_MMI2 && special6 != MMI_MMI3)
1304 debug("%s\t", mmi_names[special6]);
1305
1306 switch (special6) {
1307
1308 case MMI_MADD:
1309 case MMI_MADDU:
1310 if (rd != MIPS_GPR_ZERO) {
1311 debug("%s,", regname(cpu->machine, rd));
1312 }
1313 debug("%s", regname(cpu->machine, rs));
1314 debug(",%s", regname(cpu->machine, rt));
1315 break;
1316
1317 case MMI_MMI0:
1318 debug("%s\t", mmi0_names[c790mmifunc]);
1319 switch (c790mmifunc) {
1320
1321 case MMI0_PEXTLB:
1322 case MMI0_PEXTLH:
1323 case MMI0_PEXTLW:
1324 case MMI0_PMAXH:
1325 case MMI0_PMAXW:
1326 case MMI0_PPACB:
1327 case MMI0_PPACH:
1328 case MMI0_PPACW:
1329 debug("%s", regname(cpu->machine, rd));
1330 debug(",%s", regname(cpu->machine, rs));
1331 debug(",%s", regname(cpu->machine, rt));
1332 break;
1333
1334 default:debug("(UNIMPLEMENTED)");
1335 }
1336 break;
1337
1338 case MMI_MMI1:
1339 debug("%s\t", mmi1_names[c790mmifunc]);
1340 switch (c790mmifunc) {
1341
1342 case MMI1_PEXTUB:
1343 case MMI1_PEXTUH:
1344 case MMI1_PEXTUW:
1345 case MMI1_PMINH:
1346 case MMI1_PMINW:
1347 debug("%s", regname(cpu->machine, rd));
1348 debug(",%s", regname(cpu->machine, rs));
1349 debug(",%s", regname(cpu->machine, rt));
1350 break;
1351
1352 default:debug("(UNIMPLEMENTED)");
1353 }
1354 break;
1355
1356 case MMI_MMI2:
1357 debug("%s\t", mmi2_names[c790mmifunc]);
1358 switch (c790mmifunc) {
1359
1360 case MMI2_PMFHI:
1361 case MMI2_PMFLO:
1362 debug("%s", regname(cpu->machine, rd));
1363 break;
1364
1365 case MMI2_PHMADH:
1366 case MMI2_PHMSBH:
1367 case MMI2_PINTH:
1368 case MMI2_PMADDH:
1369 case MMI2_PMADDW:
1370 case MMI2_PMSUBH:
1371 case MMI2_PMSUBW:
1372 case MMI2_PMULTH:
1373 case MMI2_PMULTW:
1374 case MMI2_PSLLVW:
1375 debug("%s", regname(cpu->machine, rd));
1376 debug(",%s", regname(cpu->machine, rs));
1377 debug(",%s", regname(cpu->machine, rt));
1378 break;
1379
1380 default:debug("(UNIMPLEMENTED)");
1381 }
1382 break;
1383
1384 case MMI_MMI3:
1385 debug("%s\t", mmi3_names[c790mmifunc]);
1386 switch (c790mmifunc) {
1387
1388 case MMI3_PMTHI:
1389 case MMI3_PMTLO:
1390 debug("%s", regname(cpu->machine, rs));
1391 break;
1392
1393 case MMI3_PINTEH:
1394 case MMI3_PMADDUW:
1395 case MMI3_PMULTUW:
1396 case MMI3_PNOR:
1397 case MMI3_POR:
1398 case MMI3_PSRAVW:
1399 debug("%s", regname(cpu->machine, rd));
1400 debug(",%s", regname(cpu->machine, rs));
1401 debug(",%s", regname(cpu->machine, rt));
1402 break;
1403
1404 default:debug("(UNIMPLEMENTED)");
1405 }
1406 break;
1407
1408 default:debug("(UNIMPLEMENTED)");
1409 }
1410 break;
1411 }
1412
1413 /* SPECIAL2: */
1414 debug("%s\t", special2_names[special6]);
1415
1416 switch (special6) {
1417
1418 case SPECIAL2_MADD:
1419 case SPECIAL2_MADDU:
1420 case SPECIAL2_MSUB:
1421 case SPECIAL2_MSUBU:
1422 if (rd != MIPS_GPR_ZERO) {
1423 debug("WEIRD_NONZERO_RD(%s),",
1424 regname(cpu->machine, rd));
1425 }
1426 debug("%s", regname(cpu->machine, rs));
1427 debug(",%s", regname(cpu->machine, rt));
1428 break;
1429
1430 case SPECIAL2_MUL:
1431 /* Apparently used both on R5900 and MIPS32: */
1432 debug("%s", regname(cpu->machine, rd));
1433 debug(",%s", regname(cpu->machine, rs));
1434 debug(",%s", regname(cpu->machine, rt));
1435 break;
1436
1437 case SPECIAL2_CLZ:
1438 case SPECIAL2_CLO:
1439 case SPECIAL2_DCLZ:
1440 case SPECIAL2_DCLO:
1441 debug("%s", regname(cpu->machine, rd));
1442 debug(",%s", regname(cpu->machine, rs));
1443 break;
1444
1445 default:
1446 debug("(UNIMPLEMENTED)");
1447 }
1448 break;
1449
1450 case HI6_REGIMM:
1451 regimm5 = instr[2] & 0x1f;
1452 switch (regimm5) {
1453 case REGIMM_BLTZ:
1454 case REGIMM_BGEZ:
1455 case REGIMM_BLTZL:
1456 case REGIMM_BGEZL:
1457 case REGIMM_BLTZAL:
1458 case REGIMM_BLTZALL:
1459 case REGIMM_BGEZAL:
1460 case REGIMM_BGEZALL:
1461 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1462 imm = (instr[1] << 8) + instr[0];
1463 if (imm >= 32768)
1464 imm -= 65536;
1465
1466 debug("%s\t%s,", regimm_names[regimm5],
1467 regname(cpu->machine, rs));
1468
1469 addr = (dumpaddr + 4) + (imm << 2);
1470
1471 if (cpu->is_32bit)
1472 debug("0x%08"PRIx32, (uint32_t) addr);
1473 else
1474 debug("0x%016"PRIx64, (uint64_t) addr);
1475 break;
1476 default:
1477 debug("unimplemented regimm5 = 0x%02x", regimm5);
1478 }
1479 break;
1480 default:
1481 debug("unimplemented hi6 = 0x%02x", hi6);
1482 }
1483
1484 disasm_ret:
1485 debug("\n");
1486 return sizeof(instrword);
1487 }
1488
1489
1490 /*
1491 * mips_cpu_register_dump():
1492 *
1493 * Dump cpu registers in a relatively readable format.
1494 *
1495 * gprs: set to non-zero to dump GPRs and hi/lo/pc
1496 * coprocs: set bit 0..3 to dump registers in coproc 0..3.
1497 */
1498 void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
1499 {
1500 int coprocnr, i, bits32;
1501 uint64_t offset;
1502 char *symbol;
1503 int bits128 = cpu->cd.mips.cpu_type.rev == MIPS_R5900;
1504
1505 bits32 = cpu->is_32bit;
1506
1507 if (gprs) {
1508 /* Special registers (pc, hi/lo) first: */
1509 symbol = get_symbol_name(&cpu->machine->symbol_context,
1510 cpu->pc, &offset);
1511
1512 if (bits32)
1513 debug("cpu%i: pc = %08"PRIx32,
1514 cpu->cpu_id, (uint32_t) cpu->pc);
1515 else if (bits128)
1516 debug("cpu%i: pc=%016"PRIx64,
1517 cpu->cpu_id, (uint64_t) cpu->pc);
1518 else
1519 debug("cpu%i: pc = 0x%016"PRIx64,
1520 cpu->cpu_id, (uint64_t) cpu->pc);
1521
1522 debug(" <%s>\n", symbol != NULL? symbol :
1523 " no symbol ");
1524
1525 if (bits32)
1526 debug("cpu%i: hi = %08"PRIx32" lo = %08"PRIx32"\n",
1527 cpu->cpu_id, (uint32_t) cpu->cd.mips.hi,
1528 (uint32_t) cpu->cd.mips.lo);
1529 else if (bits128) {
1530 debug("cpu%i: hi=%016"PRIx64"%016"PRIx64" lo="
1531 "%016"PRIx64"%016"PRIx64"\n", cpu->cpu_id,
1532 cpu->cd.mips.hi1, cpu->cd.mips.hi,
1533 cpu->cd.mips.lo1, cpu->cd.mips.lo);
1534 } else {
1535 debug("cpu%i: hi = 0x%016"PRIx64" lo = 0x%016"
1536 PRIx64"\n", cpu->cpu_id,
1537 (uint64_t) cpu->cd.mips.hi,
1538 (uint64_t) cpu->cd.mips.lo);
1539 }
1540
1541 /* General registers: */
1542 if (bits128) {
1543 /* 128-bit: */
1544 for (i=0; i<32; i++) {
1545 int r = (i >> 1) + ((i & 1) << 4);
1546 if ((i & 1) == 0)
1547 debug("cpu%i:", cpu->cpu_id);
1548 if (r == MIPS_GPR_ZERO)
1549 debug(" "
1550 " ");
1551 else
1552 debug(" %3s=%016"PRIx64"%016"PRIx64,
1553 regname(cpu->machine, r),
1554 (uint64_t)cpu->cd.mips.gpr_quadhi[r],
1555 (uint64_t)cpu->cd.mips.gpr[r]);
1556 if ((i & 1) == 1)
1557 debug("\n");
1558 }
1559 } else if (bits32) {
1560 /* 32-bit: */
1561 for (i=0; i<32; i++) {
1562 if ((i & 3) == 0)
1563 debug("cpu%i:", cpu->cpu_id);
1564 if (i == MIPS_GPR_ZERO)
1565 debug(" ");
1566 else
1567 debug(" %3s = %08"PRIx32,
1568 regname(cpu->machine, i),
1569 (uint32_t)cpu->cd.mips.gpr[i]);
1570 if ((i & 3) == 3)
1571 debug("\n");
1572 }
1573 } else {
1574 /* 64-bit: */
1575 for (i=0; i<32; i++) {
1576 int r = (i >> 1) + ((i & 1) << 4);
1577 if ((i & 1) == 0)
1578 debug("cpu%i:", cpu->cpu_id);
1579 if (r == MIPS_GPR_ZERO)
1580 debug(" ");
1581 else
1582 debug(" %3s = 0x%016"PRIx64,
1583 regname(cpu->machine, r),
1584 (uint64_t)cpu->cd.mips.gpr[r]);
1585 if ((i & 1) == 1)
1586 debug("\n");
1587 }
1588 }
1589 }
1590
1591 for (coprocnr=0; coprocnr<4; coprocnr++) {
1592 int nm1 = 1;
1593
1594 if (bits32)
1595 nm1 = 3;
1596
1597 if (!(coprocs & (1<<coprocnr)))
1598 continue;
1599 if (cpu->cd.mips.coproc[coprocnr] == NULL) {
1600 debug("cpu%i: no coprocessor %i\n",
1601 cpu->cpu_id, coprocnr);
1602 continue;
1603 }
1604
1605 /* Coprocessor registers: */
1606 for (i=0; i<32; i++) {
1607 /* 32-bit: */
1608 if ((i & nm1) == 0)
1609 debug("cpu%i:", cpu->cpu_id);
1610
1611 if (cpu->machine->show_symbolic_register_names &&
1612 coprocnr == 0)
1613 debug(" %8s", cop0_names[i]);
1614 else
1615 debug(" c%i,%02i", coprocnr, i);
1616
1617 if (bits32)
1618 debug("=%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);
1619 else {
1620 if (coprocnr == 0 && (i == COP0_COUNT
1621 || i == COP0_COMPARE || i == COP0_INDEX
1622 || i == COP0_RANDOM || i == COP0_WIRED))
1623 debug(" = 0x%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);
1624 else
1625 debug(" = 0x%016"PRIx64, (uint64_t)
1626 cpu->cd.mips.coproc[coprocnr]->reg[i]);
1627 }
1628
1629 if ((i & nm1) == nm1)
1630 debug("\n");
1631
1632 /* Skip the last 16 cop0 registers on R3000 etc. */
1633 if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level < 3
1634 && i == 15)
1635 i = 31;
1636 }
1637
1638 if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level >= 32) {
1639 debug("cpu%i: ", cpu->cpu_id);
1640 debug("config_select1 = 0x");
1641 if (cpu->is_32bit)
1642 debug("%08"PRIx32, (uint32_t)cpu->cd.mips.cop0_config_select1);
1643 else
1644 debug("%016"PRIx64, (uint64_t)cpu->cd.mips.cop0_config_select1);
1645 debug("\n");
1646 }
1647
1648 /* Floating point control registers: */
1649 if (coprocnr == 1) {
1650 for (i=0; i<32; i++)
1651 switch (i) {
1652 case MIPS_FPU_FCIR:
1653 printf("cpu%i: fcr0 (fcir) = 0x%08x\n",
1654 cpu->cpu_id, (int)cpu->cd.mips.
1655 coproc[coprocnr]->fcr[i]);
1656 break;
1657 case MIPS_FPU_FCCR:
1658 printf("cpu%i: fcr25 (fccr) = 0x%08x\n",
1659 cpu->cpu_id, (int)cpu->cd.mips.
1660 coproc[coprocnr]->fcr[i]);
1661 break;
1662 case MIPS_FPU_FCSR:
1663 printf("cpu%i: fcr31 (fcsr) = 0x%08x\n",
1664 cpu->cpu_id, (int)cpu->cd.mips.
1665 coproc[coprocnr]->fcr[i]);
1666 break;
1667 }
1668 }
1669 }
1670
1671 if (cpu->cd.mips.rmw) {
1672 printf("cpu%i: Read-Modify-Write in progress, address "
1673 "0x%016"PRIx64"\n", cpu->cpu_id, cpu->cd.mips.rmw_addr);
1674 }
1675 }
1676
1677
1678 static void add_response_word(struct cpu *cpu, char *r, uint64_t value,
1679 size_t maxlen, int len)
1680 {
1681 char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;
1682 if (len == 4)
1683 value &= 0xffffffffULL;
1684 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
1685 if (len == 4) {
1686 value = ((value & 0xff) << 24) +
1687 ((value & 0xff00) << 8) +
1688 ((value & 0xff0000) >> 8) +
1689 ((value & 0xff000000) >> 24);
1690 } else {
1691 value = ((value & 0xff) << 56) +
1692 ((value & 0xff00) << 40) +
1693 ((value & 0xff0000) << 24) +
1694 ((value & 0xff000000ULL) << 8) +
1695 ((value & 0xff00000000ULL) >> 8) +
1696 ((value & 0xff0000000000ULL) >> 24) +
1697 ((value & 0xff000000000000ULL) >> 40) +
1698 ((value & 0xff00000000000000ULL) >> 56);
1699 }
1700 }
1701 snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);
1702 }
1703
1704
1705 /*
1706 * mips_cpu_gdb_stub():
1707 *
1708 * Execute a "remote GDB" command. Returns 1 on success, 0 on error.
1709 */
1710 char *mips_cpu_gdb_stub(struct cpu *cpu, char *cmd)
1711 {
1712 if (strcmp(cmd, "g") == 0) {
1713 /* 76 registers: gprs, sr, lo, hi, badvaddr, cause, pc,
1714 fprs, fsr, fir, fp. */
1715 int i;
1716 char *r;
1717 size_t wlen = cpu->is_32bit?
1718 sizeof(uint32_t) : sizeof(uint64_t);
1719 size_t len = 1 + 76 * wlen;
1720 r = malloc(len);
1721 if (r == NULL) {
1722 fprintf(stderr, "out of memory\n");
1723 exit(1);
1724 }
1725 r[0] = '\0';
1726 for (i=0; i<32; i++)
1727 add_response_word(cpu, r, cpu->cd.mips.gpr[i],
1728 len, wlen);
1729 add_response_word(cpu, r,
1730 cpu->cd.mips.coproc[0]->reg[COP0_STATUS], len, wlen);
1731 add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);
1732 add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);
1733 add_response_word(cpu, r,
1734 cpu->cd.mips.coproc[0]->reg[COP0_BADVADDR], len, wlen);
1735 add_response_word(cpu, r,
1736 cpu->cd.mips.coproc[0]->reg[COP0_CAUSE], len, wlen);
1737 add_response_word(cpu, r, cpu->pc, len, wlen);
1738 for (i=0; i<32; i++)
1739 add_response_word(cpu, r,
1740 cpu->cd.mips.coproc[1]->reg[i], len, wlen);
1741 add_response_word(cpu, r,
1742 cpu->cd.mips.coproc[1]->reg[31] /* fcsr */, len, wlen);
1743 add_response_word(cpu, r,
1744 cpu->cd.mips.coproc[1]->reg[0] /* fcir */, len, wlen);
1745
1746 /* TODO: fp = gpr 30? */
1747 add_response_word(cpu, r, cpu->cd.mips.gpr[30], len, wlen);
1748
1749 return r;
1750 }
1751
1752 if (cmd[0] == 'p') {
1753 int regnr = strtol(cmd + 1, NULL, 16);
1754 size_t wlen = cpu->is_32bit? sizeof(uint32_t):sizeof(uint64_t);
1755 size_t len = 2 * wlen + 1;
1756 char *r = malloc(len);
1757 r[0] = '\0';
1758 if (regnr >= 0 && regnr <= 31) {
1759 add_response_word(cpu, r,
1760 cpu->cd.mips.gpr[regnr], len, wlen);
1761 } else if (regnr == 0x20) {
1762 add_response_word(cpu, r, cpu->cd.mips.coproc[0]->
1763 reg[COP0_STATUS], len, wlen);
1764 } else if (regnr == 0x21) {
1765 add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);
1766 } else if (regnr == 0x22) {
1767 add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);
1768 } else if (regnr == 0x23) {
1769 add_response_word(cpu, r, cpu->cd.mips.coproc[0]->
1770 reg[COP0_BADVADDR], len, wlen);
1771 } else if (regnr == 0x24) {
1772 add_response_word(cpu, r, cpu->cd.mips.coproc[0]->
1773 reg[COP0_CAUSE], len, wlen);
1774 } else if (regnr == 0x25) {
1775 add_response_word(cpu, r, cpu->pc, len, wlen);
1776 } else if (regnr >= 0x26 && regnr <= 0x45 &&
1777 cpu->cd.mips.coproc[1] != NULL) {
1778 add_response_word(cpu, r, cpu->cd.mips.coproc[1]->
1779 reg[regnr - 0x26], len, wlen);
1780 } else if (regnr == 0x46) {
1781 add_response_word(cpu, r, cpu->cd.mips.coproc[1]->
1782 fcr[MIPS_FPU_FCSR], len, wlen);
1783 } else if (regnr == 0x47) {
1784 add_response_word(cpu, r, cpu->cd.mips.coproc[1]->
1785 fcr[MIPS_FPU_FCIR], len, wlen);
1786 } else {
1787 /* Unimplemented: */
1788 add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);
1789 }
1790 return r;
1791 }
1792
1793 fatal("mips_cpu_gdb_stub(): cmd='%s' TODO\n", cmd);
1794 return NULL;
1795 }
1796
1797
1798 /*
1799 * mips_cpu_interrupt():
1800 *
1801 * Cause an interrupt. If irq_nr is 2..7, then it is a MIPS hardware
1802 * interrupt. 0 and 1 are ignored (software interrupts).
1803 *
1804 * If irq_nr is >= 8, then this function calls md_interrupt().
1805 */
1806 int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
1807 {
1808 if (irq_nr >= 8) {
1809 if (cpu->machine->md_interrupt != NULL)
1810 cpu->machine->md_interrupt(cpu->machine,
1811 cpu, irq_nr, 1);
1812 else
1813 fatal("mips_cpu_interrupt(): irq_nr = %i, "
1814 "but md_interrupt = NULL ?\n", irq_nr);
1815 return 1;
1816 }
1817
1818 if (irq_nr < 2)
1819 return 0;
1820
1821 cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |=
1822 ((1 << irq_nr) << STATUS_IM_SHIFT);
1823
1824 return 1;
1825 }
1826
1827
1828 /*
1829 * mips_cpu_interrupt_ack():
1830 *
1831 * Acknowledge an interrupt. If irq_nr is 2..7, then it is a MIPS hardware
1832 * interrupt. Interrupts 0..1 are ignored (software interrupts).
1833 *
1834 * If irq_nr is >= 8, then it is machine dependent, and md_interrupt() is
1835 * called.
1836 */
1837 int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
1838 {
1839 if (irq_nr >= 8) {
1840 if (cpu->machine->md_interrupt != NULL)
1841 cpu->machine->md_interrupt(cpu->machine, cpu,
1842 irq_nr, 0);
1843 else
1844 fatal("mips_cpu_interrupt_ack(): irq_nr = %i, "
1845 "but md_interrupt = NULL ?\n", irq_nr);
1846 return 1;
1847 }
1848
1849 if (irq_nr < 2)
1850 return 0;
1851
1852 cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &=
1853 ~((1 << irq_nr) << STATUS_IM_SHIFT);
1854
1855 return 1;
1856 }
1857
1858
1859 /*
1860 * mips_cpu_exception():
1861 *
1862 * Cause an exception in a CPU. This sets a couple of coprocessor 0
1863 * registers, and the program counter.
1864 *
1865 * exccode the exception code
1866 * tlb set to non-zero if the exception handler at
1867 * 0x80000000 should be used. (normal = 0x80000180)
1868 * vaddr virtual address (for some exceptions)
1869 * coproc_nr coprocessor number (for some exceptions)
1870 * vaddr_vpn2 vpn2 (for some exceptions)
1871 * vaddr_asid asid (for some exceptions)
1872 * x_64 non-zero for 64-bit mode for R4000-style tlb misses
1873 */
1874 void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
1875 int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
1876 {
1877 uint64_t base;
1878 uint64_t *reg = &cpu->cd.mips.coproc[0]->reg[0];
1879 int exc_model = cpu->cd.mips.cpu_type.exc_model;
1880
1881 if (!quiet_mode) {
1882 uint64_t offset;
1883 int x;
1884 char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1885 cpu->pc, &offset);
1886
1887 debug("[ ");
1888 if (cpu->machine->ncpus > 1)
1889 debug("cpu%i: ", cpu->cpu_id);
1890
1891 debug("exception %s%s",
1892 exception_names[exccode], tlb? " <tlb>" : "");
1893
1894 switch (exccode) {
1895
1896 case EXCEPTION_INT:
1897 debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT));
1898 break;
1899
1900 case EXCEPTION_SYS:
1901 debug(" v0=%i", (int)cpu->cd.mips.gpr[MIPS_GPR_V0]);
1902 for (x=0; x<4; x++) {
1903 int64_t d = cpu->cd.mips.gpr[MIPS_GPR_A0 + x];
1904 char strbuf[30];
1905
1906 if (d > -256 && d < 256) {
1907 debug(" a%i=%i", x, (int)d);
1908 } else if (memory_points_to_string(cpu,
1909 cpu->mem, d, 1)) {
1910 debug(" a%i=\"%s\"", x,
1911 memory_conv_to_string(cpu, cpu->mem,
1912 d, strbuf, sizeof(strbuf)));
1913 } else {
1914 if (cpu->is_32bit)
1915 debug(" a%i=0x%"PRIx32, x,
1916 (uint32_t)d);
1917 else
1918 debug(" a%i=0x%"PRIx64, x,
1919 (uint64_t)d);
1920 }
1921 }
1922 break;
1923
1924 case EXCEPTION_CPU:
1925 debug(" coproc_nr=%i", coproc_nr);
1926 break;
1927
1928 default:
1929 if (cpu->is_32bit)
1930 debug(" vaddr=0x%08x", (int)vaddr);
1931 else
1932 debug(" vaddr=0x%016"PRIx64, (uint64_t)vaddr);
1933 }
1934
1935 if (cpu->is_32bit)
1936 debug(" pc=0x%08"PRIx32" ", (uint32_t)cpu->pc);
1937 else
1938 debug(" pc=0x%016"PRIx64" ", (uint64_t)cpu->pc);
1939
1940 if (symbol != NULL)
1941 debug("<%s> ]\n", symbol);
1942 else
1943 debug("]\n");
1944 }
1945
1946 if (tlb && vaddr < 0x1000) {
1947 uint64_t offset;
1948 char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1949 cpu->pc, &offset);
1950 fatal("[ ");
1951 if (cpu->machine->ncpus > 1)
1952 fatal("cpu%i: ", cpu->cpu_id);
1953 fatal("warning: LOW reference: vaddr=");
1954 if (cpu->is_32bit)
1955 fatal("0x%08"PRIx32, (uint32_t) vaddr);
1956 else
1957 fatal("0x%016"PRIx64, (uint64_t) vaddr);
1958 fatal(", exception %s, pc=", exception_names[exccode]);
1959 if (cpu->is_32bit)
1960 fatal("0x%08"PRIx32, (uint32_t) cpu->pc);
1961 else
1962 fatal("0x%016"PRIx64, (uint64_t)cpu->pc);
1963 fatal(" <%s> ]\n", symbol? symbol : "(no symbol)");
1964 }
1965
1966 /* Clear the exception code bits of the cause register... */
1967 if (exc_model == EXC3K)
1968 reg[COP0_CAUSE] &= ~R2K3K_CAUSE_EXCCODE_MASK;
1969 else
1970 reg[COP0_CAUSE] &= ~CAUSE_EXCCODE_MASK;
1971
1972 /* ... and OR in the exception code: */
1973 reg[COP0_CAUSE] |= (exccode << CAUSE_EXCCODE_SHIFT);
1974
1975 /* Always set CE (according to the R5000 manual): */
1976 reg[COP0_CAUSE] &= ~CAUSE_CE_MASK;
1977 reg[COP0_CAUSE] |= (coproc_nr << CAUSE_CE_SHIFT);
1978
1979 if (tlb || (exccode >= EXCEPTION_MOD && exccode <= EXCEPTION_ADES) ||
1980 exccode == EXCEPTION_VCEI || exccode == EXCEPTION_VCED) {
1981 reg[COP0_BADVADDR] = vaddr;
1982 if (cpu->is_32bit)
1983 reg[COP0_BADVADDR] = (int32_t)reg[COP0_BADVADDR];
1984
1985 if (exc_model == EXC3K) {
1986 reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK;
1987 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << R2K3K_CONTEXT_BADVPN_SHIFT) & R2K3K_CONTEXT_BADVPN_MASK);
1988
1989 reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK)
1990 | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);
1991
1992 /* Sign-extend: */
1993 reg[COP0_CONTEXT] = (int64_t)(int32_t)reg[COP0_CONTEXT];
1994 reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];
1995 } else {
1996 if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {
1997 reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK_R4100;
1998 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK_R4100);
1999
2000 /* TODO: fix these */
2001 reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
2002 reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
2003 reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
2004 reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
2005
2006 /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
2007
2008 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK | 0x1800)) | vaddr_asid;
2009 } else {
2010 reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK;
2011 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK);
2012
2013 reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
2014 reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
2015 reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
2016 reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
2017
2018 /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
2019
2020 if (cpu->cd.mips.cpu_type.mmu_model == MMU10K)
2021 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK_R10K)) | vaddr_asid;
2022 else
2023 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK)) | vaddr_asid;
2024 }
2025 }
2026 }
2027
2028 if (exc_model != EXC3K && reg[COP0_STATUS] & STATUS_EXL) {
2029 /*
2030 * Don't set EPC if STATUS_EXL is set, for R4000 and up.
2031 * This actually happens when running IRIX and Ultrix, when
2032 * they handle interrupts and/or tlb updates, I think, so
2033 * printing this with debug() looks better than with fatal().
2034 */
2035 /* debug("[ warning: cpu%i exception while EXL is set,"
2036 " not setting EPC ]\n", cpu->cpu_id); */
2037 } else {
2038 if (cpu->delay_slot || cpu->cd.mips.nullify_next) {
2039 reg[COP0_EPC] = cpu->pc - 4;
2040 reg[COP0_CAUSE] |= CAUSE_BD;
2041
2042 /* TODO: Should the BD flag actually be set
2043 on nullified slots? */
2044 } else {
2045 reg[COP0_EPC] = cpu->pc;
2046 reg[COP0_CAUSE] &= ~CAUSE_BD;
2047 }
2048 }
2049
2050 if (cpu->delay_slot)
2051 cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
2052 else
2053 cpu->delay_slot = NOT_DELAYED;
2054
2055 cpu->cd.mips.nullify_next = 0;
2056
2057 /* TODO: This is true for MIPS64, but how about others? */
2058 if (reg[COP0_STATUS] & STATUS_BEV)
2059 base = 0xffffffffbfc00200ULL;
2060 else
2061 base = 0xffffffff80000000ULL;
2062
2063 switch (exc_model) {
2064 case EXC3K:
2065 /* Userspace tlb, vs others: */
2066 if (tlb && !(vaddr & 0x80000000ULL) &&
2067 (exccode == EXCEPTION_TLBL || exccode == EXCEPTION_TLBS) )
2068 cpu->pc = base + 0x000;
2069 else
2070 cpu->pc = base + 0x080;
2071 break;
2072 default:
2073 /*
2074 * These offsets are according to the MIPS64 manual, but
2075 * should work with R4000 and the rest too (I hope).
2076 *
2077 * 0x000 TLB refill, if EXL=0
2078 * 0x080 64-bit XTLB refill, if EXL=0
2079 * 0x100 cache error (not implemented yet)
2080 * 0x180 general exception
2081 * 0x200 interrupt (if CAUSE_IV is set)
2082 */
2083 if (tlb && (exccode == EXCEPTION_TLBL ||
2084 exccode == EXCEPTION_TLBS) &&
2085 !(reg[COP0_STATUS] & STATUS_EXL)) {
2086 if (x_64)
2087 cpu->pc = base + 0x080;
2088 else
2089 cpu->pc = base + 0x000;
2090 } else {
2091 if (exccode == EXCEPTION_INT &&
2092 (reg[COP0_CAUSE] & CAUSE_IV))
2093 cpu->pc = base + 0x200;
2094 else
2095 cpu->pc = base + 0x180;
2096 }
2097 }
2098
2099 if (exc_model == EXC3K) {
2100 /* R{2,3}000: Shift the lowest 6 bits to the left two steps:*/
2101 reg[COP0_STATUS] = (reg[COP0_STATUS] & ~0x3f) +
2102 ((reg[COP0_STATUS] & 0xf) << 2);
2103 } else {
2104 /* R4000: */
2105 reg[COP0_STATUS] |= STATUS_EXL;
2106 }
2107
2108 /* Sign-extend: */
2109 reg[COP0_CAUSE] = (int64_t)(int32_t)reg[COP0_CAUSE];
2110 reg[COP0_STATUS] = (int64_t)(int32_t)reg[COP0_STATUS];
2111
2112 if (cpu->is_32bit) {
2113 reg[COP0_EPC] = (int64_t)(int32_t)reg[COP0_EPC];
2114 mips32_pc_to_pointers(cpu);
2115 } else {
2116 mips_pc_to_pointers(cpu);
2117 }
2118 }
2119
2120
2121 #include "memory_mips.c"
2122
2123
2124 #include "tmp_mips_tail.c"
2125

  ViewVC Help
Powered by ViewVC 1.1.26