/[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 38 - (show annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 53260 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


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.77 2007/04/10 17:52:27 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
628 printf("%3i: ", j);
629 switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
630 case MMU3K:
631 if (!(lo0 & R2K3K_ENTRYLO_V)) {
632 printf("(invalid)\n");
633 continue;
634 }
635 printf("vaddr=0x%08x ",
636 (int) (hi&R2K3K_ENTRYHI_VPN_MASK));
637 if (lo0 & R2K3K_ENTRYLO_G)
638 printf("(global), ");
639 else
640 printf("(asid %02x),", (int) ((hi &
641 R2K3K_ENTRYHI_ASID_MASK)
642 >> R2K3K_ENTRYHI_ASID_SHIFT));
643 printf(" paddr=0x%08x ",
644 (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));
645 if (lo0 & R2K3K_ENTRYLO_N)
646 printf("N");
647 if (lo0 & R2K3K_ENTRYLO_D)
648 printf("D");
649 printf("\n");
650 break;
651 default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
652 case MMU32:
653 printf("vaddr=0x%08"PRIx32" ",
654 (uint32_t) hi);
655 break;
656 case MMU10K:
657 default:/* R4000 etc. */
658 printf("vaddr=%016"PRIx64" ",
659 (uint64_t) hi);
660 }
661 if (hi & TLB_G)
662 printf("(global): ");
663 else
664 printf("(asid %02x):",
665 (int) (hi & ENTRYHI_ASID));
666
667 /* TODO: Coherency bits */
668
669 if (!(lo0 & ENTRYLO_V))
670 printf(" p0=(invalid) ");
671 else
672 printf(" p0=0x%09"PRIx64" ", (uint64_t)
673 (((lo0&ENTRYLO_PFN_MASK) >>
674 ENTRYLO_PFN_SHIFT) << pageshift));
675 printf(lo0 & ENTRYLO_D? "D" : " ");
676
677 if (!(lo1 & ENTRYLO_V))
678 printf(" p1=(invalid) ");
679 else
680 printf(" p1=0x%09"PRIx64" ", (uint64_t)
681 (((lo1&ENTRYLO_PFN_MASK) >>
682 ENTRYLO_PFN_SHIFT) << pageshift));
683 printf(lo1 & ENTRYLO_D? "D" : " ");
684 mask |= (1 << (pageshift+1)) - 1;
685 switch (mask) {
686 case 0x7ff: printf(" (1KB)"); break;
687 case 0x1fff: printf(" (4KB)"); break;
688 case 0x7fff: printf(" (16KB)"); break;
689 case 0x1ffff: printf(" (64KB)"); break;
690 case 0x7ffff: printf(" (256KB)"); break;
691 case 0x1fffff: printf(" (1MB)"); break;
692 case 0x7fffff: printf(" (4MB)"); break;
693 case 0x1ffffff: printf(" (16MB)"); break;
694 case 0x7ffffff: printf(" (64MB)"); break;
695 default:printf(" (mask=%08x?)", (int)mask);
696 }
697 printf("\n");
698 }
699 }
700 }
701 }
702
703
704 /*
705 * mips_cpu_disassemble_instr():
706 *
707 * Convert an instruction word into human readable format, for instruction
708 * tracing.
709 *
710 * If running is 1, cpu->pc should be the address of the instruction.
711 *
712 * If running is 0, things that depend on the runtime environment (eg.
713 * register contents) will not be shown, and addr will be used instead of
714 * cpu->pc for relative addresses.
715 *
716 * NOTE 2: coprocessor instructions are not decoded nicely yet (TODO)
717 */
718 int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
719 int running, uint64_t dumpaddr)
720 {
721 int hi6, special6, regimm5, sub;
722 int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
723 uint64_t addr, offset;
724 uint32_t instrword;
725 unsigned char instr[4];
726 char *symbol;
727
728 if (running)
729 dumpaddr = cpu->pc;
730
731 if ((dumpaddr & 3) != 0)
732 printf("WARNING: Unaligned address!\n");
733
734 symbol = get_symbol_name(&cpu->machine->symbol_context,
735 dumpaddr, &offset);
736 if (symbol != NULL && offset==0)
737 debug("<%s>\n", symbol);
738
739 if (cpu->machine->ncpus > 1 && running)
740 debug("cpu%i: ", cpu->cpu_id);
741
742 if (cpu->is_32bit)
743 debug("%08"PRIx32, (uint32_t)dumpaddr);
744 else
745 debug("%016"PRIx64, (uint64_t)dumpaddr);
746
747 *((uint32_t *)&instr[0]) = *((uint32_t *)&originstr[0]);
748
749 /*
750 * The rest of the code is written for little endian,
751 * so swap if necessary:
752 */
753 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
754 int tmp = instr[0]; instr[0] = instr[3];
755 instr[3] = tmp;
756 tmp = instr[1]; instr[1] = instr[2];
757 instr[2] = tmp;
758 }
759
760 debug(": %02x%02x%02x%02x",
761 instr[3], instr[2], instr[1], instr[0]);
762
763 if (running && cpu->delay_slot)
764 debug(" (d)");
765
766 debug("\t");
767
768 /*
769 * Decode the instruction:
770 */
771
772 hi6 = (instr[3] >> 2) & 0x3f;
773
774 switch (hi6) {
775 case HI6_SPECIAL:
776 special6 = instr[0] & 0x3f;
777 switch (special6) {
778 case SPECIAL_SLL:
779 case SPECIAL_SRL:
780 case SPECIAL_SRA:
781 case SPECIAL_DSLL:
782 case SPECIAL_DSRL:
783 case SPECIAL_DSRA:
784 case SPECIAL_DSLL32:
785 case SPECIAL_DSRL32:
786 case SPECIAL_DSRA32:
787 sub = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
788 rt = instr[2] & 31;
789 rd = (instr[1] >> 3) & 31;
790 sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
791
792 if (rd == 0 && special6 == SPECIAL_SLL) {
793 if (sa == 0)
794 debug("nop");
795 else if (sa == 1)
796 debug("ssnop");
797 else if (sa == 3)
798 debug("ehb");
799 else
800 debug("nop (weird, sa=%i)", sa);
801 break;
802 }
803
804 switch (sub) {
805 case 0x00:
806 debug("%s\t%s,",
807 special_names[special6],
808 regname(cpu->machine, rd));
809 debug("%s,%i", regname(cpu->machine, rt), sa);
810 break;
811 case 0x01:
812 debug("%s\t%s,",
813 special_rot_names[special6],
814 regname(cpu->machine, rd));
815 debug("%s,%i", regname(cpu->machine, rt), sa);
816 break;
817 default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
818 sub);
819 }
820 break;
821 case SPECIAL_DSRLV:
822 case SPECIAL_DSRAV:
823 case SPECIAL_DSLLV:
824 case SPECIAL_SLLV:
825 case SPECIAL_SRAV:
826 case SPECIAL_SRLV:
827 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
828 rt = instr[2] & 31;
829 rd = (instr[1] >> 3) & 31;
830 sub = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
831
832 switch (sub) {
833 case 0x00:
834 debug("%s\t%s", special_names[special6],
835 regname(cpu->machine, rd));
836 debug(",%s", regname(cpu->machine, rt));
837 debug(",%s", regname(cpu->machine, rs));
838 break;
839 case 0x01:
840 debug("%s\t%s", special_rot_names[special6],
841 regname(cpu->machine, rd));
842 debug(",%s", regname(cpu->machine, rt));
843 debug(",%s", regname(cpu->machine, rs));
844 break;
845 default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
846 sub);
847 }
848 break;
849 case SPECIAL_JR:
850 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
851 symbol = get_symbol_name(&cpu->machine->symbol_context,
852 cpu->cd.mips.gpr[rs], &offset);
853 /* .hb = hazard barrier hint on MIPS32/64 rev 2 */
854 debug("jr%s\t%s",
855 (instr[1] & 0x04) ? ".hb" : "",
856 regname(cpu->machine, rs));
857 if (running && symbol != NULL)
858 debug("\t<%s>", symbol);
859 break;
860 case SPECIAL_JALR:
861 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
862 rd = (instr[1] >> 3) & 31;
863 symbol = get_symbol_name(&cpu->machine->symbol_context,
864 cpu->cd.mips.gpr[rs], &offset);
865 /* .hb = hazard barrier hint on MIPS32/64 rev 2 */
866 debug("jalr%s\t%s",
867 (instr[1] & 0x04) ? ".hb" : "",
868 regname(cpu->machine, rd));
869 debug(",%s", regname(cpu->machine, rs));
870 if (running && symbol != NULL)
871 debug("\t<%s>", symbol);
872 break;
873 case SPECIAL_MFHI:
874 case SPECIAL_MFLO:
875 rd = (instr[1] >> 3) & 31;
876 debug("%s\t%s", special_names[special6],
877 regname(cpu->machine, rd));
878 break;
879 case SPECIAL_MTLO:
880 case SPECIAL_MTHI:
881 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
882 debug("%s\t%s", special_names[special6],
883 regname(cpu->machine, rs));
884 break;
885 case SPECIAL_ADD:
886 case SPECIAL_ADDU:
887 case SPECIAL_SUB:
888 case SPECIAL_SUBU:
889 case SPECIAL_AND:
890 case SPECIAL_OR:
891 case SPECIAL_XOR:
892 case SPECIAL_NOR:
893 case SPECIAL_SLT:
894 case SPECIAL_SLTU:
895 case SPECIAL_DADD:
896 case SPECIAL_DADDU:
897 case SPECIAL_DSUB:
898 case SPECIAL_DSUBU:
899 case SPECIAL_MOVZ:
900 case SPECIAL_MOVN:
901 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
902 rt = instr[2] & 31;
903 rd = (instr[1] >> 3) & 31;
904 if (cpu->is_32bit && (special6 == SPECIAL_ADDU ||
905 special6 == SPECIAL_SUBU) && rt == 0) {
906 /* Special case 1: addu/subu with
907 rt = the zero register ==> move */
908 debug("move\t%s", regname(cpu->machine, rd));
909 debug(",%s", regname(cpu->machine, rs));
910 } else if (special6 == SPECIAL_ADDU && cpu->is_32bit
911 && rs == 0) {
912 /* Special case 2: addu with
913 rs = the zero register ==> move */
914 debug("move\t%s", regname(cpu->machine, rd));
915 debug(",%s", regname(cpu->machine, rt));
916 } else {
917 debug("%s\t%s", special_names[special6],
918 regname(cpu->machine, rd));
919 debug(",%s", regname(cpu->machine, rs));
920 debug(",%s", regname(cpu->machine, rt));
921 }
922 break;
923 case SPECIAL_MULT:
924 case SPECIAL_MULTU:
925 case SPECIAL_DMULT:
926 case SPECIAL_DMULTU:
927 case SPECIAL_DIV:
928 case SPECIAL_DIVU:
929 case SPECIAL_DDIV:
930 case SPECIAL_DDIVU:
931 case SPECIAL_TGE:
932 case SPECIAL_TGEU:
933 case SPECIAL_TLT:
934 case SPECIAL_TLTU:
935 case SPECIAL_TEQ:
936 case SPECIAL_TNE:
937 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
938 rt = instr[2] & 31;
939 rd = (instr[1] >> 3) & 31;
940 debug("%s\t", special_names[special6]);
941 if (rd != 0) {
942 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
943 if (special6 == SPECIAL_MULT ||
944 special6 == SPECIAL_MULTU)
945 debug("%s,",
946 regname(cpu->machine, rd));
947 else
948 debug("WEIRD_R5900_RD,");
949 } else {
950 debug("WEIRD_RD_NONZERO,");
951 }
952 }
953 debug("%s", regname(cpu->machine, rs));
954 debug(",%s", regname(cpu->machine, rt));
955 break;
956 case SPECIAL_SYNC:
957 imm = ((instr[1] & 7) << 2) + (instr[0] >> 6);
958 debug("sync\t0x%02x", imm);
959 break;
960 case SPECIAL_SYSCALL:
961 imm = (((instr[3] << 24) + (instr[2] << 16) +
962 (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
963 if (imm != 0)
964 debug("syscall\t0x%05x", imm);
965 else
966 debug("syscall");
967 break;
968 case SPECIAL_BREAK:
969 imm = (((instr[3] << 24) + (instr[2] << 16) +
970 (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
971 if (imm != 0)
972 debug("break\t0x%05x", imm);
973 else
974 debug("break");
975 break;
976 case SPECIAL_MFSA:
977 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
978 rd = (instr[1] >> 3) & 31;
979 debug("mfsa\t%s", regname(cpu->machine, rd));
980 } else {
981 debug("unimplemented special 0x28");
982 }
983 break;
984 case SPECIAL_MTSA:
985 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
986 rs = ((instr[3] & 3) << 3) +
987 ((instr[2] >> 5) & 7);
988 debug("mtsa\t%s", regname(cpu->machine, rs));
989 } else {
990 debug("unimplemented special 0x29");
991 }
992 break;
993 default:
994 debug("%s\t= UNIMPLEMENTED", special_names[special6]);
995 }
996 break;
997 case HI6_BEQ:
998 case HI6_BEQL:
999 case HI6_BNE:
1000 case HI6_BNEL:
1001 case HI6_BGTZ:
1002 case HI6_BGTZL:
1003 case HI6_BLEZ:
1004 case HI6_BLEZL:
1005 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1006 rt = instr[2] & 31;
1007 imm = (instr[1] << 8) + instr[0];
1008 if (imm >= 32768)
1009 imm -= 65536;
1010 addr = (dumpaddr + 4) + (imm << 2);
1011
1012 if (hi6 == HI6_BEQ && rt == MIPS_GPR_ZERO &&
1013 rs == MIPS_GPR_ZERO)
1014 debug("b\t");
1015 else {
1016 debug("%s\t", hi6_names[hi6]);
1017 switch (hi6) {
1018 case HI6_BEQ:
1019 case HI6_BEQL:
1020 case HI6_BNE:
1021 case HI6_BNEL:
1022 debug("%s,", regname(cpu->machine, rt));
1023 }
1024 debug("%s,", regname(cpu->machine, rs));
1025 }
1026
1027 if (cpu->is_32bit)
1028 debug("0x%08"PRIx32, (uint32_t)addr);
1029 else
1030 debug("0x%016"PRIx64, (uint64_t)addr);
1031
1032 symbol = get_symbol_name(&cpu->machine->symbol_context,
1033 addr, &offset);
1034 if (symbol != NULL && offset != addr)
1035 debug("\t<%s>", symbol);
1036 break;
1037 case HI6_ADDI:
1038 case HI6_ADDIU:
1039 case HI6_DADDI:
1040 case HI6_DADDIU:
1041 case HI6_SLTI:
1042 case HI6_SLTIU:
1043 case HI6_ANDI:
1044 case HI6_ORI:
1045 case HI6_XORI:
1046 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1047 rt = instr[2] & 31;
1048 imm = (instr[1] << 8) + instr[0];
1049 if (imm >= 32768)
1050 imm -= 65536;
1051 debug("%s\t%s,", hi6_names[hi6], regname(cpu->machine, rt));
1052 debug("%s,", regname(cpu->machine, rs));
1053 if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI)
1054 debug("0x%04x", imm & 0xffff);
1055 else
1056 debug("%i", imm);
1057 break;
1058 case HI6_LUI:
1059 rt = instr[2] & 31;
1060 imm = (instr[1] << 8) + instr[0];
1061 debug("lui\t%s,0x%x", regname(cpu->machine, rt), imm);
1062 break;
1063 case HI6_LB:
1064 case HI6_LBU:
1065 case HI6_LH:
1066 case HI6_LHU:
1067 case HI6_LW:
1068 case HI6_LWU:
1069 case HI6_LD:
1070 case HI6_LQ_MDMX:
1071 case HI6_LWC1:
1072 case HI6_LWC2:
1073 case HI6_LWC3:
1074 case HI6_LDC1:
1075 case HI6_LDC2:
1076 case HI6_LL:
1077 case HI6_LLD:
1078 case HI6_SB:
1079 case HI6_SH:
1080 case HI6_SW:
1081 case HI6_SD:
1082 case HI6_SQ_SPECIAL3:
1083 case HI6_SC:
1084 case HI6_SCD:
1085 case HI6_SWC1:
1086 case HI6_SWC2:
1087 case HI6_SWC3:
1088 case HI6_SDC1:
1089 case HI6_SDC2:
1090 case HI6_LWL:
1091 case HI6_LWR:
1092 case HI6_LDL:
1093 case HI6_LDR:
1094 case HI6_SWL:
1095 case HI6_SWR:
1096 case HI6_SDL:
1097 case HI6_SDR:
1098 if (hi6 == HI6_LQ_MDMX &&
1099 cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1100 debug("mdmx\t(UNIMPLEMENTED)");
1101 break;
1102 }
1103 if (hi6 == HI6_SQ_SPECIAL3 &&
1104 cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1105 int msbd, lsb, sub10;
1106 special6 = instr[0] & 0x3f;
1107 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1108 rt = instr[2] & 31;
1109 rd = msbd = (instr[1] >> 3) & 31;
1110 lsb = ((instr[1] & 7) << 2) | (instr[0] >> 6);
1111 sub10 = (rs << 5) | lsb;
1112
1113 switch (special6) {
1114
1115 case SPECIAL3_EXT:
1116 case SPECIAL3_DEXT:
1117 case SPECIAL3_DEXTM:
1118 case SPECIAL3_DEXTU:
1119 debug("%s", special3_names[special6]);
1120 if (special6 == SPECIAL3_DEXTM)
1121 msbd += 32;
1122 if (special6 == SPECIAL3_DEXTU)
1123 lsb += 32;
1124 debug("\t%s", regname(cpu->machine, rt));
1125 debug(",%s", regname(cpu->machine, rs));
1126 debug(",%i,%i", lsb, msbd + 1);
1127 break;
1128
1129 case SPECIAL3_INS:
1130 case SPECIAL3_DINS:
1131 case SPECIAL3_DINSM:
1132 case SPECIAL3_DINSU:
1133 debug("%s", special3_names[special6]);
1134 if (special6 == SPECIAL3_DINSM)
1135 msbd += 32;
1136 if (special6 == SPECIAL3_DINSU) {
1137 lsb += 32;
1138 msbd += 32;
1139 }
1140 msbd -= lsb;
1141 debug("\t%s", regname(cpu->machine, rt));
1142 debug(",%s", regname(cpu->machine, rs));
1143 debug(",%i,%i", lsb, msbd + 1);
1144 break;
1145
1146 case SPECIAL3_BSHFL:
1147 switch (sub10) {
1148 case BSHFL_WSBH:
1149 case BSHFL_SEB:
1150 case BSHFL_SEH:
1151 switch (sub10) {
1152 case BSHFL_WSBH: debug("wsbh"); break;
1153 case BSHFL_SEB: debug("seb"); break;
1154 case BSHFL_SEH: debug("seh"); break;
1155 }
1156 debug("\t%s", regname(cpu->machine,rd));
1157 debug(",%s", regname(cpu->machine,rt));
1158 break;
1159 default:debug("%s", special3_names[special6]);
1160 debug("\t(UNIMPLEMENTED)");
1161 }
1162 break;
1163
1164 case SPECIAL3_DBSHFL:
1165 switch (sub10) {
1166 case BSHFL_DSBH:
1167 case BSHFL_DSHD:
1168 switch (sub10) {
1169 case BSHFL_DSBH: debug("dsbh"); break;
1170 case BSHFL_DSHD: debug("dshd"); break;
1171 }
1172 debug("\t%s", regname(cpu->machine,rd));
1173 debug(",%s", regname(cpu->machine,rt));
1174 break;
1175 default:debug("%s", special3_names[special6]);
1176 debug("\t(UNIMPLEMENTED)");
1177 }
1178 break;
1179
1180 case SPECIAL3_RDHWR:
1181 debug("%s", special3_names[special6]);
1182 debug("\t%s", regname(cpu->machine, rt));
1183 debug(",hwr%i", rd);
1184 break;
1185
1186 default:debug("%s", special3_names[special6]);
1187 debug("\t(UNIMPLEMENTED)");
1188 }
1189 break;
1190 }
1191
1192 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1193 rt = instr[2] & 31;
1194 imm = (instr[1] << 8) + instr[0];
1195 if (imm >= 32768)
1196 imm -= 65536;
1197 symbol = get_symbol_name(&cpu->machine->symbol_context,
1198 cpu->cd.mips.gpr[rs] + imm, &offset);
1199
1200 /* LWC3 is PREF in the newer ISA levels: */
1201 /* TODO: Which ISAs? IV? V? 32? 64? */
1202 if (cpu->cd.mips.cpu_type.isa_level >= 4 && hi6 == HI6_LWC3) {
1203 debug("pref\t0x%x,%i(%s)",
1204 rt, imm, regname(cpu->machine, rs));
1205
1206 if (running) {
1207 debug("\t[0x%016"PRIx64" = %s]",
1208 (uint64_t)(cpu->cd.mips.gpr[rs] + imm));
1209 if (symbol != NULL)
1210 debug(" = %s", symbol);
1211 debug("]");
1212 }
1213 goto disasm_ret;
1214 }
1215
1216 debug("%s\t", hi6_names[hi6]);
1217
1218 if (hi6 == HI6_SWC1 || hi6 == HI6_SWC2 || hi6 == HI6_SWC3 ||
1219 hi6 == HI6_SDC1 || hi6 == HI6_SDC2 ||
1220 hi6 == HI6_LWC1 || hi6 == HI6_LWC2 || hi6 == HI6_LWC3 ||
1221 hi6 == HI6_LDC1 || hi6 == HI6_LDC2)
1222 debug("r%i", rt);
1223 else
1224 debug("%s", regname(cpu->machine, rt));
1225
1226 debug(",%i(%s)", imm, regname(cpu->machine, rs));
1227
1228 if (running) {
1229 debug("\t[");
1230
1231 if (cpu->is_32bit)
1232 debug("0x%08"PRIx32,
1233 (uint32_t) (cpu->cd.mips.gpr[rs] + imm));
1234 else
1235 debug("0x%016"PRIx64,
1236 (uint64_t) (cpu->cd.mips.gpr[rs] + imm));
1237
1238 if (symbol != NULL)
1239 debug(" = %s", symbol);
1240
1241 /* TODO: In some cases, it is possible to peek into
1242 memory, and display that data here, like for the
1243 other emulation modes. */
1244
1245 debug("]");
1246 }
1247 break;
1248
1249 case HI6_J:
1250 case HI6_JAL:
1251 imm = (((instr[3] & 3) << 24) + (instr[2] << 16) +
1252 (instr[1] << 8) + instr[0]) << 2;
1253 addr = (dumpaddr + 4) & ~((1 << 28) - 1);
1254 addr |= imm;
1255 symbol = get_symbol_name(&cpu->machine->symbol_context,
1256 addr, &offset);
1257 debug("%s\t0x", hi6_names[hi6]);
1258 if (cpu->is_32bit)
1259 debug("%08"PRIx32, (uint32_t) addr);
1260 else
1261 debug("%016"PRIx64, (uint64_t) addr);
1262 if (symbol != NULL)
1263 debug("\t<%s>", symbol);
1264 break;
1265
1266 case HI6_COP0:
1267 case HI6_COP1:
1268 case HI6_COP2:
1269 case HI6_COP3:
1270 imm = (instr[3] << 24) + (instr[2] << 16) +
1271 (instr[1] << 8) + instr[0];
1272 imm &= ((1 << 26) - 1);
1273
1274 /* Call coproc_function(), but ONLY disassembly, no exec: */
1275 coproc_function(cpu, cpu->cd.mips.coproc[hi6 - HI6_COP0],
1276 hi6 - HI6_COP0, imm, 1, running);
1277 return sizeof(instrword);
1278
1279 case HI6_CACHE:
1280 rt = ((instr[3] & 3) << 3) + (instr[2] >> 5); /* base */
1281 copz = instr[2] & 31;
1282 imm = (instr[1] << 8) + instr[0];
1283 cache_op = copz >> 2;
1284 which_cache = copz & 3;
1285 showtag = 0;
1286 debug("cache\t0x%02x,0x%04x(%s)", copz, imm,
1287 regname(cpu->machine, rt));
1288 if (which_cache==0) debug(" [ primary I-cache");
1289 if (which_cache==1) debug(" [ primary D-cache");
1290 if (which_cache==2) debug(" [ secondary I-cache");
1291 if (which_cache==3) debug(" [ secondary D-cache");
1292 debug(", ");
1293 if (cache_op==0) debug("index invalidate");
1294 if (cache_op==1) debug("index load tag");
1295 if (cache_op==2) debug("index store tag"), showtag=1;
1296 if (cache_op==3) debug("create dirty exclusive");
1297 if (cache_op==4) debug("hit invalidate");
1298 if (cache_op==5) debug("fill OR hit writeback invalidate");
1299 if (cache_op==6) debug("hit writeback");
1300 if (cache_op==7) debug("hit set virtual");
1301 if (running)
1302 debug(", addr 0x%016"PRIx64,
1303 (uint64_t)(cpu->cd.mips.gpr[rt] + imm));
1304 if (showtag)
1305 debug(", taghi=%08lx lo=%08lx",
1306 (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_HI],
1307 (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_LO]);
1308 debug(" ]");
1309 break;
1310
1311 case HI6_SPECIAL2:
1312 special6 = instr[0] & 0x3f;
1313 instrword = (instr[3] << 24) + (instr[2] << 16) +
1314 (instr[1] << 8) + instr[0];
1315 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1316 rt = instr[2] & 31;
1317 rd = (instr[1] >> 3) & 31;
1318
1319 if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1320 int c790mmifunc = (instrword >> 6) & 0x1f;
1321 if (special6 != MMI_MMI0 && special6 != MMI_MMI1 &&
1322 special6 != MMI_MMI2 && special6 != MMI_MMI3)
1323 debug("%s\t", mmi_names[special6]);
1324
1325 switch (special6) {
1326
1327 case MMI_MADD:
1328 case MMI_MADDU:
1329 if (rd != MIPS_GPR_ZERO) {
1330 debug("%s,", regname(cpu->machine, rd));
1331 }
1332 debug("%s", regname(cpu->machine, rs));
1333 debug(",%s", regname(cpu->machine, rt));
1334 break;
1335
1336 case MMI_MMI0:
1337 debug("%s\t", mmi0_names[c790mmifunc]);
1338 switch (c790mmifunc) {
1339
1340 case MMI0_PEXTLB:
1341 case MMI0_PEXTLH:
1342 case MMI0_PEXTLW:
1343 case MMI0_PMAXH:
1344 case MMI0_PMAXW:
1345 case MMI0_PPACB:
1346 case MMI0_PPACH:
1347 case MMI0_PPACW:
1348 debug("%s", regname(cpu->machine, rd));
1349 debug(",%s", regname(cpu->machine, rs));
1350 debug(",%s", regname(cpu->machine, rt));
1351 break;
1352
1353 default:debug("(UNIMPLEMENTED)");
1354 }
1355 break;
1356
1357 case MMI_MMI1:
1358 debug("%s\t", mmi1_names[c790mmifunc]);
1359 switch (c790mmifunc) {
1360
1361 case MMI1_PEXTUB:
1362 case MMI1_PEXTUH:
1363 case MMI1_PEXTUW:
1364 case MMI1_PMINH:
1365 case MMI1_PMINW:
1366 debug("%s", regname(cpu->machine, rd));
1367 debug(",%s", regname(cpu->machine, rs));
1368 debug(",%s", regname(cpu->machine, rt));
1369 break;
1370
1371 default:debug("(UNIMPLEMENTED)");
1372 }
1373 break;
1374
1375 case MMI_MMI2:
1376 debug("%s\t", mmi2_names[c790mmifunc]);
1377 switch (c790mmifunc) {
1378
1379 case MMI2_PMFHI:
1380 case MMI2_PMFLO:
1381 debug("%s", regname(cpu->machine, rd));
1382 break;
1383
1384 case MMI2_PHMADH:
1385 case MMI2_PHMSBH:
1386 case MMI2_PINTH:
1387 case MMI2_PMADDH:
1388 case MMI2_PMADDW:
1389 case MMI2_PMSUBH:
1390 case MMI2_PMSUBW:
1391 case MMI2_PMULTH:
1392 case MMI2_PMULTW:
1393 case MMI2_PSLLVW:
1394 debug("%s", regname(cpu->machine, rd));
1395 debug(",%s", regname(cpu->machine, rs));
1396 debug(",%s", regname(cpu->machine, rt));
1397 break;
1398
1399 default:debug("(UNIMPLEMENTED)");
1400 }
1401 break;
1402
1403 case MMI_MMI3:
1404 debug("%s\t", mmi3_names[c790mmifunc]);
1405 switch (c790mmifunc) {
1406
1407 case MMI3_PMTHI:
1408 case MMI3_PMTLO:
1409 debug("%s", regname(cpu->machine, rs));
1410 break;
1411
1412 case MMI3_PINTEH:
1413 case MMI3_PMADDUW:
1414 case MMI3_PMULTUW:
1415 case MMI3_PNOR:
1416 case MMI3_POR:
1417 case MMI3_PSRAVW:
1418 debug("%s", regname(cpu->machine, rd));
1419 debug(",%s", regname(cpu->machine, rs));
1420 debug(",%s", regname(cpu->machine, rt));
1421 break;
1422
1423 default:debug("(UNIMPLEMENTED)");
1424 }
1425 break;
1426
1427 default:debug("(UNIMPLEMENTED)");
1428 }
1429 break;
1430 }
1431
1432 /* SPECIAL2: */
1433 debug("%s\t", special2_names[special6]);
1434
1435 switch (special6) {
1436
1437 case SPECIAL2_MADD:
1438 case SPECIAL2_MADDU:
1439 case SPECIAL2_MSUB:
1440 case SPECIAL2_MSUBU:
1441 if (rd != MIPS_GPR_ZERO) {
1442 debug("WEIRD_NONZERO_RD(%s),",
1443 regname(cpu->machine, rd));
1444 }
1445 debug("%s", regname(cpu->machine, rs));
1446 debug(",%s", regname(cpu->machine, rt));
1447 break;
1448
1449 case SPECIAL2_MUL:
1450 /* Apparently used both on R5900 and MIPS32: */
1451 debug("%s", regname(cpu->machine, rd));
1452 debug(",%s", regname(cpu->machine, rs));
1453 debug(",%s", regname(cpu->machine, rt));
1454 break;
1455
1456 case SPECIAL2_CLZ:
1457 case SPECIAL2_CLO:
1458 case SPECIAL2_DCLZ:
1459 case SPECIAL2_DCLO:
1460 debug("%s", regname(cpu->machine, rd));
1461 debug(",%s", regname(cpu->machine, rs));
1462 break;
1463
1464 default:
1465 debug("(UNIMPLEMENTED)");
1466 }
1467 break;
1468
1469 case HI6_REGIMM:
1470 regimm5 = instr[2] & 0x1f;
1471 rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1472 imm = (instr[1] << 8) + instr[0];
1473 if (imm >= 32768)
1474 imm -= 65536;
1475
1476 switch (regimm5) {
1477
1478 case REGIMM_BLTZ:
1479 case REGIMM_BGEZ:
1480 case REGIMM_BLTZL:
1481 case REGIMM_BGEZL:
1482 case REGIMM_BLTZAL:
1483 case REGIMM_BLTZALL:
1484 case REGIMM_BGEZAL:
1485 case REGIMM_BGEZALL:
1486 debug("%s\t%s,", regimm_names[regimm5],
1487 regname(cpu->machine, rs));
1488
1489 addr = (dumpaddr + 4) + (imm << 2);
1490
1491 if (cpu->is_32bit)
1492 debug("0x%08"PRIx32, (uint32_t) addr);
1493 else
1494 debug("0x%016"PRIx64, (uint64_t) addr);
1495 break;
1496
1497 case REGIMM_SYNCI:
1498 debug("%s\t%i(%s)", regimm_names[regimm5],
1499 imm, regname(cpu->machine, rs));
1500 break;
1501
1502 default:
1503 debug("unimplemented regimm5 = 0x%02x", regimm5);
1504 }
1505 break;
1506 default:
1507 debug("unimplemented hi6 = 0x%02x", hi6);
1508 }
1509
1510 disasm_ret:
1511 debug("\n");
1512 return sizeof(instrword);
1513 }
1514
1515
1516 /*
1517 * mips_cpu_register_dump():
1518 *
1519 * Dump cpu registers in a relatively readable format.
1520 *
1521 * gprs: set to non-zero to dump GPRs and hi/lo/pc
1522 * coprocs: set bit 0..3 to dump registers in coproc 0..3.
1523 */
1524 void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
1525 {
1526 int coprocnr, i, bits32;
1527 uint64_t offset;
1528 char *symbol;
1529 int bits128 = cpu->cd.mips.cpu_type.rev == MIPS_R5900;
1530
1531 bits32 = cpu->is_32bit;
1532
1533 if (gprs) {
1534 /* Special registers (pc, hi/lo) first: */
1535 symbol = get_symbol_name(&cpu->machine->symbol_context,
1536 cpu->pc, &offset);
1537
1538 if (bits32)
1539 debug("cpu%i: pc = %08"PRIx32,
1540 cpu->cpu_id, (uint32_t) cpu->pc);
1541 else if (bits128)
1542 debug("cpu%i: pc=%016"PRIx64,
1543 cpu->cpu_id, (uint64_t) cpu->pc);
1544 else
1545 debug("cpu%i: pc = 0x%016"PRIx64,
1546 cpu->cpu_id, (uint64_t) cpu->pc);
1547
1548 debug(" <%s>\n", symbol != NULL? symbol :
1549 " no symbol ");
1550
1551 if (bits32)
1552 debug("cpu%i: hi = %08"PRIx32" lo = %08"PRIx32"\n",
1553 cpu->cpu_id, (uint32_t) cpu->cd.mips.hi,
1554 (uint32_t) cpu->cd.mips.lo);
1555 else if (bits128) {
1556 debug("cpu%i: hi=%016"PRIx64"%016"PRIx64" lo="
1557 "%016"PRIx64"%016"PRIx64"\n", cpu->cpu_id,
1558 cpu->cd.mips.hi1, cpu->cd.mips.hi,
1559 cpu->cd.mips.lo1, cpu->cd.mips.lo);
1560 } else {
1561 debug("cpu%i: hi = 0x%016"PRIx64" lo = 0x%016"
1562 PRIx64"\n", cpu->cpu_id,
1563 (uint64_t) cpu->cd.mips.hi,
1564 (uint64_t) cpu->cd.mips.lo);
1565 }
1566
1567 /* General registers: */
1568 if (bits128) {
1569 /* 128-bit: */
1570 for (i=0; i<32; i++) {
1571 int r = (i >> 1) + ((i & 1) << 4);
1572 if ((i & 1) == 0)
1573 debug("cpu%i:", cpu->cpu_id);
1574 if (r == MIPS_GPR_ZERO)
1575 debug(" "
1576 " ");
1577 else
1578 debug(" %3s=%016"PRIx64"%016"PRIx64,
1579 regname(cpu->machine, r), (uint64_t)
1580 cpu->cd.mips.gpr_quadhi[r],
1581 (uint64_t)cpu->cd.mips.gpr[r]);
1582 if ((i & 1) == 1)
1583 debug("\n");
1584 }
1585 } else if (bits32) {
1586 /* 32-bit: */
1587 for (i=0; i<32; i++) {
1588 if ((i & 3) == 0)
1589 debug("cpu%i:", cpu->cpu_id);
1590 if (i == MIPS_GPR_ZERO)
1591 debug(" ");
1592 else
1593 debug(" %3s = %08"PRIx32,
1594 regname(cpu->machine, i),
1595 (uint32_t)cpu->cd.mips.gpr[i]);
1596 if ((i & 3) == 3)
1597 debug("\n");
1598 }
1599 } else {
1600 /* 64-bit: */
1601 for (i=0; i<32; i++) {
1602 int r = (i >> 1) + ((i & 1) << 4);
1603 if ((i & 1) == 0)
1604 debug("cpu%i:", cpu->cpu_id);
1605 if (r == MIPS_GPR_ZERO)
1606 debug(" ");
1607 else
1608 debug(" %3s = 0x%016"PRIx64,
1609 regname(cpu->machine, r),
1610 (uint64_t)cpu->cd.mips.gpr[r]);
1611 if ((i & 1) == 1)
1612 debug("\n");
1613 }
1614 }
1615 }
1616
1617 for (coprocnr=0; coprocnr<4; coprocnr++) {
1618 int nm1 = 1;
1619
1620 if (bits32)
1621 nm1 = 3;
1622
1623 if (!(coprocs & (1<<coprocnr)))
1624 continue;
1625 if (cpu->cd.mips.coproc[coprocnr] == NULL) {
1626 debug("cpu%i: no coprocessor %i\n",
1627 cpu->cpu_id, coprocnr);
1628 continue;
1629 }
1630
1631 /* Coprocessor registers: */
1632 for (i=0; i<32; i++) {
1633 /* 32-bit: */
1634 if ((i & nm1) == 0)
1635 debug("cpu%i:", cpu->cpu_id);
1636
1637 if (cpu->machine->show_symbolic_register_names &&
1638 coprocnr == 0)
1639 debug(" %8s", cop0_names[i]);
1640 else
1641 debug(" c%i,%02i", coprocnr, i);
1642
1643 if (bits32)
1644 debug("=%08x", (int)cpu->cd.mips.
1645 coproc[coprocnr]->reg[i]);
1646 else {
1647 if (coprocnr == 0 && (i == COP0_COUNT
1648 || i == COP0_COMPARE || i == COP0_INDEX
1649 || i == COP0_RANDOM || i == COP0_WIRED))
1650 debug(" = 0x%08x",
1651 (int) cpu->cd.mips.coproc[
1652 coprocnr]->reg[i]);
1653 else
1654 debug(" = 0x%016"PRIx64, (uint64_t)
1655 cpu->cd.mips.coproc[
1656 coprocnr]->reg[i]);
1657 }
1658
1659 if ((i & nm1) == nm1)
1660 debug("\n");
1661
1662 /* Skip the last 16 cop0 registers on R3000 etc. */
1663 if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level < 3
1664 && i == 15)
1665 i = 31;
1666 }
1667
1668 if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level >= 32) {
1669 debug("cpu%i: ", cpu->cpu_id);
1670 debug("config_select1 = 0x");
1671 if (cpu->is_32bit)
1672 debug("%08"PRIx32, (uint32_t)cpu->cd.mips.cop0_config_select1);
1673 else
1674 debug("%016"PRIx64, (uint64_t)cpu->cd.mips.cop0_config_select1);
1675 debug("\n");
1676 }
1677
1678 /* Floating point control registers: */
1679 if (coprocnr == 1) {
1680 for (i=0; i<32; i++)
1681 switch (i) {
1682 case MIPS_FPU_FCIR:
1683 printf("cpu%i: fcr0 (fcir) = 0x%08x\n",
1684 cpu->cpu_id, (int)cpu->cd.mips.
1685 coproc[coprocnr]->fcr[i]);
1686 break;
1687 case MIPS_FPU_FCCR:
1688 printf("cpu%i: fcr25 (fccr) = 0x%08x\n",
1689 cpu->cpu_id, (int)cpu->cd.mips.
1690 coproc[coprocnr]->fcr[i]);
1691 break;
1692 case MIPS_FPU_FCSR:
1693 printf("cpu%i: fcr31 (fcsr) = 0x%08x\n",
1694 cpu->cpu_id, (int)cpu->cd.mips.
1695 coproc[coprocnr]->fcr[i]);
1696 break;
1697 }
1698 }
1699 }
1700
1701 if (cpu->cd.mips.rmw) {
1702 printf("cpu%i: Read-Modify-Write in progress, address "
1703 "0x%016"PRIx64"\n", cpu->cpu_id, cpu->cd.mips.rmw_addr);
1704 }
1705 }
1706
1707
1708 /*
1709 * mips_cpu_interrupt_assert(), mips_cpu_interrupt_deassert():
1710 *
1711 * Assert or deassert a MIPS CPU interrupt by masking in or out bits
1712 * in the CAUSE register of coprocessor 0.
1713 */
1714 void mips_cpu_interrupt_assert(struct interrupt *interrupt)
1715 {
1716 struct cpu *cpu = interrupt->extra;
1717 cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |= interrupt->line;
1718 }
1719 void mips_cpu_interrupt_deassert(struct interrupt *interrupt)
1720 {
1721 struct cpu *cpu = interrupt->extra;
1722 cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &= ~interrupt->line;
1723 }
1724
1725
1726 /*
1727 * mips_cpu_exception():
1728 *
1729 * Cause an exception in a CPU. This sets a couple of coprocessor 0
1730 * registers, and the program counter.
1731 *
1732 * exccode the exception code
1733 * tlb set to non-zero if the exception handler at
1734 * 0x80000000 should be used. (normal = 0x80000180)
1735 * vaddr virtual address (for some exceptions)
1736 * coproc_nr coprocessor number (for some exceptions)
1737 * vaddr_vpn2 vpn2 (for some exceptions)
1738 * vaddr_asid asid (for some exceptions)
1739 * x_64 non-zero for 64-bit mode for R4000-style tlb misses
1740 */
1741 void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
1742 int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
1743 {
1744 uint64_t base;
1745 uint64_t *reg = &cpu->cd.mips.coproc[0]->reg[0];
1746 int exc_model = cpu->cd.mips.cpu_type.exc_model;
1747
1748 if (cpu->is_halted) {
1749 /*
1750 * If the exception occurred on a 'wait' instruction, then let
1751 * the instruction following the wait instruction be the one
1752 * we continue at when the interrupt service routine returns.
1753 */
1754 cpu->is_halted = 0;
1755 cpu->pc += sizeof(uint32_t);
1756 }
1757
1758 if (!quiet_mode) {
1759 uint64_t offset;
1760 int x;
1761 char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1762 cpu->pc, &offset);
1763
1764 debug("[ ");
1765 if (cpu->machine->ncpus > 1)
1766 debug("cpu%i: ", cpu->cpu_id);
1767
1768 debug("exception %s%s",
1769 exception_names[exccode], tlb? " <tlb>" : "");
1770
1771 switch (exccode) {
1772
1773 case EXCEPTION_INT:
1774 debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT));
1775 break;
1776
1777 case EXCEPTION_SYS:
1778 debug(" v0=%i", (int)cpu->cd.mips.gpr[MIPS_GPR_V0]);
1779 for (x=0; x<4; x++) {
1780 int64_t d = cpu->cd.mips.gpr[MIPS_GPR_A0 + x];
1781 char strbuf[30];
1782
1783 if (d > -256 && d < 256) {
1784 debug(" a%i=%i", x, (int)d);
1785 } else if (memory_points_to_string(cpu,
1786 cpu->mem, d, 1)) {
1787 debug(" a%i=\"%s\"", x,
1788 memory_conv_to_string(cpu, cpu->mem,
1789 d, strbuf, sizeof(strbuf)));
1790 } else {
1791 if (cpu->is_32bit)
1792 debug(" a%i=0x%"PRIx32, x,
1793 (uint32_t)d);
1794 else
1795 debug(" a%i=0x%"PRIx64, x,
1796 (uint64_t)d);
1797 }
1798 }
1799 break;
1800
1801 case EXCEPTION_CPU:
1802 debug(" coproc_nr=%i", coproc_nr);
1803 break;
1804
1805 default:
1806 if (cpu->is_32bit)
1807 debug(" vaddr=0x%08x", (int)vaddr);
1808 else
1809 debug(" vaddr=0x%016"PRIx64, (uint64_t)vaddr);
1810 }
1811
1812 if (cpu->is_32bit)
1813 debug(" pc=0x%08"PRIx32" ", (uint32_t)cpu->pc);
1814 else
1815 debug(" pc=0x%016"PRIx64" ", (uint64_t)cpu->pc);
1816
1817 if (symbol != NULL)
1818 debug("<%s> ]\n", symbol);
1819 else
1820 debug("]\n");
1821 }
1822
1823 if (tlb && vaddr < 0x1000) {
1824 uint64_t offset;
1825 char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1826 cpu->pc, &offset);
1827 fatal("[ ");
1828 if (cpu->machine->ncpus > 1)
1829 fatal("cpu%i: ", cpu->cpu_id);
1830 fatal("warning: LOW reference: vaddr=");
1831 if (cpu->is_32bit)
1832 fatal("0x%08"PRIx32, (uint32_t) vaddr);
1833 else
1834 fatal("0x%016"PRIx64, (uint64_t) vaddr);
1835 fatal(", exception %s, pc=", exception_names[exccode]);
1836 if (cpu->is_32bit)
1837 fatal("0x%08"PRIx32, (uint32_t) cpu->pc);
1838 else
1839 fatal("0x%016"PRIx64, (uint64_t)cpu->pc);
1840 fatal(" <%s> ]\n", symbol? symbol : "(no symbol)");
1841 }
1842
1843 /* Clear the exception code bits of the cause register... */
1844 if (exc_model == EXC3K)
1845 reg[COP0_CAUSE] &= ~R2K3K_CAUSE_EXCCODE_MASK;
1846 else
1847 reg[COP0_CAUSE] &= ~CAUSE_EXCCODE_MASK;
1848
1849 /* ... and OR in the exception code: */
1850 reg[COP0_CAUSE] |= (exccode << CAUSE_EXCCODE_SHIFT);
1851
1852 /* Always set CE (according to the R5000 manual): */
1853 reg[COP0_CAUSE] &= ~CAUSE_CE_MASK;
1854 reg[COP0_CAUSE] |= (coproc_nr << CAUSE_CE_SHIFT);
1855
1856 if (tlb || (exccode >= EXCEPTION_MOD && exccode <= EXCEPTION_ADES) ||
1857 exccode == EXCEPTION_VCEI || exccode == EXCEPTION_VCED) {
1858 reg[COP0_BADVADDR] = vaddr;
1859 if (cpu->is_32bit)
1860 reg[COP0_BADVADDR] = (int32_t)reg[COP0_BADVADDR];
1861
1862 if (exc_model == EXC3K) {
1863 reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK;
1864 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << R2K3K_CONTEXT_BADVPN_SHIFT) & R2K3K_CONTEXT_BADVPN_MASK);
1865
1866 reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK)
1867 | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);
1868
1869 /* Sign-extend: */
1870 reg[COP0_CONTEXT] = (int64_t)(int32_t)reg[COP0_CONTEXT];
1871 reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];
1872 } else {
1873 if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {
1874 reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK_R4100;
1875 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK_R4100);
1876
1877 /* TODO: fix these */
1878 reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
1879 reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
1880 reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
1881 reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1882
1883 /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1884
1885 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK | 0x1800)) | vaddr_asid;
1886 } else {
1887 reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK;
1888 reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK);
1889
1890 reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
1891 reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
1892 reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
1893 reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1894
1895 /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1896
1897 if (cpu->cd.mips.cpu_type.mmu_model == MMU10K)
1898 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK_R10K)) | vaddr_asid;
1899 else
1900 reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK)) | vaddr_asid;
1901 }
1902 }
1903 }
1904
1905 if (exc_model != EXC3K && reg[COP0_STATUS] & STATUS_EXL) {
1906 /*
1907 * Don't set EPC if STATUS_EXL is set, for R4000 and up.
1908 * This actually happens when running IRIX and Ultrix, when
1909 * they handle interrupts and/or tlb updates, I think, so
1910 * printing this with debug() looks better than with fatal().
1911 */
1912 /* debug("[ warning: cpu%i exception while EXL is set,"
1913 " not setting EPC ]\n", cpu->cpu_id); */
1914 } else {
1915 if (cpu->delay_slot) {
1916 reg[COP0_EPC] = cpu->pc - 4;
1917 reg[COP0_CAUSE] |= CAUSE_BD;
1918 } else {
1919 reg[COP0_EPC] = cpu->pc;
1920 reg[COP0_CAUSE] &= ~CAUSE_BD;
1921 }
1922 }
1923
1924 if (cpu->delay_slot)
1925 cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
1926 else
1927 cpu->delay_slot = NOT_DELAYED;
1928
1929 /* TODO: This is true for MIPS64, but how about others? */
1930 if (reg[COP0_STATUS] & STATUS_BEV)
1931 base = 0xffffffffbfc00200ULL;
1932 else
1933 base = 0xffffffff80000000ULL;
1934
1935 switch (exc_model) {
1936 case EXC3K:
1937 /* Userspace tlb, vs others: */
1938 if (tlb && !(vaddr & 0x80000000ULL) &&
1939 (exccode == EXCEPTION_TLBL || exccode == EXCEPTION_TLBS) )
1940 cpu->pc = base + 0x000;
1941 else
1942 cpu->pc = base + 0x080;
1943 break;
1944 default:
1945 /*
1946 * These offsets are according to the MIPS64 manual, but
1947 * should work with R4000 and the rest too (I hope).
1948 *
1949 * 0x000 TLB refill, if EXL=0
1950 * 0x080 64-bit XTLB refill, if EXL=0
1951 * 0x100 cache error (not implemented yet)
1952 * 0x180 general exception
1953 * 0x200 interrupt (if CAUSE_IV is set)
1954 */
1955 if (tlb && (exccode == EXCEPTION_TLBL ||
1956 exccode == EXCEPTION_TLBS) &&
1957 !(reg[COP0_STATUS] & STATUS_EXL)) {
1958 if (x_64)
1959 cpu->pc = base + 0x080;
1960 else
1961 cpu->pc = base + 0x000;
1962 } else {
1963 if (exccode == EXCEPTION_INT &&
1964 (reg[COP0_CAUSE] & CAUSE_IV))
1965 cpu->pc = base + 0x200;
1966 else
1967 cpu->pc = base + 0x180;
1968 }
1969 }
1970
1971 if (exc_model == EXC3K) {
1972 /* R{2,3}000: Shift the lowest 6 bits to the left two steps:*/
1973 reg[COP0_STATUS] = (reg[COP0_STATUS] & ~0x3f) +
1974 ((reg[COP0_STATUS] & 0xf) << 2);
1975 } else {
1976 /* R4000: */
1977 reg[COP0_STATUS] |= STATUS_EXL;
1978 }
1979
1980 /* Sign-extend: */
1981 reg[COP0_CAUSE] = (int64_t)(int32_t)reg[COP0_CAUSE];
1982 reg[COP0_STATUS] = (int64_t)(int32_t)reg[COP0_STATUS];
1983
1984 if (cpu->is_32bit) {
1985 reg[COP0_EPC] = (int64_t)(int32_t)reg[COP0_EPC];
1986 mips32_pc_to_pointers(cpu);
1987 } else {
1988 mips_pc_to_pointers(cpu);
1989 }
1990 }
1991
1992
1993 #include "memory_mips.c"
1994
1995
1996 #include "tmp_mips_tail.c"
1997

  ViewVC Help
Powered by ViewVC 1.1.26