/[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

Annotation of /trunk/src/cpus/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 7 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 dpavlin 14 /*
2 dpavlin 34 * Copyright (C) 2003-2007 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 dpavlin 38 * $Id: cpu_mips.c,v 1.77 2007/04/10 17:52:27 debug Exp $
29 dpavlin 14 *
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 dpavlin 30 #include <unistd.h>
39 dpavlin 14
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 dpavlin 32 #include "settings.h"
54 dpavlin 14 #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 dpavlin 32 static char *special_rot_names[] = SPECIAL_ROT_NAMES;
65 dpavlin 14 static char *special2_names[] = SPECIAL2_NAMES;
66 dpavlin 24 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 dpavlin 14
73     static char *regnames[] = MIPS_REGISTER_NAMES;
74     static char *cop0_names[] = COP0_NAMES;
75    
76    
77 dpavlin 22 #define DYNTRANS_DUALMODE_32
78     #define DYNTRANS_DELAYSLOT
79     #include "tmp_mips_head.c"
80    
81 dpavlin 24 void mips_pc_to_pointers(struct cpu *);
82     void mips32_pc_to_pointers(struct cpu *);
83 dpavlin 22
84 dpavlin 24
85 dpavlin 14 /*
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 dpavlin 34 * NOTE: This helper function is _NOT_ reentrant.
92 dpavlin 14 */
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 dpavlin 24 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 dpavlin 14 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 dpavlin 24 if (cpu->is_32bit) {
150 dpavlin 28 cpu->run_instr = mips32_run_instr;
151 dpavlin 24 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 dpavlin 28 cpu->run_instr = mips_run_instr;
158 dpavlin 24 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 dpavlin 14 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 dpavlin 34 /* 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 dpavlin 14 /* 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 dpavlin 26 cpu->translate_v2p = translate_v2p_mmu3k;
331 dpavlin 14 break;
332     case MMU8K:
333 dpavlin 26 cpu->translate_v2p = translate_v2p_mmu8k;
334 dpavlin 14 break;
335     case MMU10K:
336 dpavlin 26 cpu->translate_v2p = translate_v2p_mmu10k;
337 dpavlin 14 break;
338     default:
339     if (cpu->cd.mips.cpu_type.rev == MIPS_R4100)
340 dpavlin 26 cpu->translate_v2p = translate_v2p_mmu4100;
341 dpavlin 14 else
342 dpavlin 26 cpu->translate_v2p = translate_v2p_generic;
343 dpavlin 14 }
344    
345 dpavlin 32 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 dpavlin 14 return 1;
369     }
370    
371    
372     /*
373 dpavlin 22 * 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 dpavlin 24 debug("\n%i-bit %s-endian (MIPS",
385 dpavlin 22 cpu->is_32bit? 32 : 64,
386 dpavlin 24 cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
387 dpavlin 22
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 dpavlin 24 case 64:debug("%i, revision %i", ct->isa_level, ct->isa_revision);
396     break;
397 dpavlin 22 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 dpavlin 24 * mips_cpu_instruction_has_delayslot():
470 dpavlin 14 *
471 dpavlin 24 * Return 1 if an opcode is a branch, 0 otherwise.
472 dpavlin 14 */
473 dpavlin 24 int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
474 dpavlin 14 {
475 dpavlin 24 uint32_t iword = *((uint32_t *)&ib[0]);
476 dpavlin 14
477 dpavlin 24 if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
478     iword = LE32_TO_HOST(iword);
479     else
480     iword = BE32_TO_HOST(iword);
481 dpavlin 14
482 dpavlin 24 switch (iword >> 26) {
483     case HI6_SPECIAL:
484     switch (iword & 0x3f) {
485     case SPECIAL_JR:
486     case SPECIAL_JALR:
487     return 1;
488 dpavlin 14 }
489 dpavlin 24 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 dpavlin 14
516 dpavlin 24 return 0;
517 dpavlin 14 }
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 dpavlin 22 /* Raw output: */
534     if (rawflag) {
535 dpavlin 14 for (i=0; i<m->ncpus; i++) {
536 dpavlin 38 struct mips_coproc *cop0 =
537     m->cpus[i]->cd.mips.coproc[0];
538    
539 dpavlin 14 if (x >= 0 && i != x)
540     continue;
541    
542     /* Print index, random, and wired: */
543     printf("cpu%i: (", i);
544    
545 dpavlin 22 if (m->cpus[i]->is_32bit)
546 dpavlin 38 printf("index=0x%08x random=0x%08x",
547     (int) cop0->reg[COP0_INDEX],
548     (int) cop0->reg[COP0_RANDOM]);
549 dpavlin 22 else
550 dpavlin 24 printf("index=0x%016"PRIx64
551     " random=0x%016"PRIx64,
552 dpavlin 38 (uint64_t) cop0->reg[COP0_INDEX],
553     (uint64_t) cop0->reg[COP0_RANDOM]);
554 dpavlin 22
555     if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
556 dpavlin 38 printf(" wired=0x%"PRIx64,
557     (uint64_t) cop0->reg[COP0_WIRED]);
558 dpavlin 22
559 dpavlin 14 printf(")\n");
560    
561     for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
562     nr_of_tlb_entries; j++) {
563 dpavlin 22 if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
564     MMU3K)
565 dpavlin 38 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 dpavlin 22 else if (m->cpus[i]->is_32bit)
570 dpavlin 38 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 dpavlin 22 else
578 dpavlin 38 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 dpavlin 14 }
586     }
587 dpavlin 38
588 dpavlin 14 return;
589     }
590    
591 dpavlin 22 /* Nicely formatted output: */
592 dpavlin 14 for (i=0; i<m->ncpus; i++) {
593 dpavlin 22 int pageshift = 12;
594 dpavlin 38 struct mips_coproc *cop0 = m->cpus[i]->cd.mips.coproc[0];
595 dpavlin 22
596 dpavlin 14 if (x >= 0 && i != x)
597     continue;
598    
599 dpavlin 22 if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
600     pageshift = 10;
601    
602 dpavlin 14 /* Print index, random, and wired: */
603     printf("cpu%i: (", i);
604 dpavlin 22 switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
605     case 1:
606     case 2: printf("index=0x%x random=0x%x",
607 dpavlin 38 (int) ((cop0->reg[COP0_INDEX] & R2K3K_INDEX_MASK)
608 dpavlin 22 >> R2K3K_INDEX_SHIFT),
609 dpavlin 38 (int) ((cop0->reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
610 dpavlin 22 >> R2K3K_RANDOM_SHIFT));
611     break;
612     default:printf("index=0x%x random=0x%x",
613 dpavlin 38 (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 dpavlin 22 }
618 dpavlin 14
619     printf(")\n");
620    
621 dpavlin 22 for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
622     nr_of_tlb_entries; j++) {
623 dpavlin 38 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 dpavlin 22
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 dpavlin 24 printf("vaddr=0x%08"PRIx32" ",
654 dpavlin 32 (uint32_t) hi);
655 dpavlin 22 break;
656 dpavlin 32 case MMU10K:
657 dpavlin 22 default:/* R4000 etc. */
658 dpavlin 32 printf("vaddr=%016"PRIx64" ",
659     (uint64_t) hi);
660 dpavlin 22 }
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 dpavlin 24 printf(" p0=0x%09"PRIx64" ", (uint64_t)
673 dpavlin 22 (((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 dpavlin 24 printf(" p1=0x%09"PRIx64" ", (uint64_t)
681 dpavlin 22 (((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 dpavlin 14 }
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 dpavlin 24 int running, uint64_t dumpaddr)
720 dpavlin 14 {
721 dpavlin 32 int hi6, special6, regimm5, sub;
722 dpavlin 14 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 dpavlin 24 debug("%08"PRIx32, (uint32_t)dumpaddr);
744 dpavlin 14 else
745 dpavlin 24 debug("%016"PRIx64, (uint64_t)dumpaddr);
746 dpavlin 14
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 dpavlin 32 if (running && cpu->delay_slot)
764     debug(" (d)");
765 dpavlin 14
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 dpavlin 32 sub = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
788 dpavlin 14 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 dpavlin 24 else if (sa == 3)
798     debug("ehb");
799 dpavlin 14 else
800     debug("nop (weird, sa=%i)", sa);
801 dpavlin 32 break;
802     }
803    
804     switch (sub) {
805     case 0x00:
806 dpavlin 14 debug("%s\t%s,",
807     special_names[special6],
808     regname(cpu->machine, rd));
809     debug("%s,%i", regname(cpu->machine, rt), sa);
810 dpavlin 32 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 dpavlin 14 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 dpavlin 32 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 dpavlin 14 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 dpavlin 32 /* .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 dpavlin 14 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 dpavlin 32 /* .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 dpavlin 14 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 dpavlin 24 if (cpu->is_32bit && (special6 == SPECIAL_ADDU ||
905     special6 == SPECIAL_SUBU) && rt == 0) {
906     /* Special case 1: addu/subu with
907 dpavlin 14 rt = the zero register ==> move */
908     debug("move\t%s", regname(cpu->machine, rd));
909     debug(",%s", regname(cpu->machine, rs));
910 dpavlin 24 } else if (special6 == SPECIAL_ADDU && cpu->is_32bit
911     && rs == 0) {
912     /* Special case 2: addu with
913 dpavlin 14 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 dpavlin 24 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 dpavlin 14 }
952     }
953 dpavlin 24 debug("%s", regname(cpu->machine, rs));
954 dpavlin 14 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 dpavlin 24 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 dpavlin 14 break;
984     case SPECIAL_MTSA:
985 dpavlin 24 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 dpavlin 14 break;
993     default:
994 dpavlin 24 debug("%s\t= UNIMPLEMENTED", special_names[special6]);
995 dpavlin 14 }
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 dpavlin 22 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 dpavlin 14 }
1026    
1027     if (cpu->is_32bit)
1028 dpavlin 24 debug("0x%08"PRIx32, (uint32_t)addr);
1029 dpavlin 14 else
1030 dpavlin 24 debug("0x%016"PRIx64, (uint64_t)addr);
1031 dpavlin 14
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 dpavlin 24 case HI6_SQ_SPECIAL3:
1083 dpavlin 14 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 dpavlin 24 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 dpavlin 32 int msbd, lsb, sub10;
1106 dpavlin 24 special6 = instr[0] & 0x3f;
1107     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1108     rt = instr[2] & 31;
1109 dpavlin 32 rd = msbd = (instr[1] >> 3) & 31;
1110     lsb = ((instr[1] & 7) << 2) | (instr[0] >> 6);
1111     sub10 = (rs << 5) | lsb;
1112 dpavlin 24
1113     switch (special6) {
1114    
1115 dpavlin 32 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 dpavlin 24 case SPECIAL3_RDHWR:
1181 dpavlin 32 debug("%s", special3_names[special6]);
1182 dpavlin 24 debug("\t%s", regname(cpu->machine, rt));
1183     debug(",hwr%i", rd);
1184     break;
1185    
1186 dpavlin 32 default:debug("%s", special3_names[special6]);
1187 dpavlin 24 debug("\t(UNIMPLEMENTED)");
1188     }
1189     break;
1190     }
1191    
1192 dpavlin 14 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 dpavlin 24 debug("\t[0x%016"PRIx64" = %s]",
1208     (uint64_t)(cpu->cd.mips.gpr[rs] + imm));
1209 dpavlin 14 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 dpavlin 24 debug("0x%08"PRIx32,
1233     (uint32_t) (cpu->cd.mips.gpr[rs] + imm));
1234 dpavlin 14 else
1235 dpavlin 24 debug("0x%016"PRIx64,
1236     (uint64_t) (cpu->cd.mips.gpr[rs] + imm));
1237 dpavlin 14
1238     if (symbol != NULL)
1239     debug(" = %s", symbol);
1240    
1241 dpavlin 24 /* 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 dpavlin 14 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 dpavlin 24 debug("%08"PRIx32, (uint32_t) addr);
1260 dpavlin 14 else
1261 dpavlin 24 debug("%016"PRIx64, (uint64_t) addr);
1262 dpavlin 14 if (symbol != NULL)
1263     debug("\t<%s>", symbol);
1264     break;
1265 dpavlin 24
1266 dpavlin 14 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 dpavlin 24
1279 dpavlin 14 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 dpavlin 38 if (cache_op==5) debug("fill OR hit writeback invalidate");
1299 dpavlin 14 if (cache_op==6) debug("hit writeback");
1300     if (cache_op==7) debug("hit set virtual");
1301     if (running)
1302 dpavlin 24 debug(", addr 0x%016"PRIx64,
1303     (uint64_t)(cpu->cd.mips.gpr[rt] + imm));
1304 dpavlin 14 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 dpavlin 24
1311 dpavlin 14 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 dpavlin 24
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 dpavlin 14 debug(",%s", regname(cpu->machine, rt));
1447 dpavlin 24 break;
1448    
1449     case SPECIAL2_MUL:
1450 dpavlin 22 /* Apparently used both on R5900 and MIPS32: */
1451 dpavlin 24 debug("%s", regname(cpu->machine, rd));
1452 dpavlin 14 debug(",%s", regname(cpu->machine, rs));
1453     debug(",%s", regname(cpu->machine, rt));
1454 dpavlin 24 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 dpavlin 14 debug(",%s", regname(cpu->machine, rs));
1462 dpavlin 24 break;
1463    
1464     default:
1465     debug("(UNIMPLEMENTED)");
1466 dpavlin 14 }
1467     break;
1468 dpavlin 24
1469 dpavlin 14 case HI6_REGIMM:
1470     regimm5 = instr[2] & 0x1f;
1471 dpavlin 32 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 dpavlin 14 switch (regimm5) {
1477 dpavlin 32
1478 dpavlin 14 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 dpavlin 24 debug("0x%08"PRIx32, (uint32_t) addr);
1493 dpavlin 14 else
1494 dpavlin 24 debug("0x%016"PRIx64, (uint64_t) addr);
1495 dpavlin 14 break;
1496 dpavlin 32
1497     case REGIMM_SYNCI:
1498     debug("%s\t%i(%s)", regimm_names[regimm5],
1499     imm, regname(cpu->machine, rs));
1500     break;
1501    
1502 dpavlin 14 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 dpavlin 24 int bits128 = cpu->cd.mips.cpu_type.rev == MIPS_R5900;
1530 dpavlin 14
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 dpavlin 24 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 dpavlin 14 else
1545 dpavlin 24 debug("cpu%i: pc = 0x%016"PRIx64,
1546     cpu->cpu_id, (uint64_t) cpu->pc);
1547 dpavlin 14
1548     debug(" <%s>\n", symbol != NULL? symbol :
1549     " no symbol ");
1550    
1551     if (bits32)
1552 dpavlin 24 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 dpavlin 14
1567     /* General registers: */
1568 dpavlin 24 if (bits128) {
1569 dpavlin 14 /* 128-bit: */
1570     for (i=0; i<32; i++) {
1571 dpavlin 24 int r = (i >> 1) + ((i & 1) << 4);
1572 dpavlin 14 if ((i & 1) == 0)
1573     debug("cpu%i:", cpu->cpu_id);
1574 dpavlin 24 if (r == MIPS_GPR_ZERO)
1575     debug(" "
1576     " ");
1577     else
1578     debug(" %3s=%016"PRIx64"%016"PRIx64,
1579 dpavlin 38 regname(cpu->machine, r), (uint64_t)
1580     cpu->cd.mips.gpr_quadhi[r],
1581 dpavlin 24 (uint64_t)cpu->cd.mips.gpr[r]);
1582 dpavlin 14 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 dpavlin 24 debug(" %3s = %08"PRIx32,
1594     regname(cpu->machine, i),
1595     (uint32_t)cpu->cd.mips.gpr[i]);
1596 dpavlin 14 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 dpavlin 24 debug(" %3s = 0x%016"PRIx64,
1609     regname(cpu->machine, r),
1610     (uint64_t)cpu->cd.mips.gpr[r]);
1611 dpavlin 14 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 dpavlin 38 debug("=%08x", (int)cpu->cd.mips.
1645     coproc[coprocnr]->reg[i]);
1646 dpavlin 14 else {
1647     if (coprocnr == 0 && (i == COP0_COUNT
1648     || i == COP0_COMPARE || i == COP0_INDEX
1649     || i == COP0_RANDOM || i == COP0_WIRED))
1650 dpavlin 38 debug(" = 0x%08x",
1651     (int) cpu->cd.mips.coproc[
1652     coprocnr]->reg[i]);
1653 dpavlin 14 else
1654 dpavlin 24 debug(" = 0x%016"PRIx64, (uint64_t)
1655 dpavlin 38 cpu->cd.mips.coproc[
1656     coprocnr]->reg[i]);
1657 dpavlin 14 }
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 dpavlin 24 debug("%08"PRIx32, (uint32_t)cpu->cd.mips.cop0_config_select1);
1673 dpavlin 14 else
1674 dpavlin 24 debug("%016"PRIx64, (uint64_t)cpu->cd.mips.cop0_config_select1);
1675 dpavlin 14 debug("\n");
1676     }
1677    
1678     /* Floating point control registers: */
1679     if (coprocnr == 1) {
1680     for (i=0; i<32; i++)
1681     switch (i) {
1682 dpavlin 24 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 dpavlin 14 break;
1687 dpavlin 24 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 dpavlin 14 break;
1692 dpavlin 24 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 dpavlin 14 break;
1697     }
1698     }
1699     }
1700 dpavlin 24
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 dpavlin 14 }
1706    
1707    
1708 dpavlin 24 /*
1709 dpavlin 34 * mips_cpu_interrupt_assert(), mips_cpu_interrupt_deassert():
1710 dpavlin 14 *
1711 dpavlin 34 * Assert or deassert a MIPS CPU interrupt by masking in or out bits
1712     * in the CAUSE register of coprocessor 0.
1713 dpavlin 14 */
1714 dpavlin 34 void mips_cpu_interrupt_assert(struct interrupt *interrupt)
1715 dpavlin 14 {
1716 dpavlin 34 struct cpu *cpu = interrupt->extra;
1717     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |= interrupt->line;
1718 dpavlin 14 }
1719 dpavlin 34 void mips_cpu_interrupt_deassert(struct interrupt *interrupt)
1720 dpavlin 14 {
1721 dpavlin 34 struct cpu *cpu = interrupt->extra;
1722     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &= ~interrupt->line;
1723 dpavlin 14 }
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 dpavlin 30 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 dpavlin 14 if (!quiet_mode) {
1759     uint64_t offset;
1760     int x;
1761     char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1762 dpavlin 24 cpu->pc, &offset);
1763 dpavlin 14
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 dpavlin 24
1773 dpavlin 14 case EXCEPTION_INT:
1774     debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT));
1775     break;
1776 dpavlin 24
1777 dpavlin 14 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 dpavlin 24 if (d > -256 && d < 256) {
1784 dpavlin 14 debug(" a%i=%i", x, (int)d);
1785 dpavlin 24 } 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 dpavlin 14 }
1799     break;
1800 dpavlin 24
1801     case EXCEPTION_CPU:
1802     debug(" coproc_nr=%i", coproc_nr);
1803     break;
1804    
1805 dpavlin 14 default:
1806     if (cpu->is_32bit)
1807     debug(" vaddr=0x%08x", (int)vaddr);
1808     else
1809 dpavlin 24 debug(" vaddr=0x%016"PRIx64, (uint64_t)vaddr);
1810 dpavlin 14 }
1811    
1812     if (cpu->is_32bit)
1813 dpavlin 24 debug(" pc=0x%08"PRIx32" ", (uint32_t)cpu->pc);
1814 dpavlin 14 else
1815 dpavlin 24 debug(" pc=0x%016"PRIx64" ", (uint64_t)cpu->pc);
1816 dpavlin 14
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 dpavlin 24 cpu->pc, &offset);
1827 dpavlin 14 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 dpavlin 24 fatal("0x%08"PRIx32, (uint32_t) vaddr);
1833 dpavlin 14 else
1834 dpavlin 24 fatal("0x%016"PRIx64, (uint64_t) vaddr);
1835 dpavlin 14 fatal(", exception %s, pc=", exception_names[exccode]);
1836     if (cpu->is_32bit)
1837 dpavlin 24 fatal("0x%08"PRIx32, (uint32_t) cpu->pc);
1838 dpavlin 14 else
1839 dpavlin 24 fatal("0x%016"PRIx64, (uint64_t)cpu->pc);
1840 dpavlin 14 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 dpavlin 24 if (cpu->is_32bit)
1860     reg[COP0_BADVADDR] = (int32_t)reg[COP0_BADVADDR];
1861    
1862 dpavlin 14 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 dpavlin 24 if (exc_model != EXC3K && reg[COP0_STATUS] & STATUS_EXL) {
1906 dpavlin 14 /*
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 dpavlin 24 /* debug("[ warning: cpu%i exception while EXL is set,"
1913     " not setting EPC ]\n", cpu->cpu_id); */
1914 dpavlin 14 } else {
1915 dpavlin 32 if (cpu->delay_slot) {
1916 dpavlin 24 reg[COP0_EPC] = cpu->pc - 4;
1917 dpavlin 14 reg[COP0_CAUSE] |= CAUSE_BD;
1918     } else {
1919 dpavlin 24 reg[COP0_EPC] = cpu->pc;
1920 dpavlin 14 reg[COP0_CAUSE] &= ~CAUSE_BD;
1921     }
1922     }
1923    
1924 dpavlin 24 if (cpu->delay_slot)
1925     cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
1926     else
1927     cpu->delay_slot = NOT_DELAYED;
1928    
1929 dpavlin 14 /* 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 dpavlin 24 /* R{2,3}000: Shift the lowest 6 bits to the left two steps:*/
1973     reg[COP0_STATUS] = (reg[COP0_STATUS] & ~0x3f) +
1974 dpavlin 14 ((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 dpavlin 24 if (cpu->is_32bit) {
1985     reg[COP0_EPC] = (int64_t)(int32_t)reg[COP0_EPC];
1986     mips32_pc_to_pointers(cpu);
1987 dpavlin 14 } else {
1988 dpavlin 24 mips_pc_to_pointers(cpu);
1989 dpavlin 14 }
1990     }
1991    
1992    
1993 dpavlin 24 #include "memory_mips.c"
1994 dpavlin 22
1995    
1996     #include "tmp_mips_tail.c"
1997    

  ViewVC Help
Powered by ViewVC 1.1.26