/[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 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 15914 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 0.4.2  ==============


1 #ifndef CPU_H
2 #define CPU_H
3
4 /*
5 * Copyright (C) 2005-2006 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.90 2006/08/12 11:43:13 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_hppa.h"
198 #include "cpu_i960.h"
199 #include "cpu_ia64.h"
200 #include "cpu_m68k.h"
201 #include "cpu_mips.h"
202 #include "cpu_ppc.h"
203 #include "cpu_sh.h"
204 #include "cpu_sparc.h"
205 #include "cpu_transputer.h"
206 #include "cpu_x86.h"
207
208 struct cpu;
209 struct emul;
210 struct machine;
211 struct memory;
212
213
214 /*
215 * cpu_family
216 * ----------
217 *
218 * This structure consists of various pointers to functions, performing
219 * architecture-specific functions.
220 *
221 * Except for the next and arch fields at the top, all fields in the
222 * cpu_family struct are filled in by ecah CPU family's init function.
223 */
224 struct cpu_family {
225 struct cpu_family *next;
226 int arch;
227
228 /* Familty name, e.g. "MIPS", "Alpha" etc. */
229 char *name;
230
231 /* Fill in architecture specific parts of a struct cpu. */
232 int (*cpu_new)(struct cpu *cpu, struct memory *mem,
233 struct machine *machine,
234 int cpu_id, char *cpu_type_name);
235
236 /* Initialize various translation tables. */
237 void (*init_tables)(struct cpu *cpu);
238
239 /* List available CPU types for this architecture. */
240 void (*list_available_types)(void);
241
242 /* Read or write a CPU register, given a name. */
243 void (*register_match)(struct machine *m,
244 char *name, int writeflag,
245 uint64_t *valuep, int *match_register);
246
247 /* Disassemble an instruction. */
248 int (*disassemble_instr)(struct cpu *cpu,
249 unsigned char *instr, int running,
250 uint64_t dumpaddr);
251
252 /* Dump CPU registers in readable format. */
253 void (*register_dump)(struct cpu *cpu,
254 int gprs, int coprocs);
255
256 /* Dump generic CPU info in readable format. */
257 void (*dumpinfo)(struct cpu *cpu);
258
259 /* Dump TLB data for CPU id x. */
260 void (*tlbdump)(struct machine *m, int x,
261 int rawflag);
262
263 /* Assert an interrupt. */
264 int (*interrupt)(struct cpu *cpu, uint64_t irq_nr);
265
266 /* De-assert an interrupt. */
267 int (*interrupt_ack)(struct cpu *cpu,
268 uint64_t irq_nr);
269
270 /* Print architecture-specific function call arguments.
271 (This is called for each function call, if running with -t.) */
272 void (*functioncall_trace)(struct cpu *,
273 uint64_t f, int n_args);
274
275 /* GDB command handler. */
276 char *(*gdb_stub)(struct cpu *, char *cmd);
277 };
278
279
280 /*
281 * More dyntrans stuff:
282 *
283 * The translation cache begins with N_BASE_TABLE_ENTRIES uint32_t offsets
284 * into the cache, for possible translation cache structs for physical pages.
285 */
286
287 /* Meaning of delay_slot: */
288 #define NOT_DELAYED 0
289 #define DELAYED 1
290 #define TO_BE_DELAYED 2
291 #define EXCEPTION_IN_DELAY_SLOT 8
292
293 #define N_SAFE_DYNTRANS_LIMIT_SHIFT 14
294 #define N_SAFE_DYNTRANS_LIMIT ((1 << (N_SAFE_DYNTRANS_LIMIT_SHIFT - 1)) - 1)
295
296 #define DYNTRANS_CACHE_SIZE (24*1048576)
297 #define DYNTRANS_CACHE_MARGIN 300000
298
299 #define N_BASE_TABLE_ENTRIES 32768
300 #define PAGENR_TO_TABLE_INDEX(a) ((a) & (N_BASE_TABLE_ENTRIES-1))
301
302
303 /*
304 * The generic CPU struct:
305 */
306
307 struct cpu {
308 /* Pointer back to the machine this CPU is in: */
309 struct machine *machine;
310
311 /* CPU-specific name, e.g. "R2000", "21164PC", etc. */
312 char *name;
313
314 /* EMUL_LITTLE_ENDIAN or EMUL_BIG_ENDIAN. */
315 int byte_order;
316
317 /* 0-based CPU id, in an emulated SMP system. */
318 int cpu_id;
319
320 /* 0 for emulated 64-bit CPUs, 1 for 32-bit. */
321 int is_32bit;
322
323 /* 1 while running, 0 when paused/stopped. */
324 int running;
325
326 /* A pointer to the main memory connected to this CPU. */
327 struct memory *mem;
328
329 int (*run_instr)(struct cpu *cpu);
330 int (*memory_rw)(struct cpu *cpu,
331 struct memory *mem, uint64_t vaddr,
332 unsigned char *data, size_t len,
333 int writeflag, int cache_flags);
334 int (*translate_v2p)(struct cpu *, uint64_t vaddr,
335 uint64_t *return_paddr, int flags);
336 void (*update_translation_table)(struct cpu *,
337 uint64_t vaddr_page, unsigned char *host_page,
338 int writeflag, uint64_t paddr_page);
339 void (*invalidate_translation_caches)(struct cpu *,
340 uint64_t paddr, int flags);
341 void (*invalidate_code_translation)(struct cpu *,
342 uint64_t paddr, int flags);
343 void (*useremul_syscall)(struct cpu *cpu, uint32_t code);
344 int (*instruction_has_delayslot)(struct cpu *cpu,
345 unsigned char *ib);
346
347 /* The program counter. (For 32-bit modes, not all bits are used.) */
348 uint64_t pc;
349
350 /* See comment further up. */
351 int delay_slot;
352
353 /* The current depth of function call tracing. */
354 int trace_tree_depth;
355
356 /*
357 * If is_halted is true when an interrupt trap occurs, the pointer
358 * to the next instruction to execute will be the instruction
359 * following the halt instruction, not the halt instrucion itself.
360 */
361 int is_halted;
362
363 /*
364 * Dynamic translation:
365 *
366 * The number of translated instructions is assumed to be 1 per
367 * instruction call. For each case where this differs from the
368 * truth, n_translated_instrs should be modified. E.g. if 1000
369 * instruction calls are done, and n_translated_instrs is 50, then
370 * 1050 emulated instructions were actually executed.
371 *
372 * Note that it can also be adjusted negatively, that is, the way
373 * to "get out" of a dyntrans loop is to set the current instruction
374 * call pointer to the "nothing" instruction. This instruction
375 * _decreases_ n_translated_instrs. That way, once the dyntrans loop
376 * exits, only real instructions will be counted, and not the
377 * "nothing" instructions.
378 */
379 int n_translated_instrs;
380 unsigned char *translation_cache;
381 size_t translation_cache_cur_ofs;
382
383 /*
384 * CPU-family dependent:
385 *
386 * These contain everything ranging from registers, memory management,
387 * status words, etc.
388 */
389 union {
390 struct alpha_cpu alpha;
391 struct arm_cpu arm;
392 struct avr_cpu avr;
393 struct hppa_cpu hppa;
394 struct i960_cpu i960;
395 struct ia64_cpu ia64;
396 struct m68k_cpu m68k;
397 struct mips_cpu mips;
398 struct ppc_cpu ppc;
399 struct sh_cpu sh;
400 struct sparc_cpu sparc;
401 struct transputer_cpu transputer;
402 struct x86_cpu x86;
403 } cd;
404 };
405
406
407 /* cpu.c: */
408 struct cpu *cpu_new(struct memory *mem, struct machine *machine,
409 int cpu_id, char *cpu_type_name);
410 void cpu_tlbdump(struct machine *m, int x, int rawflag);
411 void cpu_register_match(struct machine *m, char *name,
412 int writeflag, uint64_t *valuep, int *match_register);
413 void cpu_register_dump(struct machine *m, struct cpu *cpu,
414 int gprs, int coprocs);
415 int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
416 unsigned char *instr, int running, uint64_t addr);
417 char *cpu_gdb_stub(struct cpu *cpu, char *cmd);
418 int cpu_interrupt(struct cpu *cpu, uint64_t irq_nr);
419 int cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr);
420 void cpu_functioncall_trace(struct cpu *cpu, uint64_t f);
421 void cpu_functioncall_trace_return(struct cpu *cpu);
422 void cpu_create_or_reset_tc(struct cpu *cpu);
423 void cpu_run_init(struct machine *machine);
424 void cpu_run_deinit(struct machine *machine);
425 void cpu_dumpinfo(struct machine *m, struct cpu *cpu);
426 void cpu_list_available_types(void);
427 void cpu_show_cycles(struct machine *machine, int forced);
428 struct cpu_family *cpu_family_ptr_by_number(int arch);
429 void cpu_init(void);
430
431
432 #define JUST_MARK_AS_NON_WRITABLE 1
433 #define INVALIDATE_ALL 2
434 #define INVALIDATE_PADDR 4
435 #define INVALIDATE_VADDR 8
436 #define INVALIDATE_VADDR_UPPER4 16 /* useful for PPC emulation */
437
438
439 #define CPU_FAMILY_INIT(n,s) int n ## _cpu_family_init( \
440 struct cpu_family *fp) { \
441 /* Fill in the cpu_family struct with valid data for this arch. */ \
442 fp->name = s; \
443 fp->cpu_new = n ## _cpu_new; \
444 fp->list_available_types = n ## _cpu_list_available_types; \
445 fp->register_match = n ## _cpu_register_match; \
446 fp->disassemble_instr = n ## _cpu_disassemble_instr; \
447 fp->register_dump = n ## _cpu_register_dump; \
448 fp->dumpinfo = n ## _cpu_dumpinfo; \
449 fp->interrupt = n ## _cpu_interrupt; \
450 fp->interrupt_ack = n ## _cpu_interrupt_ack; \
451 fp->functioncall_trace = n ## _cpu_functioncall_trace; \
452 fp->gdb_stub = n ## _cpu_gdb_stub; \
453 fp->tlbdump = n ## _cpu_tlbdump; \
454 fp->init_tables = n ## _cpu_init_tables; \
455 return 1; \
456 }
457
458
459 #endif /* CPU_H */

  ViewVC Help
Powered by ViewVC 1.1.26