aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--VERSION2
-rw-r--r--backends/rng-egd.c5
-rwxr-xr-xconfigure5
-rw-r--r--hw/core/qdev-properties-system.c9
-rw-r--r--hw/display/tcx.c26
-rw-r--r--hw/i386/kvm/pci-assign.c56
-rw-r--r--hw/i386/pc_piix.c7
-rw-r--r--hw/i386/pc_q35.c7
-rw-r--r--hw/mips/mips_jazz.c24
-rw-r--r--hw/misc/pvpanic.c5
-rw-r--r--hw/misc/vfio.c7
-rw-r--r--hw/openrisc/cputimer.c29
-rw-r--r--hw/sparc/sun4m.c17
-rw-r--r--hw/virtio/virtio-rng.c6
-rw-r--r--include/hw/i386/pc.h1
-rw-r--r--include/qemu/atomic.h6
-rw-r--r--pc-bios/QEMU,tcx.binbin0 -> 1242 bytes
-rw-r--r--pc-bios/README4
-rw-r--r--qga/commands-posix.c8
-rw-r--r--qga/guest-agent-core.h2
-rw-r--r--qga/vss-win32/install.cpp16
-rw-r--r--savevm.c2
-rw-r--r--target-i386/cpu.c14
-rw-r--r--target-i386/helper.h1
-rw-r--r--target-i386/kvm-stub.c12
-rw-r--r--target-i386/kvm.c13
-rw-r--r--target-i386/misc_helper.c22
-rw-r--r--target-i386/translate.c97
-rw-r--r--target-openrisc/cpu.h1
-rw-r--r--target-openrisc/interrupt.c25
-rw-r--r--target-openrisc/mmu.c4
-rw-r--r--target-openrisc/sys_helper.c54
-rw-r--r--target-openrisc/translate.c95
-rw-r--r--tests/tcg/openrisc/test_addc.c8
-rw-r--r--tests/tcg/openrisc/test_addic.c10
36 files changed, 337 insertions, 265 deletions
diff --git a/Makefile b/Makefile
index 3321b98167..bdff4e4684 100644
--- a/Makefile
+++ b/Makefile
@@ -293,7 +293,7 @@ ifdef INSTALL_BLOBS
BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
acpi-dsdt.aml q35-acpi-dsdt.aml \
-ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
+ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
diff --git a/VERSION b/VERSION
index 86e63cc647..56b4609ff0 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.90
+1.6.91
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 9e5a5366f7..25bb3b453b 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -91,12 +91,14 @@ static int rng_egd_chr_can_read(void *opaque)
static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
{
RngEgd *s = RNG_EGD(opaque);
+ size_t buf_offset = 0;
while (size > 0 && s->requests) {
RngRequest *req = s->requests->data;
int len = MIN(size, req->size - req->offset);
- memcpy(req->data + req->offset, buf, len);
+ memcpy(req->data + req->offset, buf + buf_offset, len);
+ buf_offset += len;
req->offset += len;
size -= len;
@@ -167,7 +169,6 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
if (b->opened) {
error_set(errp, QERR_PERMISSION_DENIED);
} else {
- g_free(s->chr_name);
s->chr_name = g_strdup(value);
}
}
diff --git a/configure b/configure
index 9b9b9fa0b5..066622865f 100755
--- a/configure
+++ b/configure
@@ -323,6 +323,9 @@ query_pkg_config() {
pkg_config=query_pkg_config
sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}"
+# If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
+ARFLAGS="${ARFLAGS-rv}"
+
# default flags for all hosts
QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
@@ -3695,6 +3698,7 @@ echo "C compiler $cc"
echo "Host C compiler $host_cc"
echo "C++ compiler $cxx"
echo "Objective-C compiler $objcc"
+echo "ARFLAGS $ARFLAGS"
echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS"
echo "LDFLAGS $LDFLAGS"
@@ -4276,6 +4280,7 @@ echo "HOST_CC=$host_cc" >> $config_host_mak
echo "CXX=$cxx" >> $config_host_mak
echo "OBJCC=$objcc" >> $config_host_mak
echo "AR=$ar" >> $config_host_mak
+echo "ARFLAGS=$ARFLAGS" >> $config_host_mak
echo "AS=$as" >> $config_host_mak
echo "CPP=$cpp" >> $config_host_mak
echo "OBJCOPY=$objcopy" >> $config_host_mak
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/display/tcx.c b/hw/display/tcx.c
index 24876d33ef..873b82c8db 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -25,8 +25,12 @@
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/pixel_ops.h"
+#include "hw/loader.h"
#include "hw/sysbus.h"
+#define TCX_ROM_FILE "QEMU,tcx.bin"
+#define FCODE_MAX_ROM_SIZE 0x10000
+
#define MAXX 1024
#define MAXY 768
#define TCX_DAC_NREGS 16
@@ -43,6 +47,8 @@ typedef struct TCXState {
QemuConsole *con;
uint8_t *vram;
uint32_t *vram24, *cplane;
+ hwaddr prom_addr;
+ MemoryRegion rom;
MemoryRegion vram_mem;
MemoryRegion vram_8bit;
MemoryRegion vram_24bit;
@@ -529,14 +535,31 @@ static int tcx_init1(SysBusDevice *dev)
{
TCXState *s = TCX(dev);
ram_addr_t vram_offset = 0;
- int size;
+ int size, ret;
uint8_t *vram_base;
+ char *fcode_filename;
memory_region_init_ram(&s->vram_mem, OBJECT(s), "tcx.vram",
s->vram_size * (1 + 4 + 4));
vmstate_register_ram_global(&s->vram_mem);
vram_base = memory_region_get_ram_ptr(&s->vram_mem);
+ /* FCode ROM */
+ memory_region_init_ram(&s->rom, NULL, "tcx.prom", FCODE_MAX_ROM_SIZE);
+ vmstate_register_ram_global(&s->rom);
+ memory_region_set_readonly(&s->rom, true);
+ sysbus_init_mmio(dev, &s->rom);
+
+ fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, TCX_ROM_FILE);
+ if (fcode_filename) {
+ ret = load_image_targphys(fcode_filename, s->prom_addr,
+ FCODE_MAX_ROM_SIZE);
+ if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
+ fprintf(stderr, "tcx: could not load prom '%s'\n", TCX_ROM_FILE);
+ return -1;
+ }
+ }
+
/* 8-bit plane */
s->vram = vram_base;
size = s->vram_size;
@@ -598,6 +621,7 @@ static Property tcx_properties[] = {
DEFINE_PROP_UINT16("width", TCXState, width, -1),
DEFINE_PROP_UINT16("height", TCXState, height, -1),
DEFINE_PROP_UINT16("depth", TCXState, depth, -1),
+ DEFINE_PROP_HEX64("prom_addr", TCXState, prom_addr, -1),
DEFINE_PROP_END_OF_LIST(),
};
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/i386/pc_piix.c b/hw/i386/pc_piix.c
index 094c4212e6..2111f0192c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -57,7 +57,6 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
-static bool has_pvpanic;
static bool has_pci_info;
static bool has_acpi_build = true;
@@ -229,10 +228,6 @@ static void pc_init1(QEMUMachineInitArgs *args,
if (pci_enabled) {
pc_pci_device_init(pci_bus);
}
-
- if (has_pvpanic) {
- pvpanic_init(isa_bus);
- }
}
static void pc_init_pci(QEMUMachineInitArgs *args)
@@ -250,13 +245,11 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args)
static void pc_compat_1_5(QEMUMachineInitArgs *args)
{
pc_compat_1_6(args);
- has_pvpanic = true;
}
static void pc_compat_1_4(QEMUMachineInitArgs *args)
{
pc_compat_1_5(args);
- has_pvpanic = false;
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 1af8e2b943..600fc02ebe 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -47,7 +47,6 @@
/* ICH9 AHCI has 6 ports */
#define MAX_SATA_PORTS 6
-static bool has_pvpanic;
static bool has_pci_info;
static bool has_acpi_build = true;
@@ -216,10 +215,6 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
if (pci_enabled) {
pc_pci_device_init(host_bus);
}
-
- if (has_pvpanic) {
- pvpanic_init(isa_bus);
- }
}
static void pc_compat_1_6(QEMUMachineInitArgs *args)
@@ -232,13 +227,11 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args)
static void pc_compat_1_5(QEMUMachineInitArgs *args)
{
pc_compat_1_6(args);
- has_pvpanic = true;
}
static void pc_compat_1_4(QEMUMachineInitArgs *args)
{
pc_compat_1_5(args);
- has_pvpanic = false;
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
}
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 49bdd024ed..5f6dd9f588 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -108,6 +108,18 @@ static void cpu_request_exit(void *opaque, int irq, int level)
}
}
+static CPUUnassignedAccess real_do_unassigned_access;
+static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
+ bool is_write, bool is_exec,
+ int opaque, unsigned size)
+{
+ if (!is_exec) {
+ /* ignore invalid access (ie do not raise exception) */
+ return;
+ }
+ (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
+}
+
static void mips_jazz_init(MemoryRegion *address_space,
MemoryRegion *address_space_io,
ram_addr_t ram_size,
@@ -117,6 +129,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
char *filename;
int bios_size, n;
MIPSCPU *cpu;
+ CPUClass *cc;
CPUMIPSState *env;
qemu_irq *rc4030, *i8259;
rc4030_dma *dmas;
@@ -154,6 +167,17 @@ static void mips_jazz_init(MemoryRegion *address_space,
env = &cpu->env;
qemu_register_reset(main_cpu_reset, cpu);
+ /* Chipset returns 0 in invalid reads and do not raise data exceptions.
+ * However, we can't simply add a global memory region to catch
+ * everything, as memory core directly call unassigned_mem_read/write
+ * on some invalid accesses, which call do_unassigned_access on the
+ * CPU, which raise an exception.
+ * Handle that case by hijacking the do_unassigned_access method on
+ * the CPU, and do not raise exceptions for data access. */
+ cc = CPU_GET_CLASS(cpu);
+ real_do_unassigned_access = cc->do_unassigned_access;
+ cc->do_unassigned_access = mips_jazz_do_unassigned_access;
+
/* allocate RAM */
memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size);
vmstate_register_ram_global(ram);
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 226e2983d3..5377feed69 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -112,11 +112,6 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
isa_register_ioport(d, &s->io, s->ioport);
}
-void pvpanic_init(ISABus *bus)
-{
- isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE);
-}
-
#define PVPANIC_IOPORT_PROP "ioport"
uint16_t pvpanic_port(void)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index fe95e03d1d..f7f8a19ee8 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -3568,6 +3568,13 @@ static int vfio_initfn(PCIDevice *pdev)
vdev->emulated_config_bits[PCI_HEADER_TYPE] =
PCI_HEADER_TYPE_MULTI_FUNCTION;
+ /* Restore or clear multifunction, this is always controlled by QEMU */
+ if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
+ vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
+ } else {
+ vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;
+ }
+
/*
* Clear host resource mapping info. If we choose not to register a
* BAR, such as might be the case with the option ROM, we can get
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/sparc/sun4m.c b/hw/sparc/sun4m.c
index a0d366cbbc..94f79508d8 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -537,24 +537,27 @@ static void tcx_init(hwaddr addr, int vram_size, int width,
qdev_prop_set_uint16(dev, "width", width);
qdev_prop_set_uint16(dev, "height", height);
qdev_prop_set_uint16(dev, "depth", depth);
+ qdev_prop_set_uint64(dev, "prom_addr", addr);
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
+ /* FCode ROM */
+ sysbus_mmio_map(s, 0, addr);
/* 8-bit plane */
- sysbus_mmio_map(s, 0, addr + 0x00800000ULL);
+ sysbus_mmio_map(s, 1, addr + 0x00800000ULL);
/* DAC */
- sysbus_mmio_map(s, 1, addr + 0x00200000ULL);
+ sysbus_mmio_map(s, 2, addr + 0x00200000ULL);
/* TEC (dummy) */
- sysbus_mmio_map(s, 2, addr + 0x00700000ULL);
+ sysbus_mmio_map(s, 3, addr + 0x00700000ULL);
/* THC 24 bit: NetBSD writes here even with 8-bit display: dummy */
- sysbus_mmio_map(s, 3, addr + 0x00301000ULL);
+ sysbus_mmio_map(s, 4, addr + 0x00301000ULL);
if (depth == 24) {
/* 24-bit plane */
- sysbus_mmio_map(s, 4, addr + 0x02000000ULL);
+ sysbus_mmio_map(s, 5, addr + 0x02000000ULL);
/* Control plane */
- sysbus_mmio_map(s, 5, addr + 0x0a000000ULL);
+ sysbus_mmio_map(s, 6, addr + 0x0a000000ULL);
} else {
/* THC 8 bit (dummy) */
- sysbus_mmio_map(s, 4, addr + 0x00300000ULL);
+ sysbus_mmio_map(s, 5, addr + 0x00300000ULL);
}
}
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/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 57e8d16180..09652fb22c 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -235,7 +235,6 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
bool isapc_ram_fw);
/* pvpanic.c */
-void pvpanic_init(ISABus *bus);
uint16_t pvpanic_port(void);
/* e820 types */
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 0aa8913301..492bce1c1b 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -168,14 +168,14 @@
#endif
#ifndef atomic_xchg
-#ifdef __ATOMIC_SEQ_CST
+#if defined(__clang__)
+#define atomic_xchg(ptr, i) __sync_swap(ptr, i)
+#elif defined(__ATOMIC_SEQ_CST)
#define atomic_xchg(ptr, i) ({ \
typeof(*ptr) _new = (i), _old; \
__atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
_old; \
})
-#elif defined __clang__
-#define atomic_xchg(ptr, i) __sync_exchange(ptr, i)
#else
/* __sync_lock_test_and_set() is documented to be an acquire barrier only. */
#define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i))
diff --git a/pc-bios/QEMU,tcx.bin b/pc-bios/QEMU,tcx.bin
new file mode 100644
index 0000000000..a8ddd70ef3
--- /dev/null
+++ b/pc-bios/QEMU,tcx.bin
Binary files differ
diff --git a/pc-bios/README b/pc-bios/README
index 1501cf14b4..a110125a97 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -11,8 +11,8 @@
firmware implementation. The goal is to implement a 100% IEEE
1275-1994 (referred to as Open Firmware) compliant firmware.
The included images for PowerPC (for 32 and 64 bit PPC CPUs),
- Sparc32 and Sparc64 are built from OpenBIOS SVN revision
- 1229.
+ Sparc32 (including QEMU,tcx.bin) and Sparc64 are built from OpenBIOS SVN
+ revision 1229.
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
implementation for certain IBM POWER hardware. The sources are at
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 10682f58dc..8100bee67e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -401,7 +401,7 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, E
return -1;
}
- slog("guest-file-open, handle: %d", handle);
+ slog("guest-file-open, handle: %" PRId64, handle);
return handle;
}
@@ -410,7 +410,7 @@ void qmp_guest_file_close(int64_t handle, Error **err)
GuestFileHandle *gfh = guest_file_handle_find(handle, err);
int ret;
- slog("guest-file-close called, handle: %ld", handle);
+ slog("guest-file-close called, handle: %" PRId64, handle);
if (!gfh) {
return;
}
@@ -451,7 +451,7 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
read_count = fread(buf, 1, count, fh);
if (ferror(fh)) {
error_setg_errno(err, errno, "failed to read file");
- slog("guest-file-read failed, handle: %ld", handle);
+ slog("guest-file-read failed, handle: %" PRId64, handle);
} else {
buf[read_count] = 0;
read_data = g_malloc0(sizeof(GuestFileRead));
@@ -496,7 +496,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
write_count = fwrite(buf, 1, count, fh);
if (ferror(fh)) {
error_setg_errno(err, errno, "failed to write to file");
- slog("guest-file-write failed, handle: %ld", handle);
+ slog("guest-file-write failed, handle: %" PRId64, handle);
} else {
write_data = g_malloc0(sizeof(GuestFileWrite));
write_data->count = write_count;
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index 624a559d94..e422208b4e 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -29,7 +29,7 @@ GACommandState *ga_command_state_new(void);
bool ga_logging_enabled(GAState *s);
void ga_disable_logging(GAState *s);
void ga_enable_logging(GAState *s);
-void slog(const gchar *fmt, ...);
+void GCC_FMT_ATTR(1, 2) slog(const gchar *fmt, ...);
void ga_set_response_delimited(GAState *s);
bool ga_is_frozen(GAState *s);
void ga_set_frozen(GAState *s);
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("")));
diff --git a/savevm.c b/savevm.c
index 2f631d4045..3f912ddcf9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -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/helper.h b/target-i386/helper.h
index d6974dfd6b..3775abeba7 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -58,6 +58,7 @@ DEF_HELPER_2(sysret, void, env, int)
DEF_HELPER_2(hlt, void, env, int)
DEF_HELPER_2(monitor, void, env, tl)
DEF_HELPER_2(mwait, void, env, int)
+DEF_HELPER_2(pause, void, env, int)
DEF_HELPER_1(debug, void, env)
DEF_HELPER_1(reset_rf, void, env)
DEF_HELPER_3(raise_interrupt, void, env, int, int)
diff --git a/target-i386/kvm-stub.c b/target-i386/kvm-stub.c
index 11429c461e..2b9e8011fb 100644
--- a/target-i386/kvm-stub.c
+++ b/target-i386/kvm-stub.c
@@ -16,3 +16,15 @@ bool kvm_allows_irq0_override(void)
{
return 1;
}
+
+#ifndef __OPTIMIZE__
+/* This function is only called inside conditionals which we
+ * rely on the compiler to optimize out when CONFIG_KVM is not
+ * defined.
+ */
+uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
+ uint32_t index, int reg)
+{
+ abort();
+}
+#endif
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/misc_helper.c b/target-i386/misc_helper.c
index 93933fd162..b6307ca386 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -566,6 +566,15 @@ void helper_rdmsr(CPUX86State *env)
}
#endif
+static void do_pause(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+
+ /* Just let another CPU run. */
+ env->exception_index = EXCP_INTERRUPT;
+ cpu_loop_exit(env);
+}
+
static void do_hlt(X86CPU *cpu)
{
CPUState *cs = CPU(cpu);
@@ -611,13 +620,22 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
cs = CPU(cpu);
/* XXX: not complete but not completely erroneous */
if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
- /* more than one CPU: do not sleep because another CPU may
- wake this one */
+ do_pause(cpu);
} else {
do_hlt(cpu);
}
}
+void helper_pause(CPUX86State *env, int next_eip_addend)
+{
+ X86CPU *cpu = x86_env_get_cpu(env);
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0);
+ env->eip += next_eip_addend;
+
+ do_pause(cpu);
+}
+
void helper_debug(CPUX86State *env)
{
env->exception_index = EXCP_DEBUG;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index eb0ea93dbb..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;
@@ -7224,7 +7226,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
goto do_xchg_reg_eax;
}
if (prefixes & PREFIX_REPZ) {
- gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
+ gen_update_cc_op(s);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
+ s->is_jmp = DISAS_TB_JUMP;
}
break;
case 0x9b: /* fwait */
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)