--- trunk/src/include/cpu.h 2007/10/08 16:20:32 29 +++ trunk/src/include/cpu.h 2007/10/08 16:20:40 30 @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * - * $Id: cpu.h,v 1.84 2006/07/20 21:53:00 debug Exp $ + * $Id: cpu.h,v 1.90 2006/08/12 11:43:13 debug Exp $ * * CPU-related definitions. */ @@ -59,9 +59,6 @@ * (several pages can be in the same chain, but only one matches the * specific physaddr.) * - * flags contains special flags. Currently only COMBINATIONS, which indicates - * that the page has instruction combinations. - * * 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. @@ -77,7 +74,6 @@ struct arch ## _instr_call ics[ARCH ## _IC_ENTRIES_PER_PAGE+2];\ uint32_t next_ofs; /* (0 for end of chain) */ \ uint32_t translations; \ - int flags; \ addrtype physaddr; \ }; \ \ @@ -87,7 +83,6 @@ addrtype vaddr_page; \ addrtype paddr_page; \ unsigned char *host_page; \ - int64_t timestamp; \ }; #define DYNTRANS_MISC64_DECLARATIONS(arch,ARCH,tlbindextype) \ @@ -216,34 +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); + + /* 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); }; @@ -254,20 +284,17 @@ * into the cache, for possible translation cache structs for physical pages. */ -/* Physpage flags: */ -#define COMBINATIONS 1 - /* 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 (32*1048576) -#define DYNTRANS_CACHE_MARGIN 350000 +#define DYNTRANS_CACHE_SIZE (24*1048576) +#define DYNTRANS_CACHE_MARGIN 300000 #define N_BASE_TABLE_ENTRIES 32768 #define PAGENR_TO_TABLE_INDEX(a) ((a) & (N_BASE_TABLE_ENTRIES-1)) @@ -281,14 +308,22 @@ /* 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); @@ -309,23 +344,47 @@ 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;