Example #1
0
static sval
decode_spr_ins(struct cpu_thread* thr, uval addr, uval32 ins)
{
	struct thread_control_area *tca = get_tca();
	uval id = thr->vregs->active_vsave;
	struct vexc_save_regs *vr = &thr->vregs->vexc_save[id];
	sval ret = -1;
	uval opcode = extract_bits(ins, 0, 6);
	uval type = extract_bits(ins, 21, 10);
	uval spr_0_4 = extract_bits(ins, 16, 5);
	uval spr_5_9 = extract_bits(ins, 11, 5);
	uval gpr  = extract_bits(ins, 6, 5);
	uval spr = (spr_0_4 << 5) | spr_5_9;

	/* mfmsr */
	if (opcode == 31 && type == 83) {
		//hprintf("mfmsr r%ld at 0x%lx\n",gpr, addr);
		mtgpr(thr, gpr, thr->vregs->v_msr);
		tca->srr0 += sizeof(uval32);
		return 0;
	}

	/* mtmsrd */
	if (opcode == 31 && (type == 178 || type == 146)) {
		uval64 val = mfgpr(thr, gpr);
		//hprintf("mtmsrd r%ld <- 0x%llx at 0x%lx\n", gpr, val, addr);

		uval64 chg_mask = ~0ULL;
		uval l = extract_bits(ins, 15, 1);
		if (type == 146) {
			// mtmsr , 32-bits
			chg_mask = 0xffffffff;
		}

		if (l == 1) {
			chg_mask = (MSR_EE | MSR_RI);
		}

		/* These are the only bits we can change here */
		val = (val & chg_mask) | (thr->vregs->v_msr & ~chg_mask);

		set_v_msr(thr, val);
		val = thr->vregs->v_msr;
		val |= V_LPAR_MSR_ON;
		val &= ~V_LPAR_MSR_OFF;
		tca->srr1 = val;
		tca->srr0 += sizeof(uval32);
		return 0;
	}

	/* mfspr */
#define SET_GPR(label, src)					\
	case label: mtgpr(thr, gpr, src); break;

	if (opcode == 31 && type == 339) {
		ret = 0;
		switch (spr) {
			SET_GPR(SPRN_SRR0, vr->v_srr0);
			SET_GPR(SPRN_SRR1, vr->v_srr1);
			SET_GPR(SPRN_PVR, mfpvr());
			SET_GPR(SPRN_PIR, mfpir());

		case SPRN_DSISR:
		case SPRN_DAR:
			mtgpr(thr, gpr, 0);
			break;
		case SPRN_HID0:
		case SPRN_HID1:
		case SPRN_HID4:
		case SPRN_HID5:
			mtgpr(thr, gpr, 0xdeadbeeffeedfaceULL);
			break;

		default:
			ret = -1;
			break;
		}

		if (ret != -1) {
			tca->srr0 += sizeof(uval32);
			return ret;
		}

	}

#define SET_VREG(label, field)						\
	case label: thr->vregs->field = mfgpr(thr, gpr); break;

	/* mtspr */
	if (opcode == 31 && type == 467) {
		ret = 0;
		switch (spr) {
			SET_VREG(SPRN_SPRG0, v_sprg0);
			SET_VREG(SPRN_SPRG1, v_sprg1);
			SET_VREG(SPRN_SPRG2, v_sprg2);
			SET_VREG(SPRN_SPRG3, v_sprg3);
		case SPRN_DEC:
			partition_set_dec(thr, mfgpr(thr, gpr));
			thr->vregs->v_dec = mfgpr(thr, gpr);
			break;
		case SPRN_SRR0:
			vr->v_srr0 = mfgpr(thr, gpr);
			break;
		case SPRN_SRR1:
			vr->v_srr1 = mfgpr(thr, gpr);
			break;

		case SPRN_DSISR:
		case SPRN_DAR:
			break;
		default:
			ret = -1;
			break;
		}

		if (ret != -1) {
			tca->srr0 += sizeof(uval32);
			return ret;
		}

	}

	/* rfid */
	if (opcode == 19 && type == 18) {

		uval val = vr->v_srr1;

		set_v_msr(thr, val);
		val |= V_LPAR_MSR_ON;
		val &= ~V_LPAR_MSR_OFF;
		tca->srr1 = val;
		tca->srr0 = vr->v_srr0;
		hprintf("rfid: %lx -> %lx\n",addr, vr->v_srr0);

		return 0;
	}

	if (ret == -1) {
		hprintf("Decode instruction: %ld %ld %ld %ld\n",
			opcode, type, spr, gpr);
	}
	return ret;
}
Example #2
0
kern_return_t
DNBArchImplI386::GetGPRState(bool force)
{
    if (force || m_state.GetError(e_regSetGPR, Read))
    {
#if DEBUG_GPR_VALUES
        SET_GPR(eax);
        SET_GPR(ebx);
        SET_GPR(ecx);
        SET_GPR(edx);
        SET_GPR(edi);
        SET_GPR(esi);
        SET_GPR(ebp);
        SET_GPR(esp);
        SET_GPR(ss);
        SET_GPR(eflags);
        SET_GPR(eip);
        SET_GPR(cs);
        SET_GPR(ds);
        SET_GPR(es);
        SET_GPR(fs);
        SET_GPR(gs);
        m_state.SetError(e_regSetGPR, Read, 0);
#else
        mach_msg_type_number_t count = e_regSetWordSizeGPR;
        m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), x86_THREAD_STATE32, (thread_state_t)&m_state.context.gpr, &count));
#endif
    }
    return m_state.GetError(e_regSetGPR, Read);
}