Beispiel #1
0
sval
vbase_config(struct cpu_thread* thr, uval vbase, uval size)
{
	uval i = 0;
	struct vstate *v;
	thr->vbo = vbase;
	thr->vbl = size;

	struct vm_class *vmc;
	thr->vmc_vregs = vmc_create_vregs();


	thr->vregs = (struct vregs*)thr->vmc_vregs->vmc_data;
	memset(thr->vregs, 0, sizeof(typeof(*thr->vregs)));
	thr->vregs->v_pir = mfpir();
	v = &thr->vstate;
	v->thread_mode = VSTATE_KERN_MODE;


	vmc = vmc_create_linear(0, 0, 1ULL << VM_CLASS_SPACE_SIZE_BITS, 0);
	thr->cpu->os->vmc_kernel[0] = vmc;


	for (i = 0 ; i < NUM_MAP_CLASSES; ++i) {
		thr->vregs->v_active_cls[i] = INVALID_CLASS;
	}

	partition_set_dec(thr, -1);

	return 0;
}
Beispiel #2
0
uval
test_os(void)
{
	reg_t mylpid;
	reg_t regsave[32];
	int i=0;
	(void)hcall_get_lpid(&mylpid);

	ctxt_count = ((uval64)mylpid) << 32;
	hputs("You should see repeated 'SUCCESS' messages.\n"
	      "This test will run until manually halted.\n");
	if (mfpir() == 0)
	    hcall_thread_control(regsave, HTC_START, 1, 0);
	while (1) {
	    hprintf("multi: %d:%d\n", mfpir(), i);
	    ++i;
	}

	return 0;
}
Beispiel #3
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;
}
int cpu_machinecheck(struct cpu_user_regs *regs)
{
    int recover = 0;
    u32 dsisr = mfdsisr();

    if (regs->msr & MCK_SRR1_RI)
        recover = 1;

    printk("MACHINE CHECK: %s Recoverable\n", recover ? "IS": "NOT");
    if (mck_cpu_stats[mfpir()] != 0)
        printk("While in CI IO\n");

    show_backtrace_regs(regs);

    printk("SRR1: 0x%016lx\n", regs->msr);
    if (regs->msr & MCK_SRR1_INSN_FETCH_UNIT)
        printk("42: Exception caused by Instruction Fetch Unit (IFU)\n"
               "    detection of a hardware uncorrectable error (UE).\n");

    if (regs->msr & MCK_SRR1_LOAD_STORE)
        printk("43: Exception caused by load/store detection of error\n"
               "    (see DSISR)\n");

    switch (regs->msr & MCK_SRR1_CAUSE_MASK) {
    case 0:
        printk("0b00: Likely caused by an asynchronous machine check,\n"
               "      see SCOM Asynchronous Machine Check Register\n");
        cpu_scom_AMCR();
        break;
    case MCK_SRR1_CAUSE_SLB_PAR:
        printk("0b01: Exception caused by an SLB parity error detected\n"
               "      while translating an instruction fetch address.\n");
        break;
    case MCK_SRR1_CAUSE_TLB_PAR:
        printk("0b10: Exception caused by a TLB parity error detected\n"
               "      while translating an instruction fetch address.\n");
        break;
    case MCK_SRR1_CAUSE_UE:
        printk("0b11: Exception caused by a hardware uncorrectable\n"
               "      error (UE) detected while doing a reload of an\n"
               "      instruction-fetch TLB tablewalk.\n");
        break;
    }

    printk("\nDSISR: 0x%08x\n", dsisr);
    if (dsisr & MCK_DSISR_UE)
        printk("16: Exception caused by a UE deferred error\n"
               "    (DAR is undefined).\n");
    
    if (dsisr & MCK_DSISR_UE_TABLE_WALK)
        printk("17: Exception caused by a UE deferred error\n"
               "    during a tablewalk (D-side).\n"); 

    if (dsisr & MCK_DSISR_L1_DCACHE_PAR)
        printk("18: Exception was caused by a software recoverable\n"
               "    parity error in the L1 D-cache.\n");

    if (dsisr & MCK_DSISR_L1_DCACHE_TAG_PAR)
        printk("19: Exception was caused by a software recoverable\n"
               "    parity error in the L1 D-cache tag.\n");

    if (dsisr & MCK_DSISR_D_ERAT_PAR)
        printk("20: Exception was caused by a software recoverable parity\n"
               "    error in the D-ERAT.\n");
        
    if (dsisr & MCK_DSISR_TLB_PAR)
        printk("21: Exception was caused by a software recoverable parity\n"
               "    error in the TLB.\n");

    if (dsisr & MCK_DSISR_SLB_PAR) {
        printk("23: Exception was caused by an SLB parity error (may not be\n"
               "    recoverable). This condition could occur if the\n"
               "    effective segment ID (ESID) fields of two or more SLB\n"
               "    entries contain the same value.\n");
        dump_segments(0);
    }

    return 0; /* for now lets not recover */
}