--- upstream/dynamips-0.2.6-RC2/mips64.h 2007/10/06 16:05:34 3 +++ upstream/dynamips-0.2.7-RC1/mips64.h 2007/10/06 16:23:47 7 @@ -1,5 +1,5 @@ /* - * Cisco 7200 (Predator) simulation platform. + * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) */ @@ -175,7 +175,8 @@ /* TLB masks and shifts */ #define MIPS_TLB_PAGE_MASK 0x01ffe000 #define MIPS_TLB_PAGE_SHIFT 13 -#define MIPS_TLB_VPN2_MASK 0xffffffffffffe000ULL +#define MIPS_TLB_VPN2_MASK_32 0xffffe000ULL +#define MIPS_TLB_VPN2_MASK_64 0xc00000ffffffe000ULL #define MIPS_TLB_PFN_MASK 0x3fffffc0 #define MIPS_TLB_ASID_MASK 0x000000ff /* "asid" in EntryHi */ #define MIPS_TLB_G_MASK 0x00001000 /* "Global" in EntryHi */ @@ -195,6 +196,7 @@ #define MIPS_MIN_PAGE_SHIFT 12 #define MIPS_MIN_PAGE_SIZE (1 << MIPS_MIN_PAGE_SHIFT) #define MIPS_MIN_PAGE_IMASK (MIPS_MIN_PAGE_SIZE - 1) +#define MIPS_MIN_PAGE_MASK 0xfffffffffffff000ULL /* Addressing mode: Kernel, Supervisor and User */ #define MIPS_MODE_KERNEL 00 @@ -231,11 +233,6 @@ #define MIPS64_XKPHYS_PHYS_MASK (MIPS64_XKPHYS_PHYS_SIZE - 1) #define MIPS64_XKPHYS_CCA_SHIFT 59 -/* Macros for CPU structure access */ -#define REG_OFFSET(reg) (OFFSET(cpu_mips_t,gpr[(reg)])) -#define CP0_REG_OFFSET(c0reg) (OFFSET(cpu_mips_t,cp0.reg[(c0reg)])) -#define MEMOP_OFFSET(op) (OFFSET(cpu_mips_t,mem_op_fn[(op)])) - /* Initial Program Counter and Stack pointer for ROM */ #define MIPS_ROM_PC 0xffffffffbfc00000ULL #define MIPS_ROM_SP 0xffffffff80004000ULL @@ -257,6 +254,9 @@ /* Enable the 64 TLB entries for R7000 CPU */ #define MIPS64_R7000_TLB64_ENABLE 0x20000000 +/* Number of instructions per page */ +#define MIPS_INSN_PER_PAGE (MIPS_MIN_PAGE_SIZE/sizeof(mips_insn_t)) + /* MIPS CPU Identifiers */ #define MIPS_PRID_R4600 0x00002012 #define MIPS_PRID_R4700 0x00002112 @@ -265,13 +265,6 @@ #define MIPS_PRID_R527x 0x00002812 #define MIPS_PRID_BCM1250 0x00040102 -/* Virtual CPU states */ -enum { - MIPS_CPU_RUNNING = 0, - MIPS_CPU_HALTED, - MIPS_CPU_SUSPENDED, -}; - /* Memory operations */ enum { MIPS_MEMOP_LOOKUP = 0, @@ -308,25 +301,9 @@ MIPS_MEMOP_MAX, }; -/* 6 bits are reserved for device ID (see the memory subsystem) */ -#define MIPS64_DEVICE_MAX (1 << 6) - -/* Number of recorded memory accesses (power of two) */ -#define MEMLOG_COUNT 16 - /* Maximum number of breakpoints */ #define MIPS64_MAX_BREAKPOINTS 8 -typedef struct memlog_access memlog_access_t; -struct memlog_access { - m_uint64_t pc; - m_uint64_t vaddr; - m_uint64_t data; - m_uint32_t data_valid; - m_uint32_t op_size; - m_uint32_t op_type; -}; - /* MIPS CPU type */ typedef struct cpu_mips cpu_mips_t; @@ -360,36 +337,13 @@ m_uint64_t reg[MIPS64_CP1_REG_NR]; }mips_cp1_t; -/* MTS64 entry */ -typedef struct mts64_entry mts64_entry_t; -struct mts64_entry { - m_uint64_t start; - m_iptr_t action; - m_uint32_t mask; - m_uint32_t phys_page; - mts64_entry_t **pself; - mts64_entry_t *next,**pprev; -}; - -/* MTS64 chunk forward declaration */ -typedef struct mts64_chunk mts64_chunk_t; - -/* Maximum results for idle pc */ -#define MIPS64_IDLE_PC_MAX_RES 10 - -/* Idle PC hash item */ -struct mips64_idle_pc { - m_uint64_t pc; - u_int count; -}; - /* MIPS CPU definition */ -struct cpu_mips { - /* MTS 1st level array */ - void *mts_l1_ptr; - - /* MTS64 cache */ - mts64_entry_t **mts64_cache; +struct cpu_mips { + /* MTS32/MTS64 caches */ + union { + mts32_entry_t *mts32_cache; + mts64_entry_t *mts64_cache; + }mts_u; /* Virtual version of CP0 Compare Register */ m_uint32_t cp0_virt_cnt_reg,cp0_virt_cmp_reg; @@ -400,7 +354,7 @@ m_uint64_t lo,hi,ret_pc; /* Code page translation cache */ - insn_block_t **exec_phys_map; + mips64_jit_tcb_t **exec_phys_map; /* Virtual address to physical page translation */ fastcall int (*translate)(cpu_mips_t *cpu,m_uint64_t vaddr, @@ -418,19 +372,15 @@ /* FPU (CP1) */ mips_cp1_t fpu; - /* MTS32 array free list */ - void *mts32_l2_free_list; - - /* Address bus mask */ + /* Address bus mask for physical addresses */ m_uint64_t addr_bus_mask; /* IRQ counters and cause */ m_uint64_t irq_count,timer_irq_count,irq_fp_count; pthread_mutex_t irq_lock; - /* Current and free lists of instruction blocks */ - insn_block_t *insn_block_list,*insn_block_last; - insn_block_t *insn_block_free_list; + /* Current and free lists of translated code blocks */ + mips64_jit_tcb_t *tcb_list,*tcb_last,*tcb_free_list; /* Executable page area */ void *exec_page_area; @@ -439,14 +389,8 @@ insn_exec_page_t *exec_page_free_list; insn_exec_page_t *exec_page_array; - /* "Idle" loop management */ + /* Idle PC value */ volatile m_uint64_t idle_pc; - u_int idle_count,idle_max,idle_sleep_time; - pthread_mutex_t idle_mutex; - pthread_cond_t idle_cond; - - /* IRQ disable flag */ - volatile u_int irq_disable; /* Timer IRQs */ volatile u_int timer_irq_pending; @@ -454,19 +398,14 @@ u_int timer_irq_check_itv; u_int timer_drift; + /* IRQ disable flag */ + volatile u_int irq_disable; + /* IRQ idling preemption */ u_int irq_idle_preempt[8]; - /* CPU identifier for MP systems */ - u_int id; - - /* CPU states */ - volatile u_int state,prev_state; - volatile m_uint64_t seq_state; - - /* Thread running this CPU */ - pthread_t cpu_thread; - int cpu_thread_running; + /* Generic CPU instance pointer */ + cpu_gen_t *gen; /* VM instance */ vm_instance_t *vm; @@ -482,18 +421,10 @@ void (*mts_unmap)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint32_t len, m_uint32_t val,int tlb_index); - void (*mts_rebuild)(cpu_mips_t *cpu); - - /* MTS64 chunk list */ - mts64_chunk_t *mts64_chunk_list; - mts64_chunk_t *mts64_chunk_free_list; - mts64_entry_t *mts64_entry_free_list; - - /* MTS64 cache statistics */ - m_uint64_t mts64_misses,mts64_lookups; + void (*mts_shutdown)(cpu_mips_t *cpu); - /* Reverse map for MTS64 */ - mts64_entry_t *mts64_rmap[MIPS64_TLB_MAX_ENTRIES]; + /* MTS cache statistics */ + m_uint64_t mts_misses,mts_lookups; /* JIT flush method */ u_int jit_flush_method; @@ -504,6 +435,9 @@ /* Fast memory operations use */ u_int fast_memop; + /* Address mode (32 or 64 bits) */ + u_int addr_mode; + /* Current exec page (non-JIT) info */ m_uint64_t njm_exec_page; mips_insn_t *njm_exec_ptr; @@ -511,24 +445,13 @@ /* Performance counter (number of instructions executed by CPU) */ m_uint64_t perf_counter; - /* Memory access log for fault debugging */ - u_int memlog_pos; - memlog_access_t memlog_array[MEMLOG_COUNT]; - /* Breakpoints */ m_uint64_t breakpoints[MIPS64_MAX_BREAKPOINTS]; u_int breakpoints_enabled; - /* Idle PC proposal */ - struct mips64_idle_pc idle_pc_prop[MIPS64_IDLE_PC_MAX_RES]; - u_int idle_pc_prop_count; - /* Symtrace */ int sym_trace; rbtree_tree *sym_tree; - - /* Next CPU in group */ - cpu_mips_t *next; }; #define MIPS64_IRQ_LOCK(cpu) pthread_mutex_lock(&(cpu)->irq_lock) @@ -552,17 +475,20 @@ /* Set the CPU PRID register */ void mips64_set_prid(cpu_mips_t *cpu,m_uint32_t prid); -/* Virtual idle loop */ -void mips64_idle_loop(cpu_mips_t *cpu); - -/* Break idle wait state */ -void mips64_idle_break_wait(cpu_mips_t *cpu); +/* Set idle PC value */ +void mips64_set_idle_pc(cpu_gen_t *cpu,m_uint64_t addr); /* Timer IRQ */ void *mips64_timer_irq_run(cpu_mips_t *cpu); /* Determine an "idling" PC */ -int mips64_get_idling_pc(cpu_mips_t *cpu); +int mips64_get_idling_pc(cpu_gen_t *cpu); + +/* Set an IRQ (VM IRQ standard routing) */ +void mips64_vm_set_irq(vm_instance_t *vm,u_int irq); + +/* Clear an IRQ (VM IRQ standard routing) */ +void mips64_vm_clear_irq(vm_instance_t *vm,u_int irq); /* Update the IRQ flag */ void mips64_update_irq_flag(cpu_mips_t *cpu); @@ -616,16 +542,19 @@ fastcall void mips64_run_breakpoint(cpu_mips_t *cpu); /* Add a virtual breakpoint */ -int mips64_add_breakpoint(cpu_mips_t *cpu,m_uint64_t pc); +int mips64_add_breakpoint(cpu_gen_t *cpu,m_uint64_t pc); /* Remove a virtual breakpoint */ -void mips64_remove_breakpoint(cpu_mips_t *cpu,m_uint64_t pc); +void mips64_remove_breakpoint(cpu_gen_t *cpu,m_uint64_t pc); /* Debugging for register-jump to address 0 */ fastcall void mips64_debug_jr0(cpu_mips_t *cpu); +/* Set a register */ +void mips64_reg_set(cpu_gen_t *cpu,u_int reg,m_uint64_t val); + /* Dump registers of a MIPS64 processor */ -void mips64_dump_regs(cpu_mips_t *cpu); +void mips64_dump_regs(cpu_gen_t *cpu); /* Dump a memory block */ void mips64_dump_memory(cpu_mips_t *cpu,m_uint64_t vaddr,u_int count); @@ -640,7 +569,7 @@ int mips64_load_raw_image(cpu_mips_t *cpu,char *filename,m_uint64_t vaddr); /* Load an ELF image into the simulated memory */ -int mips64_load_elf_image(cpu_mips_t *cpu,char *filename, +int mips64_load_elf_image(cpu_mips_t *cpu,char *filename,int skip_load, m_uint32_t *entry_point); /* Symbol lookup */