/[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 40 - (show annotations)
Mon Oct 8 16:22:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 53407 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1539 2007/05/01 04:03:51 debug Exp $
20070415	Landisk PCLOCK should be 33.33 MHz, not 50 MHz. (This makes
		the clock run at correct speed.)
		FINALLY found and fixed the bug which caused OpenBSD/landisk
		to randomly bug out: an &-sign was missing in the special case
		handling of FPSCR in the 'LDS.L @Rm+,FPSCR' instruction.
		Adding similar special case handling for 'LDC.L @Rm+,SR'
		(calling sh_update_sr() instead of just loading).
		Implementing the 'FCNVSD FPUL,DRn' and 'FCNVDS DRm,FPUL'
		SuperH instructions.
		The 'LDC Rm,SR' instruction now immediately breaks out of the
		dyntrans loop if an interrupt is to be triggered.
20070416	In memory_rw.c, if mapping a page as writable, make sure to
		invalidate code translations even if the data access was a
		read.
		Minor SuperH updates.
20070418	Removing the dummy M68K emulation mode.
		Minor SH update (turning unnecessary sts_mach_rn, sts_macl_rn,
		and sts_pr_rn instruction handlers into mov_rm_rn).
20070419	Beginning to add a skeleton for an M88K mode: Adding a hack to
		allow OpenBSD/m88k a.out binaries to be loaded, and disassembly
		of a few simple 88K instructions.
		Commenting out the 'LDC Rm,SR' fix from a few days ago, because
		it made Linux/dreamcast bug out.
		Adding a hack to dev_sh4.c (an extra translation cache
		invalidation), which allows OpenBSD/landisk to boot ok after
		an install. Upgrading the Landisk machine mode to stable,
		updating documentation, etc.
20070420	Experimenting with adding a PCI controller (pcic) to dev_sh4.
		Adding a dummy Realtek 8139C+ skeleton device (dev_rtl8139c).
		Implementing the first M88K instructions (br, or[.u] imm), and
		adding disassembly of some more instructions.
20070421	Continuing a little on dev_rtl8139c.
20070422	Implementing the 9346 EEPROM "read" command for dev_rtl8139c.
		Finally found and fixed an old bug in the log n symbol search
		(it sometimes missed symbols). Debug trace (-i, -t etc) should
		now show more symbols. :-)
20070423	Continuing a little on M88K disassembly.
20070428	Fixing a memset arg order bug in src/net/net.c (thanks to
		Nigel Horne for noticing the bug).
		Applying parts of a patch from Carl van Schaik to clear out
		bottom bits of MIPS addresses more correctly, when using large
		page sizes, and doing some other minor cleanup/refactoring.
		Fixing a couple of warnings given by gcc with the -W option (a
		few more warnings than just plain -Wall).
		Reducing SuperH dyntrans physical address space from 64-bit to
		32-bit (since SH5/SH64 isn't imlemented yet anyway).
		Adding address-to-symbol annotation to a few more instructions
		in the SuperH instruction trace output.
		Beginning regression testing for the next release.
		Reverting the value of SCIF_DELAYED_TX_VALUE from 1 to 2,
		because OpenBSD/landisk may otherwise hang randomly.
20070429	The ugly hack/workaround to get OpenBSD/landisk booting without
		crashing does NOT work anymore (with the April 21 snapshot
		of OpenBSD/landisk). Strangely enough, removing the hack
		completely causes OpenBSD/landisk to work (!).
		More regression testing (re-testing everything SuperH-related,
		and some other things).
		Cobalt interrupts were actually broken; fixing by commenting
		out the DEC21143s in the Cobalt machine.
20070430	More regression testing.
20070501	Updating the OpenBSD/landisk install instructions to use
		4.1 instead of the current snapshot.
		GAAAH! OpenBSD/landisk 4.1 _needs_ the ugly hack/workaround;
		reintroducing it again. (The 4.1 kernel is actually from
		2007-03-11.)
		Simplifying the NetBSD/evbarm install instructions a bit.
		More regression testing.

==============  RELEASE 0.4.5.1  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26