⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmio.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    rc = __vmx_identity_mapping_load(d, XEN_IA64_OPTF_IDENT_MAP_REG4,                                     &im_load.im_reg4);    if (rc)        return rc;    rc = __vmx_identity_mapping_load(d, XEN_IA64_OPTF_IDENT_MAP_REG5,                                     &im_load.im_reg5);    if (rc)        return rc;    rc = __vmx_identity_mapping_load(d, XEN_IA64_OPTF_IDENT_MAP_REG7,                                     &im_load.im_reg7);    return rc;}HVM_REGISTER_SAVE_RESTORE(OPT_FEATURE_IDENTITY_MAPPINGS,                           vmx_identity_mappings_save,                          vmx_identity_mappings_load,                          1, HVMSR_PER_DOM);static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir){    struct vcpu *v = current;    vcpu_iodata_t *vio;    ioreq_t *p;    vio = get_vio(v);    if (!vio)        panic_domain(NULL, "bad shared page\n");    p = &vio->vp_ioreq;    p->addr = TO_LEGACY_IO(pa & 0x3ffffffUL);    p->size = s;    p->count = 1;    p->dir = dir;    if (dir == IOREQ_WRITE)        p->data = *val;    else        p->data = 0;    p->data_is_ptr = 0;    p->type = 0;    p->df = 0;    p->io_count++;        if (vmx_ide_pio_intercept(p, val))        return;    if (IS_ACPI_ADDR(p->addr) && vacpi_intercept(p, val))        return;    vmx_send_assist_req(v);    if (dir == IOREQ_READ) { // read        *val=p->data;    }#ifdef DEBUG_PCI    if (dir == IOREQ_WRITE)        if (p->addr == 0xcf8UL)            printk("Write 0xcf8, with val [0x%lx]\n", p->data);    else        if (p->addr == 0xcfcUL)            printk("Read 0xcfc, with val [0x%lx]\n", p->data);#endif //DEBUG_PCI    return;}static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 iot){    perfc_incra(vmx_mmio_access, iot & 0x7);    switch (iot) {    case GPFN_PIB:               if (ma != 4)            panic_domain(NULL, "Access PIB not with UC attribute\n");        if (!dir)            vlsapic_write(vcpu, src_pa, s, *dest);        else            *dest = vlsapic_read(vcpu, src_pa, s);        break;    case GPFN_IOSAPIC:        if (!dir)            viosapic_write(vcpu, src_pa, s, *dest);        else            *dest = viosapic_read(vcpu, src_pa, s);        break;    case GPFN_FRAME_BUFFER:    case GPFN_LOW_MMIO:        low_mmio_access(vcpu, src_pa, dest, s, dir);        break;    case GPFN_LEGACY_IO:        legacy_io_access(vcpu, src_pa, dest, s, dir);        break;    default:        panic_domain(NULL,"Bad I/O access\n");        break;    }    return;}enum inst_type_en { SL_INTEGER, SL_FLOATING, SL_FLOATING_FP8 };/*   dir 1: read 0:write */void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 iot){    REGS *regs;    IA64_BUNDLE bundle;    int slot, dir=0;    enum inst_type_en inst_type;    size_t size;    u64 data, data1, temp, update_reg;    s32 imm;    INST64 inst;    unsigned long update_word;    regs = vcpu_regs(vcpu);    if (IA64_RETRY == __vmx_get_domain_bundle(regs->cr_iip, &bundle)) {        /* if fetch code fail, return and try again */        return;    }    slot = ((struct ia64_psr *)&(regs->cr_ipsr))->ri;    if (!slot)        inst.inst = bundle.slot0;    else if (slot == 1) {        u64 slot1b = bundle.slot1b;        inst.inst = bundle.slot1a + (slot1b << 18);    }    else if (slot == 2)        inst.inst = bundle.slot2;    // Integer Load/Store    if (inst.M1.major == 4 && inst.M1.m == 0 && inst.M1.x == 0) {        inst_type = SL_INTEGER;        size = (inst.M1.x6 & 0x3);        if ((inst.M1.x6 >> 2) > 0xb) {            dir = IOREQ_WRITE;            vcpu_get_gr_nat(vcpu, inst.M4.r2, &data);        } else if ((inst.M1.x6 >> 2) < 0xb) {            dir = IOREQ_READ;        }    }    // Integer Load + Reg update    else if (inst.M2.major == 4 && inst.M2.m == 1 && inst.M2.x == 0) {        inst_type = SL_INTEGER;        dir = IOREQ_READ;        size = (inst.M2.x6 & 0x3);        vcpu_get_gr_nat(vcpu, inst.M2.r3, &temp);        vcpu_get_gr_nat(vcpu, inst.M2.r2, &update_reg);        temp += update_reg;        vcpu_set_gr(vcpu, inst.M2.r3, temp, 0);    }    // Integer Load/Store + Imm update    else if (inst.M3.major == 5) {        inst_type = SL_INTEGER;        size = (inst.M3.x6 & 0x3);        if ((inst.M5.x6 >> 2) > 0xb) {            dir = IOREQ_WRITE;            vcpu_get_gr_nat(vcpu, inst.M5.r2, &data);            vcpu_get_gr_nat(vcpu, inst.M5.r3, &temp);            imm = (inst.M5.s << 31) | (inst.M5.i << 30) | (inst.M5.imm7 << 23);            temp += imm >> 23;            vcpu_set_gr(vcpu, inst.M5.r3, temp, 0);        } else if ((inst.M3.x6 >> 2) < 0xb) {            dir = IOREQ_READ;            vcpu_get_gr_nat(vcpu, inst.M3.r3, &temp);            imm = (inst.M3.s << 31) | (inst.M3.i << 30) | (inst.M3.imm7 << 23);            temp += imm >> 23;            vcpu_set_gr(vcpu, inst.M3.r3, temp, 0);        }    }    // Floating-point spill    else if (inst.M9.major == 6 && inst.M9.x6 == 0x3B &&             inst.M9.m == 0 && inst.M9.x == 0) {        struct ia64_fpreg v;        inst_type = SL_FLOATING;        dir = IOREQ_WRITE;        vcpu_get_fpreg(vcpu, inst.M9.f2, &v);        data1 = v.u.bits[1] & 0x3ffff;        data = v.u.bits[0];        size = 4;    }    // Floating-point spill + Imm update    else if (inst.M10.major == 7 && inst.M10.x6 == 0x3B) {        struct ia64_fpreg v;        inst_type = SL_FLOATING;        dir = IOREQ_WRITE;        vcpu_get_fpreg(vcpu, inst.M10.f2, &v);        vcpu_get_gr_nat(vcpu, inst.M10.r3, &temp);        imm = (inst.M10.s << 31) | (inst.M10.i << 30) | (inst.M10.imm7 << 23);        temp += imm >> 23;        vcpu_set_gr(vcpu, inst.M10.r3, temp, 0);        data1 = v.u.bits[1] & 0x3ffff;        data = v.u.bits[0];        size = 4;    }    // Floating-point stf8 + Imm update    else if (inst.M10.major == 7 && inst.M10.x6 == 0x31) {        struct ia64_fpreg v;        inst_type = SL_FLOATING;        dir = IOREQ_WRITE;        size = 3;        vcpu_get_fpreg(vcpu, inst.M10.f2, &v);        data = v.u.bits[0]; /* Significand.  */        vcpu_get_gr_nat(vcpu, inst.M10.r3, &temp);        imm = (inst.M10.s << 31) | (inst.M10.i << 30) | (inst.M10.imm7 << 23);        temp += imm >> 23;        vcpu_set_gr(vcpu, inst.M10.r3, temp, 0);    }    //  lfetch - do not perform accesses.    else if (inst.M15.major== 7 && inst.M15.x6 >=0x2c && inst.M15.x6 <= 0x2f) {        vcpu_get_gr_nat(vcpu, inst.M15.r3, &temp);        imm = (inst.M15.s << 31) | (inst.M15.i << 30) | (inst.M15.imm7 << 23);        temp += imm >> 23;        vcpu_set_gr(vcpu, inst.M15.r3, temp, 0);        vcpu_increment_iip(vcpu);        return;    }    // Floating-point Load Pair + Imm ldfp8 M12    else if (inst.M12.major == 6 && inst.M12.m == 1             && inst.M12.x == 1 && inst.M12.x6 == 1) {        inst_type = SL_FLOATING_FP8;        dir = IOREQ_READ;        size = 4;     //ldfd        vcpu_set_gr(vcpu,inst.M12.r3,padr + 16, 0);    }    else {        panic_domain            (NULL, "This memory access instr can't be emulated: %lx pc=%lx\n",             inst.inst, regs->cr_iip);    }    update_word = size | (dir << 7) | (ma << 8) | (inst_type << 12);    if (dir == IOREQ_READ) {        if (inst_type == SL_INTEGER)            update_word |= (inst.M1.r1 << 16);        else if (inst_type == SL_FLOATING_FP8)            update_word |= (inst.M12.f1 << 16) | (inst.M12.f2 << 24);    }    if (vcpu->domain->arch.is_sioemu) {        if (iot != GPFN_PIB && iot != GPFN_IOSAPIC) {            sioemu_io_emulate(padr, data, data1, update_word);            return;        }    }    if (size == 4) {        mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, iot);        size = 3;    }    mmio_access(vcpu, padr, &data, 1 << size, ma, dir, iot);    emulate_io_update(vcpu, update_word, data, data1);}voidemulate_io_update(VCPU *vcpu, u64 word, u64 data, u64 data1){    int dir = (word >> 7) & 1;    if (dir == IOREQ_READ) {        int r1 = (word >> 16) & 0xff;        int r2 = (word >> 24) & 0xff;        enum inst_type_en inst_type = (word >> 12) & 0x0f;        if (inst_type == SL_INTEGER) {            vcpu_set_gr(vcpu, r1, data, 0);        } else if (inst_type == SL_FLOATING_FP8) {            struct ia64_fpreg v;            v.u.bits[0] = data;            v.u.bits[1] = 0x1003E;            vcpu_set_fpreg(vcpu, r1, &v);            v.u.bits[0] = data1;            v.u.bits[1] = 0x1003E;            vcpu_set_fpreg(vcpu, r2, &v);        } else {            panic_domain(NULL, "Don't support ldfd now !");        }    }    vcpu_increment_iip(vcpu);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -