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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 57221 byte(s)
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