/[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 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 57221 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 0.4.2  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26