/[gxemul]/trunk/src/include/cpu_mips.h
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/include/cpu_mips.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (show annotations)
Mon Oct 8 16:22:32 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 11416 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1613 2007/06/15 20:11:26 debug Exp $
20070501	Continuing a little on m88k disassembly (control registers,
		more instructions).
		Adding a dummy mvme88k machine mode.
20070502	Re-adding MIPS load/store alignment exceptions.
20070503	Implementing more of the M88K disassembly code.
20070504	Adding disassembly of some more M88K load/store instructions.
		Implementing some relatively simple M88K instructions (br.n,
		xor[.u] imm, and[.u] imm).
20070505	Implementing M88K three-register and, or, xor, and jmp[.n],
		bsr[.n] including function call trace stuff.
		Applying a patch from Bruce M. Simpson which implements the
		SYSCON_BOARD_CPU_CLOCK_FREQ_ID object of the syscon call in
		the yamon PROM emulation.
20070506	Implementing M88K bb0[.n] and bb1[.n], and skeletons for
		ldcr and stcr (although no control regs are implemented yet).
20070509	Found and fixed the bug which caused Linux for QEMU_MIPS to
		stop working in 0.4.5.1: It was a faulty change to the MIPS
		'sc' and 'scd' instructions I made while going through gcc -W
		warnings on 20070428.
20070510	Updating the Linux/QEMU_MIPS section in guestoses.html to
		use mips-test-0.2.tar.gz instead of 0.1.
		A big thank you to Miod Vallat for sending me M88K manuals.
		Implementing more M88K instructions (addu, subu, div[u], mulu,
		ext[u], clr, set, cmp).
20070511	Fixing bugs in the M88K "and" and "and.u" instructions (found
		by comparing against the manual).
		Implementing more M88K instructions (mask[.u], mak, bcnd (auto-
		generated)) and some more control register details.
		Cleanup: Removing the experimental AVR emulation mode and
		corresponding devices; AVR emulation wasn't really meaningful.
		Implementing autogeneration of most M88K loads/stores. The
		rectangle drawing demo (with -O0) for M88K runs :-)
		Beginning on M88K exception handling.
		More M88K instructions: tb0, tb1, rte, sub, jsr[.n].
		Adding some skeleton MVME PROM ("BUG") emulation.
20070512	Fixing a bug in the M88K cmp instruction.
		Adding the M88K lda (scaled register) instruction.
		Fixing bugs in 64-bit (32-bit pairs) M88K loads/stores.
		Removing the unused tick_hz stuff from the machine struct.
		Implementing the M88K xmem instruction. OpenBSD/mvme88k gets
		far enough to display the Copyright banner :-)
		Implementing subu.co (guess), addu.co, addu.ci, ff0, and ff1.
		Adding a dev_mvme187, for MVME187-specific devices/registers.
		OpenBSD/mvme88k prints more boot messages. :)
20070515	Continuing on MVME187 emulation (adding more devices, beginning
		on the CMMUs, etc).
		Adding the M88K and.c, xor.c, and or.c instructions, and making
		sure that mul, div, etc cause exceptions if executed when SFD1
		is disabled.
20070517	Continuing on M88K and MVME187 emulation in general; moving
		the CMMU registers to the CPU struct, separating dev_pcc2 from
		dev_mvme187, and beginning on memory_m88k.c (BATC and PATC).
		Fixing a bug in 64-bit (32-bit pairs) M88K fast stores.
		Implementing the clock part of dev_mk48txx.
		Implementing the M88K fstcr and xcr instructions.
		Implementing m88k_cpu_tlbdump().
		Beginning on the implementation of a separate address space
		for M88K .usr loads/stores.
20070520	Removing the non-working (skeleton) Sandpoint, SonyNEWS, SHARK
		Dnard, and Zaurus machine modes.
		Experimenting with dyntrans to_be_translated read-ahead. It
		seems to give a very small performance increase for MIPS
		emulation, but a large performance degradation for SuperH. Hm.
20070522	Disabling correct SuperH ITLB emulation; it does not seem to be
		necessary in order to let SH4 guest OSes run, and it slows down
		userspace code.
		Implementing "samepage" branches for SuperH emulation, and some
		other minor speed hacks.
20070525	Continuing on M88K memory-related stuff: exceptions, memory
		transaction register contents, etc.
		Implementing the M88K subu.ci instruction.
		Removing the non-working (skeleton) Iyonix machine mode.
		OpenBSD/mvme88k reaches userland :-), starts executing
		/sbin/init's instructions, and issues a few syscalls, before
		crashing.
20070526	Fixing bugs in dev_mk48txx, so that OpenBSD/mvme88k detects
		the correct time-of-day.
		Implementing a generic IRQ controller for the test machines
		(dev_irqc), similar to a proposed patch from Petr Stepan.
		Experimenting some more with translation read-ahead.
		Adding an "expect" script for automated OpenBSD/landisk
		install regression/performance tests.
20070527	Adding a dummy mmEye (SH3) machine mode skeleton.
		FINALLY found the strange M88K bug I have been hunting: I had
		not emulated the SNIP value for exceptions occurring in
		branch delay slots correctly.
		Implementing correct exceptions for 64-bit M88K loads/stores.
		Address to symbol lookups are now disabled when M88K is
		running in usermode (because usermode addresses don't have
		anything to do with supervisor addresses).
20070531	Removing the mmEye machine mode skeleton.
20070604	Some minor code cleanup.
20070605	Moving src/useremul.c into a subdir (src/useremul/), and
		cleaning up some more legacy constructs.
		Adding -Wstrict-aliasing and -fstrict-aliasing detection to
		the configure script.
20070606	Adding a check for broken GCC on Solaris to the configure
		script. (GCC 3.4.3 on Solaris cannot handle static variables
		which are initialized to 0 or NULL. :-/)
		Removing the old (non-working) ARC emulation modes: NEC RD94,
		R94, R96, and R98, and the last traces of Olivetti M700 and
		Deskstation Tyne.
		Removing the non-working skeleton WDSC device (dev_wdsc).
20070607	Thinking about how to use the host's cc + ld at runtime to
		generate native code. (See experiments/native_cc_ld_test.i
		for an example.)
20070608	Adding a program counter sampling timer, which could be useful
		for native code generation experiments.
		The KN02_CSR_NRMMOD bit in the DECstation 5000/200 (KN02) CSR
		should always be set, to allow a 5000/200 PROM to boot.
20070609	Moving out breakpoint details from the machine struct into
		a helper struct, and removing the limit on max nr of
		breakpoints.
20070610	Moving out tick functions into a helper struct as well (which
		also gets rid of the max limit).
20070612	FINALLY figured out why Debian/DECstation stopped working when
		translation read-ahead was enabled: in src/memory_rw.c, the
		call to invalidate_code_translation was made also if the
		memory access was an instruction load (if the page was mapped
		as writable); it shouldn't be called in that case.
20070613	Implementing some more MIPS32/64 revision 2 instructions: di,
		ei, ext, dext, dextm, dextu, and ins.
20070614	Implementing an instruction combination for the NetBSD/arm
		idle loop (making the host not use any cpu if NetBSD/arm
		inside the emulator is not using any cpu).
		Increasing the nr of ARM VPH entries from 128 to 384.
20070615	Removing the ENABLE_arch stuff from the configure script, so
		that all included architectures are included in both release
		and development builds.
		Moving memory related helper functions from misc.c to memory.c.
		Adding preliminary instructions for netbooting NetBSD/pmppc to
		guestoses.html; it doesn't work yet, there are weird timeouts.
		Beginning a total rewrite of the userland emulation modes
		(removing all emulation modes, beginning from scratch with
		NetBSD/MIPS and FreeBSD/Alpha only).
20070616	After fixing a bug in the DEC21143 NIC (the TDSTAT_OWN bit was
		only cleared for the last segment when transmitting, not all
		segments), NetBSD/pmppc boots with root-on-nfs without the
		timeouts. Updating guestoses.html.
		Removing the skeleton PSP (Playstation Portable) mode.
		Moving X11-related stuff in the machine struct into a helper
		struct.
		Cleanup of out-of-memory checks, to use a new CHECK_ALLOCATION
		macro (which prints a meaningful error message).
		Adding a COMMENT to each machine and device (for automagic
		.index comment generation).
		Doing regression testing for the next release.

==============  RELEASE 0.4.6  ==============


1 #ifndef CPU_MIPS_H
2 #define CPU_MIPS_H
3
4 /*
5 * Copyright (C) 2003-2007 Anders Gavare. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *
31 * $Id: cpu_mips.h,v 1.59 2007/06/07 15:36:25 debug Exp $
32 */
33
34 #include "interrupt.h"
35 #include "misc.h"
36
37 struct cpu_family;
38 struct emul;
39 struct machine;
40 struct timer;
41
42 /*
43 * CPU type definitions: See mips_cpu_types.h.
44 */
45
46 struct mips_cpu_type_def {
47 char *name;
48 int rev;
49 int sub;
50 char flags;
51 char exc_model; /* EXC3K or EXC4K */
52 char mmu_model; /* MMU3K or MMU4K */
53 char isa_level; /* 1, 2, 3, 4, 5, 32, 64 */
54 char isa_revision; /* 1 or 2 (for MIPS32/64) */
55 int nr_of_tlb_entries; /* 32, 48, 64, ... */
56 char instrs_per_cycle; /* simplified, 1, 2, or 4 */
57 int picache;
58 int pilinesize;
59 int piways;
60 int pdcache;
61 int pdlinesize;
62 int pdways;
63 int scache;
64 int slinesize;
65 int sways;
66 };
67
68 #define INITIAL_PC 0xffffffffbfc00000ULL
69 #define INITIAL_STACK_POINTER (0xffffffffa0008000ULL - 256)
70
71
72 /*
73 * Coproc 0:
74 *
75 * NOTE:
76 * On R3000, only hi and lo0 are used, and then only the lowest 32 bits.
77 */
78 #define N_MIPS_COPROC_REGS 32
79 struct mips_tlb {
80 uint64_t hi;
81 uint64_t lo0;
82 uint64_t lo1;
83 uint64_t mask;
84 };
85
86
87 /*
88 * Coproc 1:
89 */
90 /* FPU control registers: */
91 #define N_MIPS_FCRS 32
92 #define MIPS_FPU_FCIR 0
93 #define MIPS_FPU_FCCR 25
94 #define MIPS_FPU_FCSR 31
95 #define MIPS_FCSR_FCC0_SHIFT 23
96 #define MIPS_FCSR_FCC1_SHIFT 25
97
98 #define N_VADDR_TO_TLB_INDEX_ENTRIES (1 << 20)
99
100 struct mips_coproc {
101 int coproc_nr;
102 uint64_t reg[N_MIPS_COPROC_REGS];
103
104 /* Only for COP0: */
105 struct mips_tlb *tlbs;
106 int nr_of_tlbs;
107
108 /* Only for COP1: floating point control registers */
109 /* (Maybe also for COP0?) */
110 uint64_t fcr[N_MIPS_FCRS];
111 };
112
113 #define N_MIPS_COPROCS 4
114
115 #define N_MIPS_GPRS 32 /* General purpose registers */
116 #define N_MIPS_FPRS 32 /* Floating point registers */
117
118 /*
119 * These should all be 2 characters wide:
120 *
121 * NOTE: These are for 32-bit ABIs. For the 64-bit ABI, registers 8..11
122 * are used to pass arguments and are then called "a4".."a7".
123 *
124 * TODO: Should there be two different variants of this? It's not really
125 * possible to figure out in some easy way if the code running was
126 * written for a 32-bit or 64-bit ABI.
127 */
128 #define MIPS_REGISTER_NAMES { \
129 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
130 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
131 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
132 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" }
133
134 #define MIPS_GPR_ZERO 0 /* zero */
135 #define MIPS_GPR_AT 1 /* at */
136 #define MIPS_GPR_V0 2 /* v0 */
137 #define MIPS_GPR_V1 3 /* v1 */
138 #define MIPS_GPR_A0 4 /* a0 */
139 #define MIPS_GPR_A1 5 /* a1 */
140 #define MIPS_GPR_A2 6 /* a2 */
141 #define MIPS_GPR_A3 7 /* a3 */
142 #define MIPS_GPR_T0 8 /* t0 */
143 #define MIPS_GPR_T1 9 /* t1 */
144 #define MIPS_GPR_T2 10 /* t2 */
145 #define MIPS_GPR_T3 11 /* t3 */
146 #define MIPS_GPR_T4 12 /* t4 */
147 #define MIPS_GPR_T5 13 /* t5 */
148 #define MIPS_GPR_T6 14 /* t6 */
149 #define MIPS_GPR_T7 15 /* t7 */
150 #define MIPS_GPR_S0 16 /* s0 */
151 #define MIPS_GPR_S1 17 /* s1 */
152 #define MIPS_GPR_S2 18 /* s2 */
153 #define MIPS_GPR_S3 19 /* s3 */
154 #define MIPS_GPR_S4 20 /* s4 */
155 #define MIPS_GPR_S5 21 /* s5 */
156 #define MIPS_GPR_S6 22 /* s6 */
157 #define MIPS_GPR_S7 23 /* s7 */
158 #define MIPS_GPR_T8 24 /* t8 */
159 #define MIPS_GPR_T9 25 /* t9 */
160 #define MIPS_GPR_K0 26 /* k0 */
161 #define MIPS_GPR_K1 27 /* k1 */
162 #define MIPS_GPR_GP 28 /* gp */
163 #define MIPS_GPR_SP 29 /* sp */
164 #define MIPS_GPR_FP 30 /* fp */
165 #define MIPS_GPR_RA 31 /* ra */
166
167 #define N_HI6 64
168 #define N_SPECIAL 64
169 #define N_REGIMM 32
170
171
172 /* An "impossible" paddr: */
173 #define IMPOSSIBLE_PADDR 0x1212343456566767ULL
174
175 #define DEFAULT_PCACHE_SIZE 15 /* 32 KB */
176 #define DEFAULT_PCACHE_LINESIZE 5 /* 32 bytes */
177
178 struct r3000_cache_line {
179 uint32_t tag_paddr;
180 int tag_valid;
181 };
182 #define R3000_TAG_VALID 1
183 #define R3000_TAG_DIRTY 2
184
185
186 #define MIPS_IC_ENTRIES_SHIFT 10
187
188 #define MIPS_N_IC_ARGS 3
189 #define MIPS_INSTR_ALIGNMENT_SHIFT 2
190 #define MIPS_IC_ENTRIES_PER_PAGE (1 << MIPS_IC_ENTRIES_SHIFT)
191 #define MIPS_PC_TO_IC_ENTRY(a) (((a)>>MIPS_INSTR_ALIGNMENT_SHIFT) \
192 & (MIPS_IC_ENTRIES_PER_PAGE-1))
193 #define MIPS_ADDR_TO_PAGENR(a) ((a) >> (MIPS_IC_ENTRIES_SHIFT \
194 + MIPS_INSTR_ALIGNMENT_SHIFT))
195
196 #define MIPS_L2N 17
197 #define MIPS_L3N 18
198
199 #define MIPS_MAX_VPH_TLB_ENTRIES 128
200
201 DYNTRANS_MISC_DECLARATIONS(mips,MIPS,uint64_t)
202 DYNTRANS_MISC64_DECLARATIONS(mips,MIPS,uint8_t)
203
204
205 struct mips_cpu {
206 struct mips_cpu_type_def cpu_type;
207
208 /* General purpose registers: */
209 uint64_t gpr[N_MIPS_GPRS];
210
211 /* Dummy destination register when writing to the zero register: */
212 uint64_t scratch;
213
214 /* Special purpose registers: */
215 uint64_t hi;
216 uint64_t lo;
217
218 /* Coprocessors: */
219 struct mips_coproc *coproc[N_MIPS_COPROCS];
220 uint64_t cop0_config_select1;
221
222 int last_written_tlb_index;
223
224 /* Count/compare timer: */
225 int compare_register_set;
226 int compare_interrupts_pending;
227 struct interrupt irq_compare;
228 struct timer *timer;
229
230 int rmw; /* Read-Modify-Write */
231 uint64_t rmw_len; /* Length of rmw modification */
232 uint64_t rmw_addr; /* Address of rmw modification */
233
234 /*
235 * NOTE: The R5900 has 128-bit registers. I'm not really sure
236 * whether they are used a lot or not, at least with code produced
237 * with gcc they are not. An important case however is lq and sq
238 * (load and store of 128-bit values). These "upper halves" of R5900
239 * quadwords can be used in those cases.
240 *
241 * hi1 and lo1 are the high 64-bit parts of the hi and lo registers.
242 * sa is a 32-bit "shift amount" register.
243 *
244 * TODO: Generalize this.
245 */
246 uint64_t gpr_quadhi[N_MIPS_GPRS];
247 uint64_t hi1;
248 uint64_t lo1;
249 uint32_t r5900_sa;
250
251
252 /*
253 * Data and Instruction caches:
254 */
255
256 /* Cache sizes: (1 << x) x=0 for default values */
257 /* This is legacy stuff. TODO: Clean up! */
258 int cache_picache;
259 int cache_pdcache;
260 int cache_secondary;
261 int cache_picache_linesize;
262 int cache_pdcache_linesize;
263 int cache_secondary_linesize;
264
265 unsigned char *cache[2];
266 void *cache_tags[2];
267 uint64_t cache_last_paddr[2];
268 int cache_size[2];
269 int cache_linesize[2];
270 int cache_mask[2];
271
272
273 /*
274 * Instruction translation cache and Virtual->Physical->Host
275 * address translation:
276 */
277 DYNTRANS_ITC(mips)
278 VPH_TLBS(mips,MIPS)
279 VPH32(mips,MIPS)
280 VPH64(mips,MIPS)
281 };
282
283
284 /* cpu_mips.c: */
285 void mips_cpu_interrupt_assert(struct interrupt *interrupt);
286 void mips_cpu_interrupt_deassert(struct interrupt *interrupt);
287 int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib);
288 void mips_cpu_tlbdump(struct machine *m, int x, int rawflag);
289 void mips_cpu_register_match(struct machine *m, char *name,
290 int writeflag, uint64_t *valuep, int *match_register);
291 void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs);
292 int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
293 int running, uint64_t addr);
294 void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
295 /* uint64_t pagemask, */ int coproc_nr, uint64_t vaddr_vpn2,
296 int vaddr_asid, int x_64);
297 int mips_cpu_run(struct emul *emul, struct machine *machine);
298 void mips_cpu_dumpinfo(struct cpu *cpu);
299 void mips_cpu_list_available_types(void);
300 int mips_cpu_family_init(struct cpu_family *);
301
302
303 /* cpu_mips_coproc.c: */
304 struct mips_coproc *mips_coproc_new(struct cpu *cpu, int coproc_nr);
305 void mips_coproc_tlb_set_entry(struct cpu *cpu, int entrynr, int size,
306 uint64_t vaddr, uint64_t paddr0, uint64_t paddr1,
307 int valid0, int valid1, int dirty0, int dirty1, int global, int asid,
308 int cachealgo0, int cachealgo1);
309 void coproc_register_read(struct cpu *cpu,
310 struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select);
311 void coproc_register_write(struct cpu *cpu,
312 struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int flag64,
313 int select);
314 void coproc_tlbpr(struct cpu *cpu, int readflag);
315 void coproc_tlbwri(struct cpu *cpu, int randomflag);
316 void coproc_rfe(struct cpu *cpu);
317 void coproc_eret(struct cpu *cpu);
318 void coproc_function(struct cpu *cpu, struct mips_coproc *cp, int cpnr,
319 uint32_t function, int unassemble_only, int running);
320
321
322 /* memory_mips.c: */
323 int memory_cache_R3000(struct cpu *cpu, int cache, uint64_t paddr,
324 int writeflag, size_t len, unsigned char *data);
325 int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
326 unsigned char *data, size_t len, int writeflag, int cache_flags);
327
328 int translate_v2p_mmu3k(struct cpu *cpu, uint64_t vaddr,
329 uint64_t *return_addr, int flags);
330 int translate_v2p_mmu8k(struct cpu *cpu, uint64_t vaddr,
331 uint64_t *return_addr, int flags);
332 int translate_v2p_mmu10k(struct cpu *cpu, uint64_t vaddr,
333 uint64_t *return_addr, int flags);
334 int translate_v2p_mmu4100(struct cpu *cpu, uint64_t vaddr,
335 uint64_t *return_addr, int flags);
336 int translate_v2p_generic(struct cpu *cpu, uint64_t vaddr,
337 uint64_t *return_addr, int flags);
338
339
340 /* Dyntrans unaligned load/store: */
341 void mips_unaligned_loadstore(struct cpu *cpu, struct mips_instr_call *ic,
342 int is_left, int wlen, int store);
343
344
345 int mips_run_instr(struct cpu *cpu);
346 void mips_timer_sample_tick(struct timer *, void *);
347 void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
348 unsigned char *host_page, int writeflag, uint64_t paddr_page);
349 void mips_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
350 void mips_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
351 int mips32_run_instr(struct cpu *cpu);
352 void mips32_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
353 unsigned char *host_page, int writeflag, uint64_t paddr_page);
354 void mips32_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
355 void mips32_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
356
357
358 #endif /* CPU_MIPS_H */

  ViewVC Help
Powered by ViewVC 1.1.26