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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (show annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 16509 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


1 #ifndef CPU_H
2 #define CPU_H
3
4 /*
5 * Copyright (C) 2005-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.h,v 1.114 2007/04/10 17:26:20 debug Exp $
32 *
33 * CPU-related definitions.
34 */
35
36
37 #include <sys/types.h>
38 #include <inttypes.h>
39 #include <sys/time.h>
40
41 /* This is needed for undefining 'mips', 'ppc' etc. on weird systems: */
42 #include "../../config.h"
43
44 /*
45 * Dyntrans misc declarations, used throughout the dyntrans code.
46 *
47 * Note that there is place for all instruction calls within a page,
48 * and then 2 more. The first one of these "extra" instruction slots is
49 * the end-of-page slot. It transfers control to the first instruction
50 * slot on the next (virtual) page.
51 *
52 * The second of these extra instruction slots is an additional
53 * end-of-page slot for delay-slot architectures. On e.g. MIPS, a branch
54 * instruction can "nullify" (skip) the delay-slot. If the end-of-page
55 * slot is skipped, then we end up one step after that. That's where the
56 * end_of_page2 slot is. :)
57 *
58 * next_ofs points to the next page in a chain of possible pages.
59 * (several pages can be in the same chain, but only one matches the
60 * specific physaddr.)
61 *
62 * translations is a tiny bitmap indicating which parts of the page have
63 * actual translations. Bit 0 corresponds to the lowest 1/32th of the page,
64 * bit 1 to the second-lowest 1/32th, and so on.
65 */
66 #define DYNTRANS_MISC_DECLARATIONS(arch,ARCH,addrtype) struct \
67 arch ## _instr_call { \
68 void (*f)(struct cpu *, struct arch ## _instr_call *); \
69 size_t arg[ARCH ## _N_IC_ARGS]; \
70 }; \
71 \
72 /* Translation cache struct for each physical page: */ \
73 struct arch ## _tc_physpage { \
74 struct arch ## _instr_call ics[ARCH ## _IC_ENTRIES_PER_PAGE+2];\
75 uint32_t next_ofs; /* (0 for end of chain) */ \
76 uint32_t translations; \
77 addrtype physaddr; \
78 }; \
79 \
80 struct arch ## _vpg_tlb_entry { \
81 uint8_t valid; \
82 uint8_t writeflag; \
83 addrtype vaddr_page; \
84 addrtype paddr_page; \
85 unsigned char *host_page; \
86 };
87
88 #define DYNTRANS_MISC64_DECLARATIONS(arch,ARCH,tlbindextype) \
89 struct arch ## _l3_64_table { \
90 unsigned char *host_load[1 << ARCH ## _L3N]; \
91 unsigned char *host_store[1 << ARCH ## _L3N]; \
92 uint64_t phys_addr[1 << ARCH ## _L3N]; \
93 tlbindextype vaddr_to_tlbindex[1 << ARCH ## _L3N]; \
94 struct arch ## _tc_physpage *phys_page[1 << ARCH ## _L3N]; \
95 struct arch ## _l3_64_table *next; \
96 int refcount; \
97 }; \
98 struct arch ## _l2_64_table { \
99 struct arch ## _l3_64_table *l3[1 << ARCH ## _L2N]; \
100 struct arch ## _l2_64_table *next; \
101 int refcount; \
102 };
103
104 /*
105 * Dyntrans "Instruction Translation Cache":
106 *
107 * cur_physpage is a pointer to the current physpage. (It _HAPPENS_ to
108 * be the same as cur_ic_page, because all the instrcalls should be placed
109 * first in the physpage struct!)
110 *
111 * cur_ic_page is a pointer to an array of xxx_IC_ENTRIES_PER_PAGE
112 * instruction call entries.
113 *
114 * next_ic points to the next such instruction call to be executed.
115 *
116 * combination_check, when set to non-NULL, is executed automatically after
117 * an instruction has been translated. (It check for combinations of
118 * instructions; low_addr is the offset of the translated instruction in the
119 * current page, NOT shifted right.)
120 */
121 #define DYNTRANS_ITC(arch) struct arch ## _tc_physpage *cur_physpage; \
122 struct arch ## _instr_call *cur_ic_page; \
123 struct arch ## _instr_call *next_ic; \
124 struct arch ## _tc_physpage *physpage_template;\
125 void (*combination_check)(struct cpu *, \
126 struct arch ## _instr_call *, int low_addr);
127
128 /*
129 * Virtual -> physical -> host address translation TLB entries:
130 * ------------------------------------------------------------
131 *
132 * Regardless of whether 32-bit or 64-bit address translation is used, the
133 * same TLB entry structure is used.
134 */
135 #define VPH_TLBS(arch,ARCH) \
136 struct arch ## _vpg_tlb_entry \
137 vph_tlb_entry[ARCH ## _MAX_VPH_TLB_ENTRIES];
138
139 /*
140 * 32-bit dyntrans emulated Virtual -> physical -> host address translation:
141 * -------------------------------------------------------------------------
142 *
143 * This stuff assumes that 4 KB pages are used. 20 bits to select a page
144 * means just 1 M entries needed. This is small enough that a couple of
145 * full-size tables can fit in virtual memory on modern hosts (both 32-bit
146 * and 64-bit hosts). :-)
147 *
148 * Usage: e.g. VPH32(arm,ARM,uint32_t,uint8_t)
149 * or VPH32(sparc,SPARC,uint64_t,uint16_t)
150 *
151 * The vph_tlb_entry entries are cpu dependent tlb entries.
152 *
153 * The host_load and host_store entries point to host pages; the phys_addr
154 * entries are uint32_t or uint64_t (emulated physical addresses).
155 *
156 * phys_page points to translation cache physpages.
157 *
158 * vaddr_to_tlbindex is a virtual address to tlb index hint table.
159 * The values in this array are the tlb index plus 1, so a value of, say,
160 * 3 means tlb index 2. A value of 0 would mean a tlb index of -1, which
161 * is not a valid index. (I.e. no hit.)
162 */
163 #define N_VPH32_ENTRIES 1048576
164 #define VPH32(arch,ARCH,paddrtype,tlbindextype) \
165 unsigned char *host_load[N_VPH32_ENTRIES]; \
166 unsigned char *host_store[N_VPH32_ENTRIES]; \
167 paddrtype phys_addr[N_VPH32_ENTRIES]; \
168 struct arch ## _tc_physpage *phys_page[N_VPH32_ENTRIES]; \
169 tlbindextype vaddr_to_tlbindex[N_VPH32_ENTRIES];
170
171 /*
172 * 64-bit dyntrans emulated Virtual -> physical -> host address translation:
173 * -------------------------------------------------------------------------
174 *
175 * Usage: e.g. VPH64(alpha,ALPHA,uint8_t)
176 * or VPH64(sparc,SPARC,uint16_t)
177 *
178 * l1_64 is an array containing poiners to l2 tables.
179 *
180 * l2_64_dummy is a pointer to a "dummy l2 table". Instead of having NULL
181 * pointers in l1_64 for unused slots, a pointer to the dummy table can be
182 * used.
183 */
184 #define DYNTRANS_L1N 17
185 #define VPH64(arch,ARCH,tlbindextype) \
186 struct arch ## _l3_64_table *l3_64_dummy; \
187 struct arch ## _l3_64_table *next_free_l3; \
188 struct arch ## _l2_64_table *l2_64_dummy; \
189 struct arch ## _l2_64_table *next_free_l2; \
190 struct arch ## _l2_64_table *l1_64[1 << DYNTRANS_L1N];
191
192
193 /* Include all CPUs' header files here: */
194 #include "cpu_alpha.h"
195 #include "cpu_arm.h"
196 #include "cpu_avr.h"
197 #include "cpu_m68k.h"
198 #include "cpu_mips.h"
199 #include "cpu_ppc.h"
200 #include "cpu_sh.h"
201 #include "cpu_sparc.h"
202
203 struct cpu;
204 struct emul;
205 struct machine;
206 struct memory;
207 struct settings;
208
209
210 /*
211 * cpu_family
212 * ----------
213 *
214 * This structure consists of various pointers to functions, performing
215 * architecture-specific functions.
216 *
217 * Except for the next and arch fields at the top, all fields in the
218 * cpu_family struct are filled in by ecah CPU family's init function.
219 */
220 struct cpu_family {
221 struct cpu_family *next;
222 int arch;
223
224 /* Familty name, e.g. "MIPS", "Alpha" etc. */
225 char *name;
226
227 /* Fill in architecture specific parts of a struct cpu. */
228 int (*cpu_new)(struct cpu *cpu, struct memory *mem,
229 struct machine *machine,
230 int cpu_id, char *cpu_type_name);
231
232 /* Initialize various translation tables. */
233 void (*init_tables)(struct cpu *cpu);
234
235 /* List available CPU types for this architecture. */
236 void (*list_available_types)(void);
237
238 /* Disassemble an instruction. */
239 int (*disassemble_instr)(struct cpu *cpu,
240 unsigned char *instr, int running,
241 uint64_t dumpaddr);
242
243 /* Dump CPU registers in readable format. */
244 void (*register_dump)(struct cpu *cpu,
245 int gprs, int coprocs);
246
247 /* Dump generic CPU info in readable format. */
248 void (*dumpinfo)(struct cpu *cpu);
249
250 /* Dump TLB data for CPU id x. */
251 void (*tlbdump)(struct machine *m, int x,
252 int rawflag);
253
254 /* Print architecture-specific function call arguments.
255 (This is called for each function call, if running with -t.) */
256 void (*functioncall_trace)(struct cpu *,
257 uint64_t f, int n_args);
258 };
259
260
261 /*
262 * More dyntrans stuff:
263 *
264 * The translation cache begins with N_BASE_TABLE_ENTRIES uint32_t offsets
265 * into the cache, for possible translation cache structs for physical pages.
266 */
267
268 /* Meaning of delay_slot: */
269 #define NOT_DELAYED 0
270 #define DELAYED 1
271 #define TO_BE_DELAYED 2
272 #define EXCEPTION_IN_DELAY_SLOT 8
273
274 #define N_SAFE_DYNTRANS_LIMIT_SHIFT 14
275 #define N_SAFE_DYNTRANS_LIMIT ((1 << (N_SAFE_DYNTRANS_LIMIT_SHIFT - 1)) - 1)
276
277 #define DEFAULT_DYNTRANS_CACHE_SIZE (40*1048576)
278 #define DYNTRANS_CACHE_MARGIN 200000
279
280 #define N_BASE_TABLE_ENTRIES 65536
281 #define PAGENR_TO_TABLE_INDEX(a) ((a) & (N_BASE_TABLE_ENTRIES-1))
282
283
284 #ifdef NATIVE_CODE_GENERATION
285 /*
286 * Intermediate Native Representation (INR).
287 * Used for native code generation.
288 */
289 #include "inr.h"
290 #endif
291
292
293 /*
294 * The generic CPU struct:
295 */
296
297 struct cpu {
298 /* Pointer back to the machine this CPU is in: */
299 struct machine *machine;
300
301 /* Settings: */
302 struct settings *settings;
303
304 /* CPU-specific name, e.g. "R2000", "21164PC", etc. */
305 char *name;
306
307 /* Full "path" to the CPU, e.g. "emul[0].machine[0].cpu[0]": */
308 char *path;
309
310 /* EMUL_LITTLE_ENDIAN or EMUL_BIG_ENDIAN. */
311 int byte_order;
312
313 /* 0-based CPU id, in an emulated SMP system. */
314 int cpu_id;
315
316 /* 0 for emulated 64-bit CPUs, 1 for 32-bit. */
317 int is_32bit;
318
319 /* 1 while running, 0 when paused/stopped. */
320 int running;
321
322 /* A pointer to the main memory connected to this CPU. */
323 struct memory *mem;
324
325 int (*run_instr)(struct cpu *cpu);
326 int (*memory_rw)(struct cpu *cpu,
327 struct memory *mem, uint64_t vaddr,
328 unsigned char *data, size_t len,
329 int writeflag, int cache_flags);
330 int (*translate_v2p)(struct cpu *, uint64_t vaddr,
331 uint64_t *return_paddr, int flags);
332 void (*update_translation_table)(struct cpu *,
333 uint64_t vaddr_page, unsigned char *host_page,
334 int writeflag, uint64_t paddr_page);
335 void (*invalidate_translation_caches)(struct cpu *,
336 uint64_t paddr, int flags);
337 void (*invalidate_code_translation)(struct cpu *,
338 uint64_t paddr, int flags);
339 void (*useremul_syscall)(struct cpu *cpu, uint32_t code);
340 int (*instruction_has_delayslot)(struct cpu *cpu,
341 unsigned char *ib);
342
343 /* The program counter. (For 32-bit modes, not all bits are used.) */
344 uint64_t pc;
345
346 /* See comment further up. */
347 int delay_slot;
348
349 /* The current depth of function call tracing. */
350 int trace_tree_depth;
351
352 /*
353 * If is_halted is true when an interrupt trap occurs, the pointer
354 * to the next instruction to execute will be the instruction
355 * following the halt instruction, not the halt instrucion itself.
356 *
357 * If has_been_idling is true when printing the number of executed
358 * instructions per second, "idling" is printed instead. (The number
359 * of instrs per second when idling is meaningless anyway.)
360 */
361 int is_halted;
362 int has_been_idling;
363
364 /*
365 * Dynamic translation:
366 *
367 * The number of translated instructions is assumed to be 1 per
368 * instruction call. For each case where this differs from the
369 * truth, n_translated_instrs should be modified. E.g. if 1000
370 * instruction calls are done, and n_translated_instrs is 50, then
371 * 1050 emulated instructions were actually executed.
372 *
373 * Note that it can also be adjusted negatively, that is, the way
374 * to "get out" of a dyntrans loop is to set the current instruction
375 * call pointer to the "nothing" instruction. This instruction
376 * _decreases_ n_translated_instrs by 1. That way, once the dyntrans
377 * loop exits, only real instructions will be counted, and not the
378 * "nothing" instructions.
379 *
380 * The translation cache is a relative large chunk of memory (say,
381 * 32 MB) which is used for translations. When it has been used up,
382 * everything restarts from scratch.
383 *
384 * The INR struct contains the Intermediate Native Representation,
385 * used during native code generation.
386 */
387 int n_translated_instrs;
388 unsigned char *translation_cache;
389 size_t translation_cache_cur_ofs;
390
391 #ifdef NATIVE_CODE_GENERATION
392 struct inr inr;
393 #endif
394
395 /*
396 * CPU-family dependent:
397 *
398 * These contain everything ranging from registers, memory management,
399 * status words, etc.
400 */
401 union {
402 struct alpha_cpu alpha;
403 struct arm_cpu arm;
404 struct avr_cpu avr;
405 struct m68k_cpu m68k;
406 struct mips_cpu mips;
407 struct ppc_cpu ppc;
408 struct sh_cpu sh;
409 struct sparc_cpu sparc;
410 } cd;
411 };
412
413
414 /* cpu.c: */
415 struct cpu *cpu_new(struct memory *mem, struct machine *machine,
416 int cpu_id, char *cpu_type_name);
417 void cpu_destroy(struct cpu *cpu);
418
419 void cpu_tlbdump(struct machine *m, int x, int rawflag);
420 void cpu_register_dump(struct machine *m, struct cpu *cpu,
421 int gprs, int coprocs);
422 int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
423 unsigned char *instr, int running, uint64_t addr);
424
425 void cpu_functioncall_trace(struct cpu *cpu, uint64_t f);
426 void cpu_functioncall_trace_return(struct cpu *cpu);
427
428 void cpu_create_or_reset_tc(struct cpu *cpu);
429
430 void cpu_run_init(struct machine *machine);
431 void cpu_run_deinit(struct machine *machine);
432
433 void cpu_dumpinfo(struct machine *m, struct cpu *cpu);
434 void cpu_list_available_types(void);
435 void cpu_show_cycles(struct machine *machine, int forced);
436
437 struct cpu_family *cpu_family_ptr_by_number(int arch);
438 void cpu_init(void);
439
440
441 #define JUST_MARK_AS_NON_WRITABLE 1
442 #define INVALIDATE_ALL 2
443 #define INVALIDATE_PADDR 4
444 #define INVALIDATE_VADDR 8
445 #define INVALIDATE_VADDR_UPPER4 16 /* useful for PPC emulation */
446
447
448 /* Note: 64-bit processors running in 32-bit mode use a 32-bit
449 display format, even though the underlying data is 64-bits. */
450 #define CPU_SETTINGS_ADD_REGISTER64(name, var) \
451 settings_add(cpu->settings, name, 1, SETTINGS_TYPE_UINT64, \
452 cpu->is_32bit? SETTINGS_FORMAT_HEX32 : SETTINGS_FORMAT_HEX64, \
453 (void *) &(var));
454 #define CPU_SETTINGS_ADD_REGISTER32(name, var) \
455 settings_add(cpu->settings, name, 1, SETTINGS_TYPE_UINT32, \
456 SETTINGS_FORMAT_HEX32, (void *) &(var));
457 #define CPU_SETTINGS_ADD_REGISTER16(name, var) \
458 settings_add(cpu->settings, name, 1, SETTINGS_TYPE_UINT16, \
459 SETTINGS_FORMAT_HEX16, (void *) &(var));
460 #define CPU_SETTINGS_ADD_REGISTER8(name, var) \
461 settings_add(cpu->settings, name, 1, SETTINGS_TYPE_UINT8, \
462 SETTINGS_FORMAT_HEX8, (void *) &(var));
463
464
465 #define CPU_FAMILY_INIT(n,s) int n ## _cpu_family_init( \
466 struct cpu_family *fp) { \
467 /* Fill in the cpu_family struct with valid data for this arch. */ \
468 fp->name = s; \
469 fp->cpu_new = n ## _cpu_new; \
470 fp->list_available_types = n ## _cpu_list_available_types; \
471 fp->disassemble_instr = n ## _cpu_disassemble_instr; \
472 fp->register_dump = n ## _cpu_register_dump; \
473 fp->dumpinfo = n ## _cpu_dumpinfo; \
474 fp->functioncall_trace = n ## _cpu_functioncall_trace; \
475 fp->tlbdump = n ## _cpu_tlbdump; \
476 fp->init_tables = n ## _cpu_init_tables; \
477 return 1; \
478 }
479
480
481 #endif /* CPU_H */

  ViewVC Help
Powered by ViewVC 1.1.26