--- trunk/src/include/cpu.h 2007/10/08 16:20:10 26 +++ trunk/src/include/cpu.h 2007/10/08 16:20:40 30 @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * - * $Id: cpu.h,v 1.79 2006/06/25 00:27:36 debug Exp $ + * $Id: cpu.h,v 1.90 2006/08/12 11:43:13 debug Exp $ * * CPU-related definitions. */ @@ -54,6 +54,14 @@ * instruction can "nullify" (skip) the delay-slot. If the end-of-page * slot is skipped, then we end up one step after that. That's where the * end_of_page2 slot is. :) + * + * next_ofs points to the next page in a chain of possible pages. + * (several pages can be in the same chain, but only one matches the + * specific physaddr.) + * + * translations is a tiny bitmap indicating which parts of the page have + * actual translations. Bit 0 corresponds to the lowest 1/32th of the page, + * bit 1 to the second-lowest 1/32th, and so on. */ #define DYNTRANS_MISC_DECLARATIONS(arch,ARCH,addrtype) struct \ arch ## _instr_call { \ @@ -65,7 +73,7 @@ struct arch ## _tc_physpage { \ struct arch ## _instr_call ics[ARCH ## _IC_ENTRIES_PER_PAGE+2];\ uint32_t next_ofs; /* (0 for end of chain) */ \ - int flags; \ + uint32_t translations; \ addrtype physaddr; \ }; \ \ @@ -75,7 +83,6 @@ addrtype vaddr_page; \ addrtype paddr_page; \ unsigned char *host_page; \ - int64_t timestamp; \ }; #define DYNTRANS_MISC64_DECLARATIONS(arch,ARCH,tlbindextype) \ @@ -148,9 +155,6 @@ * * phys_page points to translation cache physpages. * - * phystranslation is a bitmap which tells us whether a physical page has - * a code translation. - * * vaddr_to_tlbindex is a virtual address to tlb index hint table. * The values in this array are the tlb index plus 1, so a value of, say, * 3 means tlb index 2. A value of 0 would mean a tlb index of -1, which @@ -162,7 +166,6 @@ unsigned char *host_store[N_VPH32_ENTRIES]; \ paddrtype phys_addr[N_VPH32_ENTRIES]; \ struct arch ## _tc_physpage *phys_page[N_VPH32_ENTRIES]; \ - uint32_t phystranslation[N_VPH32_ENTRIES/32]; \ tlbindextype vaddr_to_tlbindex[N_VPH32_ENTRIES]; /* @@ -199,6 +202,7 @@ #include "cpu_ppc.h" #include "cpu_sh.h" #include "cpu_sparc.h" +#include "cpu_transputer.h" #include "cpu_x86.h" struct cpu; @@ -207,36 +211,69 @@ struct memory; +/* + * cpu_family + * ---------- + * + * This structure consists of various pointers to functions, performing + * architecture-specific functions. + * + * Except for the next and arch fields at the top, all fields in the + * cpu_family struct are filled in by ecah CPU family's init function. + */ struct cpu_family { struct cpu_family *next; int arch; - /* These are filled in by each CPU family's init function: */ + /* Familty name, e.g. "MIPS", "Alpha" etc. */ char *name; + + /* Fill in architecture specific parts of a struct cpu. */ int (*cpu_new)(struct cpu *cpu, struct memory *mem, struct machine *machine, int cpu_id, char *cpu_type_name); + + /* Initialize various translation tables. */ + void (*init_tables)(struct cpu *cpu); + + /* List available CPU types for this architecture. */ void (*list_available_types)(void); + + /* Read or write a CPU register, given a name. */ void (*register_match)(struct machine *m, char *name, int writeflag, uint64_t *valuep, int *match_register); + + /* Disassemble an instruction. */ int (*disassemble_instr)(struct cpu *cpu, unsigned char *instr, int running, uint64_t dumpaddr); + + /* Dump CPU registers in readable format. */ void (*register_dump)(struct cpu *cpu, int gprs, int coprocs); - int (*run_instr)(struct emul *emul, - struct cpu *cpu); + + /* Dump generic CPU info in readable format. */ void (*dumpinfo)(struct cpu *cpu); + + /* Dump TLB data for CPU id x. */ void (*tlbdump)(struct machine *m, int x, int rawflag); + + /* Assert an interrupt. */ int (*interrupt)(struct cpu *cpu, uint64_t irq_nr); + + /* De-assert an interrupt. */ int (*interrupt_ack)(struct cpu *cpu, uint64_t irq_nr); + + /* Print architecture-specific function call arguments. + (This is called for each function call, if running with -t.) */ void (*functioncall_trace)(struct cpu *, uint64_t f, int n_args); + + /* GDB command handler. */ char *(*gdb_stub)(struct cpu *, char *cmd); - void (*init_tables)(struct cpu *cpu); }; @@ -247,21 +284,17 @@ * into the cache, for possible translation cache structs for physical pages. */ -/* Physpage flags: */ -#define TRANSLATIONS 1 -#define COMBINATIONS 2 - /* Meaning of delay_slot: */ #define NOT_DELAYED 0 #define DELAYED 1 #define TO_BE_DELAYED 2 -#define EXCEPTION_IN_DELAY_SLOT 0x100 +#define EXCEPTION_IN_DELAY_SLOT 8 #define N_SAFE_DYNTRANS_LIMIT_SHIFT 14 #define N_SAFE_DYNTRANS_LIMIT ((1 << (N_SAFE_DYNTRANS_LIMIT_SHIFT - 1)) - 1) #define DYNTRANS_CACHE_SIZE (24*1048576) -#define DYNTRANS_CACHE_MARGIN 350000 +#define DYNTRANS_CACHE_MARGIN 300000 #define N_BASE_TABLE_ENTRIES 32768 #define PAGENR_TO_TABLE_INDEX(a) ((a) & (N_BASE_TABLE_ENTRIES-1)) @@ -275,15 +308,25 @@ /* Pointer back to the machine this CPU is in: */ struct machine *machine; + /* CPU-specific name, e.g. "R2000", "21164PC", etc. */ + char *name; + + /* EMUL_LITTLE_ENDIAN or EMUL_BIG_ENDIAN. */ int byte_order; - int running; - int dead; - int bootstrap_cpu_flag; + + /* 0-based CPU id, in an emulated SMP system. */ int cpu_id; - int is_32bit; /* 0 for 64-bit, 1 for 32-bit */ - char *name; + /* 0 for emulated 64-bit CPUs, 1 for 32-bit. */ + int is_32bit; + + /* 1 while running, 0 when paused/stopped. */ + int running; + + /* A pointer to the main memory connected to this CPU. */ struct memory *mem; + + int (*run_instr)(struct cpu *cpu); int (*memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, @@ -301,37 +344,62 @@ int (*instruction_has_delayslot)(struct cpu *cpu, unsigned char *ib); + /* The program counter. (For 32-bit modes, not all bits are used.) */ uint64_t pc; + /* See comment further up. */ + int delay_slot; + + /* The current depth of function call tracing. */ int trace_tree_depth; /* + * If is_halted is true when an interrupt trap occurs, the pointer + * to the next instruction to execute will be the instruction + * following the halt instruction, not the halt instrucion itself. + */ + int is_halted; + + /* * Dynamic translation: + * + * The number of translated instructions is assumed to be 1 per + * instruction call. For each case where this differs from the + * truth, n_translated_instrs should be modified. E.g. if 1000 + * instruction calls are done, and n_translated_instrs is 50, then + * 1050 emulated instructions were actually executed. + * + * Note that it can also be adjusted negatively, that is, the way + * to "get out" of a dyntrans loop is to set the current instruction + * call pointer to the "nothing" instruction. This instruction + * _decreases_ n_translated_instrs. That way, once the dyntrans loop + * exits, only real instructions will be counted, and not the + * "nothing" instructions. */ - int running_translated; int n_translated_instrs; unsigned char *translation_cache; size_t translation_cache_cur_ofs; - uint64_t delay_jmpaddr; /* only used if delay_slot > 0 */ - int delay_slot; - /* * CPU-family dependent: + * + * These contain everything ranging from registers, memory management, + * status words, etc. */ union { - struct alpha_cpu alpha; - struct arm_cpu arm; - struct avr_cpu avr; - struct hppa_cpu hppa; - struct i960_cpu i960; - struct ia64_cpu ia64; - struct m68k_cpu m68k; - struct mips_cpu mips; - struct ppc_cpu ppc; - struct sh_cpu sh; - struct sparc_cpu sparc; - struct x86_cpu x86; + struct alpha_cpu alpha; + struct arm_cpu arm; + struct avr_cpu avr; + struct hppa_cpu hppa; + struct i960_cpu i960; + struct ia64_cpu ia64; + struct m68k_cpu m68k; + struct mips_cpu mips; + struct ppc_cpu ppc; + struct sh_cpu sh; + struct sparc_cpu sparc; + struct transputer_cpu transputer; + struct x86_cpu x86; } cd; }; @@ -383,7 +451,6 @@ fp->functioncall_trace = n ## _cpu_functioncall_trace; \ fp->gdb_stub = n ## _cpu_gdb_stub; \ fp->tlbdump = n ## _cpu_tlbdump; \ - fp->run_instr = n ## _cpu_run_instr; \ fp->init_tables = n ## _cpu_init_tables; \ return 1; \ }