aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile47
-rw-r--r--Makefile.hw2
-rw-r--r--Makefile.objs2
-rw-r--r--Makefile.target11
-rw-r--r--QMP/qmp-spec.txt55
-rw-r--r--audio/audio_template.h2
-rw-r--r--block/curl.c14
-rw-r--r--block/qcow2.c8
-rw-r--r--bsd-user/main.c9
-rw-r--r--check-qdict.c3
-rw-r--r--check-qfloat.c5
-rw-r--r--check-qint.c3
-rw-r--r--check-qlist.c4
-rw-r--r--check-qstring.c3
-rw-r--r--console.h2
-rw-r--r--darwin-user/commpage.c2
-rw-r--r--darwin-user/syscall.c2
-rw-r--r--default-configs/i386-softmmu.mak2
-rw-r--r--default-configs/mips-softmmu.mak2
-rw-r--r--default-configs/mips64-softmmu.mak2
-rw-r--r--default-configs/mips64el-softmmu.mak2
-rw-r--r--default-configs/mipsel-softmmu.mak2
-rw-r--r--default-configs/ppc-softmmu.mak2
-rw-r--r--default-configs/ppc64-softmmu.mak2
-rw-r--r--default-configs/ppcemb-softmmu.mak2
-rw-r--r--default-configs/sparc64-softmmu.mak1
-rw-r--r--default-configs/x86_64-softmmu.mak2
-rw-r--r--exec.c5
-rw-r--r--hw/arm_timer.c4
-rw-r--r--hw/axis_dev88.c31
-rw-r--r--hw/cirrus_vga.c1
-rw-r--r--hw/dma.c17
-rw-r--r--hw/elf_ops.h5
-rw-r--r--hw/isa.h2
-rw-r--r--hw/lsi53c895a.c4
-rw-r--r--hw/mips_jazz.c13
-rw-r--r--hw/mips_malta.c13
-rw-r--r--hw/pc.c46
-rw-r--r--hw/pc.h5
-rw-r--r--hw/pci-hotplug.c51
-rw-r--r--hw/pckbd.c112
-rw-r--r--hw/pflash_cfi01.c20
-rw-r--r--hw/ppc_prep.c15
-rw-r--r--hw/sparc32_dma.c12
-rw-r--r--hw/sun4m.c6
-rw-r--r--hw/sun4u.c6
-rw-r--r--hw/vga.c2
-rw-r--r--hw/vhost_net.c2
-rw-r--r--hw/vmmouse.c2
-rw-r--r--hxtool16
-rw-r--r--ia64-dis.c9
-rw-r--r--linux-user/main.c24
-rw-r--r--linux-user/syscall.c99
-rw-r--r--linux-user/syscall_defs.h8
-rw-r--r--monitor.c4
-rw-r--r--nbd.c3
-rw-r--r--qbool.c8
-rw-r--r--qdict.c6
-rw-r--r--qdict.h12
-rw-r--r--qemu-img-cmds.hx2
-rw-r--r--qemu-img.c10
-rw-r--r--qemu-io.c58
-rw-r--r--qemu-monitor.hx6
-rw-r--r--qemu-objects.h5
-rw-r--r--qemu-options.hx15
-rw-r--r--qerror.c2
-rw-r--r--qerror.h2
-rw-r--r--qfloat.c8
-rw-r--r--qint.c7
-rw-r--r--qint.h12
-rw-r--r--qlist.c7
-rw-r--r--qlist.h7
-rw-r--r--qobject.h4
-rw-r--r--qstring.c7
-rw-r--r--qstring.h12
-rw-r--r--rules.mak2
-rw-r--r--sysemu.h9
-rw-r--r--target-cris/translate.c4
-rw-r--r--target-ppc/translate.c7
-rw-r--r--target-sparc/cpu.h73
-rw-r--r--target-sparc/helper.c130
-rw-r--r--target-sparc/op_helper.c30
-rw-r--r--target-sparc/translate.c14
-rw-r--r--tcg/hppa/tcg-target.c12
-rw-r--r--tcg/i386/tcg-target.c504
-rw-r--r--tcg/ia64/tcg-target.c199
-rw-r--r--tcg/tcg.c3
-rw-r--r--tcg/tcg.h1
-rw-r--r--vl.c18
89 files changed, 1214 insertions, 712 deletions
diff --git a/Makefile b/Makefile
index 306a1a4038..7986bf6922 100644
--- a/Makefile
+++ b/Makefile
@@ -299,43 +299,22 @@ tar:
cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS --exclude .git --exclude .svn
rm -rf /tmp/$(FILE)
+SYSTEM_TARGETS=$(filter %-softmmu,$(TARGET_DIRS))
+SYSTEM_PROGS=$(patsubst qemu-system-i386,qemu, \
+ $(patsubst %-softmmu,qemu-system-%, \
+ $(SYSTEM_TARGETS)))
+
+USER_TARGETS=$(filter %-user,$(TARGET_DIRS))
+USER_PROGS=$(patsubst %-bsd-user,qemu-%, \
+ $(patsubst %-darwin-user,qemu-%, \
+ $(patsubst %-linux-user,qemu-%, \
+ $(USER_TARGETS))))
+
# generate a binary distribution
tarbin:
cd / && tar zcvf ~/qemu-$(VERSION)-$(ARCH).tar.gz \
- $(bindir)/qemu \
- $(bindir)/qemu-system-x86_64 \
- $(bindir)/qemu-system-arm \
- $(bindir)/qemu-system-cris \
- $(bindir)/qemu-system-m68k \
- $(bindir)/qemu-system-microblaze \
- $(bindir)/qemu-system-mips \
- $(bindir)/qemu-system-mipsel \
- $(bindir)/qemu-system-mips64 \
- $(bindir)/qemu-system-mips64el \
- $(bindir)/qemu-system-ppc \
- $(bindir)/qemu-system-ppcemb \
- $(bindir)/qemu-system-ppc64 \
- $(bindir)/qemu-system-sh4 \
- $(bindir)/qemu-system-sh4eb \
- $(bindir)/qemu-system-sparc \
- $(bindir)/qemu-i386 \
- $(bindir)/qemu-x86_64 \
- $(bindir)/qemu-alpha \
- $(bindir)/qemu-arm \
- $(bindir)/qemu-armeb \
- $(bindir)/qemu-cris \
- $(bindir)/qemu-m68k \
- $(bindir)/qemu-microblaze \
- $(bindir)/qemu-mips \
- $(bindir)/qemu-mipsel \
- $(bindir)/qemu-ppc \
- $(bindir)/qemu-ppc64 \
- $(bindir)/qemu-ppc64abi32 \
- $(bindir)/qemu-sh4 \
- $(bindir)/qemu-sh4eb \
- $(bindir)/qemu-sparc \
- $(bindir)/qemu-sparc64 \
- $(bindir)/qemu-sparc32plus \
+ $(patsubst %,$(bindir)/%, $(SYSTEM_PROGS)) \
+ $(patsubst %,$(bindir)/%, $(USER_PROGS)) \
$(bindir)/qemu-img \
$(bindir)/qemu-nbd \
$(datadir)/bios.bin \
diff --git a/Makefile.hw b/Makefile.hw
index be35359e8c..b9181ab122 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -18,7 +18,7 @@ all: $(hw-obj-y)
@true
clean:
- rm -f *.o *.d *.a *~
+ rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~
# Include automatically generated dependency files
-include $(wildcard *.d */*.d)
diff --git a/Makefile.objs b/Makefile.objs
index acbaf22745..15851010ca 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -151,10 +151,12 @@ hw-obj-$(CONFIG_SERIAL) += serial.o
hw-obj-$(CONFIG_PARALLEL) += parallel.o
hw-obj-$(CONFIG_I8254) += i8254.o
hw-obj-$(CONFIG_PCSPK) += pcspk.o
+hw-obj-$(CONFIG_PCKBD) += pckbd.o
hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
hw-obj-$(CONFIG_FDC) += fdc.o
hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
+hw-obj-$(CONFIG_DMA) += dma.o
# PPC devices
hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/Makefile.target b/Makefile.target
index a22484e1e9..fda5bf3c73 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,6 @@ obj-y += rtl8139.o
obj-y += e1000.o
# Hardware support
-obj-i386-y = pckbd.o dma.o
obj-i386-y += vga.o
obj-i386-y += mc146818rtc.o i8259.o pc.o
obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o
@@ -199,9 +198,9 @@ obj-i386-y += pc_piix.o
# shared objects
obj-ppc-y = ppc.o
-obj-ppc-y += vga.o dma.o
+obj-ppc-y += vga.o
# PREP target
-obj-ppc-y += pckbd.o i8259.o mc146818rtc.o
+obj-ppc-y += i8259.o mc146818rtc.o
obj-ppc-y += ppc_prep.o
# OldWorld PowerMac
obj-ppc-y += ppc_oldworld.o
@@ -217,9 +216,9 @@ obj-ppc-$(CONFIG_FDT) += device_tree.o
obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
obj-mips-y += mips_addr.o mips_timer.o mips_int.o
-obj-mips-y += dma.o vga.o i8259.o
+obj-mips-y += vga.o i8259.o
obj-mips-y += g364fb.o jazz_led.o
-obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
+obj-mips-y += gt64xxx.o mc146818rtc.o
obj-mips-y += piix4.o cirrus_vga.o
obj-microblaze-y = petalogix_s3adsp1800_mmu.o
@@ -243,7 +242,7 @@ obj-cris-y += etraxfs_timer.o
obj-cris-y += etraxfs_ser.o
ifeq ($(TARGET_ARCH), sparc64)
-obj-sparc-y = sun4u.o pckbd.o apb_pci.o
+obj-sparc-y = sun4u.o apb_pci.o
obj-sparc-y += vga.o
obj-sparc-y += mc146818rtc.o
obj-sparc-y += cirrus_vga.o
diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt
index f3c0327703..9d30a8ce6e 100644
--- a/QMP/qmp-spec.txt
+++ b/QMP/qmp-spec.txt
@@ -215,3 +215,58 @@ Additionally, Clients must not assume any particular:
- Order of json-object members or json-array elements
- Amount of errors generated by a command, that is, new errors can be added
to any existing command in newer versions of the Server
+
+6. Downstream extension of QMP
+------------------------------
+
+We recommend that downstream consumers of QEMU do *not* modify QMP.
+Management tools should be able to support both upstream and downstream
+versions of QMP without special logic, and downstream extensions are
+inherently at odds with that.
+
+However, we recognize that it is sometimes impossible for downstreams to
+avoid modifying QMP. Both upstream and downstream need to take care to
+preserve long-term compatibility and interoperability.
+
+To help with that, QMP reserves JSON object member names beginning with
+'__' (double underscore) for downstream use ("downstream names"). This
+means upstream will never use any downstream names for its commands,
+arguments, errors, asynchronous events, and so forth.
+
+Any new names downstream wishes to add must begin with '__'. To
+ensure compatibility with other downstreams, it is strongly
+recommended that you prefix your downstram names with '__RFQDN_' where
+RFQDN is a valid, reverse fully qualified domain name which you
+control. For example, a qemu-kvm specific monitor command would be:
+
+ (qemu) __org.linux-kvm_enable_irqchip
+
+Downstream must not change the server greeting (section 2.2) other than
+to offer additional capabilities. But see below for why even that is
+discouraged.
+
+Section '5 Compatibility Considerations' applies to downstream as well
+as to upstream, obviously. It follows that downstream must behave
+exactly like upstream for any input not containing members with
+downstream names ("downstream members"), except it may add members
+with downstream names to its output.
+
+Thus, a client should not be able to distinguish downstream from
+upstream as long as it doesn't send input with downstream members, and
+properly ignores any downstream members in the output it receives.
+
+Advice on downstream modifications:
+
+1. Introducing new commands is okay. If you want to extend an existing
+ command, consider introducing a new one with the new behaviour
+ instead.
+
+2. Introducing new asynchronous messages is okay. If you want to extend
+ an existing message, consider adding a new one instead.
+
+3. Introducing new errors for use in new commands is okay. Adding new
+ errors to existing commands counts as extension, so 1. applies.
+
+4. New capabilities are strongly discouraged. Capabilities are for
+ evolving the basic protocol, and multiple diverging basic protocol
+ dialects are most undesirable.
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 6b19848af4..2f5224ba29 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -541,7 +541,7 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
cur_ts = sw->hw->ts_helper;
old_ts = ts->old_ts;
- /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
+ /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */
if (cur_ts >= old_ts) {
delta = cur_ts - old_ts;
diff --git a/block/curl.c b/block/curl.c
index b944740fb9..407f0955a3 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -104,10 +104,11 @@ static size_t curl_size_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
CURLState *s = ((CURLState*)opaque);
size_t realsize = size * nmemb;
- long long fsize;
+ size_t fsize;
- if(sscanf(ptr, "Content-Length: %lld", &fsize) == 1)
+ if(sscanf(ptr, "Content-Length: %zd", &fsize) == 1) {
s->s->len = fsize;
+ }
return realsize;
}
@@ -118,7 +119,7 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
size_t realsize = size * nmemb;
int i;
- DPRINTF("CURL: Just reading %lld bytes\n", (unsigned long long)realsize);
+ DPRINTF("CURL: Just reading %zd bytes\n", realsize);
if (!s || !s->orig_buf)
goto read_end;
@@ -368,7 +369,7 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags)
s->len = (size_t)d;
else if(!s->len)
goto out;
- DPRINTF("CURL: Size = %lld\n", (long long)s->len);
+ DPRINTF("CURL: Size = %zd\n", s->len);
curl_clean_state(state);
curl_easy_cleanup(state->curl);
@@ -450,8 +451,9 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
state->orig_buf = qemu_malloc(state->buf_len);
state->acb[0] = acb;
- snprintf(state->range, 127, "%lld-%lld", (long long)start, (long long)end);
- DPRINTF("CURL (AIO): Reading %d at %lld (%s)\n", (nb_sectors * SECTOR_SIZE), start, state->range);
+ snprintf(state->range, 127, "%zd-%zd", start, end);
+ DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n",
+ (nb_sectors * SECTOR_SIZE), start, state->range);
curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
curl_multi_add_handle(s->multi, state->curl);
diff --git a/block/qcow2.c b/block/qcow2.c
index 0ce71507e9..5b72758915 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -93,8 +93,9 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
#endif
if (bdrv_pread(bs->file, offset, &ext, sizeof(ext)) != sizeof(ext)) {
- fprintf(stderr, "qcow_handle_extension: ERROR: pread fail from offset %llu\n",
- (unsigned long long)offset);
+ fprintf(stderr, "qcow_handle_extension: ERROR: "
+ "pread fail from offset %" PRIu64 "\n",
+ offset);
return 1;
}
be32_to_cpus(&ext.magic);
@@ -1245,7 +1246,8 @@ static void dump_refcounts(BlockDriverState *bs)
k++;
while (k < nb_clusters && get_refcount(bs, k) == refcount)
k++;
- printf("%lld: refcount=%d nb=%lld\n", k, refcount, k - k1);
+ printf("%" PRId64 ": refcount=%d nb=%" PRId64 "\n", k, refcount,
+ k - k1);
}
}
#endif
diff --git a/bsd-user/main.c b/bsd-user/main.c
index b1c438d895..05cc3d92b7 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -30,7 +30,7 @@
#include "qemu-common.h"
/* For tb_lock */
#include "exec-all.h"
-
+#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
@@ -970,6 +970,13 @@ int main(int argc, char **argv)
syscall_init();
signal_init();
+#if defined(CONFIG_USE_GUEST_BASE)
+ /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
+ generating the prologue until now so that the prologue can take
+ the real value of GUEST_BASE into account. */
+ tcg_prologue_init(&tcg_ctx);
+#endif
+
/* build Task State */
memset(ts, 0, sizeof(TaskState));
init_task_state(ts);
diff --git a/check-qdict.c b/check-qdict.c
index f2b4826560..2c3089fa66 100644
--- a/check-qdict.c
+++ b/check-qdict.c
@@ -5,6 +5,9 @@
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
#include <check.h>
diff --git a/check-qfloat.c b/check-qfloat.c
index 3758700cb8..b71d9834f0 100644
--- a/check-qfloat.c
+++ b/check-qfloat.c
@@ -1,11 +1,6 @@
/*
* QFloat unit-tests.
*
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
* Copyright IBM, Corp. 2009
*
* Authors:
diff --git a/check-qint.c b/check-qint.c
index 49887bb7d9..f3b031698c 100644
--- a/check-qint.c
+++ b/check-qint.c
@@ -5,6 +5,9 @@
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
#include <check.h>
diff --git a/check-qlist.c b/check-qlist.c
index 0117ef32e8..58984cbfcc 100644
--- a/check-qlist.c
+++ b/check-qlist.c
@@ -6,8 +6,8 @@
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
#include <check.h>
diff --git a/check-qstring.c b/check-qstring.c
index c308a63eaf..c9bafc26b3 100644
--- a/check-qstring.c
+++ b/check-qstring.c
@@ -5,6 +5,9 @@
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
#include <check.h>
diff --git a/console.h b/console.h
index 6def1152e6..3a75bcc4d0 100644
--- a/console.h
+++ b/console.h
@@ -306,6 +306,8 @@ static inline int ds_get_bytes_per_pixel(DisplayState *ds)
typedef unsigned long console_ch_t;
static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
{
+ if (!(ch & 0xff))
+ ch |= ' ';
cpu_to_le32wu((uint32_t *) dest, ch);
}
diff --git a/darwin-user/commpage.c b/darwin-user/commpage.c
index 2b41bc5e3a..f6aa71e058 100644
--- a/darwin-user/commpage.c
+++ b/darwin-user/commpage.c
@@ -237,7 +237,7 @@ void do_compare_and_swap64(void *cpu_env, int num)
uint64_t *value = (uint64_t*)((CPUX86State*)cpu_env)->regs[R_ESI];
old = (uint64_t)((uint64_t)((CPUX86State*)cpu_env)->regs[R_EDX]) << 32 | (uint64_t)((CPUX86State*)cpu_env)->regs[R_EAX];
- DPRINTF("commpage: compare_and_swap64(%llx,new,%p)\n", old, value);
+ DPRINTF("commpage: compare_and_swap64(%" PRIx64 ",new,%p)\n", old, value);
swapped_val = tswap64(*value);
if(old == swapped_val)
diff --git a/darwin-user/syscall.c b/darwin-user/syscall.c
index d774ad353e..060acc889d 100644
--- a/darwin-user/syscall.c
+++ b/darwin-user/syscall.c
@@ -858,7 +858,7 @@ long no_syscall(void *cpu_env, int num);
long do_pread(uint32_t arg1, void * arg2, size_t arg3, off_t arg4)
{
- DPRINTF("0x%x, %p, 0x%lx, 0x%llx\n", arg1, arg2, arg3, arg4);
+ DPRINTF("0x%x, %p, 0x%lx, 0x%" PRIx64 "\n", arg1, arg2, arg3, arg4);
long ret = pread(arg1, arg2, arg3, arg4);
return ret;
}
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 4fbd8aae2c..ed00471da2 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -8,10 +8,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index fd6fbc1808..29be52eb1d 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -10,10 +10,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak
index dfd30dbbea..9bae8a7bc2 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -10,10 +10,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak
index 6fa54a3e15..b372c1dfa1 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -10,10 +10,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak
index 8203997b69..10ef483799 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -10,10 +10,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 958bf755a7..c026bbb00e 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -8,7 +8,9 @@ CONFIG_M48T59=y
CONFIG_VGA_PCI=y
CONFIG_SERIAL=y
CONFIG_I8254=y
+CONFIG_PCKBD=y
CONFIG_FDC=y
+CONFIG_DMA=y
CONFIG_OPENPIC=y
CONFIG_PREP_PCI=y
CONFIG_MACIO=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 9896662a1e..0101a283e3 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -8,7 +8,9 @@ CONFIG_M48T59=y
CONFIG_VGA_PCI=y
CONFIG_SERIAL=y
CONFIG_I8254=y
+CONFIG_PCKBD=y
CONFIG_FDC=y
+CONFIG_DMA=y
CONFIG_OPENPIC=y
CONFIG_PREP_PCI=y
CONFIG_MACIO=y
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index 2e41a942bc..8ba9ac179f 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -8,7 +8,9 @@ CONFIG_M48T59=y
CONFIG_VGA_PCI=y
CONFIG_SERIAL=y
CONFIG_I8254=y
+CONFIG_PCKBD=y
CONFIG_FDC=y
+CONFIG_DMA=y
CONFIG_OPENPIC=y
CONFIG_PREP_PCI=y
CONFIG_MACIO=y
diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak
index 514d3347e5..1cc3f13079 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -6,6 +6,7 @@ CONFIG_PTIMER=y
CONFIG_VGA_PCI=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
+CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index ffedfdbd68..518320377f 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -8,10 +8,12 @@ CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
CONFIG_PCSPK=y
+CONFIG_PCKBD=y
CONFIG_USB_UHCI=y
CONFIG_FDC=y
CONFIG_ACPI=y
CONFIG_APM=y
+CONFIG_DMA=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_IDE_PCI=y
diff --git a/exec.c b/exec.c
index 56b5561884..bb3dcadcde 100644
--- a/exec.c
+++ b/exec.c
@@ -574,6 +574,11 @@ void cpu_exec_init_all(unsigned long tb_size)
#if !defined(CONFIG_USER_ONLY)
io_mem_init();
#endif
+#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
+ /* There's no guest base to take into account, so go ahead and
+ initialize the prologue now. */
+ tcg_prologue_init(&tcg_ctx);
+#endif
}
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 9fef191cbc..9073ffc007 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -71,7 +71,7 @@ static void arm_timer_recalibrate(arm_timer_state *s, int reload)
{
uint32_t limit;
- if ((s->control & TIMER_CTRL_PERIODIC) == 0) {
+ if ((s->control & (TIMER_CTRL_PERIODIC | TIMER_CTRL_ONESHOT)) == 0) {
/* Free running. */
if (s->control & TIMER_CTRL_32BIT)
limit = 0xffffffff;
@@ -113,7 +113,7 @@ static void arm_timer_write(void *opaque, target_phys_addr_t offset,
case 1: freq >>= 4; break;
case 2: freq >>= 8; break;
}
- arm_timer_recalibrate(s, 0);
+ arm_timer_recalibrate(s, s->control & TIMER_CTRL_ENABLE);
ptimer_set_freq(s->timer, freq);
if (s->control & TIMER_CTRL_ENABLE) {
/* Restart the timer if still enabled. */
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 5516e42528..7d59c96ca1 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -240,13 +240,22 @@ static CPUWriteMemoryFunc * const gpio_write[] = {
#define INTMEM_SIZE (128 * 1024)
-static uint32_t bootstrap_pc;
+static struct {
+ uint32_t bootstrap_pc;
+ uint32_t regs[16];
+} loadargs;
+
static void main_cpu_reset(void *opaque)
{
+ int i;
+
CPUState *env = opaque;
cpu_reset(env);
- env->pc = bootstrap_pc;
+ env->pc = loadargs.bootstrap_pc;
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = loadargs.regs[i];
+ }
}
static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
@@ -352,15 +361,15 @@ void axisdev88_init (ram_addr_t ram_size,
devboard SDK. */
kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
&entry, NULL, &high, 0, ELF_MACHINE, 0);
- bootstrap_pc = entry;
+ loadargs.bootstrap_pc = entry;
if (kernel_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
kernel_size = load_image_targphys(kernel_filename, 0x40004000,
ram_size);
- bootstrap_pc = 0x40004000;
- env->regs[9] = 0x40004000 + kernel_size;
+ loadargs.bootstrap_pc = 0x40004000;
+ loadargs.regs[9] = 0x40004000 + kernel_size;
}
- env->regs[8] = 0x56902387; /* RAM init magic. */
+ loadargs.regs[8] = 0x56902387; /* RAM init magic. */
if (kernel_cmdline && (kcmdline_len = strlen(kernel_cmdline))) {
if (kcmdline_len > 256) {
@@ -368,15 +377,11 @@ void axisdev88_init (ram_addr_t ram_size,
exit(1);
}
/* Let the kernel know we are modifying the cmdline. */
- env->regs[10] = 0x87109563;
- env->regs[11] = 0x40000000;
- pstrcpy_targphys("cmdline", env->regs[11], 256, kernel_cmdline);
+ loadargs.regs[10] = 0x87109563;
+ loadargs.regs[11] = 0x40000000;
+ pstrcpy_targphys("cmdline", loadargs.regs[11], 256, kernel_cmdline);
}
}
- env->pc = bootstrap_pc;
-
- printf ("pc =%x\n", env->pc);
- printf ("ram size =%ld\n", ram_size);
}
static QEMUMachine axisdev88_machine = {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 9f61a01d45..ba4828996a 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2985,7 +2985,6 @@ static const VMStateDescription vmstate_pci_cirrus_vga = {
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
- .post_load = cirrus_post_load,
.fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
diff --git a/hw/dma.c b/hw/dma.c
index e5f7af7a88..5b215211e1 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -57,6 +57,7 @@ static struct dma_cont {
uint8_t flip_flop;
int dshift;
struct dma_regs regs[4];
+ qemu_irq *cpu_request_exit;
} dma_controllers[2];
enum {
@@ -444,9 +445,9 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len)
/* request the emulator to transfer a new DMA memory block ASAP */
void DMA_schedule(int nchan)
{
- CPUState *env = cpu_single_env;
- if (env)
- cpu_exit(env);
+ struct dma_cont *d = &dma_controllers[nchan > 3];
+
+ qemu_irq_pulse(*d->cpu_request_exit);
}
static void dma_reset(void *opaque)
@@ -464,12 +465,14 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
+ int page_base, int pageh_base,
+ qemu_irq *cpu_request_exit)
{
static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
int i;
d->dshift = dshift;
+ d->cpu_request_exit = cpu_request_exit;
for (i = 0; i < 8; i++) {
register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
@@ -539,12 +542,12 @@ static const VMStateDescription vmstate_dma = {
}
};
-void DMA_init (int high_page_enable)
+void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
{
dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
+ high_page_enable ? 0x480 : -1, cpu_request_exit);
dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
+ high_page_enable ? 0x488 : -1, cpu_request_exit);
vmstate_register (0, &vmstate_dma, &dma_controllers[0]);
vmstate_register (1, &vmstate_dma, &dma_controllers[1]);
diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 69c07571b6..27d1ab9bc2 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -216,6 +216,11 @@ static int glue(load_elf, SZ)(const char *name, int fd,
if (EM_386 != ehdr.e_machine)
goto fail;
break;
+ case EM_MICROBLAZE:
+ if (EM_MICROBLAZE != ehdr.e_machine)
+ if (EM_MICROBLAZE_OLD != ehdr.e_machine)
+ goto fail;
+ break;
default:
if (elf_machine != ehdr.e_machine)
goto fail;
diff --git a/hw/isa.h b/hw/isa.h
index 97f69a25cb..aaf0272c25 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -41,7 +41,7 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size);
void DMA_hold_DREQ (int nchan);
void DMA_release_DREQ (int nchan);
void DMA_schedule(int nchan);
-void DMA_init (int high_page_enable);
+void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit);
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 9d3c44d1c7..f5a91ba10a 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -543,7 +543,7 @@ static void lsi_do_dma(LSIState *s, int out)
return;
}
- id = s->current->tag >> 8;
+ id = (s->current->tag >> 8) & 0xf;
dev = s->bus.devs[id];
if (!dev) {
lsi_bad_selection(s, id);
@@ -745,7 +745,7 @@ static void lsi_do_command(LSIState *s)
s->sfbr = buf[0];
s->command_complete = 0;
- id = s->select_tag >> 8;
+ id = (s->select_tag >> 8) & 0xf;
dev = s->bus.devs[id];
if (!dev) {
lsi_bad_selection(s, id);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 6e0ec8fd36..ead3a00c3d 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -114,6 +114,15 @@ static void audio_init(qemu_irq *pic)
#define MAGNUM_BIOS_SIZE_MAX 0x7e000
#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
+static void cpu_request_exit(void *opaque, int irq, int level)
+{
+ CPUState *env = cpu_single_env;
+
+ if (env && level) {
+ cpu_exit(env);
+ }
+}
+
static
void mips_jazz_init (ram_addr_t ram_size,
const char *cpu_model,
@@ -130,6 +139,7 @@ void mips_jazz_init (ram_addr_t ram_size,
PITState *pit;
DriveInfo *fds[MAX_FD];
qemu_irq esp_reset;
+ qemu_irq *cpu_exit_irq;
ram_addr_t ram_offset;
ram_addr_t bios_offset;
@@ -189,7 +199,8 @@ void mips_jazz_init (ram_addr_t ram_size,
i8259 = i8259_init(env->irq[4]);
isa_bus_new(NULL);
isa_bus_irqs(i8259);
- DMA_init(0);
+ cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+ DMA_init(0, cpu_exit_irq);
pit = pit_init(0x40, i8259[0]);
pcspk_init(pit);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 792709bf5a..a8f9d152dd 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -763,6 +763,15 @@ static void main_cpu_reset(void *opaque)
}
}
+static void cpu_request_exit(void *opaque, int irq, int level)
+{
+ CPUState *env = cpu_single_env;
+
+ if (env && level) {
+ cpu_exit(env);
+ }
+}
+
static
void mips_malta_init (ram_addr_t ram_size,
const char *boot_device,
@@ -781,6 +790,7 @@ void mips_malta_init (ram_addr_t ram_size,
FDCtrl *floppy_controller;
MaltaFPGAState *malta_fpga;
qemu_irq *i8259;
+ qemu_irq *cpu_exit_irq;
int piix4_devfn;
uint8_t *eeprom_buf;
i2c_bus *smbus;
@@ -943,7 +953,8 @@ void mips_malta_init (ram_addr_t ram_size,
qdev_init_nofail(eeprom);
}
pit = pit_init(0x40, isa_reserve_irq(0));
- DMA_init(0);
+ cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+ DMA_init(0, cpu_exit_irq);
/* Super I/O */
isa_dev = isa_create_simple("i8042");
diff --git a/hw/pc.c b/hw/pc.c
index 7715b17d56..e7f31d3848 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -365,26 +365,12 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
rtc_set_memory(s, 0x39, val);
}
-void ioport_set_a20(int enable)
+static void handle_a20_line_change(void *opaque, int irq, int level)
{
- /* XXX: send to all CPUs ? */
- cpu_x86_set_a20(first_cpu, enable);
-}
-
-int ioport_get_a20(void)
-{
- return ((first_cpu->a20_mask >> 20) & 1);
-}
+ CPUState *cpu = opaque;
-static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
-{
- ioport_set_a20((val >> 1) & 1);
- /* XXX: bit 0 is fast reset */
-}
-
-static uint32_t ioport92_read(void *opaque, uint32_t addr)
-{
- return ioport_get_a20() << 1;
+ /* XXX: send to all CPUs ? */
+ cpu_x86_set_a20(cpu, level);
}
/***********************************************************/
@@ -928,6 +914,15 @@ void pc_vga_init(PCIBus *pci_bus)
}
}
+static void cpu_request_exit(void *opaque, int irq, int level)
+{
+ CPUState *env = cpu_single_env;
+
+ if (env && level) {
+ cpu_exit(env);
+ }
+}
+
void pc_basic_device_init(qemu_irq *isa_irq,
FDCtrl **floppy_controller,
ISADevice **rtc_state)
@@ -935,6 +930,9 @@ void pc_basic_device_init(qemu_irq *isa_irq,
int i;
DriveInfo *fd[MAX_FD];
PITState *pit;
+ qemu_irq *a20_line;
+ ISADevice *i8042;
+ qemu_irq *cpu_exit_irq;
register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
@@ -944,9 +942,6 @@ void pc_basic_device_init(qemu_irq *isa_irq,
qemu_register_boot_set(pc_boot_set, *rtc_state);
- register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
- register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
-
pit = pit_init(0x40, isa_reserve_irq(0));
pcspk_init(pit);
if (!no_hpet) {
@@ -965,8 +960,13 @@ void pc_basic_device_init(qemu_irq *isa_irq,
}
}
- isa_create_simple("i8042");
- DMA_init(0);
+ a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1);
+ i8042 = isa_create_simple("i8042");
+ i8042_setup_a20_line(i8042, a20_line);
+ vmmouse_init(i8042);
+
+ cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+ DMA_init(0, cpu_exit_irq);
for(i = 0; i < MAX_FD; i++) {
fd[i] = drive_get(IF_FLOPPY, 0, i);
diff --git a/hw/pc.h b/hw/pc.h
index 654b7b33d6..73cccefff7 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -75,6 +75,8 @@ void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
target_phys_addr_t base, ram_addr_t size,
target_phys_addr_t mask);
+void i8042_isa_mouse_fake_event(void *opaque);
+void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out);
/* pc.c */
extern int fd_bootchk;
@@ -104,9 +106,6 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
FDCtrl *floppy_controller, ISADevice *s);
void pc_pci_device_init(PCIBus *pci_bus);
-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-
typedef void (*cpu_set_smm_t)(int smm, void *arg);
void cpu_smm_register(cpu_set_smm_t callback, void *arg);
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index cc45c504ad..37ac015f7d 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -33,7 +33,6 @@
#include "scsi.h"
#include "virtio-blk.h"
#include "qemu-config.h"
-#include "qemu-objects.h"
#if defined(TARGET_I386)
static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
@@ -224,36 +223,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
return dev;
}
-void pci_device_hot_add_print(Monitor *mon, const QObject *data)
-{
- QDict *qdict;
-
- assert(qobject_type(data) == QTYPE_QDICT);
- qdict = qobject_to_qdict(data);
-
- monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
- (int) qdict_get_int(qdict, "domain"),
- (int) qdict_get_int(qdict, "bus"),
- (int) qdict_get_int(qdict, "slot"),
- (int) qdict_get_int(qdict, "function"));
-
-}
-
-/**
- * pci_device_hot_add(): Hot add a PCI device
- *
- * Return a QDict with the following device information:
- *
- * - "domain": domain number
- * - "bus": bus number
- * - "slot": slot number
- * - "function": function number
- *
- * Example:
- *
- * { "domain": 0, "bus": 0, "slot": 5, "function": 0 }
- */
-int pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void pci_device_hot_add(Monitor *mon, const QDict *qdict)
{
PCIDevice *dev = NULL;
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
@@ -278,20 +248,14 @@ int pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
} else {
monitor_printf(mon, "invalid type: %s\n", type);
- return -1;
}
if (dev) {
- *ret_data =
- qobject_from_jsonf("{ 'domain': 0, 'bus': %d, 'slot': %d, "
- "'function': %d }", pci_bus_num(dev->bus),
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
- } else {
+ monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
+ 0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn));
+ } else
monitor_printf(mon, "failed to add %s\n", opts);
- return -1;
- }
-
- return 0;
}
#endif
@@ -313,8 +277,7 @@ int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
return qdev_unplug(&d->qdev);
}
-int do_pci_device_hot_remove(Monitor *mon, const QDict *qdict,
- QObject **ret_data)
+void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict)
{
- return pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));
+ pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));
}
diff --git a/hw/pckbd.c b/hw/pckbd.c
index e83b8a6bcb..381228479e 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -29,6 +29,12 @@
/* debug PC keyboard */
//#define DEBUG_KBD
+#ifdef DEBUG_KBD
+#define DPRINTF(fmt, ...) \
+ do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...)
+#endif
/* Keyboard Controller Commands */
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
@@ -87,6 +93,12 @@
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
+/* Output Port Bits */
+#define KBD_OUT_RESET 0x01 /* 1=normal mode, 0=reset */
+#define KBD_OUT_A20 0x02 /* x86 only */
+#define KBD_OUT_OBF 0x10 /* Keyboard output buffer full */
+#define KBD_OUT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+
/* Mouse Commands */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
@@ -116,6 +128,7 @@ typedef struct KBDState {
uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
uint8_t status;
uint8_t mode;
+ uint8_t outport;
/* Bitmask of devices with data available. */
uint8_t pending;
void *kbd;
@@ -123,6 +136,7 @@ typedef struct KBDState {
qemu_irq irq_kbd;
qemu_irq irq_mouse;
+ qemu_irq *a20_out;
target_phys_addr_t mask;
} KBDState;
@@ -136,11 +150,14 @@ static void kbd_update_irq(KBDState *s)
irq_kbd_level = 0;
irq_mouse_level = 0;
s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
+ s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
if (s->pending) {
s->status |= KBD_STAT_OBF;
+ s->outport |= KBD_OUT_OBF;
/* kbd data takes priority over aux data. */
if (s->pending == KBD_PENDING_AUX) {
s->status |= KBD_STAT_MOUSE_OBF;
+ s->outport |= KBD_OUT_MOUSE_OBF;
if (s->mode & KBD_MODE_MOUSE_INT)
irq_mouse_level = 1;
} else {
@@ -180,9 +197,7 @@ static uint32_t kbd_read_status(void *opaque, uint32_t addr)
KBDState *s = opaque;
int val;
val = s->status;
-#if defined(DEBUG_KBD)
- printf("kbd: read status=0x%02x\n", val);
-#endif
+ DPRINTF("kbd: read status=0x%02x\n", val);
return val;
}
@@ -194,13 +209,35 @@ static void kbd_queue(KBDState *s, int b, int aux)
ps2_queue(s->kbd, b);
}
+static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ KBDState *s = opaque;
+
+ DPRINTF("kbd: write outport=0x%02x\n", val);
+ s->outport = val;
+ if (s->a20_out) {
+ qemu_set_irq(*s->a20_out, (val >> 1) & 1);
+ }
+ if (!(val & 1)) {
+ qemu_system_reset_request();
+ }
+}
+
+static uint32_t ioport92_read(void *opaque, uint32_t addr)
+{
+ KBDState *s = opaque;
+ uint32_t ret;
+
+ ret = s->outport;
+ DPRINTF("kbd: read outport=0x%02x\n", ret);
+ return ret;
+}
+
static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
{
KBDState *s = opaque;
-#ifdef DEBUG_KBD
- printf("kbd: write cmd=0x%02x\n", val);
-#endif
+ DPRINTF("kbd: write cmd=0x%02x\n", val);
switch(val) {
case KBD_CCMD_READ_MODE:
kbd_queue(s, s->mode, 0);
@@ -240,26 +277,20 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
kbd_queue(s, 0x00, 0);
break;
case KBD_CCMD_READ_OUTPORT:
- /* XXX: check that */
-#ifdef TARGET_I386
- val = 0x01 | (ioport_get_a20() << 1);
-#else
- val = 0x01;
-#endif
- if (s->status & KBD_STAT_OBF)
- val |= 0x10;
- if (s->status & KBD_STAT_MOUSE_OBF)
- val |= 0x20;
- kbd_queue(s, val, 0);
+ kbd_queue(s, s->outport, 0);
break;
-#ifdef TARGET_I386
case KBD_CCMD_ENABLE_A20:
- ioport_set_a20(1);
+ if (s->a20_out) {
+ qemu_irq_raise(*s->a20_out);
+ }
+ s->outport |= KBD_OUT_A20;
break;
case KBD_CCMD_DISABLE_A20:
- ioport_set_a20(0);
+ if (s->a20_out) {
+ qemu_irq_lower(*s->a20_out);
+ }
+ s->outport &= ~KBD_OUT_A20;
break;
-#endif
case KBD_CCMD_RESET:
qemu_system_reset_request();
break;
@@ -282,9 +313,7 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr)
else
val = ps2_read_data(s->kbd);
-#if defined(DEBUG_KBD)
- printf("kbd: read data=0x%02x\n", val);
-#endif
+ DPRINTF("kbd: read data=0x%02x\n", val);
return val;
}
@@ -292,9 +321,7 @@ static void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
{
KBDState *s = opaque;
-#ifdef DEBUG_KBD
- printf("kbd: write data=0x%02x\n", val);
-#endif
+ DPRINTF("kbd: write data=0x%02x\n", val);
switch(s->write_cmd) {
case 0:
@@ -313,12 +340,7 @@ static void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
kbd_queue(s, val, 1);
break;
case KBD_CCMD_WRITE_OUTPORT:
-#ifdef TARGET_I386
- ioport_set_a20((val >> 1) & 1);
-#endif
- if (!(val & 1)) {
- qemu_system_reset_request();
- }
+ ioport92_write(s, 0, val);
break;
case KBD_CCMD_WRITE_MOUSE:
ps2_write_mouse(s->mouse, val);
@@ -335,6 +357,7 @@ static void kbd_reset(void *opaque)
s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
+ s->outport = KBD_OUT_RESET | KBD_OUT_A20;
}
static const VMStateDescription vmstate_kbd = {
@@ -401,9 +424,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
-#ifdef TARGET_I386
- vmmouse_init(s->mouse);
-#endif
qemu_register_reset(kbd_reset, s);
}
@@ -412,6 +432,21 @@ typedef struct ISAKBDState {
KBDState kbd;
} ISAKBDState;
+void i8042_isa_mouse_fake_event(void *opaque)
+{
+ ISADevice *dev = opaque;
+ KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+ ps2_mouse_fake_event(s->mouse);
+}
+
+void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out)
+{
+ KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+ s->a20_out = a20_out;
+}
+
static const VMStateDescription vmstate_kbd_isa = {
.name = "pckbd",
.version_id = 3,
@@ -434,12 +469,11 @@ static int i8042_initfn(ISADevice *dev)
register_ioport_write(0x60, 1, 1, kbd_write_data, s);
register_ioport_read(0x64, 1, 1, kbd_read_status, s);
register_ioport_write(0x64, 1, 1, kbd_write_command, s);
+ register_ioport_read(0x92, 1, 1, ioport92_read, s);
+ register_ioport_write(0x92, 1, 1, ioport92_write, s);
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
-#ifdef TARGET_I386
- vmmouse_init(s->mouse);
-#endif
qemu_register_reset(kbd_reset, s);
return 0;
}
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 20fe93d63c..19e13d632d 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -166,6 +166,22 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset,
ret = pfl->status;
DPRINTF("%s: status %x\n", __func__, ret);
break;
+ case 0x90:
+ switch (boff) {
+ case 0:
+ ret = pfl->ident[0] << 8 | pfl->ident[1];
+ DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret);
+ break;
+ case 1:
+ ret = pfl->ident[2] << 8 | pfl->ident[3];
+ DPRINTF("%s: Device ID Code %04x\n", __func__, ret);
+ break;
+ default:
+ DPRINTF("%s: Read Device Information boff=%x\n", __func__, boff);
+ ret = 0;
+ break;
+ }
+ break;
case 0x98: /* Query mode */
if (boff > pfl->cfi_len)
ret = 0;
@@ -283,6 +299,10 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
DPRINTF("%s: Read status register\n", __func__);
pfl->cmd = cmd;
return;
+ case 0x90: /* Read Device ID */
+ DPRINTF("%s: Read Device information\n", __func__);
+ pfl->cmd = cmd;
+ return;
case 0x98: /* CFI query */
DPRINTF("%s: CFI query\n", __func__);
break;
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 09a98819d1..16c9950740 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -547,6 +547,15 @@ static CPUReadMemoryFunc * const PPC_prep_io_read[] = {
#define NVRAM_SIZE 0x2000
+static void cpu_request_exit(void *opaque, int irq, int level)
+{
+ CPUState *env = cpu_single_env;
+
+ if (env && level) {
+ cpu_exit(env);
+ }
+}
+
/* PowerPC PREP hardware initialisation */
static void ppc_prep_init (ram_addr_t ram_size,
const char *boot_device,
@@ -565,6 +574,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
PCIBus *pci_bus;
qemu_irq *i8259;
+ qemu_irq *cpu_exit_irq;
int ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
DriveInfo *fd[MAX_FD];
@@ -719,7 +729,10 @@ static void ppc_prep_init (ram_addr_t ram_size,
hd[2 * i + 1]);
}
isa_create_simple("i8042");
- DMA_init(1);
+
+ cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+ DMA_init(1, cpu_exit_irq);
+
// SB16_init();
for(i = 0; i < MAX_FD; i++) {
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 3ceb851e91..b52170787b 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -62,6 +62,9 @@
#define DMA_DRAIN_FIFO 0x40
#define DMA_RESET 0x80
+/* XXX SCSI and ethernet should have different read-only bit masks */
+#define DMA_CSR_RO_MASK 0xfe000007
+
typedef struct DMAState DMAState;
struct DMAState {
@@ -187,7 +190,7 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
switch (saddr) {
case 0:
if (val & DMA_INTREN) {
- if (val & DMA_INTR) {
+ if (s->dmaregs[0] & DMA_INTR) {
DPRINTF("Raise IRQ\n");
qemu_irq_raise(s->irq);
}
@@ -204,16 +207,17 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
val &= ~DMA_DRAIN_FIFO;
} else if (val == 0)
val = DMA_DRAIN_FIFO;
- val &= 0x0fffffff;
+ val &= ~DMA_CSR_RO_MASK;
val |= DMA_VER;
+ s->dmaregs[0] = (s->dmaregs[0] & DMA_CSR_RO_MASK) | val;
break;
case 1:
s->dmaregs[0] |= DMA_LOADED;
- break;
+ /* fall through */
default:
+ s->dmaregs[saddr] = val;
break;
}
- s->dmaregs[saddr] = val;
}
static CPUReadMemoryFunc * const dma_mem_read[3] = {
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 9a79120b1d..7ba0f763bc 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -152,7 +152,11 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size)
void DMA_hold_DREQ (int nchan) {}
void DMA_release_DREQ (int nchan) {}
void DMA_schedule(int nchan) {}
-void DMA_init (int high_page_enable) {}
+
+void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
+{
+}
+
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 24ea367d1a..e9a1e231e9 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -105,7 +105,11 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size)
void DMA_hold_DREQ (int nchan) {}
void DMA_release_DREQ (int nchan) {}
void DMA_schedule(int nchan) {}
-void DMA_init (int high_page_enable) {}
+
+void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
+{
+}
+
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque)
diff --git a/hw/vga.c b/hw/vga.c
index 87a1bb06d1..01de1e1b04 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -232,7 +232,7 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
"clocking_mode = %d\n"
"clock_sel = %d %d\n"
"dots = %d\n"
- "ticks/char = %lld\n"
+ "ticks/char = %" PRId64 "\n"
"\n",
(double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars),
htotal_chars,
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 2e292eea26..26dae797bf 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -99,7 +99,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd)
goto fail;
}
if (~net->dev.features & net->dev.backend_features) {
- fprintf(stderr, "vhost lacks feature mask %llu for backend\n",
+ fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",
~net->dev.features & net->dev.backend_features);
vhost_dev_cleanup(&net->dev);
goto fail;
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index bb6e6056d6..afebad9a0a 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -97,7 +97,7 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
/* need to still generate PS2 events to notify driver to
read from queue */
- ps2_mouse_fake_event(s->ps2_mouse);
+ i8042_isa_mouse_fake_event(s->ps2_mouse);
}
static void vmmouse_update_handler(VMMouseState *s)
diff --git a/hxtool b/hxtool
index 0fdbc641c6..8f655320be 100644
--- a/hxtool
+++ b/hxtool
@@ -19,11 +19,24 @@ hxtoh()
hxtotexi()
{
flag=0
+ line=1
while read -r str; do
case "$str" in
HXCOMM*)
;;
- STEXI*|ETEXI*) flag=$(($flag^1))
+ STEXI*)
+ if test $flag -eq 1 ; then
+ echo "line $line: syntax error: expected ETEXI, found $str" >&2
+ exit 1
+ fi
+ flag=1
+ ;;
+ ETEXI*)
+ if test $flag -ne 1 ; then
+ echo "line $line: syntax error: expected STEXI, found $str" >&2
+ exit 1
+ fi
+ flag=0
;;
DEFHEADING*)
echo "$(expr "$str" : "DEFHEADING(\(.*\))")"
@@ -32,6 +45,7 @@ hxtotexi()
test $flag -eq 1 && echo "$str"
;;
esac
+ line=$((line+1))
done
}
diff --git a/ia64-dis.c b/ia64-dis.c
index da73a98ba5..2886df3614 100644
--- a/ia64-dis.c
+++ b/ia64-dis.c
@@ -10560,11 +10560,14 @@ print_insn_ia64 (bfd_vma memaddr, struct disassemble_info *info)
if (str)
(*info->fprintf_func) (info->stream, "%s", str);
else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_SIGNED)
- (*info->fprintf_func) (info->stream, "%lld", (long long) value);
+ (*info->fprintf_func) (info->stream, "%" PRId64,
+ (int64_t) value);
else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_UNSIGNED)
- (*info->fprintf_func) (info->stream, "%llu", (long long) value);
+ (*info->fprintf_func) (info->stream, "%" PRIu64,
+ (uint64_t) value);
else
- (*info->fprintf_func) (info->stream, "0x%llx", (long long) value);
+ (*info->fprintf_func) (info->stream, "0x%" PRIx64,
+ (uint64_t) value);
break;
case IA64_OPND_CLASS_REL:
diff --git a/linux-user/main.c b/linux-user/main.c
index 99a7cde559..b240f290f7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -31,7 +31,7 @@
#include "cache-utils.h"
/* For tb_lock */
#include "exec-all.h"
-
+#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
@@ -2434,7 +2434,7 @@ void cpu_loop (CPUState *env)
info.si_signo = TARGET_SIGSEGV;
info.si_errno = 0;
info.si_code = 0; /* ??? SEGV_MAPERR vs SEGV_ACCERR. */
- info._sifields._sigfault._addr = env->pc;
+ info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
queue_signal(env, info.si_signo, &info);
break;
case EXCP_DTB_MISS_PAL:
@@ -2458,7 +2458,7 @@ void cpu_loop (CPUState *env)
info.si_signo = TARGET_SIGBUS;
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
- info._sifields._sigfault._addr = env->pc;
+ info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
queue_signal(env, info.si_signo, &info);
break;
case EXCP_OPCDEC:
@@ -2499,8 +2499,15 @@ void cpu_loop (CPUState *env)
env->ir[IR_A0], env->ir[IR_A1],
env->ir[IR_A2], env->ir[IR_A3],
env->ir[IR_A4], env->ir[IR_A5]);
- if (trapnr != TARGET_NR_sigreturn
- && trapnr != TARGET_NR_rt_sigreturn) {
+ if (trapnr == TARGET_NR_sigreturn
+ || trapnr == TARGET_NR_rt_sigreturn) {
+ break;
+ }
+ /* Syscall writes 0 to V0 to bypass error check, similar
+ to how this is handled internal to Linux kernel. */
+ if (env->ir[IR_V0] == 0) {
+ env->ir[IR_V0] = sysret;
+ } else {
env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret);
env->ir[IR_A3] = (sysret < 0);
}
@@ -2977,6 +2984,13 @@ int main(int argc, char **argv, char **envp)
syscall_init();
signal_init();
+#if defined(CONFIG_USE_GUEST_BASE)
+ /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
+ generating the prologue until now so that the prologue can take
+ the real value of GUEST_BASE into account. */
+ tcg_prologue_init(&tcg_ctx);
+#endif
+
#if defined(TARGET_I386)
cpu_x86_set_cpl(env, 3);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce728faa4d..8222cb92f1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -718,9 +718,17 @@ abi_long do_brk(abi_ulong new_brk)
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
- if (!is_error(mapped_addr))
+#if defined(TARGET_ALPHA)
+ /* We (partially) emulate OSF/1 on Alpha, which requires we
+ return a proper errno, not an unchanged brk value. */
+ if (is_error(mapped_addr)) {
+ return -TARGET_ENOMEM;
+ }
+#endif
+
+ if (!is_error(mapped_addr)) {
target_brk = new_brk;
-
+ }
return target_brk;
}
@@ -987,7 +995,8 @@ static abi_long do_pipe2(int host_pipe[], int flags)
#endif
}
-static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
+static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
+ int flags, int is_pipe2)
{
int host_pipe[2];
abi_long ret;
@@ -995,20 +1004,25 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
if (is_error(ret))
return get_errno(ret);
-#if defined(TARGET_MIPS)
- ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
- ret = host_pipe[0];
-#else
-#if defined(TARGET_SH4)
- if (!flags) {
+
+ /* Several targets have special calling conventions for the original
+ pipe syscall, but didn't replicate this into the pipe2 syscall. */
+ if (!is_pipe2) {
+#if defined(TARGET_ALPHA)
+ ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
+ return host_pipe[0];
+#elif defined(TARGET_MIPS)
+ ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
+ return host_pipe[0];
+#elif defined(TARGET_SH4)
((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
- ret = host_pipe[0];
- } else
+ return host_pipe[0];
#endif
+ }
+
if (put_user_s32(host_pipe[0], pipedes)
|| put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
return -TARGET_EFAULT;
-#endif
return get_errno(ret);
}
@@ -4483,13 +4497,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_lseek:
ret = get_errno(lseek(arg1, arg2, arg3));
break;
-#ifdef TARGET_NR_getxpid
+#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
+ /* Alpha specific */
case TARGET_NR_getxpid:
-#else
- case TARGET_NR_getpid:
+ ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
+ ret = get_errno(getpid());
+ break;
#endif
+#ifdef TARGET_NR_getpid
+ case TARGET_NR_getpid:
ret = get_errno(getpid());
break;
+#endif
case TARGET_NR_mount:
{
/* need to look at the data field */
@@ -4698,11 +4717,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(dup(arg1));
break;
case TARGET_NR_pipe:
- ret = do_pipe(cpu_env, arg1, 0);
+ ret = do_pipe(cpu_env, arg1, 0, 0);
break;
#ifdef TARGET_NR_pipe2
case TARGET_NR_pipe2:
- ret = do_pipe(cpu_env, arg1, arg2);
+ ret = do_pipe(cpu_env, arg1, arg2, 1);
break;
#endif
case TARGET_NR_times:
@@ -4964,11 +4983,41 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_sigprocmask
case TARGET_NR_sigprocmask:
{
- int how = arg1;
+#if defined(TARGET_ALPHA)
+ sigset_t set, oldset;
+ abi_ulong mask;
+ int how;
+
+ switch (arg1) {
+ case TARGET_SIG_BLOCK:
+ how = SIG_BLOCK;
+ break;
+ case TARGET_SIG_UNBLOCK:
+ how = SIG_UNBLOCK;
+ break;
+ case TARGET_SIG_SETMASK:
+ how = SIG_SETMASK;
+ break;
+ default:
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
+ mask = arg2;
+ target_to_host_old_sigset(&set, &mask);
+
+ ret = get_errno(sigprocmask(how, &set, &oldset));
+
+ if (!is_error(ret)) {
+ host_to_target_old_sigset(&mask, &oldset);
+ ret = mask;
+ ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
+ }
+#else
sigset_t set, oldset, *set_ptr;
+ int how;
if (arg2) {
- switch(how) {
+ switch (arg1) {
case TARGET_SIG_BLOCK:
how = SIG_BLOCK;
break;
@@ -4991,13 +5040,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
how = 0;
set_ptr = NULL;
}
- ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
+ ret = get_errno(sigprocmask(how, set_ptr, &oldset));
if (!is_error(ret) && arg3) {
if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
goto efault;
host_to_target_old_sigset(p, &oldset);
unlock_user(p, arg3, sizeof(target_sigset_t));
}
+#endif
}
break;
#endif
@@ -5069,10 +5119,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_sigsuspend:
{
sigset_t set;
+#if defined(TARGET_ALPHA)
+ abi_ulong mask = arg1;
+ target_to_host_old_sigset(&set, &mask);
+#else
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
goto efault;
target_to_host_old_sigset(&set, p);
unlock_user(p, arg1, 0);
+#endif
ret = get_errno(sigsuspend(&set));
}
break;
@@ -5213,6 +5268,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_pselect6
+ case TARGET_NR_pselect6:
+ goto unimplemented_nowarn;
+#endif
case TARGET_NR_symlink:
{
void *p2;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 6f5a0aada8..681021ca0e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -336,6 +336,14 @@ int do_sigaction(int sig, const struct target_sigaction *act,
#if !defined(TARGET_ABI_MIPSN32) && !defined(TARGET_ABI_MIPSN64)
#define TARGET_SA_RESTORER 0x04000000 /* Only for O32 */
#endif
+#elif defined(TARGET_ALPHA)
+#define TARGET_SA_ONSTACK 0x00000001
+#define TARGET_SA_RESTART 0x00000002
+#define TARGET_SA_NOCLDSTOP 0x00000004
+#define TARGET_SA_NODEFER 0x00000008
+#define TARGET_SA_RESETHAND 0x00000010
+#define TARGET_SA_NOCLDWAIT 0x00000020 /* not supported yet */
+#define TARGET_SA_SIGINFO 0x00000040
#else
#define TARGET_SA_NOCLDSTOP 0x00000001
#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
diff --git a/monitor.c b/monitor.c
index a1ebc5d4d2..ad50f12edb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1021,7 +1021,9 @@ static void do_info_cpu_stats(Monitor *mon)
static int do_quit(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
monitor_suspend(mon);
- qemu_system_exit_request();
+ no_shutdown = 0;
+ qemu_system_shutdown_request();
+
return 0;
}
diff --git a/nbd.c b/nbd.c
index 337eeba873..a9f295f2bb 100644
--- a/nbd.c
+++ b/nbd.c
@@ -353,8 +353,7 @@ int nbd_init(int fd, int csock, off_t size, size_t blocksize)
return -1;
}
- TRACE("Setting size to %llu block(s)",
- (unsigned long long)(size / blocksize));
+ TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize));
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) {
int serrno = errno;
diff --git a/qbool.c b/qbool.c
index 5ab734c2c7..ad4873f62c 100644
--- a/qbool.c
+++ b/qbool.c
@@ -1,14 +1,6 @@
/*
* QBool Module
*
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
* Copyright IBM, Corp. 2009
*
* Authors:
diff --git a/qdict.c b/qdict.c
index aae57bf450..175bc178f0 100644
--- a/qdict.c
+++ b/qdict.c
@@ -1,13 +1,13 @@
/*
- * QDict data type.
+ * QDict Module
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
#include "qint.h"
diff --git a/qdict.h b/qdict.h
index 579dcddc74..5e5902caea 100644
--- a/qdict.h
+++ b/qdict.h
@@ -1,3 +1,15 @@
+/*
+ * QDict Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
#ifndef QDICT_H
#define QDICT_H
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index c079019048..c4cf3e7542 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -7,7 +7,7 @@ HXCOMM HXCOMM can be used for comments, discarded from both texi and C
STEXI
@table @option
-STEXI
+ETEXI
DEF("check", img_check,
"check [-f fmt] filename")
diff --git a/qemu-img.c b/qemu-img.c
index d3c30a74f3..cb007b757d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -701,9 +701,9 @@ static int img_convert(int argc, char **argv)
bs_offset += bs_sectors;
bdrv_get_geometry(bs[bs_i], &bs_sectors);
bs_num = 0;
- /* printf("changing part: sector_num=%lld, "
- "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
- sector_num, bs_i, bs_offset, bs_sectors); */
+ /* printf("changing part: sector_num=%" PRId64 ", "
+ "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
+ "\n", sector_num, bs_i, bs_offset, bs_sectors); */
}
assert (bs_num < bs_sectors);
@@ -749,8 +749,8 @@ static int img_convert(int argc, char **argv)
assert (bs_i < bs_n);
bs_offset += bs_sectors;
bdrv_get_geometry(bs[bs_i], &bs_sectors);
- /* printf("changing part: sector_num=%lld, bs_i=%d, "
- "bs_offset=%lld, bs_sectors=%lld\n",
+ /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
+ "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
sector_num, bs_i, bs_offset, bs_sectors); */
}
diff --git a/qemu-io.c b/qemu-io.c
index 8517b909c7..f39109e231 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -84,7 +84,7 @@ dump_buffer(const void *buffer, int64_t offset, int len)
for (i = 0, p = buffer; i < len; i += 16) {
const uint8_t *s = p;
- printf("%08llx: ", (unsigned long long)offset + i);
+ printf("%08" PRIx64 ": ", offset + i);
for (j = 0; j < 16 && i + j < len; j++, p++)
printf("%02x ", *p);
printf(" ");
@@ -108,8 +108,8 @@ print_report(const char *op, struct timeval *t, int64_t offset,
if (!Cflag) {
cvtstr((double)total, s1, sizeof(s1));
cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
- printf("%s %d/%d bytes at offset %lld\n",
- op, total, count, (long long)offset);
+ printf("%s %d/%d bytes at offset %" PRId64 "\n",
+ op, total, count, offset);
printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
s1, cnt, ts, s2, tdiv((double)cnt, *t));
} else {/* bytes,ops,time,bytes/sec,ops/sec */
@@ -135,7 +135,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
for (i = 0; i < nr_iov; i++) {
char *arg = argv[i];
- long long len;
+ uint64_t len;
len = cvtnum(arg);
if (len < 0) {
@@ -150,8 +150,8 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
}
if (len & 0x1ff) {
- printf("length argument %lld is not sector aligned\n",
- len);
+ printf("length argument %" PRId64
+ " is not sector aligned\n", len);
goto fail;
}
@@ -398,8 +398,8 @@ read_f(int argc, char **argv)
if (!pflag)
if (offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ offset);
return 0;
if (count & 0x1ff) {
@@ -429,9 +429,9 @@ read_f(int argc, char **argv)
void* cmp_buf = malloc(pattern_count);
memset(cmp_buf, pattern, pattern_count);
if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
- printf("Pattern verification failed at offset %lld, "
- "%d bytes\n",
- (long long) offset + pattern_offset, pattern_count);
+ printf("Pattern verification failed at offset %"
+ PRId64 ", %d bytes\n",
+ offset + pattern_offset, pattern_count);
}
free(cmp_buf);
}
@@ -533,8 +533,8 @@ readv_f(int argc, char **argv)
optind++;
if (offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ offset);
return 0;
}
@@ -554,9 +554,9 @@ readv_f(int argc, char **argv)
void* cmp_buf = malloc(qiov.size);
memset(cmp_buf, pattern, qiov.size);
if (memcmp(buf, cmp_buf, qiov.size)) {
- printf("Pattern verification failed at offset %lld, "
- "%zd bytes\n",
- (long long) offset, qiov.size);
+ printf("Pattern verification failed at offset %"
+ PRId64 ", %zd bytes\n",
+ offset, qiov.size);
}
free(cmp_buf);
}
@@ -669,8 +669,8 @@ write_f(int argc, char **argv)
if (!pflag) {
if (offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ offset);
return 0;
}
@@ -783,8 +783,8 @@ writev_f(int argc, char **argv)
optind++;
if (offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ offset);
return 0;
}
@@ -868,9 +868,9 @@ aio_read_done(void *opaque, int ret)
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
- printf("Pattern verification failed at offset %lld, "
- "%zd bytes\n",
- (long long) ctx->offset, ctx->qiov.size);
+ printf("Pattern verification failed at offset %"
+ PRId64 ", %zd bytes\n",
+ ctx->offset, ctx->qiov.size);
}
free(cmp_buf);
}
@@ -969,8 +969,8 @@ aio_read_f(int argc, char **argv)
optind++;
if (ctx->offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)ctx->offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ ctx->offset);
free(ctx);
return 0;
}
@@ -1064,8 +1064,8 @@ aio_write_f(int argc, char **argv)
optind++;
if (ctx->offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)ctx->offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ ctx->offset);
free(ctx);
return 0;
}
@@ -1214,8 +1214,8 @@ alloc_f(int argc, char **argv)
offset = cvtnum(argv[1]);
if (offset & 0x1ff) {
- printf("offset %lld is not sector aligned\n",
- (long long)offset);
+ printf("offset %" PRId64 " is not sector aligned\n",
+ offset);
return 0;
}
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index a8f194c301..b6e3467c08 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -858,8 +858,7 @@ ETEXI
.args_type = "pci_addr:s,type:s,opts:s?",
.params = "auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...",
.help = "hot-add PCI device",
- .user_print = pci_device_hot_add_print,
- .mhandler.cmd_new = pci_device_hot_add,
+ .mhandler.cmd = pci_device_hot_add,
},
#endif
@@ -875,8 +874,7 @@ ETEXI
.args_type = "pci_addr:s",
.params = "[[<domain>:]<bus>:]<slot>",
.help = "hot remove PCI device",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_pci_device_hot_remove,
+ .mhandler.cmd = do_pci_device_hot_remove,
},
#endif
diff --git a/qemu-objects.h b/qemu-objects.h
index e1d1e0ca72..c53fbaa217 100644
--- a/qemu-objects.h
+++ b/qemu-objects.h
@@ -6,9 +6,10 @@
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
+
#ifndef QEMU_OBJECTS_H
#define QEMU_OBJECTS_H
diff --git a/qemu-options.hx b/qemu-options.hx
index 12f6b5179d..03e95fd2bf 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -464,18 +464,15 @@ DEF("device", HAS_ARG, QEMU_OPTION_device,
" add device (based on driver)\n"
" prop=value,... sets driver properties\n"
" use -device ? to print all possible drivers\n"
- " use -device driver,? to print all possible options\n"
- " use -device driver,option=? to print a help for value\n",
+ " use -device driver,? to print all possible properties\n",
QEMU_ARCH_ALL)
STEXI
-@item -device @var{driver}[,@var{option}[=@var{value}][,...]]
+@item -device @var{driver}[,@var{prop}[=@var{value}][,...]]
@findex -device
-Add device @var{driver}. Depending on the device type,
-@var{option} (with default or given @var{value}) may be useful.
-To get a help on possible @var{driver}s, @var{option}s or @var{value}s, use
-@code{-device ?},
-@code{-device @var{driver},?} or
-@code{-device @var{driver},@var{option}=?}.
+Add device @var{driver}. @var{prop}=@var{value} sets driver
+properties. Valid properties depend on the driver. To get help on
+possible drivers and properties, use @code{-device ?} and
+@code{-device @var{driver},?}.
ETEXI
#ifdef CONFIG_LINUX
diff --git a/qerror.c b/qerror.c
index 034c7deaad..44d0bf82b4 100644
--- a/qerror.c
+++ b/qerror.c
@@ -1,5 +1,5 @@
/*
- * QError: QEMU Error data-type.
+ * QError Module
*
* Copyright (C) 2009 Red Hat Inc.
*
diff --git a/qerror.h b/qerror.h
index c98c61ad11..77ae57464e 100644
--- a/qerror.h
+++ b/qerror.h
@@ -1,5 +1,5 @@
/*
- * QError header file.
+ * QError Module
*
* Copyright (C) 2009 Red Hat Inc.
*
diff --git a/qfloat.c b/qfloat.c
index 05215f5027..f8c8a2eb21 100644
--- a/qfloat.c
+++ b/qfloat.c
@@ -1,14 +1,6 @@
/*
* QFloat Module
*
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
* Copyright IBM, Corp. 2009
*
* Authors:
diff --git a/qint.c b/qint.c
index 447e847af3..fb3823a7f4 100644
--- a/qint.c
+++ b/qint.c
@@ -1,14 +1,15 @@
/*
- * QInt data type.
+ * QInt Module
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
+
#include "qint.h"
#include "qobject.h"
#include "qemu-common.h"
diff --git a/qint.h b/qint.h
index 672b32196c..6b1a15c088 100644
--- a/qint.h
+++ b/qint.h
@@ -1,3 +1,15 @@
+/*
+ * QInt Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
#ifndef QINT_H
#define QINT_H
diff --git a/qlist.c b/qlist.c
index 5fccb7d095..5730fb87f7 100644
--- a/qlist.c
+++ b/qlist.c
@@ -1,14 +1,15 @@
/*
- * QList data type.
+ * QList Module
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
+
#include "qlist.h"
#include "qobject.h"
#include "qemu-queue.h"
diff --git a/qlist.h b/qlist.h
index a3261e1781..dbe7b92db5 100644
--- a/qlist.h
+++ b/qlist.h
@@ -1,14 +1,15 @@
/*
- * QList data type header.
+ * QList Module
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
+
#ifndef QLIST_H
#define QLIST_H
diff --git a/qobject.h b/qobject.h
index 07de211ef0..d42386dde1 100644
--- a/qobject.h
+++ b/qobject.h
@@ -8,8 +8,8 @@
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*
* QObject Reference Counts Terminology
* ------------------------------------
diff --git a/qstring.c b/qstring.c
index 740a1067d2..4e2ba083b7 100644
--- a/qstring.c
+++ b/qstring.c
@@ -1,14 +1,15 @@
/*
- * QString data type.
+ * QString Module
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
*/
+
#include "qobject.h"
#include "qstring.h"
#include "qemu-common.h"
diff --git a/qstring.h b/qstring.h
index 6aaa7d5c83..84ccd96d61 100644
--- a/qstring.h
+++ b/qstring.h
@@ -1,3 +1,15 @@
+/*
+ * QString Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
#ifndef QSTRING_H
#define QSTRING_H
diff --git a/rules.mak b/rules.mak
index 7e10432596..c843a131e8 100644
--- a/rules.mak
+++ b/rules.mak
@@ -12,7 +12,7 @@ MAKEFLAGS += -rR
%.mak:
# Flags for dependency generation
-QEMU_DGFLAGS += -MMD -MP -MT $@
+QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
%.o: %.c
$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@")
diff --git a/sysemu.h b/sysemu.h
index fa921df94a..879446ab9e 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -45,11 +45,9 @@ void cpu_disable_ticks(void);
void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
-void qemu_system_exit_request(void);
int qemu_shutdown_requested(void);
int qemu_reset_requested(void);
int qemu_powerdown_requested(void);
-int qemu_exit_requested(void);
extern qemu_irq qemu_system_powerdown;
void qemu_system_reset(void);
@@ -130,6 +128,7 @@ extern int max_cpus;
extern int cursor_hide;
extern int graphic_rotate;
extern int no_quit;
+extern int no_shutdown;
extern int semihosting_enabled;
extern int old_param;
extern int boot_menu;
@@ -201,12 +200,10 @@ extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error);
DriveInfo *add_init_drive(const char *opts);
/* pci-hotplug */
-void pci_device_hot_add_print(Monitor *mon, const QObject *data);
-int pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
+void pci_device_hot_add(Monitor *mon, const QDict *qdict);
void drive_hot_add(Monitor *mon, const QDict *qdict);
int pci_device_hot_remove(Monitor *mon, const char *pci_addr);
-int do_pci_device_hot_remove(Monitor *mon, const QDict *qdict,
- QObject **ret_data);
+void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
/* serial ports */
diff --git a/target-cris/translate.c b/target-cris/translate.c
index a7014face6..6c1d9e026e 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3226,14 +3226,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log(
- "srch=%d pc=%x %x flg=%llx bt=%x ds=%u ccs=%x\n"
+ "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
"pid=%x usp=%x\n"
"%x.%x.%x.%x\n"
"%x.%x.%x.%x\n"
"%x.%x.%x.%x\n"
"%x.%x.%x.%x\n",
search_pc, dc->pc, dc->ppc,
- (unsigned long long)tb->flags,
+ (uint64_t)tb->flags,
env->btarget, (unsigned)tb->flags & 7,
env->pregs[PR_CCS],
env->pregs[PR_PID], env->pregs[PR_USP],
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 86cca5182d..66e1c0d3bf 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -8918,7 +8918,7 @@ void cpu_dump_statistics (CPUState *env, FILE*f,
if (handler->count == 0)
continue;
cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
- "%016llx %lld\n",
+ "%016" PRIx64 " %" PRId64 "\n",
op1, op2, op3, op1, (op3 << 5) | op2,
handler->oname,
handler->count, handler->count);
@@ -8927,7 +8927,7 @@ void cpu_dump_statistics (CPUState *env, FILE*f,
if (handler->count == 0)
continue;
cpu_fprintf(f, "%02x %02x (%02x %04d) %16s: "
- "%016llx %lld\n",
+ "%016" PRIx64 " %" PRId64 "\n",
op1, op2, op1, op2, handler->oname,
handler->count, handler->count);
}
@@ -8935,7 +8935,8 @@ void cpu_dump_statistics (CPUState *env, FILE*f,
} else {
if (handler->count == 0)
continue;
- cpu_fprintf(f, "%02x (%02x ) %16s: %016llx %lld\n",
+ cpu_fprintf(f, "%02x (%02x ) %16s: %016" PRIx64
+ " %" PRId64 "\n",
op1, op1, handler->oname,
handler->count, handler->count);
}
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 27b020b541..8f0484b24a 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -92,12 +92,14 @@
#define PSR_CARRY_SHIFT 20
#define PSR_CARRY (1 << PSR_CARRY_SHIFT)
#define PSR_ICC (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
+#if !defined(TARGET_SPARC64)
#define PSR_EF (1<<12)
#define PSR_PIL 0xf00
#define PSR_S (1<<7)
#define PSR_PS (1<<6)
#define PSR_ET (1<<5)
#define PSR_CWP 0x1f
+#endif
#define CC_SRC (env->cc_src)
#define CC_SRC2 (env->cc_src2)
@@ -341,14 +343,16 @@ typedef struct CPUSPARCState {
uint32_t wim; /* window invalid mask */
#endif
target_ulong tbr; /* trap base register */
+#if !defined(TARGET_SPARC64)
int psrs; /* supervisor mode (extracted from PSR) */
int psrps; /* previous supervisor mode */
-#if !defined(TARGET_SPARC64)
int psret; /* enable traps */
#endif
uint32_t psrpil; /* interrupt blocking level */
uint32_t pil_in; /* incoming interrupt level bitmap */
+#if !defined(TARGET_SPARC64)
int psref; /* enable fpu */
+#endif
target_ulong version;
int interrupt_index;
uint32_t nwindows;
@@ -508,21 +512,41 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
#define CPU_SAVE_VERSION 6
/* MMU modes definitions */
+#if defined (TARGET_SPARC64)
+#define MMU_USER_IDX 0
#define MMU_MODE0_SUFFIX _user
-#define MMU_MODE1_SUFFIX _kernel
-#ifdef TARGET_SPARC64
-#define MMU_MODE2_SUFFIX _hypv
-#define MMU_MODE3_SUFFIX _nucleus
-#define MMU_MODE4_SUFFIX _user_secondary
-#define MMU_MODE5_SUFFIX _kernel_secondary
-#endif
+#define MMU_USER_SECONDARY_IDX 1
+#define MMU_MODE1_SUFFIX _user_secondary
+#define MMU_KERNEL_IDX 2
+#define MMU_MODE2_SUFFIX _kernel
+#define MMU_KERNEL_SECONDARY_IDX 3
+#define MMU_MODE3_SUFFIX _kernel_secondary
+#define MMU_NUCLEUS_IDX 4
+#define MMU_MODE4_SUFFIX _nucleus
+#define MMU_HYPV_IDX 5
+#define MMU_MODE5_SUFFIX _hypv
+#else
#define MMU_USER_IDX 0
+#define MMU_MODE0_SUFFIX _user
#define MMU_KERNEL_IDX 1
-#define MMU_HYPV_IDX 2
-#ifdef TARGET_SPARC64
-#define MMU_NUCLEUS_IDX 3
-#define MMU_USER_SECONDARY_IDX 4
-#define MMU_KERNEL_SECONDARY_IDX 5
+#define MMU_MODE1_SUFFIX _kernel
+#endif
+
+#if defined (TARGET_SPARC64)
+static inline int cpu_has_hypervisor(CPUState *env1)
+{
+ return env1->def->features & CPU_FEATURE_HYPV;
+}
+
+static inline int cpu_hypervisor_mode(CPUState *env1)
+{
+ return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV);
+}
+
+static inline int cpu_supervisor_mode(CPUState *env1)
+{
+ return env1->pstate & PS_PRIV;
+}
#endif
static inline int cpu_mmu_index(CPUState *env1)
@@ -532,12 +556,15 @@ static inline int cpu_mmu_index(CPUState *env1)
#elif !defined(TARGET_SPARC64)
return env1->psrs;
#else
- if (!env1->psrs)
- return MMU_USER_IDX;
- else if ((env1->hpstate & HS_PRIV) == 0)
- return MMU_KERNEL_IDX;
- else
+ if (env1->tl > 0) {
+ return MMU_NUCLEUS_IDX;
+ } else if (cpu_hypervisor_mode(env1)) {
return MMU_HYPV_IDX;
+ } else if (cpu_supervisor_mode(env1)) {
+ return MMU_KERNEL_IDX;
+ } else {
+ return MMU_USER_IDX;
+ }
#endif
}
@@ -611,9 +638,13 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*cs_base = env->npc;
#ifdef TARGET_SPARC64
// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = ((env->pstate & PS_AM) << 2)
- | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
- | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
+ *flags = ((env->pstate & PS_AM) << 2) /* 5 */
+ | (((env->pstate & PS_PEF) >> 1) /* 3 */
+ | ((env->fprs & FPRS_FEF) << 2)) /* 4 */
+ | (env->pstate & PS_PRIV) /* 2 */
+ | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
+ | ((env->tl & 0xff) << 8)
+ | (env->dmmu.mmu_primary_context << 16); /* 16... */
#else
// FPU enable . Supervisor
*flags = (env->psref << 4) | env->psrs;
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 582de1082c..96a22f3475 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -30,6 +30,13 @@
//#define DEBUG_MMU
//#define DEBUG_FEATURES
+#ifdef DEBUG_MMU
+#define DPRINTF_MMU(fmt, ...) \
+ do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF_MMU(fmt, ...) do {} while (0)
+#endif
+
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
/* Sparc MMU emulation */
@@ -451,42 +458,50 @@ static int get_physical_address_data(CPUState *env,
for (i = 0; i < 64; i++) {
// ctx match, vaddr match, valid?
- if (ultrasparc_tag_match(&env->dtlb[i],
- address, context, physical)) {
+ if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
+
+ uint8_t fault_type = 0;
+
// access ok?
- if (((env->dtlb[i].tte & 0x4) && is_user) ||
- (!(env->dtlb[i].tte & 0x2) && (rw == 1))) {
- uint8_t fault_type = 0;
+ if ((env->dtlb[i].tte & 0x4) && is_user) {
+ fault_type |= 1; /* privilege violation */
+ env->exception_index = TT_DFAULT;
- if ((env->dtlb[i].tte & 0x4) && is_user) {
- fault_type |= 1; /* privilege violation */
- }
+ DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
+ " mmu_idx=%d tl=%d\n",
+ address, context, mmu_idx, env->tl);
+ } else if (!(env->dtlb[i].tte & 0x2) && (rw == 1)) {
+ env->exception_index = TT_DPROT;
+
+ DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
+ " mmu_idx=%d tl=%d\n",
+ address, context, mmu_idx, env->tl);
+ } else {
+ *prot = PAGE_READ;
+ if (env->dtlb[i].tte & 0x2)
+ *prot |= PAGE_WRITE;
- if (env->dmmu.sfsr & 1) /* Fault status register */
- env->dmmu.sfsr = 2; /* overflow (not read before
+ TTE_SET_USED(env->dtlb[i].tte);
+
+ return 0;
+ }
+
+ if (env->dmmu.sfsr & 1) /* Fault status register */
+ env->dmmu.sfsr = 2; /* overflow (not read before
another fault) */
- env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
+ env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
- env->dmmu.sfsr |= (fault_type << 7);
+ env->dmmu.sfsr |= (fault_type << 7);
- env->dmmu.sfar = address; /* Fault address register */
- env->exception_index = TT_DFAULT;
-#ifdef DEBUG_MMU
- printf("DFAULT at 0x%" PRIx64 "\n", address);
-#endif
- return 1;
- }
- *prot = PAGE_READ;
- if (env->dtlb[i].tte & 0x2)
- *prot |= PAGE_WRITE;
- TTE_SET_USED(env->dtlb[i].tte);
- return 0;
+ env->dmmu.sfar = address; /* Fault address register */
+ return 1;
}
}
-#ifdef DEBUG_MMU
- printf("DMISS at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
env->dmmu.tag_access = (address & ~0x1fffULL) | context;
env->exception_index = TT_DMISS;
return 1;
@@ -528,9 +543,10 @@ static int get_physical_address_code(CPUState *env,
another fault) */
env->immu.sfsr |= (is_user << 3) | 1;
env->exception_index = TT_TFAULT;
-#ifdef DEBUG_MMU
- printf("TFAULT at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
return 1;
}
*prot = PAGE_EXEC;
@@ -538,9 +554,10 @@ static int get_physical_address_code(CPUState *env,
return 0;
}
}
-#ifdef DEBUG_MMU
- printf("TMISS at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
/* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
env->immu.tag_access = (address & ~0x1fffULL) | context;
env->exception_index = TT_TMISS;
@@ -555,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
/* ??? We treat everything as a small page, then explicitly flush
everything when an entry is evicted. */
*page_size = TARGET_PAGE_SIZE;
+
+#if defined (DEBUG_MMU)
+ /* safety net to catch wrong softmmu index use from dynamic code */
+ if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
+ DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d"
+ " primary context=%" PRIx64
+ " secondary context=%" PRIx64
+ " address=%" PRIx64
+ "\n",
+ (rw == 2 ? "CODE" : "DATA"),
+ env->tl, mmu_idx,
+ env->dmmu.mmu_primary_context,
+ env->dmmu.mmu_secondary_context,
+ address);
+ }
+#endif
+
if (rw == 2)
return get_physical_address_code(env, physical, prot, address,
mmu_idx);
@@ -578,10 +612,18 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
virt_addr = address & TARGET_PAGE_MASK;
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
(TARGET_PAGE_SIZE - 1));
-#ifdef DEBUG_MMU
- printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
- "\n", address, paddr, vaddr);
-#endif
+
+ DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 ","
+ " vaddr %" PRIx64
+ " mmu_idx=%d"
+ " tl=%d"
+ " primary context=%" PRIx64
+ " secondary context=%" PRIx64
+ "\n",
+ address, paddr, vaddr, mmu_idx, env->tl,
+ env->dmmu.mmu_primary_context,
+ env->dmmu.mmu_secondary_context);
+
tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
return 0;
}
@@ -628,7 +670,7 @@ void dump_mmu(CPUState *env)
env->dtlb[i].tte & 0x2? "RW": "RO",
env->dtlb[i].tte & 0x40? "locked": "unlocked",
env->dtlb[i].tag & (uint64_t)0x1fffULL,
- TTE_IS_GLOBAL(env->dtlb[i].tag)? "global" : "local");
+ TTE_IS_GLOBAL(env->dtlb[i].tte)? "global" : "local");
}
}
}
@@ -662,7 +704,7 @@ void dump_mmu(CPUState *env)
env->itlb[i].tte & 0x4? "priv": "user",
env->itlb[i].tte & 0x40? "locked": "unlocked",
env->itlb[i].tag & (uint64_t)0x1fffULL,
- TTE_IS_GLOBAL(env->itlb[i].tag)? "global" : "local");
+ TTE_IS_GLOBAL(env->itlb[i].tte)? "global" : "local");
}
}
}
@@ -693,7 +735,7 @@ target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{
- return cpu_get_phys_page_nofault(env, addr, MMU_KERNEL_IDX);
+ return cpu_get_phys_page_nofault(env, addr, cpu_mmu_index(env));
}
#endif
@@ -721,12 +763,12 @@ void cpu_reset(CPUSPARCState *env)
#else
#if !defined(TARGET_SPARC64)
env->psret = 0;
-#endif
env->psrs = 1;
env->psrps = 1;
+#endif
#ifdef TARGET_SPARC64
env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
- env->hpstate = HS_PRIV;
+ env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
env->tl = env->maxtl;
cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
env->lsu = 0;
@@ -1310,7 +1352,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
char *featurestr, *name = strtok(s, ",");
uint32_t plus_features = 0;
uint32_t minus_features = 0;
- long long iu_version;
+ uint64_t iu_version;
uint32_t fpu_version, mmu_version, nwindows;
for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
@@ -1342,7 +1384,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
}
cpu_def->iu_version = iu_version;
#ifdef DEBUG_FEATURES
- fprintf(stderr, "iu_version %llx\n", iu_version);
+ fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
#endif
} else if (!strcmp(featurestr, "fpu_version")) {
char *err;
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index d0bc27766e..edeeb4469a 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1404,11 +1404,7 @@ static target_ulong get_psr(void)
(env->psrps? PSR_PS : 0) |
(env->psret? PSR_ET : 0) | env->cwp;
#else
- return env->version | (env->psr & PSR_ICC) |
- (env->psref? PSR_EF : 0) |
- (env->psrpil << 8) |
- (env->psrs? PSR_S : 0) |
- (env->psrps? PSR_PS : 0) | env->cwp;
+ return env->psr & PSR_ICC;
#endif
}
@@ -1427,17 +1423,19 @@ target_ulong cpu_get_psr(CPUState *env1)
static void put_psr(target_ulong val)
{
env->psr = val & PSR_ICC;
+#if !defined (TARGET_SPARC64)
env->psref = (val & PSR_EF)? 1 : 0;
env->psrpil = (val & PSR_PIL) >> 8;
+#endif
#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY))
cpu_check_irqs(env);
#endif
+#if !defined (TARGET_SPARC64)
env->psrs = (val & PSR_S)? 1 : 0;
env->psrps = (val & PSR_PS)? 1 : 0;
-#if !defined (TARGET_SPARC64)
env->psret = (val & PSR_ET)? 1 : 0;
-#endif
set_cwp(val & PSR_CWP);
+#endif
env->cc_op = CC_OP_FLAGS;
}
@@ -2326,7 +2324,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
asi &= 0xff;
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
@@ -2361,8 +2359,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
case 0xe2: // UA2007 Primary block init
case 0xe3: // UA2007 Secondary block init
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
- if ((env->def->features & CPU_FEATURE_HYPV)
- && env->hpstate & HS_PRIV) {
+ if (cpu_hypervisor_mode(env)) {
switch(size) {
case 1:
ret = ldub_hypv(addr);
@@ -2678,7 +2675,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
asi &= 0xff;
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
@@ -2722,8 +2719,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
case 0xe2: // UA2007 Primary block init
case 0xe3: // UA2007 Secondary block init
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
- if ((env->def->features & CPU_FEATURE_HYPV)
- && env->hpstate & HS_PRIV) {
+ if (cpu_hypervisor_mode(env)) {
switch(size) {
case 1:
stb_hypv(addr, val);
@@ -2963,9 +2959,15 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
break;
case 1: // Primary context
env->dmmu.mmu_primary_context = val;
+ /* can be optimized to only flush MMU_USER_IDX
+ and MMU_KERNEL_IDX entries */
+ tlb_flush(env, 1);
break;
case 2: // Secondary context
env->dmmu.mmu_secondary_context = val;
+ /* can be optimized to only flush MMU_USER_SECONDARY_IDX
+ and MMU_KERNEL_SECONDARY_IDX entries */
+ tlb_flush(env, 1);
break;
case 5: // TSB access
DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
@@ -3048,7 +3050,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
void helper_ldda_asi(target_ulong addr, int asi, int rd)
{
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 8129b79d16..72ca0b4dce 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -183,9 +183,9 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
#define hypervisor(dc) 0
#endif
#else
-#define supervisor(dc) (dc->mem_idx >= 1)
+#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
#ifdef TARGET_SPARC64
-#define hypervisor(dc) (dc->mem_idx == 2)
+#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
#else
#endif
#endif
@@ -3484,14 +3484,14 @@ static void disas_sparc_insn(DisasContext * dc)
case 6: // pstate
save_state(dc, cpu_cond);
gen_helper_wrpstate(cpu_tmp0);
- gen_op_next_insn();
- tcg_gen_exit_tb(0);
- dc->is_br = 1;
+ dc->npc = DYNAMIC_PC;
break;
case 7: // tl
+ save_state(dc, cpu_cond);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, cpu_env,
offsetof(CPUSPARCState, tl));
+ dc->npc = DYNAMIC_PC;
break;
case 8: // pil
gen_helper_wrpil(cpu_tmp0);
@@ -4550,6 +4550,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 4);
+ dc->npc = DYNAMIC_PC;
break;
case 0x15: /* stba, store byte alternate */
#ifndef TARGET_SPARC64
@@ -4560,6 +4561,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 1);
+ dc->npc = DYNAMIC_PC;
break;
case 0x16: /* stha, store halfword alternate */
#ifndef TARGET_SPARC64
@@ -4570,6 +4572,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 2);
+ dc->npc = DYNAMIC_PC;
break;
case 0x17: /* stda, store double word alternate */
#ifndef TARGET_SPARC64
@@ -4594,6 +4597,7 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x1e: /* V9 stxa */
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 8);
+ dc->npc = DYNAMIC_PC;
break;
#endif
default:
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index cb605f1061..558c21f67f 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1629,11 +1629,10 @@ void tcg_target_qemu_prologue(TCGContext *s)
}
#ifdef CONFIG_USE_GUEST_BASE
- /* Note that GUEST_BASE can change after the prologue is generated.
- To combat that, load the value from the variable instead of
- embedding a constant here. */
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG,
- TCG_REG_R0, (tcg_target_long)&guest_base);
+ if (GUEST_BASE != 0) {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+ }
#endif
/* Jump to TB, and adjust R18 to be the return address. */
@@ -1679,9 +1678,6 @@ void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP); /* data pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
-#ifdef CONFIG_USE_GUEST_BASE
- tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
-#endif
tcg_add_target_add_op_defs(hppa_op_defs);
}
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 904d2e57be..396a2f1d53 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -50,7 +50,7 @@ static const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
static uint8_t *tb_ret_addr;
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend)
{
value += addend;
@@ -158,19 +158,48 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define P_EXT 0x100 /* 0x0f opcode prefix */
+#define OPC_ARITH_EvIz (0x81)
+#define OPC_ARITH_EvIb (0x83)
+#define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
+#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
#define OPC_BSWAP (0xc8 | P_EXT)
+#define OPC_CALL_Jz (0xe8)
+#define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
+#define OPC_DEC_r32 (0x48)
+#define OPC_IMUL_GvEv (0xaf | P_EXT)
+#define OPC_IMUL_GvEvIb (0x6b)
+#define OPC_IMUL_GvEvIz (0x69)
+#define OPC_INC_r32 (0x40)
#define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
#define OPC_JCC_short (0x70) /* ... plus condition code */
#define OPC_JMP_long (0xe9)
#define OPC_JMP_short (0xeb)
+#define OPC_LEA (0x8d)
#define OPC_MOVB_EvGv (0x88) /* stores, more or less */
#define OPC_MOVL_EvGv (0x89) /* stores, more or less */
#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
+#define OPC_MOVL_Iv (0xb8)
+#define OPC_MOVSBL (0xbe | P_EXT)
+#define OPC_MOVSWL (0xbf | P_EXT)
+#define OPC_MOVZBL (0xb6 | P_EXT)
+#define OPC_MOVZWL (0xb7 | P_EXT)
+#define OPC_POP_r32 (0x58)
+#define OPC_PUSH_r32 (0x50)
+#define OPC_PUSH_Iv (0x68)
+#define OPC_PUSH_Ib (0x6a)
+#define OPC_RET (0xc3)
+#define OPC_SETCC (0x90 | P_EXT) /* ... plus condition code */
#define OPC_SHIFT_1 (0xd1)
#define OPC_SHIFT_Ib (0xc1)
#define OPC_SHIFT_cl (0xd3)
+#define OPC_TESTL (0x85)
+#define OPC_XCHG_ax_r32 (0x90)
-/* Group 1 opcode extensions for 0x80-0x83. */
+#define OPC_GRP3_Ev (0xf7)
+#define OPC_GRP5 (0xff)
+
+/* Group 1 opcode extensions for 0x80-0x83.
+ These are also used as modifiers for OPC_ARITH. */
#define ARITH_ADD 0
#define ARITH_OR 1
#define ARITH_ADC 2
@@ -187,8 +216,17 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define SHIFT_SHR 5
#define SHIFT_SAR 7
-/* Group 5 opcode extensions for 0xff. */
-#define EXT_JMPN_Ev 4
+/* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
+#define EXT3_NOT 2
+#define EXT3_NEG 3
+#define EXT3_MUL 4
+#define EXT3_IMUL 5
+#define EXT3_DIV 6
+#define EXT3_IDIV 7
+
+/* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
+#define EXT5_CALLN_Ev 2
+#define EXT5_JMPN_Ev 4
/* Condition codes to be added to OPC_JCC_{long,short}. */
#define JCC_JMP (-1)
@@ -209,8 +247,6 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define JCC_JLE 0xe
#define JCC_JG 0xf
-#define P_EXT 0x100 /* 0x0f opcode prefix */
-
static const uint8_t tcg_cond_to_jcc[10] = {
[TCG_COND_EQ] = JCC_JE,
[TCG_COND_NE] = JCC_JNE,
@@ -237,40 +273,76 @@ static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
tcg_out8(s, 0xc0 | (r << 3) | rm);
}
-/* rm == -1 means no register index */
-static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
- int32_t offset)
+/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
+ We handle either RM and INDEX missing with a -1 value. */
+
+static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
+ int index, int shift, int32_t offset)
{
+ int mod, len;
+
+ if (index == -1 && rm == -1) {
+ /* Absolute address. */
+ tcg_out_opc(s, opc);
+ tcg_out8(s, (r << 3) | 5);
+ tcg_out32(s, offset);
+ return;
+ }
+
tcg_out_opc(s, opc);
+
+ /* Find the length of the immediate addend. Note that the encoding
+ that would be used for (%ebp) indicates absolute addressing. */
if (rm == -1) {
- tcg_out8(s, 0x05 | (r << 3));
- tcg_out32(s, offset);
+ mod = 0, len = 4, rm = 5;
} else if (offset == 0 && rm != TCG_REG_EBP) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x04 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x00 | (r << 3) | rm);
- }
- } else if ((int8_t)offset == offset) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x44 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x40 | (r << 3) | rm);
- }
- tcg_out8(s, offset);
+ mod = 0, len = 0;
+ } else if (offset == (int8_t)offset) {
+ mod = 0x40, len = 1;
+ } else {
+ mod = 0x80, len = 4;
+ }
+
+ /* Use a single byte MODRM format if possible. Note that the encoding
+ that would be used for %esp is the escape to the two byte form. */
+ if (index == -1 && rm != TCG_REG_ESP) {
+ /* Single byte MODRM format. */
+ tcg_out8(s, mod | (r << 3) | rm);
} else {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x84 | (r << 3));
- tcg_out8(s, 0x24);
+ /* Two byte MODRM+SIB format. */
+
+ /* Note that the encoding that would place %esp into the index
+ field indicates no index register. */
+ if (index == -1) {
+ index = 4;
} else {
- tcg_out8(s, 0x80 | (r << 3) | rm);
+ assert(index != TCG_REG_ESP);
}
+
+ tcg_out8(s, mod | (r << 3) | 4);
+ tcg_out8(s, (shift << 6) | (index << 3) | rm);
+ }
+
+ if (len == 1) {
+ tcg_out8(s, offset);
+ } else if (len == 4) {
tcg_out32(s, offset);
}
}
+/* rm == -1 means no register index */
+static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
+ int32_t offset)
+{
+ tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
+}
+
+/* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
+static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
+{
+ tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3), dest, src);
+}
+
static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
{
if (arg != ret) {
@@ -282,14 +354,34 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
int ret, int32_t arg)
{
if (arg == 0) {
- /* xor r0,r0 */
- tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret);
+ tgen_arithr(s, ARITH_XOR, ret, ret);
} else {
- tcg_out8(s, 0xb8 + ret);
+ tcg_out8(s, OPC_MOVL_Iv + ret);
tcg_out32(s, arg);
}
}
+static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
+{
+ if (val == (int8_t)val) {
+ tcg_out_opc(s, OPC_PUSH_Ib);
+ tcg_out8(s, val);
+ } else {
+ tcg_out_opc(s, OPC_PUSH_Iv);
+ tcg_out32(s, val);
+ }
+}
+
+static inline void tcg_out_push(TCGContext *s, int reg)
+{
+ tcg_out_opc(s, OPC_PUSH_r32 + reg);
+}
+
+static inline void tcg_out_pop(TCGContext *s, int reg)
+{
+ tcg_out_opc(s, OPC_POP_r32 + reg);
+}
+
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
int arg1, tcg_target_long arg2)
{
@@ -323,25 +415,50 @@ static inline void tcg_out_rolw_8(TCGContext *s, int reg)
tcg_out_shifti(s, SHIFT_ROL, reg, 8);
}
-static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val, int cf)
+static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
+{
+ /* movzbl */
+ assert(src < 4);
+ tcg_out_modrm(s, OPC_MOVZBL, dest, src);
+}
+
+static void tcg_out_ext8s(TCGContext *s, int dest, int src)
{
- if (!cf && ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1))) {
- /* inc */
- tcg_out_opc(s, 0x40 + r0);
- } else if (!cf && ((c == ARITH_ADD && val == -1) || (c == ARITH_SUB && val == 1))) {
- /* dec */
- tcg_out_opc(s, 0x48 + r0);
+ /* movsbl */
+ assert(src < 4);
+ tcg_out_modrm(s, OPC_MOVSBL, dest, src);
+}
+
+static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
+{
+ /* movzwl */
+ tcg_out_modrm(s, OPC_MOVZWL, dest, src);
+}
+
+static inline void tcg_out_ext16s(TCGContext *s, int dest, int src)
+{
+ /* movswl */
+ tcg_out_modrm(s, OPC_MOVSWL, dest, src);
+}
+
+static inline void tgen_arithi(TCGContext *s, int c, int r0,
+ int32_t val, int cf)
+{
+ /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
+ partial flags update stalls on Pentium4 and are not recommended
+ by current Intel optimization manuals. */
+ if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
+ int opc = ((c == ARITH_ADD) ^ (val < 0) ? OPC_INC_r32 : OPC_DEC_r32);
+ tcg_out_opc(s, opc + r0);
} else if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83, c, r0);
+ tcg_out_modrm(s, OPC_ARITH_EvIb, c, r0);
tcg_out8(s, val);
} else if (c == ARITH_AND && val == 0xffu && r0 < 4) {
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, r0, r0);
+ tcg_out_ext8u(s, r0, r0);
} else if (c == ARITH_AND && val == 0xffffu) {
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0);
+ tcg_out_ext16u(s, r0, r0);
} else {
- tcg_out_modrm(s, 0x81, c, r0);
+ tcg_out_modrm(s, OPC_ARITH_EvIz, c, r0);
tcg_out32(s, val);
}
}
@@ -357,7 +474,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
{
int32_t val, val1;
TCGLabel *l = &s->labels[label_index];
-
+
if (l->has_value) {
val = l->u.value - (tcg_target_long)s->code_ptr;
val1 = val - 2;
@@ -405,12 +522,12 @@ static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
if (const_arg2) {
if (arg2 == 0) {
/* test r, r */
- tcg_out_modrm(s, 0x85, arg1, arg1);
+ tcg_out_modrm(s, OPC_TESTL, arg1, arg1);
} else {
tgen_arithi(s, ARITH_CMP, arg1, arg2, 0);
}
} else {
- tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1);
+ tgen_arithr(s, ARITH_CMP, arg1, arg2);
}
}
@@ -508,9 +625,8 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGArg dest,
TCGArg arg1, TCGArg arg2, int const_arg2)
{
tcg_out_cmp(s, arg1, arg2, const_arg2);
- /* setcc */
- tcg_out_modrm(s, 0x90 | tcg_cond_to_jcc[cond] | P_EXT, 0, dest);
- tgen_arithi(s, ARITH_AND, dest, 0xff, 0);
+ tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
+ tcg_out_ext8u(s, dest, dest);
}
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
@@ -555,6 +671,12 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
}
}
+static void tcg_out_calli(TCGContext *s, tcg_target_long dest)
+{
+ tcg_out_opc(s, OPC_CALL_Jz);
+ tcg_out32(s, dest - (tcg_target_long)s->code_ptr - 4);
+}
+
#if defined(CONFIG_SOFTMMU)
#include "../../softmmu_defs.h"
@@ -611,28 +733,23 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
r1 = TCG_REG_EDX;
#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
+ tcg_out_mov(s, r1, addr_reg);
+ tcg_out_mov(s, r0, addr_reg);
- tcg_out_mov(s, r0, addr_reg);
-
tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+ tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
+ tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
+ tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
+ offsetof(CPUState,
+ tlb_table[mem_index][0].addr_read));
/* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
-
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
+
tcg_out_mov(s, r0, addr_reg);
-
+
#if TARGET_LONG_BITS == 32
/* je label1 */
tcg_out8(s, OPC_JCC_short + JCC_JE);
@@ -643,15 +760,15 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out8(s, OPC_JCC_short + JCC_JNE);
label3_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
/* je label1 */
tcg_out8(s, OPC_JCC_short + JCC_JE);
label1_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* label3: */
*label3_ptr = s->code_ptr - label3_ptr - 1;
#endif
@@ -663,26 +780,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
#endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
+ tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
switch(opc) {
case 0 | 4:
- /* movsbl */
- tcg_out_modrm(s, 0xbe | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext8s(s, data_reg, TCG_REG_EAX);
break;
case 1 | 4:
- /* movswl */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext16s(s, data_reg, TCG_REG_EAX);
break;
case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
break;
case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, data_reg, TCG_REG_EAX);
+ tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
break;
case 2:
default:
@@ -690,7 +801,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
break;
case 3:
if (data_reg == TCG_REG_EDX) {
- tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */
+ /* xchg %edx, %eax */
+ tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX);
tcg_out_mov(s, data_reg2, TCG_REG_EAX);
} else {
tcg_out_mov(s, data_reg, TCG_REG_EAX);
@@ -703,12 +815,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out8(s, OPC_JMP_short);
label2_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* label1: */
*label1_ptr = s->code_ptr - label1_ptr - 1;
/* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
+ tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
+ offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_read));
#else
r0 = addr_reg;
@@ -722,27 +835,27 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
switch(opc) {
case 0:
/* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, OPC_MOVZBL, data_reg, r0, GUEST_BASE);
break;
case 0 | 4:
/* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, OPC_MOVSBL, data_reg, r0, GUEST_BASE);
break;
case 1:
/* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, OPC_MOVZWL, data_reg, r0, GUEST_BASE);
if (bswap) {
tcg_out_rolw_8(s, data_reg);
}
break;
case 1 | 4:
/* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, OPC_MOVSWL, data_reg, r0, GUEST_BASE);
if (bswap) {
tcg_out_rolw_8(s, data_reg);
/* movswl data_reg, data_reg */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, data_reg);
+ tcg_out_modrm(s, OPC_MOVSWL, data_reg, data_reg);
}
break;
case 2:
@@ -785,6 +898,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
{
int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
#if defined(CONFIG_SOFTMMU)
+ int stack_adjust;
uint8_t *label1_ptr, *label2_ptr;
#endif
#if TARGET_LONG_BITS == 64
@@ -811,28 +925,23 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
r1 = TCG_REG_EDX;
#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
+ tcg_out_mov(s, r1, addr_reg);
+ tcg_out_mov(s, r0, addr_reg);
- tcg_out_mov(s, r0, addr_reg);
-
tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+ tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
+ tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
+ tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
+ offsetof(CPUState,
+ tlb_table[mem_index][0].addr_write));
/* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
-
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
+
tcg_out_mov(s, r0, addr_reg);
-
+
#if TARGET_LONG_BITS == 32
/* je label1 */
tcg_out8(s, OPC_JCC_short + JCC_JE);
@@ -843,15 +952,15 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
tcg_out8(s, OPC_JCC_short + JCC_JNE);
label3_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
+ tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
/* je label1 */
tcg_out8(s, OPC_JCC_short + JCC_JE);
label1_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* label3: */
*label3_ptr = s->code_ptr - label3_ptr - 1;
#endif
@@ -861,76 +970,68 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
if (opc == 3) {
tcg_out_mov(s, TCG_REG_EDX, data_reg);
tcg_out_mov(s, TCG_REG_ECX, data_reg2);
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 4);
+ tcg_out_pushi(s, mem_index);
+ stack_adjust = 4;
} else {
switch(opc) {
case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_EDX, data_reg);
+ tcg_out_ext8u(s, TCG_REG_EDX, data_reg);
break;
case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_EDX, data_reg);
+ tcg_out_ext16u(s, TCG_REG_EDX, data_reg);
break;
case 2:
tcg_out_mov(s, TCG_REG_EDX, data_reg);
break;
}
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
+ stack_adjust = 0;
}
#else
if (opc == 3) {
tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out_opc(s, 0x50 + data_reg2); /* push */
- tcg_out_opc(s, 0x50 + data_reg); /* push */
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 12);
+ tcg_out_pushi(s, mem_index);
+ tcg_out_push(s, data_reg2);
+ tcg_out_push(s, data_reg);
+ stack_adjust = 12;
} else {
tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
switch(opc) {
case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_ECX, data_reg);
+ tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
break;
case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_ECX, data_reg);
+ tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
break;
case 2:
tcg_out_mov(s, TCG_REG_ECX, data_reg);
break;
}
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 4);
+ tcg_out_pushi(s, mem_index);
+ stack_adjust = 4;
}
#endif
-
+
+ tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
+
+ if (stack_adjust == 4) {
+ /* Pop and discard. This is 2 bytes smaller than the add. */
+ tcg_out_pop(s, TCG_REG_ECX);
+ } else if (stack_adjust != 0) {
+ tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
+ }
+
/* jmp label2 */
tcg_out8(s, OPC_JMP_short);
label2_ptr = s->code_ptr;
s->code_ptr++;
-
+
/* label1: */
*label1_ptr = s->code_ptr - label1_ptr - 1;
/* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
+ tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
+ offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_write));
#else
r0 = addr_reg;
@@ -990,7 +1091,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg *args, const int *const_args)
{
int c;
-
+
switch(opc) {
case INDEX_op_exit_tb:
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
@@ -1005,17 +1106,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out32(s, 0);
} else {
/* indirect jump method */
- tcg_out_modrm_offset(s, 0xff, EXT_JMPN_Ev, -1,
+ tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
(tcg_target_long)(s->tb_next + args[0]));
}
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
break;
case INDEX_op_call:
if (const_args[0]) {
- tcg_out8(s, 0xe8);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
+ tcg_out_calli(s, args[0]);
} else {
- tcg_out_modrm(s, 0xff, 2, args[0]);
+ /* call *reg */
+ tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
}
break;
case INDEX_op_jmp:
@@ -1024,7 +1125,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
} else {
/* jmp *reg */
- tcg_out_modrm(s, 0xff, EXT_JMPN_Ev, args[0]);
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
}
break;
case INDEX_op_br:
@@ -1035,19 +1136,19 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_ld8u_i32:
/* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
+ tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
break;
case INDEX_op_ld8s_i32:
/* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
+ tcg_out_modrm_offset(s, OPC_MOVSBL, args[0], args[1], args[2]);
break;
case INDEX_op_ld16u_i32:
/* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
+ tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
break;
case INDEX_op_ld16s_i32:
/* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
+ tcg_out_modrm_offset(s, OPC_MOVSWL, args[0], args[1], args[2]);
break;
case INDEX_op_ld_i32:
tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
@@ -1064,6 +1165,25 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_st_i32:
tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
break;
+ case INDEX_op_add_i32:
+ /* For 3-operand addition, use LEA. */
+ if (args[0] != args[1]) {
+ TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
+
+ if (const_args[2]) {
+ c3 = a2, a2 = -1;
+ } else if (a0 == a2) {
+ /* Watch out for dest = src + dest, since we've removed
+ the matching constraint on the add. */
+ tgen_arithr(s, ARITH_ADD, a0, a1);
+ break;
+ }
+
+ tcg_out_modrm_sib_offset(s, OPC_LEA, a0, a1, a2, 0, c3);
+ break;
+ }
+ c = ARITH_ADD;
+ goto gen_arith;
case INDEX_op_sub_i32:
c = ARITH_SUB;
goto gen_arith;
@@ -1076,13 +1196,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_xor_i32:
c = ARITH_XOR;
goto gen_arith;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
gen_arith:
if (const_args[2]) {
tgen_arithi(s, c, args[0], args[2], 0);
} else {
- tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
+ tgen_arithr(s, c, args[0], args[2]);
}
break;
case INDEX_op_mul_i32:
@@ -1090,24 +1208,24 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
int32_t val;
val = args[2];
if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b, args[0], args[0]);
+ tcg_out_modrm(s, OPC_IMUL_GvEvIb, args[0], args[0]);
tcg_out8(s, val);
} else {
- tcg_out_modrm(s, 0x69, args[0], args[0]);
+ tcg_out_modrm(s, OPC_IMUL_GvEvIz, args[0], args[0]);
tcg_out32(s, val);
}
} else {
- tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
+ tcg_out_modrm(s, OPC_IMUL_GvEv, args[0], args[2]);
}
break;
case INDEX_op_mulu2_i32:
- tcg_out_modrm(s, 0xf7, 4, args[3]);
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
break;
case INDEX_op_div2_i32:
- tcg_out_modrm(s, 0xf7, 7, args[4]);
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_IDIV, args[4]);
break;
case INDEX_op_divu2_i32:
- tcg_out_modrm(s, 0xf7, 6, args[4]);
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_DIV, args[4]);
break;
case INDEX_op_shl_i32:
c = SHIFT_SHL;
@@ -1132,24 +1250,28 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
goto gen_shift32;
case INDEX_op_add2_i32:
- if (const_args[4])
+ if (const_args[4]) {
tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADD << 3), args[4], args[0]);
- if (const_args[5])
+ } else {
+ tgen_arithr(s, ARITH_ADD, args[0], args[4]);
+ }
+ if (const_args[5]) {
tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADC << 3), args[5], args[1]);
+ } else {
+ tgen_arithr(s, ARITH_ADC, args[1], args[5]);
+ }
break;
case INDEX_op_sub2_i32:
- if (const_args[4])
+ if (const_args[4]) {
tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SUB << 3), args[4], args[0]);
- if (const_args[5])
+ } else {
+ tgen_arithr(s, ARITH_SUB, args[0], args[4]);
+ }
+ if (const_args[5]) {
tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]);
+ } else {
+ tgen_arithr(s, ARITH_SBB, args[1], args[5]);
+ }
break;
case INDEX_op_brcond_i32:
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
@@ -1167,24 +1289,24 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_neg_i32:
- tcg_out_modrm(s, 0xf7, 3, args[0]);
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, args[0]);
break;
case INDEX_op_not_i32:
- tcg_out_modrm(s, 0xf7, 2, args[0]);
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NOT, args[0]);
break;
case INDEX_op_ext8s_i32:
- tcg_out_modrm(s, 0xbe | P_EXT, args[0], args[1]);
+ tcg_out_ext8s(s, args[0], args[1]);
break;
case INDEX_op_ext16s_i32:
- tcg_out_modrm(s, 0xbf | P_EXT, args[0], args[1]);
+ tcg_out_ext16s(s, args[0], args[1]);
break;
case INDEX_op_ext8u_i32:
- tcg_out_modrm(s, 0xb6 | P_EXT, args[0], args[1]);
+ tcg_out_ext8u(s, args[0], args[1]);
break;
case INDEX_op_ext16u_i32:
- tcg_out_modrm(s, 0xb7 | P_EXT, args[0], args[1]);
+ tcg_out_ext16u(s, args[0], args[1]);
break;
case INDEX_op_setcond_i32:
@@ -1212,7 +1334,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_qemu_ld64:
tcg_out_qemu_ld(s, args, 3);
break;
-
+
case INDEX_op_qemu_st8:
tcg_out_qemu_st(s, args, 0);
break;
@@ -1248,7 +1370,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_st16_i32, { "r", "r" } },
{ INDEX_op_st_i32, { "r", "r" } },
- { INDEX_op_add_i32, { "r", "0", "ri" } },
+ { INDEX_op_add_i32, { "r", "r", "ri" } },
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
{ INDEX_op_mul_i32, { "r", "0", "ri" } },
{ INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
@@ -1279,8 +1401,8 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_ext8s_i32, { "r", "q" } },
{ INDEX_op_ext16s_i32, { "r", "r" } },
- { INDEX_op_ext8u_i32, { "r", "q"} },
- { INDEX_op_ext16u_i32, { "r", "r"} },
+ { INDEX_op_ext8u_i32, { "r", "q" } },
+ { INDEX_op_ext16u_i32, { "r", "r" } },
{ INDEX_op_setcond_i32, { "q", "r", "ri" } },
{ INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
@@ -1321,21 +1443,11 @@ static int tcg_target_callee_save_regs[] = {
TCG_REG_EDI,
};
-static inline void tcg_out_push(TCGContext *s, int reg)
-{
- tcg_out_opc(s, 0x50 + reg);
-}
-
-static inline void tcg_out_pop(TCGContext *s, int reg)
-{
- tcg_out_opc(s, 0x58 + reg);
-}
-
/* Generate global QEMU prologue and epilogue code */
void tcg_target_qemu_prologue(TCGContext *s)
{
int i, frame_size, push_size, stack_addend;
-
+
/* TB prologue */
/* save all callee saved registers */
for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
@@ -1344,20 +1456,20 @@ void tcg_target_qemu_prologue(TCGContext *s)
/* reserve some stack space */
push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
- frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
+ frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
stack_addend = frame_size - push_size;
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
- tcg_out_modrm(s, 0xff, EXT_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
-
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
+
/* TB epilogue */
tb_ret_addr = s->code_ptr;
tcg_out_addi(s, TCG_REG_ESP, stack_addend);
for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
tcg_out_pop(s, tcg_target_callee_save_regs[i]);
}
- tcg_out8(s, 0xc3); /* ret */
+ tcg_out_opc(s, OPC_RET);
}
void tcg_target_init(TCGContext *s)
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 6e69ef4b49..905f48b3b3 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -40,6 +40,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
};
#endif
+#ifdef CONFIG_USE_GUEST_BASE
+#define TCG_GUEST_BASE_REG TCG_REG_R55
+#else
+#define TCG_GUEST_BASE_REG TCG_REG_R0
+#endif
+
/* Branch registers */
enum {
TCG_REG_B0 = 0,
@@ -1640,9 +1646,13 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
{
+ static uint64_t const opc_ld_m1[4] = {
+ OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
+ };
+ static uint64_t const opc_sxt_i29[4] = {
+ OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0
+ };
int addr_reg, data_reg, mem_index, s_bits, bswap;
- uint64_t opc_ld_m1[4] = { OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1 };
- uint64_t opc_sxt_i29[8] = { OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0 };
data_reg = *args++;
addr_reg = *args++;
@@ -1655,19 +1665,21 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
bswap = 0;
#endif
- tcg_out_bundle(s, mLX,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
- tcg_opc_l2 ((tcg_target_long) GUEST_BASE),
- tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R2,
- GUEST_BASE));
-
#if TARGET_LONG_BITS == 32
- tcg_out_bundle(s, mII,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
- tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
- TCG_REG_R3, addr_reg),
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, TCG_REG_R3));
+ if (GUEST_BASE != 0) {
+ tcg_out_bundle(s, mII,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+ TCG_REG_R3, addr_reg),
+ tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+ TCG_GUEST_BASE_REG, TCG_REG_R3));
+ } else {
+ tcg_out_bundle(s, miI,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+ TCG_REG_R2, addr_reg),
+ tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+ }
if (!bswap || s_bits == 0) {
if (s_bits == opc) {
@@ -1723,12 +1735,20 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
}
}
#else
- tcg_out_bundle(s, MmI,
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, addr_reg),
- tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
- data_reg, TCG_REG_R2),
- tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+ if (GUEST_BASE != 0) {
+ tcg_out_bundle(s, MmI,
+ tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+ TCG_GUEST_BASE_REG, addr_reg),
+ tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
+ data_reg, TCG_REG_R2),
+ tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+ } else {
+ tcg_out_bundle(s, mmI,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
+ data_reg, addr_reg),
+ tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+ }
if (bswap && s_bits == 1) {
tcg_out_bundle(s, mII,
@@ -1763,8 +1783,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
{
+ static uint64_t const opc_st_m4[4] = {
+ OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
+ };
int addr_reg, data_reg, bswap;
- uint64_t opc_st_m4[4] = { OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4 };
+#if TARGET_LONG_BITS == 64
+ uint64_t add_guest_base;
+#endif
data_reg = *args++;
addr_reg = *args++;
@@ -1775,19 +1800,22 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
bswap = 0;
#endif
- tcg_out_bundle(s, mLX,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
- tcg_opc_l2 ((tcg_target_long) GUEST_BASE),
- tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R2,
- GUEST_BASE));
-
#if TARGET_LONG_BITS == 32
- tcg_out_bundle(s, mII,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
- tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
- TCG_REG_R3, addr_reg),
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, TCG_REG_R3));
+ if (GUEST_BASE != 0) {
+ tcg_out_bundle(s, mII,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+ TCG_REG_R3, addr_reg),
+ tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+ TCG_GUEST_BASE_REG, TCG_REG_R3));
+ } else {
+ tcg_out_bundle(s, miI,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
+ TCG_REG_R3, addr_reg),
+ tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+ }
+
if (bswap) {
if (opc == 1) {
tcg_out_bundle(s, mII,
@@ -1820,18 +1848,24 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
#else
+ if (GUEST_BASE != 0) {
+ add_guest_base = tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
+ TCG_GUEST_BASE_REG, addr_reg);
+ addr_reg = TCG_REG_R2;
+ } else {
+ add_guest_base = tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0);
+ }
+
if (!bswap || opc == 0) {
- tcg_out_bundle(s, MmI,
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, addr_reg),
+ tcg_out_bundle(s, (GUEST_BASE ? MmI : mmI),
+ add_guest_base,
tcg_opc_m4 (TCG_REG_P0, opc_st_m4[opc],
- data_reg, TCG_REG_R2),
+ data_reg, addr_reg),
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
} else {
if (opc == 1) {
tcg_out_bundle(s, mII,
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, addr_reg),
+ add_guest_base,
tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
TCG_REG_R3, data_reg, 15, 15),
tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
@@ -1839,8 +1873,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
data_reg = TCG_REG_R3;
} else if (opc == 2) {
tcg_out_bundle(s, mII,
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, addr_reg),
+ add_guest_base,
tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
TCG_REG_R3, data_reg, 31, 31),
tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
@@ -1848,8 +1881,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
data_reg = TCG_REG_R3;
} else if (opc == 3) {
tcg_out_bundle(s, miI,
- tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
- TCG_REG_R2, addr_reg),
+ add_guest_base,
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0),
tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
TCG_REG_R3, data_reg, 0xb));
@@ -1857,7 +1889,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
}
tcg_out_bundle(s, miI,
tcg_opc_m4 (TCG_REG_P0, opc_st_m4[opc],
- data_reg, TCG_REG_R2),
+ data_reg, addr_reg),
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0),
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
}
@@ -2254,6 +2286,18 @@ void tcg_target_qemu_prologue(TCGContext *s)
TCG_REG_B6, TCG_REG_R32, 0),
tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
TCG_REG_R32, TCG_REG_B0));
+
+ /* ??? If GUEST_BASE < 0x200000, we could load the register via
+ an ADDL in the M slot of the next bundle. */
+ if (GUEST_BASE != 0) {
+ tcg_out_bundle(s, mlx,
+ tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_l2 (GUEST_BASE),
+ tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2,
+ TCG_GUEST_BASE_REG, GUEST_BASE));
+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+ }
+
tcg_out_bundle(s, miB,
tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
@@ -2282,39 +2326,56 @@ void tcg_target_init(TCGContext *s)
0xffffffffffffffffull);
tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64],
0xffffffffffffffffull);
- tcg_regset_set(tcg_target_call_clobber_regs,
- (1 << TCG_REG_R8) |
- (1 << TCG_REG_R9) |
- (1 << TCG_REG_R10) |
- (1 << TCG_REG_R11) |
- (1 << TCG_REG_R13) |
- (1 << TCG_REG_R14) |
- (1 << TCG_REG_R15) |
- (1 << TCG_REG_R16) |
- (1 << TCG_REG_R17) |
- (1 << TCG_REG_R18) |
- (1 << TCG_REG_R19) |
- (1 << TCG_REG_R20) |
- (1 << TCG_REG_R21) |
- (1 << TCG_REG_R22) |
- (1 << TCG_REG_R23) |
- (1 << TCG_REG_R24) |
- (1 << TCG_REG_R25) |
- (1 << TCG_REG_R26) |
- (1 << TCG_REG_R27) |
- (1 << TCG_REG_R28) |
- (1 << TCG_REG_R29) |
- (1 << TCG_REG_R30) |
- (1 << TCG_REG_R31));
- tcg_regset_clear(s->reserved_regs);
+ tcg_regset_clear(tcg_target_call_clobber_regs);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R15);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R16);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R17);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R18);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R19);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R27);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R28);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R29);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R30);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R31);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R56);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R57);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R58);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R59);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R60);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R61);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R62);
+ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R63);
+
+ tcg_regset_clear(s->reserved_regs);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* zero register */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* global pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* internal use */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3); /* internal use */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* stack pointer */
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R32); /* return address */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33); /* PFS */
+ /* The following 3 are not in use, are call-saved, but *not* saved
+ by the prologue. Therefore we cannot use them without modifying
+ the prologue. There doesn't seem to be any good reason to use
+ these as opposed to the windowed registers. */
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R4);
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R5);
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
+
tcg_add_target_add_op_defs(ia64_op_defs);
}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a99ecb9a9e..880e7ceef9 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -240,7 +240,10 @@ void tcg_context_init(TCGContext *s)
}
tcg_target_init(s);
+}
+void tcg_prologue_init(TCGContext *s)
+{
/* init global prologue and epilogue */
s->code_buf = code_gen_prologue;
s->code_ptr = s->code_buf;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 44856e1dd5..58538235de 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -346,6 +346,7 @@ static inline void *tcg_malloc(int size)
}
void tcg_context_init(TCGContext *s);
+void tcg_prologue_init(TCGContext *s);
void tcg_func_start(TCGContext *s);
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
diff --git a/vl.c b/vl.c
index d77b47c6f7..8c818f0d24 100644
--- a/vl.c
+++ b/vl.c
@@ -1708,7 +1708,6 @@ static int shutdown_requested;
static int powerdown_requested;
int debug_requested;
int vmstop_requested;
-static int exit_requested;
int qemu_shutdown_requested(void)
{
@@ -1731,12 +1730,6 @@ int qemu_powerdown_requested(void)
return r;
}
-int qemu_exit_requested(void)
-{
- /* just return it, we'll exit() anyway */
- return exit_requested;
-}
-
static int qemu_debug_requested(void)
{
int r = debug_requested;
@@ -1807,12 +1800,6 @@ void qemu_system_powerdown_request(void)
qemu_notify_event();
}
-void qemu_system_exit_request(void)
-{
- exit_requested = 1;
- qemu_notify_event();
-}
-
#ifdef _WIN32
static void host_main_loop_wait(int *timeout)
{
@@ -1949,8 +1936,6 @@ static int vm_can_run(void)
return 0;
if (debug_requested)
return 0;
- if (exit_requested)
- return 0;
return 1;
}
@@ -2003,9 +1988,6 @@ static void main_loop(void)
if ((r = qemu_vmstop_requested())) {
vm_stop(r);
}
- if (qemu_exit_requested()) {
- exit(0);
- }
}
pause_all_vcpus();
}