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; }
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; }
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 */ }