Пример #1
0
static void
debug_action( int action )
{
	stop_emulation();

	switch( action ) {
	case kDbgNOP:
		break;
	case kDbgGo:
		resume_emulation();
		break;
	case kDbgGoRFI:
		set_break_flag( BREAK_RFI );
		resume_emulation();
		break;
	case kDbgGoUser:
		set_break_flag( BREAK_USER );
		resume_emulation();
		break;
	case kDbgStep:
		set_break_flag( BREAK_SINGLE_STEP );
		restore_breakpoints();
		resume_emulation();
		break;
	case kDbgStop:
		stop_emulation();
		break;
	case kDbgExit:
		// quit_emulation();
		break;
	}
}
Пример #2
0
static int
rvec_debugger( int dummy_rvec, int num )
{
	printm("RVEC-DEBUGGER <%x>\n", num );
	stop_emulation();
	return 0;
}
Пример #3
0
static int
rvec_unusual_prog_excep( int dummy_rvec, ulong opcode, ulong srr1 )
{
	printm("Unusual program exception occured (SRR1 = %08lX)\n", srr1 );
	stop_emulation();
	return 0;
}
Пример #4
0
static int
rvec_spr_write( int dummy_rvec, int sprnum, ulong value )
{
	switch( sprnum ) {
	case S_THRM1:			/* Thermal 1 */
	case S_THRM2:			/* Thermal 2 */
	case S_THRM3:			/* Thermal 3 */
		mregs->spr[sprnum] = value;
		fix_thrm_spr();
		break;
	case S_MSSCR0:
		value &= ~MOL_BIT(8);			/* 7400 DL1HWF, L1 data cache hw flush */
		break;
	case S_L2CR:					/* L2 Cache Control Register */
		/* 750 doesn't clear L2I but 7455 does */
		value &= ~(MOL_BIT(10) | MOL_BIT(31));		/* Clear L2I and L2IP */
		break;
	case S_L3CR:					/* L3 Cache Control Register */
		value &= ~(MOL_BIT(20) | MOL_BIT(21));		/* Clear L3HWF and L3I */	
		mregs->spr[sprnum] = value;
		break;
	default:
		printm("Write to unimplemented SPR #%d (%08lX)\n", sprnum, value );
		mregs->spr[sprnum] = value;
		stop_emulation();
	}
	mregs->nip += 4;
	return 0;
}
Пример #5
0
static int
rvec_priv_inst( int dummy_rvec, ulong inst )
{
	int op, op_ext, b1, b2, b3;

	/* unhandled privileged instruction in supervisor mode */
	/* IMPORTANT: The GPRs are not available here! */

	op = OPCODE_PRIM( inst );
	op_ext = OPCODE_EXT( inst );
	b1 = B1( inst );	/* bit 6-10 */
	b2 = B2( inst );	/* bit 11-15 */
	b3 = B3( inst );	/* bit 16-20 */

	switch( OPCODE(op,op_ext) ) {
	case OPCODE( 31, 370 ):	/* tlbia (opt.) */
		/* not implemented on the 601,603,604,G3 (G4?) */
		break;
	case OPCODE( 31, 470 ):  /* dcbi rA,rB  -- rA=b2 rB=b3 */
		printm("dcbi treated as nop\n");
		mregs->nip += 4;
		return 0;
	default:
		printm("Unknown privileged instruction, opcode %lX\n", inst);
		stop_emulation();
		break;
	}
	mac_exception( 0x700, MOL_BIT(13) );
	return 0;
}
Пример #6
0
static int __dbg
rvec_break( int dummy_rvec, int break_flag )
{
	switch( break_flag ) {
	case BREAK_RFI:
		if( (molcpu.break_flags & BREAK_USER) ) {
			if( !(mregs->msr & MSR_PR) )
				return 0;
			clear_break_flag( BREAK_USER );
		}
		printm("BREAK-RFI (%08lX)\n", mregs->nip );
		break;
	case BREAK_EA_PAGE:
		/* breakpoint might not have been written */
		printm("ea-break at %08lX\n", mregs->nip );
		restore_breakpoints();
		setup_breakpoints();
		break;
	case BREAK_SINGLE_STEP:
		if( molcpu.break_flags & BREAK_SINGLE_STEP_CONT ) {
			if( !is_stop_breakpoint( mregs->nip ) )
				return 0;
			clear_break_flag( BREAK_SINGLE_STEP_CONT );
		}
		//setup_breakpoints();
		break;
	default:
		printm("rvec_break: Unknown break flag %d\n", break_flag );
		break;
	}
	stop_emulation();
	clear_break_flag( break_flag );
	return 0;
}
Пример #7
0
static int
rvec_illegal_inst( int dummy_rvec, ulong inst )
{
	/* IMPORTANT: The GPRs are not available here! */

	if( inst == BREAKPOINT_OPCODE ) {
		int val = is_stop_breakpoint( mregs->nip );
		if( val > 0 )
			stop_emulation();
		if( val ) {
			/* conditional breakpoint */
			return 0;
		}
		/* no breakpoint - take an exception */
	}

	/* printm("ILLEGAL INSTRUCTION %08lX\n", inst ); */
	mac_exception( 0x700, MOL_BIT(12) );
	return 0;
}
Пример #8
0
int
_rvec_spr_read( int dummy_rvec, int sprnum, int gprnum )
{
	switch( sprnum ) {
	case S_THRM1:			/* Thermal 1 */
	case S_THRM2:			/* Thermal 2 */
	case S_THRM3:			/* Thermal 3 */
		fix_thrm_spr();
		/* fall through */
	case S_L2CR:
	case S_L3CR:
	case S_MSSCR0:
		break;
	default:
		printm("Read from unimplemented SPR #%d\n", sprnum );
		stop_emulation();
	}
	mregs->gpr[gprnum] = mregs->spr[sprnum];
	mregs->nip += 4;
	return 0;
}
Пример #9
0
static int
rvec_unexpected_mmu_cond( int rvec, int param1, int param2 )
{
	switch( rvec ) {
	case RVEC_UNUSUAL_DSISR_BITS:	/* dar, dsisr */
		printm("RVEC_UNUSUAL_DSISR_BITS: dar %08X, dsisr %08X\n", param1, param2 );
		break;
	case RVEC_MMU_IO_SEG_ACCESS:
		printm("RVEC_MMU_IO_SEG_ACCESS\n");
		break;
	case RVEC_BAD_NIP: /* nip_phys */
		printm("Instruction Pointer not in ROM/RAM (nip %08lX, nip_phys %08X)\n", mregs->nip, param1 );
		if( !debugger_enabled() )
			quit_emulation();
		stop_emulation();
		break;
	default:
		printm("rvec_unexpected_mmu_cond, unimplemented vector %d\n", rvec );
		break;
	}
	return 0;
}
Пример #10
0
/* returns 1 if GPRs have been modified */
int
_rvec_io_write( int dummy_rvec, ulong mphys_ioaddr, void *usr_data )
{
	int op, op_ext, rS, rA, rB, d, flag=0, ret=0;
	ulong ea, cont, len, inst=mregs->inst_opcode;

	enum {	byte=1, half=2, word=4, len_mask=7, indexed=8, update=16, 
		reverse=32, nop=64, fpinst=128 };

	/* do_io_write() is considered FPU-unsafe */
	shield_fpu( mregs );

	/* break instruction into parts */
	op = OPCODE_PRIM( inst );
	op_ext = OPCODE_EXT( inst );
	rS = B1( inst );	/* bit 6-10 */
	rA = B2( inst );	/* bit 11-15 */
	rB = B3( inst );	/* bit 16-20 */
	d = BD( inst );		/* bit 16-31 sign extended */

	switch( op ) {
	case 38: /* stb rS,d(rA) */
		flag = byte ; break;
	case 39: /* stbu rS,d(rA) */
		flag = byte | update; break;
	case 44: /* sth rS,d(rA) */
		flag = half ;  break;
	case 45: /* sthu rS,d(rA) */
		flag = half | update; break;
	case 36: /* stw rS,d(rA) */
		flag = word ; break;
	case 37: /* stwud rS,d(rA) */
		flag = word | update; break;
	case 54: /* stfd frS,d(rA) */			/* FPU */
		flag = word | fpinst; break;
	case 55: /* stfdu frS,d(rA) */			/* FPU */
		flag = word | fpinst | update; break;
	}

	if( !flag && op==31 ) {
		switch( op_ext ) {
		case 215: /* stbx rS,rA,rB */
			flag = byte | indexed ; break;
		case 247: /* stbux rS,rA,rB */
			flag = byte | indexed | update; break;
		case 407: /* sthx rS,rA,rB */
			flag = half | indexed ; break;
		case 439: /* sthux rS,rA,rB */
			flag = half | indexed | update; break;
		case 151: /* stwx rS,rA,rB */
			flag = word | indexed ; break;
		case 183: /* stwux rS,rA,rB */
			flag = word | indexed | update; break;
		case 918: /* sthbrx rS,rA,rB */
			flag = half | indexed | reverse; break;
		case 662: /* stwbrx rS,rA,rB */
			flag = word | indexed | reverse; break;
		case 727: /* stfdx frS,rA,rB */
			/* printm("FPU store inst\n"); */
			flag = word | indexed | fpinst; break;
		case 759: /* stfdux frS,rA,rB */
			/* printm("FPU store inst\n"); */
			flag = word | indexed | update | fpinst; break;
		}
	}

	if( flag & len_mask ) {	/* instruction found */
		if( flag & indexed ) { /* stxxx rS,rA,rB */
			ea = mregs->gpr[rB];
			ea += rA ? mregs->gpr[rA] : 0;
		} else { /* stxxx rS,d(rA) */
			ea = rA ? mregs->gpr[rA] : 0;
			ea += d;
		}
		if( !(flag & fpinst ) )
			cont = mregs->gpr[rS];
		else {
			save_fpu_completely( mregs );
			cont = mregs->fpr[rS].h;
		}
		len = flag & len_mask;
		if( flag & byte ) {
			cont &= 0xff;
		} else if( flag & half ) {
			if( !(flag & reverse) )
				cont &= 0xffff;
			else
				cont = bswap_16( cont );
		} else if( flag & reverse )
			cont = ld_le32(&cont);

		/* ea is the mac untranslated address,
		 * mregs->mmu_ioaddr holds the translated address
		 */
		do_io_write( usr_data, mphys_ioaddr, cont, len );
		if( flag & fpinst ) {
			if( ((mphys_ioaddr+4) & 0xfff) < 4 )
				printm("emulate store data inst: Possible MMU translation error\n");
			do_io_write( usr_data, mphys_ioaddr+4, mregs->fpr[rS].l, 4 );
		}
		
		if( (flag & update) && rA  ) {
			mregs->gpr[rA] = ea;
			ret = 1;
		}
	}

	if( flag )
		mregs->nip += 4;
	else {
		printm("Unimplemented store instruction %08lX\n", inst );
		stop_emulation();
	}
	return ret;
}
Пример #11
0
/* returns 1 if GPRs have been modified */
int
_rvec_io_read( int dummy_rvec, ulong mphys_ioaddr, void *usr_data )
{
	ulong ea, cont, inst=mregs->inst_opcode;
	int op, op_ext, rD, rA, rB, d;
	int flag=0, ret=1;

	enum {	byte=1, half=2, word=4, len_mask=7, indexed=8, update=16, 
		zero=32, reverse=64, nop=128, fpinst=256 };

	/* do_io_read() is considered FPU-unsafe */
	shield_fpu( mregs );

	/* break instruction into parts */
	op = OPCODE_PRIM( inst );	/* bit 0-5 */
	op_ext = OPCODE_EXT( inst );
	rD = B1( inst );	/* bit 6-10 */
	rA = B2( inst );	/* bit 11-15 */
	rB = B3( inst );	/* bit 16-20 */
	d = BD( inst );		/* bit 16-31 sign extended */

	switch( op ) {
	case 34: /* lbz rD,d(rA) */
		flag = byte | zero; break;
	case 35: /* lbzu rD,d(rA) */
		flag = byte | zero | update; break;
	case 40: /* lhz rD,d(rA) */
		flag = half | zero; break;
	case 41: /* lhzu rD,d(rA) */
		flag = half | zero | update; break;
	case 42: /* lha rD,d(rA) */
		flag = half; break;
	case 43: /* lhau rD,d(rA) */
		flag = half | update; break;
	case 32: /* lwz rD,d(rA) */
		flag = word | zero; break;
	case 33: /* lwzu, rD,d(rA) */
		flag = word | zero | update; break;
	case 50: /* lfd frD,d(rA) */			/* FPU */
		flag = word | fpinst | zero; break;
	case 51: /* lfdu frD, d(rA) */			/* FPU */
		flag = word | fpinst | update | zero; break;
	}

	if( !flag && op==31 ) {
		switch( op_ext ) {  /* lxxx rD,rA,rB */
		case 87: /* lbzx rD,rA,rB */
			flag = byte | indexed | zero; break;
		case 119: /* lbzux rD,rA,rB */
			flag = byte | indexed | zero | update; break;
		case 279: /* lhzx rD,rA,rB */
			flag = half | indexed | zero; break;
		case 311: /* lhzux rD,rA,rB */
			flag = half | indexed | zero | update; break;
		case 343: /* lhax rD,rA,rB */
			flag = half | indexed; break;
		case 375: /* lhaux rD,rA,rB */
			flag = half | indexed | update; break;
		case 23: /* lwzx rD,rA,rB */
			flag = word | indexed | zero; break;
		case 55: /* lwzux rD,rA,rB */
			flag = word | indexed | zero | update; break;
		case 790: /* lhbrx rS,rA,rB */
			flag = half | indexed | zero | reverse; break;
		case 534: /* lwbrx rS,rA,rB */
			flag = word | indexed | zero | reverse; break;
		case 599: /* lfdx frD,rA,rB */				/* FPU */
			flag = word | indexed | zero | fpinst; break;
		case 631: /* lfdux frD,rA,rB */				/* FPU */
			flag = word | indexed | zero | update | fpinst; break;
		case 86: /* dcbf rA,rB - cache instruction*/
			/* treat as nop if data-translation is off */
			flag = (mregs->msr & MSR_DR) ? 0 : nop; break;
		}
	}

	if( flag & len_mask) {	/* instruction found */
		if( flag & indexed ) { /* lxxx rD,rA,rB */
			ea = mregs->gpr[rB];
			ea += rA ? mregs->gpr[rA] : 0;
		} else { /* lxxx rD,d(rA) */
			ea = rA ? mregs->gpr[rA] : 0;
			ea += d;
		}

		/* ea is the mac untranslated address, */
		/* mphys_ioaddr is the mac-physical address */

		cont = 0;
		do_io_read( usr_data, mphys_ioaddr, (flag & len_mask), &cont );

		if( flag & byte ){
			cont &= 0xff;
		} else if( flag & half ) {
			cont &= 0xffff;
			if( !(flag & zero) )	/* algebraic */
				cont |= (cont & 0x8000)? 0xffff0000 : 0;
			if( flag & reverse )
				cont = bswap_16( cont );
		} else if( flag & reverse)
			cont = ld_le32(&cont);
		if( !(flag & fpinst) )
			mregs->gpr[rD] = cont;
		else {
			/* FPU instruction */
			save_fpu_completely( mregs );
			ret = 0;
			
			mregs->fpr[rD].h = cont;

			/* check for 4K boundary crossings... */
			if( ((mphys_ioaddr+4) & 0xfff) < 4 )
				printm("emulate_load_data_inst: MMU translation might be bad\n");
			do_io_read( usr_data, mphys_ioaddr+4, 4, &cont );
			mregs->fpr[rD].l = cont;

			reload_tophalf_fpu( mregs );
		}
			
		if( (flag & update) && rA && (rA!=rD || (flag & fpinst)) ) {
			ret = 1;
			mregs->gpr[rA] = ea;
		}
	}

	if( flag )
		mregs->nip += 4;
	else {
		printm("Unimplemented load instruction %08lX\n", inst );
		stop_emulation();
	}
	return ret;
}
Пример #12
0
void DCPUToolchain::Stop(DebuggingSession* session)
{
    gl->killWidgets();
    paused = true;
    stop_emulation();
}