From b8140a08bfadfd8cf95b83d19dd03c599f7f99f5 Mon Sep 17 00:00:00 2001 From: Ron Unrau Date: Fri, 31 Jul 1998 22:02:12 +0000 Subject: [PATCH] * sim-main.h: shadow NUM_CORE_REGS from tm-txvu.h * interp.c: use NUM_CORE_REGS * sky-gdb.c (set_fifo_breakpoints): use VIF interrupt bit for break * sky-pke.c (pke_issue): use interrupt bit for break points --- sim/mips/interp.c | 164 ++++++++++++++++++++++++++------------------ sim/mips/sim-main.h | 20 ++++-- sim/mips/sky-pke.c | 17 ++--- 3 files changed, 121 insertions(+), 80 deletions(-) diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 8b10b1fa60..4c9747dc3e 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -46,9 +46,7 @@ code on the hardware. #include "sky-libvpe.h" #include "sky-pke.h" #include "idecode.h" -#include "support.h" #include "sky-gdb.h" -#undef SD #endif /* end-sanitize-sky */ @@ -179,6 +177,9 @@ static DECLARE_OPTION_HANDLER (mips_option_handler); enum { OPTION_DINERO_TRACE = OPTION_START, OPTION_DINERO_FILE, + /* start-stanitize-branchbug4011 */ + OPTION_BRANCH_BUG_4011, + /* end-stanitize-branchbug4011 */ OPTION_BOARD }; @@ -194,6 +195,32 @@ mips_option_handler (sd, cpu, opt, arg, is_command) int cpu_nr; switch (opt) { + /* start-sanitize-branchbug4011 */ + case OPTION_BRANCH_BUG_4011: + { + for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) + { + sim_cpu *cpu = STATE_CPU (sd, cpu_nr); + if (arg == NULL) + BRANCHBUG4011_OPTION = 1; + else if (strcmp (arg, "yes") == 0) + BRANCHBUG4011_OPTION = 1; + else if (strcmp (arg, "no") == 0) + BRANCHBUG4011_OPTION = 0; + else if (strcmp (arg, "on") == 0) + BRANCHBUG4011_OPTION = 1; + else if (strcmp (arg, "off") == 0) + BRANCHBUG4011_OPTION = 0; + else + { + fprintf (stderr, "Unrecognized check-4011-branch-bug option `%s'\n", arg); + return SIM_RC_FAIL; + } + } + return SIM_RC_OK; + } + + /* end-sanitize-branchbug4011 */ case OPTION_DINERO_TRACE: /* ??? */ #if defined(TRACE) /* Eventually the simTRACE flag could be treated as a toggle, to @@ -266,6 +293,11 @@ static const OPTION mips_options[] = { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE}, '\0', "on|off", "Enable dinero tracing", mips_option_handler }, + /* start-sanitize-branchbug4011 */ + { {"check-4011-branch-bug", optional_argument, NULL, OPTION_BRANCH_BUG_4011}, + '\0', "on|off", "Enable checking for 4011 branch bug", + mips_option_handler }, + /* end-sanitize-branchbug4011 */ { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE}, '\0', "FILE", "Write dinero trace to FILE", mips_option_handler }, @@ -330,7 +362,6 @@ sim_open (kind, cb, abfd, argv) SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); - /* FIXME: watchpoints code shouldn't need this */ STATE_WATCHPOINTS (sd)->pc = &(PC); STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); @@ -539,18 +570,18 @@ sim_open (kind, cb, abfd, argv) #ifdef TARGET_SKY /* Now the VU registers */ for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) { - cpu->register_widths[rn + NUM_R5900_REGS] = 16; - cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 16; + cpu->register_widths[rn + NUM_CORE_REGS] = 16; + cpu->register_widths[rn + NUM_CORE_REGS + NUM_VU_REGS] = 16; } for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) { - cpu->register_widths[rn + NUM_R5900_REGS] = 32; - cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 32; + cpu->register_widths[rn + NUM_CORE_REGS] = 32; + cpu->register_widths[rn + NUM_CORE_REGS + NUM_VU_REGS] = 32; } /* Finally the VIF registers */ for( rn = 2*NUM_VU_REGS; rn < 2*NUM_VU_REGS + 2*NUM_VIF_REGS; rn++ ) - cpu->register_widths[rn + NUM_R5900_REGS] = 32; + cpu->register_widths[rn + NUM_CORE_REGS] = 32; cpu->cur_device = 0; #endif @@ -794,9 +825,9 @@ sim_store_register (sd,rn,memory,length) /* start-sanitize-sky */ #ifdef TARGET_SKY - if (rn >= NUM_R5900_REGS) + if (rn >= NUM_CORE_REGS) { - rn = rn - NUM_R5900_REGS; + rn = rn - NUM_CORE_REGS; if( rn < NUM_VU_REGS ) { @@ -969,9 +1000,9 @@ sim_fetch_register (sd,rn,memory,length) /* start-sanitize-sky */ #ifdef TARGET_SKY - if (rn >= NUM_R5900_REGS) + if (rn >= NUM_CORE_REGS) { - rn = rn - NUM_R5900_REGS; + rn = rn - NUM_CORE_REGS; if (rn < NUM_VU_REGS) { @@ -3207,8 +3238,12 @@ decode_coproc (SIM_DESC sd, case 0: /* standard CPU control and cache registers */ { int code = ((instruction >> 21) & 0x1F); + int rt = ((instruction >> 16) & 0x1F); + int rd = ((instruction >> 11) & 0x1F); + int tail = instruction & 0x3ff; /* R4000 Users Manual (second edition) lists the following CP0 instructions: + CODE><-RT><--TAIL---> DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000) DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000) MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000) @@ -3220,10 +3255,9 @@ decode_coproc (SIM_DESC sd, CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii) ERET Exception return (VR4100 = 01000010000000000000000000011000) */ - if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0)) + if (((code == 0x00) || (code == 0x04)) && tail == 0) { - int rt = ((instruction >> 16) & 0x1F); - int rd = ((instruction >> 11) & 0x1F); + /* M[TF]C0 - 32 bit word */ switch (rd) /* NOTEs: Standard CP0 registers */ { @@ -3311,13 +3345,37 @@ decode_coproc (SIM_DESC sd, GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */ /* CPR[0,rd] = GPR[rt]; */ default: + if (code == 0x00) + GPR[rt] = (signed_word) (signed32) COP0_GPR[rd]; + else + COP0_GPR[rd] = GPR[rt]; +#if 0 if (code == 0x00) sim_io_printf(sd,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd); else sim_io_printf(sd,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd); +#endif } } - else if (code == 0x10 && (instruction & 0x3f) == 0x18) + /* start-sanitize-r5900 */ + else if (((code == 0x00) || (code == 0x04)) && rd == 0x18 && tail > 0 && tail < NR_COP0_BP) + /* Break-point registers */ + { + if (code == 0x00) + GPR[rt] = (signed_word) (signed32) COP0_BP[tail]; + else + COP0_BP[tail] = GPR[rt]; + } + else if (((code == 0x00) || (code == 0x04)) && rd == 0x19 && tail > 0 && tail < NR_COP0_P) + /* Performance registers */ + { + if (code == 0x00) + GPR[rt] = (signed_word) (signed32) COP0_P[tail]; + else + COP0_P[tail] = GPR[rt]; + } + /* end-sanitize-r5900 */ + else if (code == 0x10 && (tail & 0x3f) == 0x18) { /* ERET */ if (SR & status_ERL) @@ -3333,7 +3391,7 @@ decode_coproc (SIM_DESC sd, SR &= ~status_EXL; } } - else if (code == 0x10 && (instruction & 0x3f) == 0x10) + else if (code == 0x10 && (tail & 0x3f) == 0x10) { /* RFE */ #ifdef SUBTARGET_R3900 @@ -3345,7 +3403,7 @@ decode_coproc (SIM_DESC sd, /* TODO: CACHE register */ #endif /* SUBTARGET_R3900 */ } - else if (code == 0x10 && (instruction & 0x3f) == 0x1F) + else if (code == 0x10 && (tail & 0x3f) == 0x1F) { /* DERET */ Debug &= ~Debug_DM; @@ -3378,10 +3436,6 @@ decode_coproc (SIM_DESC sd, int i_10_6 = (instruction >> 6) & 0x1f; int i_5_0 = instruction & 0x03f; int interlock = instruction & 0x01; - /* setup for semantic.c-like actions below */ - typedef unsigned_4 instruction_word; - int CIA = cia; - int NIA = cia + 4; handle = 1; @@ -3392,33 +3446,8 @@ decode_coproc (SIM_DESC sd, /* NOTREACHED */ } -#define MY_INDEX itable_COPz_NORMAL -#define MY_PREFIX COPz_NORMAL -#define MY_NAME "COPz_NORMAL" + /* BC2T/BC2F/BC2TL/BC2FL handled in r5900.igen */ - /* classify & execute basic COP2 instructions */ - if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */ - { - address_word offset = EXTEND16(i_15_0) << 2; - if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset); - } - else if(i_25_21 == 0x08 && i_20_16==0x02) /* BC2FL */ - { - address_word offset = EXTEND16(i_15_0) << 2; - if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset); - else NULLIFY_NEXT_INSTRUCTION(); - } - else if(i_25_21 == 0x08 && i_20_16 == 0x01) /* BC2T */ - { - address_word offset = EXTEND16(i_15_0) << 2; - if(vu0_busy()) DELAY_SLOT(cia + 4 + offset); - } - else if(i_25_21 == 0x08 && i_20_16 == 0x03) /* BC2TL */ - { - address_word offset = EXTEND16(i_15_0) << 2; - if(vu0_busy()) DELAY_SLOT(cia + 4 + offset); - else NULLIFY_NEXT_INSTRUCTION(); - } else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */ (i_25_21 == 0x01)) /* QMFC2 */ { @@ -3430,17 +3459,19 @@ decode_coproc (SIM_DESC sd, while(vu0_busy() && interlock) vu0_issue(sd); - /* perform VU register address */ + /* perform VU register access */ if(i_25_21 == 0x01) /* QMFC2 */ { - unsigned_16 xyzw; + unsigned_4 x,y,z,w; + /* one word at a time, argh! */ - read_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3)); - read_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2)); - read_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1)); - read_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0)); - GPR[rt] = T2H_8(* A8_16(& xyzw, 1)); - GPR1[rt] = T2H_8(* A8_16(& xyzw, 0)); + read_vu_vec_reg(&(vu0_device.regs), id, 3, &w); + read_vu_vec_reg(&(vu0_device.regs), id, 2, &z); + read_vu_vec_reg(&(vu0_device.regs), id, 1, &y); + read_vu_vec_reg(&(vu0_device.regs), id, 0, &x); + + GPR[rt] = U8_4(T2H_4(y), T2H_4(x)); + GPR1[rt] = U8_4(T2H_4(w), T2H_4(z)); } else /* CFC2 */ { @@ -3466,17 +3497,21 @@ decode_coproc (SIM_DESC sd, vu0_issue(sd); } - /* perform VU register address */ + /* perform VU register access */ if(i_25_21 == 0x05) /* QMTC2 */ { - unsigned_16 xyzw = U16_8(GPR1[rt], GPR[rt]); + unsigned_4 x,y,z,w; + + x = H2T_4(V4_8(GPR[rt], 1)); + y = H2T_4(V4_8(GPR[rt], 0)); + z = H2T_4(V4_8(GPR1[rt], 1)); + w = H2T_4(V4_8(GPR1[rt], 0)); - xyzw = H2T_16(xyzw); /* one word at a time, argh! */ - write_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3)); - write_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2)); - write_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1)); - write_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0)); + write_vu_vec_reg(&(vu0_device.regs), id, 3, & w); + write_vu_vec_reg(&(vu0_device.regs), id, 2, & z); + write_vu_vec_reg(&(vu0_device.regs), id, 1, & y); + write_vu_vec_reg(&(vu0_device.regs), id, 0, & x); } else /* CTC2 */ { @@ -3560,9 +3595,6 @@ decode_coproc (SIM_DESC sd, /* NOTREACHED */ } - /* cleanup for semantic.c-like actions above */ - PC = NIA; - #undef MY_INDEX #undef MY_PREFIX #undef MY_NAME diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index a664122ba8..1f91594645 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -568,10 +568,10 @@ struct _sim_cpu { #define NUM_VIF_REGS 26 #define FIRST_VEC_REG 25 -#define NUM_R5900_REGS 128 +#define NUM_CORE_REGS 128 #undef NUM_REGS -#define NUM_REGS (NUM_R5900_REGS + 2*(NUM_VU_REGS) + 2*(NUM_VIF_REGS)) +#define NUM_REGS (NUM_CORE_REGS + 2*(NUM_VU_REGS) + 2*(NUM_VIF_REGS)) #endif /* no tm-txvu.h */ #endif /* TARGET_SKY */ /* end-sanitize-sky */ @@ -1027,15 +1027,20 @@ char* pr_uword64 PARAMS ((uword64 addr)); #endif void sky_sim_engine_halt PARAMS ((SIM_DESC sd, sim_cpu *last, sim_cia cia)); -#define SIM_ENGINE_HALT_HOOK(sd, last, cia) sky_sim_engine_halt(sd, last, cia); +#define SIM_ENGINE_HALT_HOOK(sd, last, cia) sky_sim_engine_halt(sd, last, cia) #ifdef SIM_ENGINE_RESTART_HOOK #undef SIM_ENGINE_RESTART_HOOK #endif void sky_sim_engine_restart PARAMS ((SIM_DESC sd, sim_cpu *last, sim_cia cia)); -#define SIM_ENGINE_RESTART_HOOK(sd, L, pc) sky_sim_engine_restart(sd, L, pc); +#define SIM_ENGINE_RESTART_HOOK(sd, L, pc) sky_sim_engine_restart(sd, L, pc) +/* for resume/suspend modules */ +SIM_RC sky_sim_module_install PARAMS ((SIM_DESC sd)); + +#define MODULE_LIST sky_sim_module_install, + #ifndef TM_TXVU_H /* In case GDB hasn't been configured yet */ enum txvu_cpu_context { @@ -1049,7 +1054,7 @@ enum txvu_cpu_context }; /* memory segment for communication with GDB */ -#define GDB_COMM_AREA 0x21010000 +#define GDB_COMM_AREA 0x21010000 /* Random choice */ #define GDB_COMM_SIZE 0x4000 /* Memory address containing last device to execute */ @@ -1059,8 +1064,11 @@ enum txvu_cpu_context #define FIFO_BPT_CNT (GDB_COMM_AREA + 4) #define FIFO_BPT_TBL (GDB_COMM_AREA + 8) +/* Each element of the breakpoint table is three four-byte integers. */ +#define BPT_ELEM_SZ 4*3 + #define TXVU_VU_BRK_MASK 0x02 /* Breakpoint bit is #57 for VU insns */ -#define TXVU_VIF_BRK_MASK 0x0f /* Breakpoint opcode for VIF insns */ +#define TXVU_VIF_BRK_MASK 0x80 /* Use interrupt bit for VIF insns */ #endif /* !TM_TXVU_H */ #endif /* TARGET_SKY */ diff --git a/sim/mips/sky-pke.c b/sim/mips/sky-pke.c index e89385f845..9a2c1518e0 100644 --- a/sim/mips/sky-pke.c +++ b/sim/mips/sky-pke.c @@ -594,7 +594,6 @@ pke_issue(SIM_DESC sd, struct pke_device* me) /* store word in PKECODE register */ me->regs[PKE_REG_CODE][0] = fw; - /* 2 -- test go / no-go for PKE execution */ /* switch on STAT:PSS if PSS-pending and in idle state */ @@ -633,6 +632,15 @@ pke_issue(SIM_DESC sd, struct pke_device* me) /* handle interrupts */ if(intr) { + /* check to see if the interrupt bit is being used for a breakpoint */ + if (is_vif_breakpoint ((fqw->source_address & ~15) | (me->qw_pc << 2))) + { + sim_cpu *cpu = STATE_CPU (sd, 0); + unsigned_4 pc_addr = (fqw->source_address & ~15) | (me->qw_pc << 2); + + sim_engine_halt (sd, cpu, NULL, pc_addr, sim_stopped, SIM_SIGTRAP); + } + /* are we resuming an interrupt-stalled instruction? */ if(me->flags & PKE_FLAG_INT_NOLOOP) { @@ -735,13 +743,6 @@ pke_issue(SIM_DESC sd, struct pke_device* me) pke_code_mpg(me, fw); else if(me->pke_number == 1 && IS_PKE_CMD(cmd, MSKPATH3)) pke_code_mskpath3(me, fw); - else if(cmd == TXVU_VIF_BRK_MASK) - { - sim_cpu *cpu = STATE_CPU (sd, 0); - unsigned_4 pc_addr = (fqw->source_address & ~15) | (me->qw_pc << 2); - - sim_engine_halt (sd, cpu, NULL, pc_addr, sim_stopped, SIM_SIGTRAP); - } /* ... no other commands ... */ else pke_code_error(me, fw); -- 2.34.1