|
|
1.1 ! root 1: /* ! 2: * Cisco 7200 (Predator) simulation platform. ! 3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected]) ! 4: */ ! 5: ! 6: #ifndef __MIPS_64_H__ ! 7: #define __MIPS_64_H__ ! 8: ! 9: #include <pthread.h> ! 10: ! 11: #include "utils.h" ! 12: #include "rbtree.h" ! 13: ! 14: /* MIPS General Purpose Registers */ ! 15: #define MIPS_GPR_ZERO 0 /* zero */ ! 16: #define MIPS_GPR_AT 1 /* at */ ! 17: #define MIPS_GPR_V0 2 /* v0 */ ! 18: #define MIPS_GPR_V1 3 /* v1 */ ! 19: #define MIPS_GPR_A0 4 /* a0 */ ! 20: #define MIPS_GPR_A1 5 /* a1 */ ! 21: #define MIPS_GPR_A2 6 /* a2 */ ! 22: #define MIPS_GPR_A3 7 /* a3 */ ! 23: #define MIPS_GPR_T0 8 /* t0 */ ! 24: #define MIPS_GPR_T1 9 /* t1 */ ! 25: #define MIPS_GPR_T2 10 /* t2 */ ! 26: #define MIPS_GPR_T3 11 /* t3 */ ! 27: #define MIPS_GPR_T4 12 /* t4 */ ! 28: #define MIPS_GPR_T5 13 /* t5 */ ! 29: #define MIPS_GPR_T6 14 /* t6 */ ! 30: #define MIPS_GPR_T7 15 /* t7 */ ! 31: #define MIPS_GPR_S0 16 /* s0 */ ! 32: #define MIPS_GPR_S1 17 /* s1 */ ! 33: #define MIPS_GPR_S2 18 /* s2 */ ! 34: #define MIPS_GPR_S3 19 /* s3 */ ! 35: #define MIPS_GPR_S4 20 /* s4 */ ! 36: #define MIPS_GPR_S5 21 /* s5 */ ! 37: #define MIPS_GPR_S6 22 /* s6 */ ! 38: #define MIPS_GPR_S7 23 /* s7 */ ! 39: #define MIPS_GPR_T8 24 /* t8 */ ! 40: #define MIPS_GPR_T9 25 /* t9 */ ! 41: #define MIPS_GPR_K0 26 /* k0 */ ! 42: #define MIPS_GPR_K1 27 /* k1 */ ! 43: #define MIPS_GPR_GP 28 /* gp */ ! 44: #define MIPS_GPR_SP 29 /* sp */ ! 45: #define MIPS_GPR_FP 30 /* fp */ ! 46: #define MIPS_GPR_RA 31 /* ra */ ! 47: ! 48: /* ! 49: * Coprocessor 0 (System Coprocessor) Register definitions ! 50: */ ! 51: #define MIPS_CP0_INDEX 0 /* TLB Index */ ! 52: #define MIPS_CP0_RANDOM 1 /* TLB Random */ ! 53: #define MIPS_CP0_TLB_LO_0 2 /* TLB Entry Lo0 */ ! 54: #define MIPS_CP0_TLB_LO_1 3 /* TLB Entry Lo1 */ ! 55: #define MIPS_CP0_CONTEXT 4 /* Kernel PTE pointer */ ! 56: #define MIPS_CP0_PAGEMASK 5 /* TLB Page Mask */ ! 57: #define MIPS_CP0_WIRED 6 /* TLB Wired */ ! 58: #define MIPS_CP0_BADVADDR 8 /* Bad Virtual Address */ ! 59: #define MIPS_CP0_COUNT 9 /* Count */ ! 60: #define MIPS_CP0_TLB_HI 10 /* TLB Entry Hi */ ! 61: #define MIPS_CP0_COMPARE 11 /* Timer Compare */ ! 62: #define MIPS_CP0_STATUS 12 /* Status */ ! 63: #define MIPS_CP0_CAUSE 13 /* Cause */ ! 64: #define MIPS_CP0_EPC 14 /* Exception PC */ ! 65: #define MIPS_CP0_PRID 15 /* Proc Rev ID */ ! 66: #define MIPS_CP0_CONFIG 16 /* Configuration */ ! 67: #define MIPS_CP0_LLADDR 17 /* Load/Link address */ ! 68: #define MIPS_CP0_WATCHLO 18 /* Low Watch address */ ! 69: #define MIPS_CP0_WATCHHI 19 /* High Watch address */ ! 70: #define MIPS_CP0_XCONTEXT 20 /* Extended context */ ! 71: #define MIPS_CP0_ECC 26 /* ECC and parity */ ! 72: #define MIPS_CP0_CACHERR 27 /* Cache Err/Status */ ! 73: #define MIPS_CP0_TAGLO 28 /* Cache Tag Lo */ ! 74: #define MIPS_CP0_TAGHI 29 /* Cache Tag Hi */ ! 75: #define MIPS_CP0_ERR_EPC 30 /* Error exception PC */ ! 76: ! 77: /* ! 78: * CP0 Status Register ! 79: */ ! 80: #define MIPS_CP0_STATUS_CU0 0x10000000 ! 81: #define MIPS_CP0_STATUS_CU1 0x20000000 ! 82: #define MIPS_CP0_STATUS_BEV 0x00400000 ! 83: #define MIPS_CP0_STATUS_TS 0x00200000 ! 84: #define MIPS_CP0_STATUS_SR 0x00100000 ! 85: #define MIPS_CP0_STATUS_CH 0x00040000 ! 86: #define MIPS_CP0_STATUS_CE 0x00020000 ! 87: #define MIPS_CP0_STATUS_DE 0x00010000 ! 88: #define MIPS_CP0_STATUS_RP 0x08000000 ! 89: #define MIPS_CP0_STATUS_FR 0x04000000 ! 90: #define MIPS_CP0_STATUS_RE 0x02000000 ! 91: #define MIPS_CP0_STATUS_KX 0x00000080 ! 92: #define MIPS_CP0_STATUS_SX 0x00000040 ! 93: #define MIPS_CP0_STATUS_UX 0x00000020 ! 94: #define MIPS_CP0_STATUS_KSU 0x00000018 ! 95: #define MIPS_CP0_STATUS_ERL 0x00000004 ! 96: #define MIPS_CP0_STATUS_EXL 0x00000002 ! 97: #define MIPS_CP0_STATUS_IE 0x00000001 ! 98: #define MIPS_CP0_STATUS_IMASK8 0x00000000 ! 99: #define MIPS_CP0_STATUS_IMASK7 0x00008000 ! 100: #define MIPS_CP0_STATUS_IMASK6 0x00004000 ! 101: #define MIPS_CP0_STATUS_IMASK5 0x00002000 ! 102: #define MIPS_CP0_STATUS_IMASK4 0x00001000 ! 103: #define MIPS_CP0_STATUS_IMASK3 0x00000800 ! 104: #define MIPS_CP0_STATUS_IMASK2 0x00000400 ! 105: #define MIPS_CP0_STATUS_IMASK1 0x00000200 ! 106: #define MIPS_CP0_STATUS_IMASK0 0x00000100 ! 107: ! 108: #define MIPS_CP0_STATUS_DS_MASK 0x00770000 ! 109: #define MIPS_CP0_STATUS_CU_MASK 0xF0000000 ! 110: #define MIPS_CP0_STATUS_IMASK 0x0000FF00 ! 111: ! 112: /* Addressing mode: Kernel, Supervisor and User */ ! 113: #define MIPS_CP0_STATUS_KSU_SHIFT 0x03 ! 114: #define MIPS_CP0_STATUS_KSU_MASK 0x03 ! 115: ! 116: #define MIPS_CP0_STATUS_KM 0x00 ! 117: #define MIPS_CP0_STATUS_SM 0x01 ! 118: #define MIPS_CP0_STATUS_UM 0x10 ! 119: ! 120: ! 121: /* ! 122: * CP0 Cause register ! 123: */ ! 124: #define MIPS_CP0_CAUSE_BD_SLOT 0x80000000 ! 125: ! 126: #define MIPS_CP0_CAUSE_MASK 0x0000007C ! 127: #define MIPS_CP0_CAUSE_CEMASK 0x30000000 ! 128: #define MIPS_CP0_CAUSE_IMASK 0x0000FF00 ! 129: ! 130: #define MIPS_CP0_CAUSE_SHIFT 2 ! 131: #define MIPS_CP0_CAUSE_CESHIFT 28 ! 132: #define MIPS_CP0_CAUSE_ISHIFT 8 ! 133: ! 134: #define MIPS_CP0_CAUSE_INTERRUPT 0 ! 135: #define MIPS_CP0_CAUSE_TLB_MOD 1 ! 136: #define MIPS_CP0_CAUSE_TLB_LOAD 2 ! 137: #define MIPS_CP0_CAUSE_TLB_SAVE 3 ! 138: #define MIPS_CP0_CAUSE_ADDR_LOAD 4 /* ADEL */ ! 139: #define MIPS_CP0_CAUSE_ADDR_SAVE 5 /* ADES */ ! 140: #define MIPS_CP0_CAUSE_BUS_INSTR 6 ! 141: #define MIPS_CP0_CAUSE_BUS_DATA 7 ! 142: #define MIPS_CP0_CAUSE_SYSCALL 8 ! 143: #define MIPS_CP0_CAUSE_BP 9 ! 144: #define MIPS_CP0_CAUSE_ILLOP 10 ! 145: #define MIPS_CP0_CAUSE_CP_UNUSABLE 11 ! 146: #define MIPS_CP0_CAUSE_OVFLW 12 ! 147: #define MIPS_CP0_CAUSE_TRAP 13 ! 148: #define MIPS_CP0_CAUSE_VC_INSTR 14 /* Virtual Coherency */ ! 149: #define MIPS_CP0_CAUSE_FPE 15 ! 150: #define MIPS_CP0_CAUSE_WATCH 23 ! 151: #define MIPS_CP0_CAUSE_VC_DATA 31 /* Virtual Coherency */ ! 152: ! 153: #define MIPS_CP0_CAUSE_IBIT7 0x00008000 ! 154: #define MIPS_CP0_CAUSE_IBIT6 0x00004000 ! 155: #define MIPS_CP0_CAUSE_IBIT5 0x00002000 ! 156: #define MIPS_CP0_CAUSE_IBIT4 0x00001000 ! 157: #define MIPS_CP0_CAUSE_IBIT3 0x00000800 ! 158: #define MIPS_CP0_CAUSE_IBIT2 0x00000400 ! 159: #define MIPS_CP0_CAUSE_IBIT1 0x00000200 ! 160: #define MIPS_CP0_CAUSE_IBIT0 0x00000100 ! 161: ! 162: ! 163: /* TLB masks and shifts */ ! 164: #define MIPS_TLB_PAGE_MASK 0x01ffe000 ! 165: #define MIPS_TLB_PAGE_SHIFT 13 ! 166: #define MIPS_TLB_VPN2_MASK 0xffffffffffffe000ULL ! 167: #define MIPS_TLB_PFN_MASK 0x3fffffc0 ! 168: #define MIPS_TLB_ASID_MASK 0x000000ff /* "asid" in EntryHi */ ! 169: #define MIPS_TLB_G_MASK 0x00001000 /* "Global" in EntryHi */ ! 170: #define MIPS_TLB_V_MASK 0x2 /* "Valid" in EntryLo */ ! 171: #define MIPS_TLB_D_MASK 0x4 /* "Dirty" in EntryLo */ ! 172: ! 173: #define MIPS_CP0_LO_G_MASK 0x00000001 /* "Global" in Lo0/1 reg */ ! 174: #define MIPS_CP0_HI_SAFE_MASK 0xffffe0ff /* Safety mask for Hi reg */ ! 175: #define MIPS_CP0_LO_SAFE_MASK 0x7fffffff /* Safety mask for Lo reg */ ! 176: ! 177: /* MIPS "jr ra" instruction */ ! 178: #define MIPS_INSN_JR_RA 0x03e00008 ! 179: ! 180: /* Minimum page size: 4 Kb */ ! 181: #define MIPS_MIN_PAGE_SIZE (1 << 12) ! 182: ! 183: /* Addressing mode: Kernel, Supervisor and User */ ! 184: #define MIPS_MODE_KERNEL 00 ! 185: ! 186: /* Segments in 32-bit User mode */ ! 187: #define MIPS_USEG_BASE 0x00000000 ! 188: #define MIPS_USEG_SIZE 0x80000000 ! 189: ! 190: /* Segments in 32-bit Supervisor mode */ ! 191: #define MIPS_SUSEG_BASE 0x00000000 ! 192: #define MIPS_SUSEG_SIZE 0x80000000 ! 193: #define MIPS_SSEG_BASE 0xc0000000 ! 194: #define MIPS_SSEG_SIZE 0x20000000 ! 195: ! 196: /* Segments in 32-bit Kernel mode */ ! 197: #define MIPS_KUSEG_BASE 0x00000000 ! 198: #define MIPS_KUSEG_SIZE 0x80000000 ! 199: ! 200: #define MIPS_KSEG0_BASE 0x80000000 ! 201: #define MIPS_KSEG0_SIZE 0x20000000 ! 202: ! 203: #define MIPS_KSEG1_BASE 0xa0000000 ! 204: #define MIPS_KSEG1_SIZE 0x20000000 ! 205: ! 206: #define MIPS_KSSEG_BASE 0xc0000000 ! 207: #define MIPS_KSSEG_SIZE 0x20000000 ! 208: ! 209: #define MIPS_KSEG3_BASE 0xe0000000 ! 210: #define MIPS_KSEG3_SIZE 0x20000000 ! 211: ! 212: /* Macros for CPU structure access */ ! 213: #define REG_OFFSET(reg) (OFFSET(cpu_mips_t,gpr[(reg)])) ! 214: #define CP0_REG_OFFSET(c0reg) (OFFSET(cpu_mips_t,cp0.reg[(c0reg)])) ! 215: #define MEMOP_OFFSET(op) (OFFSET(cpu_mips_t,mem_op_fn[(op)])) ! 216: ! 217: /* Initial Program Counter and Stack pointer for ROM */ ! 218: #define MIPS_ROM_PC 0xffffffffbfc00000ULL ! 219: #define MIPS_ROM_SP 0xffffffff80004000ULL ! 220: ! 221: /* Number of GPR (general purpose registers) */ ! 222: #define MIPS64_GPR_NR 32 ! 223: ! 224: /* Number of registers in CP0 */ ! 225: #define MIPS64_CP0_REG_NR 32 ! 226: ! 227: /* Number of registers in CP1 */ ! 228: #define MIPS64_CP1_REG_NR 32 ! 229: ! 230: /* Number of TLB entries */ ! 231: #define MIPS64_TLB_ENTRIES 64 ! 232: #define MIPS64_TLB_IDX_MASK 0x3f /* 6 bits */ ! 233: ! 234: /* Virtual CPU states */ ! 235: enum { ! 236: MIPS_CPU_RUNNING = 0, ! 237: MIPS_CPU_HALTED, ! 238: MIPS_CPU_SUSPENDED, ! 239: }; ! 240: ! 241: /* Memory operations */ ! 242: enum { ! 243: MIPS_MEMOP_LB = 0, ! 244: MIPS_MEMOP_LBU, ! 245: MIPS_MEMOP_LH, ! 246: MIPS_MEMOP_LHU, ! 247: MIPS_MEMOP_LW, ! 248: MIPS_MEMOP_LWU, ! 249: MIPS_MEMOP_LD, ! 250: MIPS_MEMOP_SB, ! 251: MIPS_MEMOP_SH, ! 252: MIPS_MEMOP_SW, ! 253: MIPS_MEMOP_SD, ! 254: ! 255: MIPS_MEMOP_LWL, ! 256: MIPS_MEMOP_LWR, ! 257: MIPS_MEMOP_LDL, ! 258: MIPS_MEMOP_LDR, ! 259: MIPS_MEMOP_SWL, ! 260: MIPS_MEMOP_SWR, ! 261: MIPS_MEMOP_SDL, ! 262: MIPS_MEMOP_SDR, ! 263: ! 264: MIPS_MEMOP_LL, ! 265: MIPS_MEMOP_SC, ! 266: ! 267: MIPS_MEMOP_LDC1, ! 268: MIPS_MEMOP_SDC1, ! 269: ! 270: MIPS_MEMOP_CACHE, ! 271: ! 272: MIPS_MEMOP_MAX, ! 273: }; ! 274: ! 275: /* 6 bits are reserved for device ID (see the memory subsystem) */ ! 276: #define MIPS64_DEVICE_MAX (1 << 6) ! 277: ! 278: /* Number of recorded memory accesses (power of two) */ ! 279: #define MEMLOG_COUNT 16 ! 280: ! 281: /* Maximum number of breakpoints */ ! 282: #define MIPS64_MAX_BREAKPOINTS 8 ! 283: ! 284: typedef struct memlog_access memlog_access_t; ! 285: struct memlog_access { ! 286: m_uint64_t pc; ! 287: m_uint64_t vaddr; ! 288: m_uint64_t data; ! 289: m_uint32_t data_valid; ! 290: m_uint32_t op_size; ! 291: m_uint32_t op_type; ! 292: }; ! 293: ! 294: /* MIPS CPU type */ ! 295: typedef struct cpu_mips cpu_mips_t; ! 296: ! 297: /* Memory operation function prototype */ ! 298: typedef fastcall u_int (*mips_memop_fn)(cpu_mips_t *cpu,m_uint64_t vaddr, ! 299: u_int reg); ! 300: ! 301: /* TLB entry definition */ ! 302: typedef struct { ! 303: m_uint64_t mask; ! 304: m_uint64_t hi; ! 305: m_uint64_t lo0; ! 306: m_uint64_t lo1; ! 307: }tlb_entry_t; ! 308: ! 309: /* System Coprocessor (CP0) definition */ ! 310: typedef struct { ! 311: m_uint64_t reg[MIPS64_CP0_REG_NR]; ! 312: tlb_entry_t tlb[MIPS64_TLB_ENTRIES]; ! 313: }mips_cp0_t; ! 314: ! 315: /* FPU Coprocessor (CP1) definition */ ! 316: typedef struct { ! 317: m_uint64_t reg[MIPS64_CP1_REG_NR]; ! 318: }mips_cp1_t; ! 319: ! 320: /* CPU definition */ ! 321: struct cpu_mips { ! 322: m_uint64_t gpr[MIPS64_GPR_NR]; ! 323: m_uint64_t pc; ! 324: m_uint64_t lo,hi; ! 325: m_uint32_t irq_pending; ! 326: ! 327: /* Red-Black tree to locate PC */ ! 328: rbtree_tree *insn_block_tree; ! 329: ! 330: /* MTS 1st level array */ ! 331: void *mts_l1_ptr; ! 332: ! 333: /* MTS32 array free list */ ! 334: void *mts32_l2_free_list; ! 335: ! 336: /* Memory lookup function (to load ELF image,...) */ ! 337: void *(*mem_op_lookup)(cpu_mips_t *cpu,m_uint64_t vaddr); ! 338: ! 339: /* Memory access functions */ ! 340: mips_memop_fn mem_op_fn[MIPS_MEMOP_MAX]; ! 341: ! 342: /* LL/SC information */ ! 343: u_int ll_bit; ! 344: ! 345: /* Virtual version of CP0 Compare Register */ ! 346: m_uint32_t cp0_virt_cmp_reg; ! 347: m_uint32_t cp0_virt_cnt_reg; ! 348: ! 349: /* Address bus mask */ ! 350: m_uint64_t addr_bus_mask; ! 351: ! 352: /* System coprocessor (CP0) */ ! 353: mips_cp0_t cp0; ! 354: ! 355: /* FPU (CP1) */ ! 356: mips_cp1_t fpu; ! 357: ! 358: /* CPU identifier for MP systems and CPU state */ ! 359: u_int id,state; ! 360: ! 361: /* Next CPU in group */ ! 362: cpu_mips_t *next; ! 363: ! 364: /* Memory mapped devices */ ! 365: struct vdevice *dev_array[MIPS64_DEVICE_MAX]; ! 366: ! 367: /* Thread running this CPU */ ! 368: pthread_t cpu_thread; ! 369: ! 370: /* Memory access log for fault debugging */ ! 371: u_int memlog_pos; ! 372: memlog_access_t memlog_array[MEMLOG_COUNT]; ! 373: ! 374: /* Breakpoints */ ! 375: m_uint64_t breakpoints[MIPS64_MAX_BREAKPOINTS]; ! 376: u_int breakpoint_enabled; ! 377: ! 378: /* non-JIT mode instruction counter */ ! 379: m_uint64_t insn_exec_count; ! 380: }; ! 381: ! 382: /* Register names */ ! 383: extern char *mips64_gpr_reg_names[]; ! 384: ! 385: /* Initialize a MIPS64 processor */ ! 386: void mips64_init(cpu_mips_t *cpu); ! 387: ! 388: /* Update the IRQ flag */ ! 389: void mips64_update_irq_flag(cpu_mips_t *cpu); ! 390: ! 391: /* Generate an exception */ ! 392: void mips64_trigger_exception(cpu_mips_t *cpu,u_int exc_code,int bd_slot); ! 393: ! 394: /* ! 395: * Increment count register and trigger the timer IRQ if value in compare ! 396: * register is the same. ! 397: */ ! 398: fastcall void mips64_exec_inc_cp0_cnt(cpu_mips_t *cpu); ! 399: ! 400: /* Trigger the Timer IRQ */ ! 401: fastcall void mips64_trigger_timer_irq(cpu_mips_t *cpu); ! 402: ! 403: /* Execute ERET instruction */ ! 404: fastcall void mips64_exec_eret(cpu_mips_t *cpu); ! 405: ! 406: /* Execute SYSCALL instruction */ ! 407: fastcall void mips64_exec_syscall(cpu_mips_t *cpu); ! 408: ! 409: /* Execute BREAK instruction */ ! 410: fastcall void mips64_exec_break(cpu_mips_t *cpu,u_int code); ! 411: ! 412: /* Trigger a Trap Exception */ ! 413: asmlinkage void mips64_trigger_trap_exception(cpu_mips_t *cpu); ! 414: ! 415: /* Trigger IRQs */ ! 416: fastcall void mips64_trigger_irq(cpu_mips_t *cpu); ! 417: ! 418: /* Set an IRQ */ ! 419: void mips64_set_irq(cpu_mips_t *cpu,u_int irq); ! 420: ! 421: /* Clear an IRQ */ ! 422: void mips64_clear_irq(cpu_mips_t *cpu,u_int irq); ! 423: ! 424: /* DMFC1 */ ! 425: fastcall void mips64_exec_dmfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); ! 426: ! 427: /* DMTC1 */ ! 428: fastcall void mips64_exec_dmtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); ! 429: ! 430: /* MFC1 */ ! 431: fastcall void mips64_exec_mfc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); ! 432: ! 433: /* MTC1 */ ! 434: fastcall void mips64_exec_mtc1(cpu_mips_t *cpu,u_int gp_reg,u_int cp1_reg); ! 435: ! 436: /* Virtual breakpoint */ ! 437: fastcall void mips64_run_breakpoint(cpu_mips_t *cpu); ! 438: ! 439: /* Dump registers of a MIPS64 processor */ ! 440: void mips64_dump_regs(cpu_mips_t *cpu); ! 441: ! 442: /* Dump a memory block */ ! 443: void mips64_dump_memory(cpu_mips_t *cpu,m_uint64_t vaddr,u_int count); ! 444: ! 445: /* Dump the stack */ ! 446: void mips64_dump_stack(cpu_mips_t *cpu,u_int count); ! 447: ! 448: /* Save the CPU state into a file */ ! 449: int mips64_save_state(cpu_mips_t *cpu,char *filename); ! 450: ! 451: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.