/[gxemul]/trunk/src/cpus/cpu_mips.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 34 - (show annotations)
Mon Oct 8 16:21:17 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 57367 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1480 2007/02/19 01:34:42 debug Exp $
20061029	Changing usleep(1) calls in the debugger to usleep(10000)
20061107	Adding a new disk image option (-d o...) which sets the ISO9660
		filesystem base offset; also making some other hacks to allow
		NetBSD/dreamcast and homebrew demos/games to boot directly
		from a filesystem image.
		Moving Dreamcast-specific stuff in the documentation to its
		own page (dreamcast.html).
		Adding a border to the Dreamcast PVR framebuffer.
20061108	Adding a -T command line option (again?), for halting the
		emulator on unimplemented memory accesses.
20061109	Continuing on various SH4 and Dreamcast related things.
		The emulator should now halt on more unimplemented device
		accesses, instead of just printing a warning, forcing me to
		actually implement missing stuff :)
20061111	Continuing on SH4 and Dreamcast stuff.
		Adding a bogus Landisk (SH4) machine mode.
20061112	Implementing some parts of the Dreamcast GDROM device. With
		some ugly hacks, NetBSD can (barely) mount an ISO image.
20061113	NetBSD/dreamcast now starts booting from the Live CD image,
		but crashes randomly quite early on in the boot process.
20061122	Beginning on a skeleton interrupt.h and interrupt.c for the
		new interrupt subsystem.
20061124	Continuing on the new interrupt system; taking the first steps
		to attempt to connect CPUs (SuperH and MIPS) and devices
		(dev_cons and SH4 timer interrupts) to it. Many things will
		probably break from now on.
20061125	Converting dev_ns16550, dev_8253 to the new interrupt system.
		Attempting to begin to convert the ISA bus.
20061130	Incorporating a patch from Brian Foley for the configure
		script, which checks for X11 libs in /usr/X11R6/lib64 (which
		is used on some Linux systems).
20061227	Adding a note in the man page about booting from Dreamcast
		CDROM images (i.e. that no external kernel is needed).
20061229	Continuing on the interrupt system rewrite: beginning to
		convert more devices, adding abort() calls for legacy interrupt
		system calls so that everything now _has_ to be rewritten!
		Almost all machine modes are now completely broken.
20061230	More progress on removing old interrupt code, mostly related
		to the ISA bus + devices, the LCA bus (on AlphaBook1), and
		the Footbridge bus (for CATS). And some minor PCI stuff.
		Connecting the ARM cpu to the new interrupt system.
		The CATS, NetWinder, and QEMU_MIPS machine modes now work with
		the new interrupt system :)
20061231	Connecting PowerPC CPUs to the new interrupt system.
		Making PReP machines (IBM 6050) work again.
		Beginning to convert the GT PCI controller (for e.g. Malta
		and Cobalt emulation). Some things work, but not everything.
		Updating Copyright notices for 2007.
20070101	Converting dev_kn02 from legacy style to devinit; the 3max
		machine mode now works with the new interrupt system :-]
20070105	Beginning to convert the SGI O2 machine to the new interrupt
		system; finally converting O2 (IP32) devices to devinit, etc.
20070106	Continuing on the interrupt system redesign/rewrite; KN01
		(PMAX), KN230, and Dreamcast ASIC interrupts should work again,
		moving out stuff from machine.h and devices.h into the
		corresponding devices, beginning the rewrite of i80321
		interrupts, etc.
20070107	Beginning on the rewrite of Eagle interrupt stuff (PReP, etc).
20070117	Beginning the rewrite of Algor (V3) interrupts (finally
		changing dev_v3 into devinit style).
20070118	Removing the "bus" registry concept from machine.h, because
		it was practically meaningless.
		Continuing on the rewrite of Algor V3 ISA interrupts.
20070121	More work on Algor interrupts; they are now working again,
		well enough to run NetBSD/algor. :-)
20070122	Converting VR41xx (HPCmips) interrupts. NetBSD/hpcmips
		can be installed using the new interrupt system :-)
20070123	Making the testmips mode work with the new interrupt system.
20070127	Beginning to convert DEC5800 devices to devinit, and to the
		new interrupt system.
		Converting Playstation 2 devices to devinit, and converting
		the interrupt system. Also fixing a severe bug: the interrupt
		mask register on Playstation 2 is bitwise _toggled_ on writes.
20070128	Removing the dummy NetGear machine mode and the 8250 device
		(which was only used by the NetGear machine).
		Beginning to convert the MacPPC GC (Grand Central) interrupt
		controller to the new interrupt system.
		Converting Jazz interrupts (PICA61 etc.) to the new interrupt
		system. NetBSD/arc can be installed again :-)
		Fixing the JAZZ timer (hardcoding it at 100 Hz, works with
		NetBSD and it is better than a completely dummy timer as it
		was before).
		Converting dev_mp to the new interrupt system, although I
		haven't had time to actually test it yet.
		Completely removing src/machines/interrupts.c, cpu_interrupt
		and cpu_interrupt_ack in src/cpu.c, and
		src/include/machine_interrupts.h! Adding fatal error messages
		+ abort() in the few places that are left to fix.
		Converting dev_z8530 to the new interrupt system.
		FINALLY removing the md_int struct completely from the
		machine struct.
		SH4 fixes (adding a PADDR invalidation in the ITLB replacement
		code in memory_sh.c); the NetBSD/dreamcast LiveCD now runs
		all the way to the login prompt, and can be interacted with :-)
		Converting the CPC700 controller (PCI and interrupt controller
		for PM/PPC) to the new interrupt system.
20070129	Fixing MACE ISA interrupts (SGI IP32 emulation). Both NetBSD/
		sgimips' and OpenBSD/sgi's ramdisk kernels can now be
		interacted with again.
20070130	Moving out the MIPS multi_lw and _sw instruction combinations
		so that they are auto-generated at compile time instead.
20070131	Adding detection of amd64/x86_64 hosts in the configure script,
		for doing initial experiments (again :-) with native code
		generation.
		Adding a -k command line option to set the size of the dyntrans
		cache, and a -B command line option to disable native code
		generation, even if GXemul was compiled with support for
		native code generation for the specific host CPU architecture.
20070201	Experimenting with a skeleton for native code generation.
		Changing the default behaviour, so that native code generation
		is now disabled by default, and has to be enabled by using
		-b on the command line.
20070202	Continuing the native code generation experiments.
		Making PCI interrupts work for Footbridge again.
20070203	More native code generation experiments.
		Removing most of the native code generation experimental code,
		it does not make sense to include any quick hacks like this.
		Minor cleanup/removal of some more legacy MIPS interrupt code.
20070204	Making i80321 interrupts work again (for NetBSD/evbarm etc.),
		and fixing the timer at 100 Hz.
20070206	Experimenting with removing the wdc interrupt slowness hack.
20070207	Lowering the number of dyntrans TLB entries for MIPS from
		192 to 128, resulting in a minor speed improvement.
		Minor optimization to the code invalidation routine in
		cpu_dyntrans.c.
20070208	Increasing (experimentally) the nr of dyntrans instructions per
		loop from 60 to 120.
20070210	Commenting out (experimentally) the dyntrans_device_danger
		detection in memory_rw.c.
		Changing the testmips and baremips machines to use a revision 2
		MIPS64 CPU by default, instead of revision 1.
		Removing the dummy i960, IA64, x86, AVR32, and HP PA-RISC
		files, the PC bios emulation, and the Olivetti M700 (ARC) and
		db64360 emulation modes.
20070211	Adding an "mp" demo to the demos directory, which tests the
		SMP functionality of the testmips machine.
		Fixing PReP interrupts some more. NetBSD/prep now boots again.
20070216	Adding a "nop workaround" for booting Mach/PMAX to the
		documentation; thanks to Artur Bujdoso for the values.
		Converting more of the MacPPC interrupt stuff to the new
		system.
		Beginning to convert BeBox interrupts to the new system.
		PPC603e should NOT have the PPC_NO_DEC flag! Removing it.
		Correcting BeBox clock speed (it was set to 100 in the NetBSD
		bootinfo block, but should be 33000000/4), allowing NetBSD
		to start without using the (incorrect) PPC_NO_DEC hack.
20070217	Implementing (slow) AltiVec vector loads and stores, allowing
		NetBSD/macppc to finally boot using the GENERIC kernel :-)
		Updating the documentation with install instructions for
		NetBSD/macppc.
20070218-19	Regression testing for the release.

==============  RELEASE 0.4.4  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26