diff options
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | hw/core/qdev-properties-system.c | 9 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 16 | ||||
-rw-r--r-- | hw/i386/bios-linker-loader.c | 8 | ||||
-rw-r--r-- | hw/i386/kvm/pci-assign.c | 56 | ||||
-rw-r--r-- | hw/openrisc/cputimer.c | 29 | ||||
-rw-r--r-- | hw/s390x/ipl.c | 17 | ||||
-rw-r--r-- | hw/virtio/virtio-rng.c | 6 | ||||
-rw-r--r-- | qga/vss-win32/install.cpp | 16 | ||||
-rw-r--r-- | savevm.c | 2 | ||||
-rw-r--r-- | target-i386/cpu.c | 14 | ||||
-rw-r--r-- | target-i386/kvm.c | 13 | ||||
-rw-r--r-- | target-i386/translate.c | 92 | ||||
-rw-r--r-- | target-openrisc/cpu.h | 1 | ||||
-rw-r--r-- | target-openrisc/interrupt.c | 25 | ||||
-rw-r--r-- | target-openrisc/mmu.c | 4 | ||||
-rw-r--r-- | target-openrisc/sys_helper.c | 54 | ||||
-rw-r--r-- | target-openrisc/translate.c | 95 | ||||
-rw-r--r-- | tests/tcg/openrisc/test_addc.c | 8 | ||||
-rw-r--r-- | tests/tcg/openrisc/test_addic.c | 10 |
20 files changed, 238 insertions, 239 deletions
@@ -1 +1 @@ -1.6.90 +1.6.91 diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 0eada32dcf..729efa81a2 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -205,6 +205,11 @@ static int parse_netdev(DeviceState *dev, const char *str, void **ptr) goto err; } + if (ncs[i]) { + ret = -EINVAL; + goto err; + } + ncs[i] = peers[i]; ncs[i]->queue_index = i; } @@ -301,6 +306,10 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, *ptr = NULL; return; } + if (*ptr) { + error_set_from_qdev_prop_error(errp, -EINVAL, dev, prop, name); + return; + } hubport = net_hub_port_find(id); if (!hubport) { diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 486e7055a6..5f36e7ec02 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -287,16 +287,17 @@ static inline void build_append_array(GArray *array, GArray *val) static void build_append_nameseg(GArray *array, const char *format, ...) { - GString *s = g_string_new(""); + /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */ + char s[] = "XXXX"; + int len; va_list args; va_start(args, format); - g_string_vprintf(s, format, args); + len = vsnprintf(s, sizeof s, format, args); va_end(args); - assert(s->len == 4); - g_array_append_vals(array, s->str, s->len); - g_string_free(s, true); + assert(len == 4); + g_array_append_vals(array, s, len); } /* 5.4 Definition Block Encoding */ @@ -424,7 +425,10 @@ static inline void *acpi_data_push(GArray *table_data, unsigned size) static unsigned acpi_data_len(GArray *table) { - return table->len * g_array_get_element_size(table); +#if GLIB_CHECK_VERSION(2, 14, 0) + assert(g_array_get_element_size(table) == 1); +#endif + return table->len; } static void acpi_align_size(GArray *blob, unsigned align) diff --git a/hw/i386/bios-linker-loader.c b/hw/i386/bios-linker-loader.c index 083385332e..fd23611008 100644 --- a/hw/i386/bios-linker-loader.c +++ b/hw/i386/bios-linker-loader.c @@ -90,7 +90,7 @@ enum { GArray *bios_linker_loader_init(void) { - return g_array_new(false, true /* clear */, sizeof(BiosLinkerLoaderEntry)); + return g_array_new(false, true /* clear */, 1); } /* Free linker wrapper and return the linker array. */ @@ -115,7 +115,7 @@ void bios_linker_loader_alloc(GArray *linker, BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH); /* Alloc entries must come first, so prepend them */ - g_array_prepend_val(linker, entry); + g_array_prepend_vals(linker, &entry, sizeof entry); } void bios_linker_loader_add_checksum(GArray *linker, const char *file, @@ -132,7 +132,7 @@ void bios_linker_loader_add_checksum(GArray *linker, const char *file, entry.cksum.start = cpu_to_le32((uint8_t *)start - (uint8_t *)table); entry.cksum.length = cpu_to_le32(size); - g_array_append_val(linker, entry); + g_array_append_vals(linker, &entry, sizeof entry); } void bios_linker_loader_add_pointer(GArray *linker, @@ -154,5 +154,5 @@ void bios_linker_loader_add_pointer(GArray *linker, assert(pointer_size == 1 || pointer_size == 2 || pointer_size == 4 || pointer_size == 8); - g_array_append_val(linker, entry); + g_array_append_vals(linker, &entry, sizeof entry); } diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index aae43097aa..968680104b 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -154,55 +154,19 @@ static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, uint64_t val = 0; int fd = dev_region->region->resource_fd; - if (fd >= 0) { - if (data) { - DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr); - if (pwrite(fd, data, size, addr) != size) { - error_report("%s - pwrite failed %s", - __func__, strerror(errno)); - } - } else { - if (pread(fd, &val, size, addr) != size) { - error_report("%s - pread failed %s", - __func__, strerror(errno)); - val = (1UL << (size * 8)) - 1; - } - DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr); + if (data) { + DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx + ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr); + if (pwrite(fd, data, size, addr) != size) { + error_report("%s - pwrite failed %s", __func__, strerror(errno)); } } else { - uint32_t port = addr + dev_region->u.r_baseport; - - if (data) { - DEBUG("out data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", host=%x\n", *data, size, addr, port); - switch (size) { - case 1: - outb(*data, port); - break; - case 2: - outw(*data, port); - break; - case 4: - outl(*data, port); - break; - } - } else { - switch (size) { - case 1: - val = inb(port); - break; - case 2: - val = inw(port); - break; - case 4: - val = inl(port); - break; - } - DEBUG("in data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", host=%x\n", val, size, addr, port); + if (pread(fd, &val, size, addr) != size) { + error_report("%s - pread failed %s", __func__, strerror(errno)); + val = (1UL << (size * 8)) - 1; } + DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx + ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr); } return val; } diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c index 988ca20898..9c54945107 100644 --- a/hw/openrisc/cputimer.c +++ b/hw/openrisc/cputimer.c @@ -30,19 +30,28 @@ static int is_counting; void cpu_openrisc_count_update(OpenRISCCPU *cpu) { - uint64_t now, next; - uint32_t wait; + uint64_t now; - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (!is_counting) { - timer_del(cpu->env.timer); - last_clk = now; return; } - + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); cpu->env.ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ, get_ticks_per_sec()); last_clk = now; +} + +void cpu_openrisc_timer_update(OpenRISCCPU *cpu) +{ + uint32_t wait; + uint64_t now, next; + + if (!is_counting) { + return; + } + + cpu_openrisc_count_update(cpu); + now = last_clk; if ((cpu->env.ttmr & TTMR_TP) <= (cpu->env.ttcr & TTMR_TP)) { wait = TTMR_TP - (cpu->env.ttcr & TTMR_TP) + 1; @@ -50,7 +59,6 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu) } else { wait = (cpu->env.ttmr & TTMR_TP) - (cpu->env.ttcr & TTMR_TP); } - next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ); timer_mod(cpu->env.timer, next); } @@ -63,8 +71,9 @@ void cpu_openrisc_count_start(OpenRISCCPU *cpu) void cpu_openrisc_count_stop(OpenRISCCPU *cpu) { - is_counting = 0; + timer_del(cpu->env.timer); cpu_openrisc_count_update(cpu); + is_counting = 0; } static void openrisc_timer_cb(void *opaque) @@ -84,15 +93,15 @@ static void openrisc_timer_cb(void *opaque) break; case TIMER_INTR: cpu->env.ttcr = 0; - cpu_openrisc_count_start(cpu); break; case TIMER_SHOT: cpu_openrisc_count_stop(cpu); break; case TIMER_CONT: - cpu_openrisc_count_start(cpu); break; } + + cpu_openrisc_timer_update(cpu); } void cpu_openrisc_clock_init(OpenRISCCPU *cpu) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index d69adb2f5b..65d39da314 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -62,10 +62,10 @@ typedef struct S390IPLState { static int s390_ipl_init(SysBusDevice *dev) { S390IPLState *ipl = S390_IPL(dev); - ram_addr_t kernel_size = 0; + int kernel_size; if (!ipl->kernel) { - ram_addr_t bios_size = 0; + int bios_size; char *bios_filename; /* Load zipl bootloader */ @@ -80,7 +80,7 @@ static int s390_ipl_init(SysBusDevice *dev) bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL, NULL, 1, ELF_MACHINE, 0); - if (bios_size == -1UL) { + if (bios_size == -1) { bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); ipl->start_addr = ZIPL_IMAGE_START; @@ -90,17 +90,17 @@ static int s390_ipl_init(SysBusDevice *dev) } g_free(bios_filename); - if ((long)bios_size < 0) { + if (bios_size == -1) { hw_error("could not load bootloader '%s'\n", bios_name); } return 0; } else { kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); - if (kernel_size == -1UL) { + if (kernel_size == -1) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } - if (kernel_size == -1UL) { + if (kernel_size == -1) { fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); return -1; } @@ -115,7 +115,8 @@ static int s390_ipl_init(SysBusDevice *dev) ipl->start_addr = KERN_IMAGE_START; } if (ipl->initrd) { - ram_addr_t initrd_offset, initrd_size; + ram_addr_t initrd_offset; + int initrd_size; initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { @@ -123,7 +124,7 @@ static int s390_ipl_init(SysBusDevice *dev) } initrd_size = load_image_targphys(ipl->initrd, initrd_offset, ram_size - initrd_offset); - if (initrd_size == -1UL) { + if (initrd_size == -1) { fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd); exit(1); } diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 314e393520..b22ccf1008 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -139,6 +139,12 @@ static int virtio_rng_device_init(VirtIODevice *vdev) VirtIORNG *vrng = VIRTIO_RNG(vdev); Error *local_err = NULL; + if (!vrng->conf.period_ms > 0) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "period", + "a positive number"); + return -1; + } + if (vrng->conf.rng == NULL) { vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM)); diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp index 37731a7271..b791a6c33b 100644 --- a/qga/vss-win32/install.cpp +++ b/qga/vss-win32/install.cpp @@ -25,8 +25,8 @@ extern HINSTANCE g_hinstDll; const GUID CLSID_COMAdminCatalog = { 0xF618C514, 0xDFB8, 0x11d1, {0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} }; -const GUID IID_ICOMAdminCatalog = { 0xDD662187, 0xDFC2, 0x11d1, - {0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} }; +const GUID IID_ICOMAdminCatalog2 = { 0x790C6E0B, 0x9194, 0x4cc9, + {0x94, 0x26, 0xA4, 0x8A, 0x63, 0x18, 0x56, 0x96} }; const GUID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0, {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} }; const GUID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf, @@ -141,7 +141,7 @@ static HRESULT QGAProviderFind( HRESULT hr; COMInitializer initializer; COMPointer<IUnknown> pUnknown; - COMPointer<ICOMAdminCatalog> pCatalog; + COMPointer<ICOMAdminCatalog2> pCatalog; COMPointer<ICatalogCollection> pColl; COMPointer<ICatalogObject> pObj; _variant_t var; @@ -149,7 +149,7 @@ static HRESULT QGAProviderFind( chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)pUnknown.replace())); - chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog, + chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2, (void **)pCatalog.replace())); chk(pCatalog->GetCollection(_bstr_t(L"Applications"), (IDispatch **)pColl.replace())); @@ -206,7 +206,7 @@ STDAPI COMRegister(void) HRESULT hr; COMInitializer initializer; COMPointer<IUnknown> pUnknown; - COMPointer<ICOMAdminCatalog> pCatalog; + COMPointer<ICOMAdminCatalog2> pCatalog; COMPointer<ICatalogCollection> pApps, pRoles, pUsersInRole; COMPointer<ICatalogObject> pObj; long n; @@ -229,7 +229,7 @@ STDAPI COMRegister(void) chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)pUnknown.replace())); - chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog, + chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2, (void **)pCatalog.replace())); /* Install COM+ Component */ @@ -273,6 +273,10 @@ STDAPI COMRegister(void) goto out; } + chk(pCatalog->CreateServiceForApplication( + _bstr_t(QGA_PROVIDER_LNAME), _bstr_t(QGA_PROVIDER_LNAME), + _bstr_t(L"SERVICE_AUTO_START"), _bstr_t(L"SERVICE_ERROR_NORMAL"), + _bstr_t(L""), _bstr_t(L".\\localsystem"), _bstr_t(L""), FALSE)); chk(pCatalog->InstallComponent(_bstr_t(QGA_PROVIDER_LNAME), _bstr_t(dllPath), _bstr_t(tlbPath), _bstr_t(""))); @@ -794,7 +794,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) if (l > size) l = size; memcpy(f->buf + f->buf_index, buf, l); - f->bytes_xfer += size; + f->bytes_xfer += l; if (f->ops->writev_buffer) { add_to_iovec(f, f->buf + f->buf_index, l); } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80eb47..47af9a8816 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2086,14 +2086,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* cache info: needed for Core compatibility */ if (cpu->cache_info_passthrough) { host_cpuid(index, count, eax, ebx, ecx, edx); - break; - } - if (cs->nr_cores > 1) { - *eax = (cs->nr_cores - 1) << 26; + *eax &= ~0xFC000000; } else { *eax = 0; - } - switch (count) { + switch (count) { case 0: /* L1 dcache info */ *eax |= CPUID_4_TYPE_DCACHE | \ CPUID_4_LEVEL(1) | \ @@ -2133,6 +2129,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; + } + } + + /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */ + if ((*eax & 31) && cs->nr_cores > 1) { + *eax |= (cs->nr_cores - 1) << 26; } break; case 5: diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 749aa09a21..1188482359 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -456,11 +456,12 @@ int kvm_arch_init_vcpu(CPUState *cs) uint32_t signature[3]; int r; + memset(&cpuid_data, 0, sizeof(cpuid_data)); + cpuid_i = 0; /* Paravirtualization CPUIDs */ c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_SIGNATURE; if (!hyperv_enabled(cpu)) { memcpy(signature, "KVMKVMKVM\0\0\0", 12); @@ -474,7 +475,6 @@ int kvm_arch_init_vcpu(CPUState *cs) c->edx = signature[2]; c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_FEATURES; c->eax = env->features[FEAT_KVM]; @@ -483,13 +483,11 @@ int kvm_arch_init_vcpu(CPUState *cs) c->eax = signature[0]; c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_VERSION; c->eax = 0x00001bbc; c->ebx = 0x00060001; c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_FEATURES; if (cpu->hyperv_relaxed_timing) { c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; @@ -500,7 +498,6 @@ int kvm_arch_init_vcpu(CPUState *cs) } c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; @@ -511,13 +508,11 @@ int kvm_arch_init_vcpu(CPUState *cs) c->ebx = cpu->hyperv_spinlock_attempts; c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_IMPLEMENT_LIMITS; c->eax = 0x40; c->ebx = 0x40; c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_SIGNATURE_NEXT; memcpy(signature, "KVMKVMKVM\0\0\0", 12); c->eax = 0; @@ -1314,8 +1309,8 @@ static int kvm_get_xcrs(X86CPU *cpu) for (i = 0; i < xcrs.nr_xcrs; i++) { /* Only support xcr0 now */ - if (xcrs.xcrs[0].xcr == 0) { - env->xcr0 = xcrs.xcrs[0].value; + if (xcrs.xcrs[i].xcr == 0) { + env->xcr0 = xcrs.xcrs[i].value; break; } } diff --git a/target-i386/translate.c b/target-i386/translate.c index ecf16b389b..7916e5b1f6 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2090,6 +2090,7 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, int scale; int opreg; int mod, rm, code, override, must_add_seg; + TCGv sum; override = s->override; must_add_seg = s->addseg; @@ -2099,10 +2100,9 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, rm = modrm & 7; if (s->aflag) { - havesib = 0; base = rm; - index = 0; + index = -1; scale = 0; if (base == 4) { @@ -2110,6 +2110,9 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, code = cpu_ldub_code(env, s->pc++); scale = (code >> 6) & 3; index = ((code >> 3) & 7) | REX_X(s); + if (index == 4) { + index = -1; /* no index */ + } base = (code & 7); } base |= REX_B(s); @@ -2137,59 +2140,57 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, break; } - if (base >= 0) { - /* for correct popl handling with esp */ - if (base == 4 && s->popl_esp_hack) - disp += s->popl_esp_hack; -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_movq_A0_reg(base); - if (disp != 0) { - gen_op_addq_A0_im(disp); - } - } else -#endif - { - gen_op_movl_A0_reg(base); - if (disp != 0) - gen_op_addl_A0_im(disp); + /* For correct popl handling with esp. */ + if (base == R_ESP && s->popl_esp_hack) { + disp += s->popl_esp_hack; + } + + /* Compute the address, with a minimum number of TCG ops. */ + TCGV_UNUSED(sum); + if (index >= 0) { + if (scale == 0) { + sum = cpu_regs[index]; + } else { + tcg_gen_shli_tl(cpu_A0, cpu_regs[index], scale); + sum = cpu_A0; } - } else { -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_movq_A0_im(disp); - } else -#endif - { - gen_op_movl_A0_im(disp); + if (base >= 0) { + tcg_gen_add_tl(cpu_A0, sum, cpu_regs[base]); + sum = cpu_A0; } + } else if (base >= 0) { + sum = cpu_regs[base]; } - /* index == 4 means no index */ - if (havesib && (index != 4)) { -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_addq_A0_reg_sN(scale, index); - } else -#endif - { - gen_op_addl_A0_reg_sN(scale, index); - } + if (TCGV_IS_UNUSED(sum)) { + tcg_gen_movi_tl(cpu_A0, disp); + } else { + tcg_gen_addi_tl(cpu_A0, sum, disp); } + if (must_add_seg) { if (override < 0) { - if (base == R_EBP || base == R_ESP) + if (base == R_EBP || base == R_ESP) { override = R_SS; - else + } else { override = R_DS; + } } -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_addq_A0_seg(override); - } else -#endif - { - gen_op_addl_A0_seg(s, override); + + tcg_gen_ld_tl(cpu_tmp0, cpu_env, + offsetof(CPUX86State, segs[override].base)); + if (CODE64(s)) { + if (s->aflag != 2) { + tcg_gen_ext32u_tl(cpu_A0, cpu_A0); + } + tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); + goto done; } + + tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); + } + + if (s->aflag != 2) { + tcg_gen_ext32u_tl(cpu_A0, cpu_A0); } } else { switch (mod) { @@ -2259,6 +2260,7 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, } } + done: opreg = OR_A0; disp = 0; *reg_ptr = opreg; diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 8fd0bc0bf0..0f9efdf6de 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -373,6 +373,7 @@ void cpu_openrisc_pic_init(OpenRISCCPU *cpu); /* hw/openrisc_timer.c */ void cpu_openrisc_clock_init(OpenRISCCPU *cpu); void cpu_openrisc_count_update(OpenRISCCPU *cpu); +void cpu_openrisc_timer_update(OpenRISCCPU *cpu); void cpu_openrisc_count_start(OpenRISCCPU *cpu); void cpu_openrisc_count_stop(OpenRISCCPU *cpu); diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c index 16ef4b3e79..2153e7ea7e 100644 --- a/target-openrisc/interrupt.c +++ b/target-openrisc/interrupt.c @@ -30,26 +30,15 @@ void openrisc_cpu_do_interrupt(CPUState *cs) OpenRISCCPU *cpu = OPENRISC_CPU(cs); CPUOpenRISCState *env = &cpu->env; #ifndef CONFIG_USER_ONLY - if (env->flags & D_FLAG) { /* Delay Slot insn */ + + env->epcr = env->pc; + if (env->flags & D_FLAG) { env->flags &= ~D_FLAG; env->sr |= SR_DSX; - if (env->exception_index == EXCP_TICK || - env->exception_index == EXCP_INT || - env->exception_index == EXCP_SYSCALL || - env->exception_index == EXCP_FPE) { - env->epcr = env->jmp_pc; - } else { - env->epcr = env->pc - 4; - } - } else { - if (env->exception_index == EXCP_TICK || - env->exception_index == EXCP_INT || - env->exception_index == EXCP_SYSCALL || - env->exception_index == EXCP_FPE) { - env->epcr = env->npc; - } else { - env->epcr = env->pc; - } + env->epcr -= 4; + } + if (env->exception_index == EXCP_SYSCALL) { + env->epcr += 4; } /* For machine-state changed between user-mode and supervisor mode, diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index 22d7cbec18..dd487bd0d1 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -32,7 +32,7 @@ int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu, int *prot, target_ulong address, int rw) { *physical = address; - *prot = PAGE_READ | PAGE_WRITE; + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; return TLBRET_MATCH; } @@ -187,7 +187,7 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, if (ret == TLBRET_MATCH) { tlb_set_page(env, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, + physical & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); ret = 0; } else if (ret < 0) { diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c index cccbc0e939..be06c4565b 100644 --- a/target-openrisc/sys_helper.c +++ b/target-openrisc/sys_helper.c @@ -81,7 +81,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(0, 64): /* ESR */ env->esr = rb; break; - case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr - TO_SPR(1, 512); if (!(rb & 1)) { tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK); @@ -89,7 +89,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, env->tlb->dtlb[0][idx].mr = rb; break; - case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ + case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */ idx = spr - TO_SPR(1, 640); env->tlb->dtlb[0][idx].tr = rb; break; @@ -100,7 +100,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ break; - case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ + case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */ idx = spr - TO_SPR(2, 512); if (!(rb & 1)) { tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK); @@ -108,7 +108,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, env->tlb->itlb[0][idx].mr = rb; break; - case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ + case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */ idx = spr - TO_SPR(2, 640); env->tlb->itlb[0][idx].tr = rb; break; @@ -127,33 +127,31 @@ void HELPER(mtspr)(CPUOpenRISCState *env, break; case TO_SPR(10, 0): /* TTMR */ { + if ((env->ttmr & TTMR_M) ^ (rb & TTMR_M)) { + switch (rb & TTMR_M) { + case TIMER_NONE: + cpu_openrisc_count_stop(cpu); + break; + case TIMER_INTR: + case TIMER_SHOT: + case TIMER_CONT: + cpu_openrisc_count_start(cpu); + break; + default: + break; + } + } + int ip = env->ttmr & TTMR_IP; if (rb & TTMR_IP) { /* Keep IP bit. */ - env->ttmr = (rb & ~TTMR_IP) + ip; + env->ttmr = (rb & ~TTMR_IP) | ip; } else { /* Clear IP bit. */ env->ttmr = rb & ~TTMR_IP; cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; } - cpu_openrisc_count_update(cpu); - - switch (env->ttmr & TTMR_M) { - case TIMER_NONE: - cpu_openrisc_count_stop(cpu); - break; - case TIMER_INTR: - cpu_openrisc_count_start(cpu); - break; - case TIMER_SHOT: - cpu_openrisc_count_start(cpu); - break; - case TIMER_CONT: - cpu_openrisc_count_start(cpu); - break; - default: - break; - } + cpu_openrisc_timer_update(cpu); } break; @@ -162,7 +160,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, if (env->ttmr & TIMER_NONE) { return; } - cpu_openrisc_count_start(cpu); + cpu_openrisc_timer_update(cpu); break; default: @@ -214,11 +212,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(0, 64): /* ESR */ return env->esr; - case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr - TO_SPR(1, 512); return env->tlb->dtlb[0][idx].mr; - case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ + case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */ idx = spr - TO_SPR(1, 640); return env->tlb->dtlb[0][idx].tr; @@ -230,11 +228,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ break; - case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ + case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */ idx = spr - TO_SPR(2, 512); return env->tlb->itlb[0][idx].mr; - case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ + case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */ idx = spr - TO_SPR(2, 640); return env->tlb->itlb[0][idx].tr; diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 8908a2e32b..91c60ebaae 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -209,42 +209,49 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) { target_ulong tmp_pc; - int lab = gen_new_label(); - TCGv sr_f = tcg_temp_new(); /* N26, 26bits imm */ tmp_pc = sign_extend((imm<<2), 26) + dc->pc; - tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); - if (op0 == 0x00) { /* l.j */ + switch (op0) { + case 0x00: /* l.j */ tcg_gen_movi_tl(jmp_pc, tmp_pc); - } else if (op0 == 0x01) { /* l.jal */ + break; + case 0x01: /* l.jal */ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); tcg_gen_movi_tl(jmp_pc, tmp_pc); - } else if (op0 == 0x03) { /* l.bnf */ - tcg_gen_movi_tl(jmp_pc, dc->pc+8); - tcg_gen_brcondi_i32(TCG_COND_EQ, sr_f, SR_F, lab); - tcg_gen_movi_tl(jmp_pc, tmp_pc); - gen_set_label(lab); - } else if (op0 == 0x04) { /* l.bf */ - tcg_gen_movi_tl(jmp_pc, dc->pc+8); - tcg_gen_brcondi_i32(TCG_COND_NE, sr_f, SR_F, lab); - tcg_gen_movi_tl(jmp_pc, tmp_pc); - gen_set_label(lab); - } else if (op0 == 0x11) { /* l.jr */ + break; + case 0x03: /* l.bnf */ + case 0x04: /* l.bf */ + { + int lab = gen_new_label(); + TCGv sr_f = tcg_temp_new(); + tcg_gen_movi_tl(jmp_pc, dc->pc+8); + tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); + tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, + sr_f, SR_F, lab); + tcg_gen_movi_tl(jmp_pc, tmp_pc); + gen_set_label(lab); + tcg_temp_free(sr_f); + } + break; + case 0x11: /* l.jr */ tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); - } else if (op0 == 0x12) { /* l.jalr */ + break; + case 0x12: /* l.jalr */ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); - } else { + break; + default: gen_illegal_exception(dc); + break; } - tcg_temp_free(sr_f); dc->delayed_branch = 2; dc->tb_flags |= D_FLAG; gen_sync_flags(dc); } + static void dec_calc(DisasContext *dc, uint32_t insn) { uint32_t op0, op1, op2; @@ -904,29 +911,33 @@ static void dec_misc(DisasContext *dc, uint32_t insn) case 0x27: /* l.addi */ LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); { - int lab = gen_new_label(); - TCGv_i64 ta = tcg_temp_new_i64(); - TCGv_i64 td = tcg_temp_local_new_i64(); - TCGv_i32 res = tcg_temp_local_new_i32(); - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); - tcg_gen_extu_i32_i64(ta, cpu_R[ra]); - tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); - tcg_gen_trunc_i64_i32(res, td); - tcg_gen_shri_i64(td, td, 32); - tcg_gen_andi_i64(td, td, 0x3); - /* Jump to lab when no overflow. */ - tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); - tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); - tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); - gen_exception(dc, EXCP_RANGE); - gen_set_label(lab); - tcg_gen_mov_i32(cpu_R[rd], res); - tcg_temp_free_i64(ta); - tcg_temp_free_i64(td); - tcg_temp_free_i32(res); - tcg_temp_free_i32(sr_ove); + if (I16 == 0) { + tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]); + } else { + int lab = gen_new_label(); + TCGv_i64 ta = tcg_temp_new_i64(); + TCGv_i64 td = tcg_temp_local_new_i64(); + TCGv_i32 res = tcg_temp_local_new_i32(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + tcg_gen_extu_i32_i64(ta, cpu_R[ra]); + tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); + tcg_gen_trunc_i64_i32(res, td); + tcg_gen_shri_i64(td, td, 32); + tcg_gen_andi_i64(td, td, 0x3); + /* Jump to lab when no overflow. */ + tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); + tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); + tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab); + tcg_gen_mov_i32(cpu_R[rd], res); + tcg_temp_free_i64(ta); + tcg_temp_free_i64(td); + tcg_temp_free_i32(res); + tcg_temp_free_i32(sr_ove); + } } break; diff --git a/tests/tcg/openrisc/test_addc.c b/tests/tcg/openrisc/test_addc.c index 05d18f8ce5..a8f756a69b 100644 --- a/tests/tcg/openrisc/test_addc.c +++ b/tests/tcg/openrisc/test_addc.c @@ -7,9 +7,10 @@ int main(void) b = 0x01; c = 0xffffffff; - result = 1; + result = 0; __asm - ("l.addc %0, %1, %2\n\t" + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addc %0, %1, %2\n\t" : "=r"(a) : "r"(b), "r"(c) ); @@ -22,7 +23,8 @@ int main(void) c = 0xffffffff; result = 0x80000001; __asm - ("l.addc %0, %1, %2\n\t" + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addc %0, %1, %2\n\t" "l.movhi %2, 0x7fff\n\t" "l.ori %2, %2, 0xffff\n\t" "l.addc %0, %1, %2\n\t" diff --git a/tests/tcg/openrisc/test_addic.c b/tests/tcg/openrisc/test_addic.c index 4ba7432521..857aaa1330 100644 --- a/tests/tcg/openrisc/test_addic.c +++ b/tests/tcg/openrisc/test_addic.c @@ -6,9 +6,10 @@ int main(void) int result; a = 1; - result = 0x1; + result = 0x0; __asm - ("l.addic %0, %0, 0xffff\n\t" + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addic %0, %0, 0xffff\n\t" : "+r"(a) ); if (a != result) { @@ -16,10 +17,11 @@ int main(void) return -1; } - a = 0x1; + a = -1; result = 0x201; __asm - ("l.addic %0, %0, 0xffff\n\t" + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addic %0, %0, 0x1\n\t" "l.ori %0, r0, 0x100\n\t" "l.addic %0, %0, 0x100\n\t" : "+r"(a) |