📄 emul.h
字号:
#ifndef _EMUL_H_#define _EMUL_H_#include "cache.h"#include "cpu.h"/* 16 bit implementation and revision fields. The upper 8 bits are 0x20 * for R3000. The lower 8 bits should distinguish the * simulator. */#define ImpRev 0x2070/* Some instruction latencies. These are for R4600. On R4700, both all * four multiplication latencies are decreased by four cycles. */#define mult_latency 10#define multu_latency 10#define div_latency 42#define divu_latency 42#define dmult_latency 12#define dmultu_latency 12#define ddiv_latency 74#define ddivu_latency 74/* Asynchronous event constants. Each interrupt source corresponds to a * single bit of the (events) word. Bits 8 through 16 correspond to * interrupts 0 through 7. Other bits represent the three reset exceptions * as follows: */#define cold_reset_event (1 << 0)#define soft_reset_event (1 << 1)#define nmi_event (1 << 2)/* Cache of some strategic CPU mode bits. This shortcut is used to avoid * parsing of the somewhat convoluted Status register during address * translation and instruction decoding. */#define xmode (1 << 0) // 64 bit mode ([USK]X & [usk]mode)#define cmode (1 << 1) // 32 bit (compatibility) mode (!xmode)#define bmode (1 << 2) // big-endian-cpu (big_endian_mem() ^ reverse_endian())#define rmode (1 << 3) // reverse-endian (RE && umode)#define umode (1 << 4) // user mode#define smode (1 << 5) // supervisor mode#define kmode (1 << 6) // kernel mode/* Pipeline information. This is fairly ad hoc, but it is still useful */#define nothing_special 0 // nothing special#define branch_delay 1 // current instruction in the branch-delay slot#define instr_addr_error 2 // instruction address error#define branch_nodelay 3 // syscall instruction or eret instruction/* Coprocessor 1 (FPU) simulator *///static const char* condname[16];#define FCR0 0#define FP_Rev_Last 7#define FP_Rev_First 0#define FP_Imp_Last 15#define FP_Imp_First 8#define FCR31 31#define FP_RM_Last 1#define FP_RM_First 0#define FP_Flag_Last 6#define FP_Flag_First 2#define FP_Enable_Last 11#define FP_Enable_First 7#define FP_Cause_Last 17#define FP_Cause_First 12#define FP_C 23#define FP_FS 24/* Software IEC/IEEE floating-point rounding mode */#define float_round_nearest_even 0#define float_round_to_zero 1#define float_round_up 2#define float_round_down 3/* Software IEC/IEEE floating-point exception flags */#define float_flag_inexact 1#define float_flag_underflow 2#define float_flag_overflow 4#define float_flag_divbyzero 8#define float_flag_invalid 16#define float_flag_unimplemented 32/* An invalid ASID bit used to mark unused TLB entries */#define invalid_asid (1 << 6) //Shi yang 2006-08-08/* An global ASID bit */#define global_asid (1 << 6) //Shi yang 2006-08-08/* Geometry of the TLB lookup map (see below.) */#define log2_tlb_map_size 6 //Shi yang 2006-08-08#define tlb_map_size (1 << log2_tlb_map_size)/* An invalid cache tag used to mark unused cache lines */#define bad_tag ~(UInt32)0/* An invalid ibuf tag used to marked unused icache buffers */#define bad_ibuf_tag ~(VA)0/* An invalid physical address returned by translate_vaddr() on cache * operations that specify an invalid address. */#define bad_pa ~(PA)0/* TLB access types, used to select the appropriate TLB miss handler */#define instr_fetch 0 //instruction fetch#define data_load 1 //data load#define data_store 2 //data store#define cache_op 3 //cache operations (ignore errors)#define no_tracing 0#define report_interrupts 1#define report_exceptions 2#define print_instructions 3#define dump_gprs 4/* The NOP guard */#define catch_nops 128/* if return 0, translate * 0 means find the correct PA * 1 means some TLB exception happened */#define TLB_FAIL -1#define TLB_SUCC 0#define TLB_EXP 1/* A TLB Entry structure */typedef struct TLBEntry_s { struct TLBEntry_s* next; // the hash chain struct TLBEntry_s* prev; // the hash chain UInt16 page_mask; UInt32 hi; // VPN << 12 UInt32 lo_reg[2]; // EntryLo0 Int16 asid; // the ASID, sign bit set for global entries. UInt16 index; // TLB index UInt16 hash; // TLB map index}TLBEntry;/* The two-entry ITLB. Each entry maps a 4KB page */typedef struct ITLBEntry_s { VA vpn; // virtual address page number (va / 4KB) PA pa; // physical address and the caching algorithm Int16 asid; // ASID and the global bit.}ITLBEntry;/* Although not in real hardware, we also cache the two most recent * I-cache accesses, as simulating cache lookups is slow, and as many as 8 * instructions can be fetched from one cache line. */typedef struct ICacheBuffer_s { VA tag; // address of the cache shifted by log2_icache_line UInt32* line; // pointer to the ICache line.}ICacheBuffer;typedef struct MIPS_State_s{ // The register set. VA pc; // Program Counter UInt32 gpr[32]; // General Purpose Registers UInt32 fpr[32]; // Floating-Point General Purpose Registers UInt32 fir,fcsr; // Floating-point implementation register and control-status register UInt32 cp0[32]; // CP0 Registers UInt32 cp0_config1; UInt32 cp1[32]; // CP1 Registers UInt32 hi, lo; // Multiply and Divide Registers int ll_bit; // The Load-Linked Bit ClockValue now; int warm; //flag:warm_reset or cold_reset int nop_count; //nop instruction count // CPU state. Int16 asid; // same as the ASID field in EntryHi UInt16 events; // external events: this also replaces Cause[15:8]. UInt8 pipeline; // current instruction in the branch-delay slot UInt8 mode; // CPU mode int sync_bit; // true after executing the SYNC instruction. VA branch_target; // next PC when in the branch delay slot /* cp0[Random] is not updated on each clock cycle. Instead, its value is * updated when either cp0[Random] or cp0[Wired] is set, and the current * value is computed using the time elapsed since then. */ ClockValue random_seed; // Similary, we lazily compute the value of the Count register. ClockValue count_seed; // ITLB data. (lru_itlb) stores the index of the least-recently used entry. ITLBEntry itlb[2]; int lru_itlb; /* I-cache buffer data (lru_ibuf) stores the index of the least-recently * used entry (0 or 1). */ ICacheBuffer ibuf[2]; int lru_ibuf; int env; //The longjmp buffer used for handling exceptions. /* The TLB and L1 caches */ TLBEntry tlb[tlb_size]; ICache icache; DCache dcache; /* The TLB map used to simulate the direct-mapped TLB lookup. There's an * extra entry at the end that contains the hash chain of all unused TLB * entries (that way, there is always exactly (tlb_size) mappings in the * hash table). */ TLBEntry* tlb_map[tlb_map_size + 1]; int trace_level; // Finally, some configuration data. struct conf_t{ char* bus; int ec; char* ep; int be; int trace; } conf; unsigned bigendSig; int irq_pending;}MIPS_State;void reset(int warm);/* Interrupt delivery functions */void deliver_cold_reset(MIPS_State* mstate);void deliver_soft_reset(MIPS_State* mstate);/* TLB operations */void reset_tlb(MIPS_State* mstate);void dump_tlb();TLBEntry* probe_tlb(MIPS_State* mstate, VA va);void set_tlb_entry(MIPS_State* mstate, int index);int translate_vaddr(MIPS_State* mstate, VA va, int type, PA *pa);/* Instruction cache operations */void reset_icache(MIPS_State* mstate);void control_icache(MIPS_State* mstate, VA va, PA pa, int op, int type);Instr fetch(MIPS_State* mstate, VA va, PA pa);/* Data cache operations*/void reset_dcache(MIPS_State* mstate);void control_dcache(MIPS_State* mstate, VA va, PA pa, int op, int type);UInt32 load_left(UInt32 x, VA va, int syscmd); // LDL, LWLUInt32 load_right(UInt32 x, VA va, int syscmd); // LDR, LWRvoid store_left(UInt32 x, VA va, int syscmd); // SDL, SWLvoid store_right(UInt32 x, VA va, int syscmd); // SDR, SWR/* Complete any pending memory operations *///void sync();void process_reset(MIPS_State* mstate);void process_exception(MIPS_State* mstate, UInt32 cause, int vec);/* Set the Coprocessor 0 timer interrupt */void set_timer();/* Coprocessor 0 register access. This is necessary as some registers * are computed on demand, and most registers have some read-only fields. */UInt32 read_cp0(MIPS_State* mstate, int n, int sel) ;void write_cp0(MIPS_State* mstate, int n, UInt32 x);/* The main instruction decoder with satelite functions for some of the * more elaborate instructions. */int decode(MIPS_State* mstate, Instr instr);int decode_cop0(MIPS_State* mstate, Instr instr);int decode_cop1(MIPS_State* mstate, Instr instr);int decode_cache(MIPS_State* mstate, Instr instr);int decode_ldc1(MIPS_State* mstate, Instr instr);int decode_lwc1(MIPS_State* mstate, Instr instr);int decode_sdc1(MIPS_State* mstate, Instr instr);int decode_swc1(MIPS_State* mstate, Instr instr);/* Some debugging help */void dump_gpr_registers() ;void dump_fpr_registers() ;#endif //end of _EMUL_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -