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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26