summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-07-28 20:52:11 +0300
committerAvi Kivity <avi@redhat.com>2009-07-28 20:52:11 +0300
commit47159e9b25e1d05b5cd591e295e97897c53a9f75 (patch)
tree1563bcfa1c3a76c5b2123f436582a59d5ee39240
parentMerge commit '42bc608b2a144dfa5141dd6ba5d12cb97ac804a7' into upstream-merge (diff)
parentintroduce on_vcpu (diff)
downloadqemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.tar.gz
qemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.tar.bz2
qemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.zip
Merge commit '452e475196a3f8b6b96d16bbaca727ebc1278a97' into upstream-merge
* commit '452e475196a3f8b6b96d16bbaca727ebc1278a97': (55 commits) introduce on_vcpu qemu-io: reject invalid pattern qemu-io: Rework alloc command qmu-img: fix qemu-img convert to generate a valid image when the source referenced a backing file vmdk: Fix backing file handling use struct initializer for audio.c Add save/restore support to the LSI logic SCSI device model. Handle BH's queued by AIO completions in qemu_aio_flush() Fake dirty loggin when it's not there Use correct input constant Fix warning in kvm-all.c Set PVR in sregs Enable PPC KVM for non-embedded Sparc32: convert Sun4c interrupt controller to qdev Sparc32: convert SBI to qdev Fix CONFIG_PROFILER Sparc32/64: use 64 bit type for memory size qdev: add 64 bit type Sparc64: refactor kernel init Sparc64: refactor CPU init ... Conflicts: kvm-all.c Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--Makefile.target5
-rw-r--r--VERSION2
-rw-r--r--aio.c2
-rw-r--r--audio/alsaaudio.c4
-rw-r--r--audio/audio.c52
-rw-r--r--block/qcow2-refcount.c4
-rw-r--r--block/raw-posix.c1
-rw-r--r--block/vmdk.c29
-rw-r--r--bsd-user/elfload.c2
-rw-r--r--bsd-user/strace.c4
-rw-r--r--bsd-user/uaccess.c2
-rw-r--r--buffered_file.c4
-rwxr-xr-xconfigure30
-rw-r--r--cpu-all.h9
-rw-r--r--elf.h2
-rw-r--r--exec.c25
-rw-r--r--hw/apb_pci.c103
-rw-r--r--hw/cirrus_vga.c5
-rw-r--r--hw/eccmemctl.c2
-rw-r--r--hw/escc.c8
-rw-r--r--hw/fdc.c140
-rw-r--r--hw/i8259.c1
-rw-r--r--hw/iommu.c2
-rw-r--r--hw/lsi53c895a.c172
-rw-r--r--hw/openpic.c31
-rw-r--r--hw/pci.c8
-rw-r--r--hw/ppc_prep.c3
-rw-r--r--hw/ppce500_pci.c13
-rw-r--r--hw/qdev-properties.c62
-rw-r--r--hw/qdev.c1
-rw-r--r--hw/qdev.h7
-rw-r--r--hw/sbi.c58
-rw-r--r--hw/scsi-disk.c12
-rw-r--r--hw/slavio_timer.c8
-rw-r--r--hw/sun4c_intctl.c70
-rw-r--r--hw/sun4m.c32
-rw-r--r--hw/sun4m.h6
-rw-r--r--hw/sun4u.c283
-rw-r--r--hw/usb-ohci.c4
-rw-r--r--hw/usb-uhci.c2
-rw-r--r--hw/vga.c12
-rw-r--r--kvm-all.c51
-rw-r--r--linux-user/elfload.c162
-rw-r--r--linux-user/main.c45
-rw-r--r--linux-user/mmap.c16
-rw-r--r--linux-user/qemu.h3
-rw-r--r--linux-user/signal.c12
-rw-r--r--linux-user/syscall.c2
-rw-r--r--loader.c3
-rw-r--r--qemu-doc.texi6
-rw-r--r--qemu-img.c20
-rw-r--r--qemu-io.c66
-rw-r--r--qemu-tool.c3
-rw-r--r--target-i386/helper.c9
-rw-r--r--target-ppc/helper.c20
-rw-r--r--target-ppc/kvm.c18
-rw-r--r--target-sparc/helper.c20
-rw-r--r--target-sparc/op_helper.c14
-rw-r--r--tcg/arm/tcg-target.c78
-rw-r--r--tcg/arm/tcg-target.h10
-rw-r--r--tcg/i386/tcg-target.c36
-rw-r--r--tcg/i386/tcg-target.h2
-rw-r--r--tcg/ppc/tcg-target.c86
-rw-r--r--tcg/ppc/tcg-target.h2
-rw-r--r--tcg/ppc64/tcg-target.c82
-rw-r--r--tcg/ppc64/tcg-target.h2
-rw-r--r--tcg/tcg-op.h2
-rw-r--r--tcg/tcg.c12
-rw-r--r--tcg/x86_64/tcg-target.c56
-rw-r--r--tcg/x86_64/tcg-target.h2
-rw-r--r--vl.c2
71 files changed, 1451 insertions, 613 deletions
diff --git a/Makefile.target b/Makefile.target
index a158c4ccc..72f14f6de 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -299,8 +299,6 @@ endif
obj-y = main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \
elfload.o linuxload.o uaccess.o envlist.o gdbstub.o gdbstub-xml.o \
ioport-user.o
-LIBS+= $(PTHREADLIBS)
-LIBS+= $(CLOCKLIBS)
obj-$(TARGET_HAS_BFLT) += flatload.o
ifdef TARGET_HAS_ELFLOAD32
@@ -326,6 +324,9 @@ signal.o: CFLAGS += $(HELPER_CFLAGS)
ARLIBS=../libqemu_user.a libqemu.a
endif #CONFIG_LINUX_USER
+LIBS+= $(PTHREADLIBS)
+LIBS+= $(CLOCKLIBS)
+
#########################################################
# Darwin user emulator target
diff --git a/VERSION b/VERSION
index 02daa1b60..93d635abd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.10.50
+0.11.50
diff --git a/aio.c b/aio.c
index dc9b85d16..efc63fd9a 100644
--- a/aio.c
+++ b/aio.c
@@ -112,7 +112,7 @@ void qemu_aio_flush(void)
LIST_FOREACH(node, &aio_handlers, node) {
ret |= node->io_flush(node->opaque);
}
- } while (ret > 0);
+ } while (qemu_bh_poll() || ret > 0);
}
void qemu_aio_wait(void)
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index f1d573a8f..d0b7cd0bd 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -25,6 +25,10 @@
#include "qemu-common.h"
#include "audio.h"
+#if QEMU_GNUC_PREREQ(4, 3)
+#pragma GCC diagnostic ignored "-Waddress"
+#endif
+
#define AUDIO_CAP "alsa"
#include "audio_int.h"
diff --git a/audio/audio.c b/audio/audio.c
index 72a18ec03..f4eca6e9c 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -60,45 +60,45 @@ static struct {
int plive;
int log_to_monitor;
} conf = {
- { /* DAC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16, /* fmt */
- AUDIO_HOST_ENDIANNESS
+ .fixed_out = { /* DAC fixed settings */
+ .enabled = 1,
+ .nb_voices = 1,
+ .greedy = 1,
+ .settings = {
+ .freq = 44100,
+ .nchannels = 2,
+ .fmt = AUD_FMT_S16,
+ .endianness = AUDIO_HOST_ENDIANNESS,
}
},
- { /* ADC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16, /* fmt */
- AUDIO_HOST_ENDIANNESS
+ .fixed_in = { /* ADC fixed settings */
+ .enabled = 1,
+ .nb_voices = 1,
+ .greedy = 1,
+ .settings = {
+ .freq = 44100,
+ .nchannels = 2,
+ .fmt = AUD_FMT_S16,
+ .endianness = AUDIO_HOST_ENDIANNESS,
}
},
- { 250 }, /* period */
- 0, /* plive */
- 0 /* log_to_monitor */
+ .period = { .ticks = 250 },
+ .plive = 0,
+ .log_to_monitor = 0,
};
static AudioState glob_audio_state;
struct mixeng_volume nominal_volume = {
- 0,
+ .mute = 0,
#ifdef FLOAT_MIXENG
- 1.0,
- 1.0
+ .r = 1.0,
+ .l = 1.0,
#else
- 1ULL << 32,
- 1ULL << 32
+ .r = 1ULL << 32,
+ .l = 1ULL << 32,
#endif
};
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index e6c857e08..0aac2edee 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -277,7 +277,7 @@ static int update_refcount(BlockDriverState *bs,
int first_index = -1, last_index = -1;
#ifdef DEBUG_ALLOC2
- printf("update_refcount: offset=%lld size=%lld addend=%d\n",
+ printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
offset, length, addend);
#endif
if (length <= 0)
@@ -380,7 +380,7 @@ retry:
goto retry;
}
#ifdef DEBUG_ALLOC2
- printf("alloc_clusters: size=%lld -> %lld\n",
+ printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
size,
(s->free_cluster_index - nb_clusters) << s->cluster_bits);
#endif
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 994bf7b32..74821506a 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -24,6 +24,7 @@
#include "qemu-common.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "qemu-log.h"
#include "block_int.h"
#include "module.h"
#include "compatfd.h"
diff --git a/block/vmdk.c b/block/vmdk.c
index f21f02bc5..4e486225b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -170,7 +170,7 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
{
#ifdef CHECK_CID
BDRVVmdkState *s = bs->opaque;
- BlockDriverState *p_bs = s->hd->backing_hd;
+ BlockDriverState *p_bs = bs->backing_hd;
uint32_t cur_pcid;
if (p_bs) {
@@ -338,26 +338,26 @@ static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
p_name += sizeof("parentFileNameHint") + 1;
if ((end_name = strchr(p_name,'\"')) == NULL)
return -1;
- if ((end_name - p_name) > sizeof (s->hd->backing_file) - 1)
+ if ((end_name - p_name) > sizeof (bs->backing_file) - 1)
return -1;
- pstrcpy(s->hd->backing_file, end_name - p_name + 1, p_name);
- if (stat(s->hd->backing_file, &file_buf) != 0) {
+ pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
+ if (stat(bs->backing_file, &file_buf) != 0) {
path_combine(parent_img_name, sizeof(parent_img_name),
- filename, s->hd->backing_file);
+ filename, bs->backing_file);
} else {
pstrcpy(parent_img_name, sizeof(parent_img_name),
- s->hd->backing_file);
+ bs->backing_file);
}
- s->hd->backing_hd = bdrv_new("");
- if (!s->hd->backing_hd) {
+ bs->backing_hd = bdrv_new("");
+ if (!bs->backing_hd) {
failure:
bdrv_close(s->hd);
return -1;
}
parent_open = 1;
- if (bdrv_open(s->hd->backing_hd, parent_img_name, BDRV_O_RDONLY) < 0)
+ if (bdrv_open(bs->backing_hd, parent_img_name, BDRV_O_RDONLY) < 0)
goto failure;
parent_open = 0;
}
@@ -464,13 +464,14 @@ static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
// we will be here if it's first write on non-exist grain(cluster).
// try to read from parent image, if exist
- if (s->hd->backing_hd) {
- BDRVVmdkState *ps = s->hd->backing_hd->opaque;
+ if (bs->backing_hd) {
+ BDRVVmdkState *ps = bs->backing_hd->opaque;
if (!vmdk_is_cid_valid(bs))
return -1;
- parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, NULL, offset, allocate);
+ parent_cluster_offset = get_cluster_offset(bs->backing_hd, NULL,
+ offset, allocate);
if (parent_cluster_offset) {
BDRVVmdkState *act_s = activeBDRV.hd->opaque;
@@ -621,10 +622,10 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
n = nb_sectors;
if (!cluster_offset) {
// try to read from parent image, if exist
- if (s->hd->backing_hd) {
+ if (bs->backing_hd) {
if (!vmdk_is_cid_valid(bs))
return -1;
- ret = bdrv_read(s->hd->backing_hd, sector_num, buf, n);
+ ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
if (ret < 0)
return -1;
} else {
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index de7b4de7d..ed25e8519 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -1295,7 +1295,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
}
if (interp_elf_ex.e_ident[0] != 0x7f ||
- strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
+ strncmp((char *)&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
interpreter_type &= ~INTERPRETER_ELF;
}
diff --git a/bsd-user/strace.c b/bsd-user/strace.c
index 0998dc5ba..d73bbcaba 100644
--- a/bsd-user/strace.c
+++ b/bsd-user/strace.c
@@ -36,7 +36,7 @@ print_execve(const struct syscallname *name,
unlock_user(s, arg1, 0);
for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
- abi_ulong *arg_ptr, arg_addr, s_addr;
+ abi_ulong *arg_ptr, arg_addr;
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
if (!arg_ptr)
@@ -47,7 +47,7 @@ print_execve(const struct syscallname *name,
break;
if ((s = lock_user_string(arg_addr))) {
gemu_log("\"%s\",", s);
- unlock_user(s, s_addr, 0);
+ unlock_user(s, arg_addr, 0);
}
}
diff --git a/bsd-user/uaccess.c b/bsd-user/uaccess.c
index 9ec1b2343..677f19c26 100644
--- a/bsd-user/uaccess.c
+++ b/bsd-user/uaccess.c
@@ -51,7 +51,7 @@ abi_long target_strlen(abi_ulong guest_addr1)
ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
if (!ptr)
return -TARGET_EFAULT;
- len = qemu_strnlen(ptr, max_len);
+ len = qemu_strnlen((char *)ptr, max_len);
unlock_user(ptr, guest_addr, 0);
guest_addr += len;
/* we don't allow wrapping or integer overflow */
diff --git a/buffered_file.c b/buffered_file.c
index 364b912f2..63de17d8f 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -113,7 +113,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in
int offset = 0;
ssize_t ret;
- dprintf("putting %ld bytes at %Ld\n", size, pos);
+ dprintf("putting %d bytes at %" PRId64 "\n", size, pos);
if (s->has_error) {
dprintf("flush when error, bailing\n");
@@ -151,7 +151,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in
}
if (offset >= 0) {
- dprintf("buffering %ld bytes\n", size - offset);
+ dprintf("buffering %d bytes\n", size - offset);
buffered_append(s, buf + offset, size - offset);
offset = size;
}
diff --git a/configure b/configure
index 9344f3bd5..819fca9d0 100755
--- a/configure
+++ b/configure
@@ -195,6 +195,7 @@ softmmu="yes"
linux_user="no"
darwin_user="no"
bsd_user="no"
+guest_base=""
build_docs="yes"
uname_release=""
curses="yes"
@@ -497,6 +498,10 @@ for opt do
;;
--enable-bsd-user) bsd_user="yes"
;;
+ --enable-guest-base) guest_base="yes"
+ ;;
+ --disable-guest-base) guest_base="no"
+ ;;
--enable-uname-release=*) uname_release="$optarg"
;;
--sparc_cpu=*)
@@ -582,6 +587,7 @@ fi
# If cpu ~= sparc and sparc_cpu hasn't been defined, plug in the right
# ARCH_CFLAGS/ARCH_LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
#
+host_guest_base="no"
case "$cpu" in
sparc) if test -z "$sparc_cpu" ; then
ARCH_CFLAGS="-m32 -mcpu=ultrasparc -D__sparc_v8plus__"
@@ -614,13 +620,23 @@ case "$cpu" in
i386)
ARCH_CFLAGS="-m32"
ARCH_LDFLAGS="-m32"
+ host_guest_base="yes"
;;
x86_64)
ARCH_CFLAGS="-m64"
ARCH_LDFLAGS="-m64"
+ host_guest_base="yes"
+ ;;
+ arm*)
+ host_guest_base="yes"
+ ;;
+ ppc*)
+ host_guest_base="yes"
;;
esac
+[ -z "$guest_base" ] && guest_base="$host_guest_base"
+
if test x"$show_help" = x"yes" ; then
cat << EOF
@@ -679,6 +695,9 @@ echo " --enable-darwin-user enable all darwin usermode emulation targets"
echo " --disable-darwin-user disable all darwin usermode emulation targets"
echo " --enable-bsd-user enable all BSD usermode emulation targets"
echo " --disable-bsd-user disable all BSD usermode emulation targets"
+echo " --enable-guest-base enable GUEST_BASE support for usermode"
+echo " emulation targets"
+echo " --disable-guest-base disable GUEST_BASE support"
echo " --fmod-lib path to FMOD library"
echo " --fmod-inc path to FMOD includes"
echo " --oss-lib path to OSS library"
@@ -1584,6 +1603,7 @@ echo "Documentation $build_docs"
[ ! -z "$uname_release" ] && \
echo "uname -r $uname_release"
echo "NPTL support $nptl"
+echo "GUEST_BASE $guest_base"
echo "vde support $vde"
echo "AIO support $aio"
echo "IO thread $io_thread"
@@ -1635,10 +1655,10 @@ echo "EXESUF=$EXESUF" >> $config_host_mak
echo "PTHREADLIBS=$PTHREADLIBS" >> $config_host_mak
echo "CLOCKLIBS=$CLOCKLIBS" >> $config_host_mak
case "$cpu" in
- i386|x86_64|alpha|cris|hppa|ia64|m68k|microbaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
+ i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
ARCH=$cpu
;;
- armv4b|arm4l)
+ armv4b|armv4l)
ARCH=arm
;;
*)
@@ -2196,11 +2216,12 @@ case "$target_arch2" in
fi
esac
case "$target_arch2" in
- i386|x86_64|ppcemb)
+ i386|x86_64|ppcemb|ppc|ppc64)
# Make sure the target and host cpus are compatible
if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
\( "$target_arch2" = "$cpu" -o \
\( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc" \) -o \
+ \( "$target_arch2" = "ppc64" -a "$cpu" = "ppc" \) -o \
\( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \
\( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then
echo "CONFIG_KVM=y" >> $config_mak
@@ -2251,6 +2272,9 @@ fi
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
echo "TARGET_HAS_ELFLOAD32=y" >> $config_mak
fi
+if test "$target_user_only" = "yes" -a "$guest_base" = "yes"; then
+ echo "CONFIG_USE_GUEST_BASE=y" >> $config_mak
+fi
if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=y" >> $config_mak
fi
diff --git a/cpu-all.h b/cpu-all.h
index 3381125c8..d8891f835 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -624,8 +624,13 @@ static inline void stfq_be_p(void *ptr, float64 v)
/* On some host systems the guest address space is reserved on the host.
* This allows the guest address space to be offset to a convenient location.
*/
-//#define GUEST_BASE 0x20000000
-#define GUEST_BASE 0
+#if defined(CONFIG_USE_GUEST_BASE)
+extern unsigned long guest_base;
+extern int have_guest_base;
+#define GUEST_BASE guest_base
+#else
+#define GUEST_BASE 0ul
+#endif
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
diff --git a/elf.h b/elf.h
index b0420029d..11674d75e 100644
--- a/elf.h
+++ b/elf.h
@@ -454,7 +454,9 @@ typedef struct {
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
+#ifndef R_PPC_NUM
#define R_PPC_NUM 37
+#endif
/* ARM specific declarations */
diff --git a/exec.c b/exec.c
index f825fd158..2134697ba 100644
--- a/exec.c
+++ b/exec.c
@@ -672,7 +672,8 @@ static void tb_invalidate_check(target_ulong address)
for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
address >= tb->pc + tb->size)) {
- printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
+ printf("ERROR invalidate: address=" TARGET_FMT_lx
+ " PC=%08lx size=%04x\n",
address, (long)tb->pc, tb->size);
}
}
@@ -697,26 +698,6 @@ static void tb_page_check(void)
}
}
-static void tb_jmp_check(TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* check end of list */
- if (tb1 != tb) {
- printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
- }
-}
-
#endif
/* invalidate one TB */
@@ -3067,7 +3048,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
idx = SUBPAGE_IDX(start);
eidx = SUBPAGE_IDX(end);
#if defined(DEBUG_SUBPAGE)
- printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__,
+ printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
mmio, start, end, idx, eidx, memory);
#endif
memory >>= IO_MEM_SHIFT;
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 9f2a44d55..8b42fa869 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -26,7 +26,7 @@
Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
the secondary PCI bridge. */
-#include "hw.h"
+#include "sysbus.h"
#include "pci.h"
/* debug APB */
@@ -42,7 +42,10 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
typedef target_phys_addr_t pci_addr_t;
#include "pci_host.h"
-typedef PCIHostState APBState;
+typedef struct APBState {
+ SysBusDevice busdev;
+ PCIHostState host_state;
+} APBState;
static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
uint32_t val)
@@ -54,7 +57,7 @@ static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
#endif
APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr,
val);
- s->config_reg = val;
+ s->host_state.config_reg = val;
}
static uint32_t pci_apb_config_readl (void *opaque,
@@ -63,7 +66,7 @@ static uint32_t pci_apb_config_readl (void *opaque,
APBState *s = opaque;
uint32_t val;
- val = s->config_reg;
+ val = s->host_state.config_reg;
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap32(val);
#endif
@@ -225,34 +228,65 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
target_phys_addr_t mem_base,
qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
{
- APBState *s;
- PCIDevice *d;
- int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
+ DeviceState *dev;
+ SysBusDevice *s;
+ APBState *d;
- s = qemu_mallocz(sizeof(APBState));
/* Ultrasparc PBM main bus */
- s->bus = pci_register_bus(NULL, "pci",
- pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
+ dev = qdev_create(NULL, "pbm");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ /* apb_config */
+ sysbus_mmio_map(s, 0, special_base + 0x2000ULL);
+ /* pci_ioport */
+ sysbus_mmio_map(s, 1, special_base + 0x2000000ULL);
+ /* mem_config: XXX size should be 4G-prom */
+ sysbus_mmio_map(s, 2, special_base + 0x1000000ULL);
+ /* mem_data */
+ sysbus_mmio_map(s, 3, mem_base);
+ d = FROM_SYSBUS(APBState, s);
+ d->host_state.bus = pci_register_bus(NULL, "pci",
+ pci_apb_set_irq, pci_pbm_map_irq, pic,
+ 0, 32);
+ pci_create_simple(d->host_state.bus, 0, "pbm");
+ /* APB secondary busses */
+ *bus2 = pci_bridge_init(d->host_state.bus, 8, PCI_VENDOR_ID_SUN,
+ PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
+ "Advanced PCI Bus secondary bridge 1");
+ *bus3 = pci_bridge_init(d->host_state.bus, 9, PCI_VENDOR_ID_SUN,
+ PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
+ "Advanced PCI Bus secondary bridge 2");
- pci_mem_config = cpu_register_io_memory(pci_apb_config_read,
- pci_apb_config_write, s);
+ return d->host_state.bus;
+}
+
+static void pci_pbm_init_device(SysBusDevice *dev)
+{
+
+ APBState *s;
+ int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
+
+ s = FROM_SYSBUS(APBState, dev);
+ /* apb_config */
apb_config = cpu_register_io_memory(apb_config_read,
apb_config_write, s);
- pci_mem_data = cpu_register_io_memory(pci_apb_read,
- pci_apb_write, s);
+ sysbus_init_mmio(dev, 0x40ULL, apb_config);
+ /* pci_ioport */
pci_ioport = cpu_register_io_memory(pci_apb_ioread,
pci_apb_iowrite, s);
+ sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
+ /* mem_config */
+ pci_mem_config = cpu_register_io_memory(pci_apb_config_read,
+ pci_apb_config_write, s);
+ sysbus_init_mmio(dev, 0x10ULL, pci_mem_config);
+ /* mem_data */
+ pci_mem_data = cpu_register_io_memory(pci_apb_read,
+ pci_apb_write, &s->host_state);
+ sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
+}
- cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
- cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10,
- pci_mem_config);
- cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000,
- pci_ioport);
- cpu_register_physical_memory(mem_base, 0x10000000,
- pci_mem_data); // XXX size should be 4G-prom
-
- d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
- 0, NULL, NULL);
+static void pbm_pci_host_init(PCIDevice *d)
+{
pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
d->config[0x04] = 0x06; // command = bus master, pci mem
@@ -264,13 +298,18 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
d->config[0x0D] = 0x10; // latency_timer
d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
+}
- /* APB secondary busses */
- *bus2 = pci_bridge_init(s->bus, 8, PCI_VENDOR_ID_SUN,
- PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
- "Advanced PCI Bus secondary bridge 1");
- *bus3 = pci_bridge_init(s->bus, 9, PCI_VENDOR_ID_SUN,
- PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
- "Advanced PCI Bus secondary bridge 2");
- return s->bus;
+static PCIDeviceInfo pbm_pci_host_info = {
+ .qdev.name = "pbm",
+ .qdev.size = sizeof(PCIDevice),
+ .init = pbm_pci_host_init,
+};
+
+static void pbm_register_devices(void)
+{
+ sysbus_register_dev("pbm", sizeof(APBState), pci_pbm_init_device);
+ pci_qdev_register(&pbm_pci_host_info);
}
+
+device_init(pbm_register_devices)
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 8567df8da..9e775a992 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2030,7 +2030,7 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
} else {
val = 0xff;
#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_readb %06x\n", addr);
+ printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
#endif
}
return val;
@@ -2125,7 +2125,8 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
}
} else {
#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
+ printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr,
+ mem_value);
#endif
}
}
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index c5d644908..dca397d1c 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -358,7 +358,7 @@ static SysBusDeviceInfo ecc_info = {
.qdev.props = (Property[]) {
{
.name = "version",
- .info = &qdev_prop_uint32,
+ .info = &qdev_prop_hex32,
.offset = offsetof(ECCState, version),
.defval = (uint32_t[]) { -1 },
},
diff --git a/hw/escc.c b/hw/escc.c
index 9abd092ae..2264f5d3a 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -970,22 +970,22 @@ static SysBusDeviceInfo escc_info = {
{
.name = "chrB",
.info = &qdev_prop_ptr,
- .offset = offsetof(SerialState, chn[1].chr),
+ .offset = offsetof(SerialState, chn[0].chr),
},
{
.name = "chrA",
.info = &qdev_prop_ptr,
- .offset = offsetof(SerialState, chn[0].chr),
+ .offset = offsetof(SerialState, chn[1].chr),
},
{
.name = "chnBtype",
.info = &qdev_prop_uint32,
- .offset = offsetof(SerialState, chn[1].type),
+ .offset = offsetof(SerialState, chn[0].type),
},
{
.name = "chnAtype",
.info = &qdev_prop_uint32,
- .offset = offsetof(SerialState, chn[0].type),
+ .offset = offsetof(SerialState, chn[1].type),
},
{/* end of list */}
}
diff --git a/hw/fdc.c b/hw/fdc.c
index fa154a30c..096f12ee0 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -33,6 +33,7 @@
#include "qemu-timer.h"
#include "isa.h"
#include "sysbus.h"
+#include "qdev-addr.h"
/********************************************************/
/* debug Floppy devices */
@@ -476,7 +477,6 @@ struct fdctrl_t {
/* HW */
qemu_irq irq;
int dma_chann;
- target_phys_addr_t io_base;
/* Controller state */
QEMUTimer *result_timer;
uint8_t sra;
@@ -511,8 +511,6 @@ struct fdctrl_t {
/* Floppy drives */
fdrive_t drives[MAX_FD];
int reset_sensei;
- uint32_t strict_io;
- uint32_t mem_mapped;
};
static uint32_t fdctrl_read (void *opaque, uint32_t reg)
@@ -1854,39 +1852,12 @@ static void fdctrl_result_timer(void *opaque)
}
/* Init functions */
-static void fdctrl_init_common (fdctrl_t *fdctrl, int dma_chann,
- target_phys_addr_t io_base,
- BlockDriverState **fds)
+static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds)
{
- int i, j;
-
- /* Fill 'command_to_handler' lookup table */
- for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
- for (j = 0; j < sizeof(command_to_handler); j++) {
- if ((j & handlers[i].mask) == handlers[i].value)
- command_to_handler[j] = i;
- }
- }
+ unsigned int i;
- FLOPPY_DPRINTF("init controller\n");
- fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
- fdctrl->result_timer = qemu_new_timer(vm_clock,
- fdctrl_result_timer, fdctrl);
-
- fdctrl->version = 0x90; /* Intel 82078 controller */
- fdctrl->dma_chann = dma_chann;
- fdctrl->io_base = io_base;
- fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
- if (fdctrl->dma_chann != -1) {
- DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- }
for (i = 0; i < MAX_FD; i++) {
fd_init(&fdctrl->drives[i], fds[i]);
- }
- fdctrl_external_reset(fdctrl);
- register_savevm("fdc", io_base, 2, fdc_save, fdc_load, fdctrl);
- qemu_register_reset(fdctrl_external_reset, fdctrl);
- for (i = 0; i < MAX_FD; i++) {
fd_revalidate(&fdctrl->drives[i]);
}
}
@@ -1900,9 +1871,6 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
fdctrl_t *fdctrl;
dev = qdev_create(NULL, "fdc");
- qdev_prop_set_uint32(dev, "strict_io", 0);
- qdev_prop_set_uint32(dev, "mem_mapped", mem_mapped);
- qdev_prop_set_uint32(dev, "sun4m", 0);
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_connect_irq(s, 0, irq);
@@ -1919,8 +1887,10 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
register_ioport_write((uint32_t)io_base + 0x07, 1, 1,
&fdctrl_write_port, fdctrl);
}
+ fdctrl->dma_chann = dma_chann;
+ DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- fdctrl_init_common(fdctrl, dma_chann, io_base, fds);
+ fdctrl_connect_drives(fdctrl, fds);
return fdctrl;
}
@@ -1932,10 +1902,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
SysBusDevice *s;
fdctrl_t *fdctrl;
- dev = qdev_create(NULL, "fdc");
- qdev_prop_set_uint32(dev, "strict_io", 1);
- qdev_prop_set_uint32(dev, "mem_mapped", 1);
- qdev_prop_set_uint32(dev, "sun4m", 1);
+ dev = qdev_create(NULL, "SUNW,fdtwo");
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_connect_irq(s, 0, irq);
@@ -1943,60 +1910,85 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
*fdc_tc = qdev_get_gpio_in(dev, 0);
fdctrl = FROM_SYSBUS(fdctrl_t, s);
- fdctrl_init_common(fdctrl, -1, io_base, fds);
+
+ fdctrl->dma_chann = -1;
+
+ fdctrl_connect_drives(fdctrl, fds);
return fdctrl;
}
-static void fdc_init1(SysBusDevice *dev)
+static void fdctrl_init_common(SysBusDevice *dev, fdctrl_t *fdctrl,
+ int is_sun4m, int io)
{
- fdctrl_t *s = FROM_SYSBUS(fdctrl_t, dev);
- int io;
+ int i, j;
+ static int command_tables_inited = 0;
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(dev, &fdctrl->irq);
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
- if (s->strict_io) {
- io = cpu_register_io_memory(fdctrl_mem_read_strict,
- fdctrl_mem_write_strict, s);
- } else {
- io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, s);
- }
sysbus_init_mmio(dev, 0x08, io);
+
+ /* Fill 'command_to_handler' lookup table */
+ if (!command_tables_inited) {
+ command_tables_inited = 1;
+ for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
+ for (j = 0; j < sizeof(command_to_handler); j++) {
+ if ((j & handlers[i].mask) == handlers[i].value) {
+ command_to_handler[j] = i;
+ }
+ }
+ }
+ }
+
+ FLOPPY_DPRINTF("init controller\n");
+ fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
+ fdctrl->result_timer = qemu_new_timer(vm_clock,
+ fdctrl_result_timer, fdctrl);
+
+ fdctrl->version = 0x90; /* Intel 82078 controller */
+ fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
+ fdctrl->sun4m = is_sun4m;
+
+ fdctrl_external_reset(fdctrl);
+ register_savevm("fdc", -1, 2, fdc_save, fdc_load, fdctrl);
+ qemu_register_reset(fdctrl_external_reset, fdctrl);
}
+static void fdc_init1(SysBusDevice *dev)
+{
+ fdctrl_t *fdctrl = FROM_SYSBUS(fdctrl_t, dev);
+ int io;
+
+ io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, fdctrl);
+ fdctrl_init_common(dev, fdctrl, 0, io);
+}
+
+static void sun4m_fdc_init1(SysBusDevice *dev)
+{
+ fdctrl_t *fdctrl = FROM_SYSBUS(fdctrl_t, dev);
+ int io;
+
+ io = cpu_register_io_memory(fdctrl_mem_read_strict,
+ fdctrl_mem_write_strict, fdctrl);
+ fdctrl_init_common(dev, fdctrl, 1, io);
+}
static SysBusDeviceInfo fdc_info = {
.init = fdc_init1,
.qdev.name = "fdc",
.qdev.size = sizeof(fdctrl_t),
- .qdev.props = (Property[]) {
- {
- .name = "io_base",
- .info = &qdev_prop_uint32,
- .offset = offsetof(fdctrl_t, io_base),
- },
- {
- .name = "strict_io",
- .info = &qdev_prop_uint32,
- .offset = offsetof(fdctrl_t, strict_io),
- },
- {
- .name = "mem_mapped",
- .info = &qdev_prop_uint32,
- .offset = offsetof(fdctrl_t, mem_mapped),
- },
- {
- .name = "sun4m",
- .info = &qdev_prop_uint32,
- .offset = offsetof(fdctrl_t, sun4m),
- },
- {/* end of properties */}
- }
+};
+
+static SysBusDeviceInfo sun4m_fdc_info = {
+ .init = sun4m_fdc_init1,
+ .qdev.name = "SUNW,fdtwo",
+ .qdev.size = sizeof(fdctrl_t),
};
static void fdc_register_devices(void)
{
sysbus_register_withprop(&fdc_info);
+ sysbus_register_withprop(&sun4m_fdc_info);
}
device_init(fdc_register_devices)
diff --git a/hw/i8259.c b/hw/i8259.c
index 9165a5dcc..19c9d170a 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -25,6 +25,7 @@
#include "pc.h"
#include "isa.h"
#include "monitor.h"
+#include "qemu-timer.h"
#include "qemu-kvm.h"
diff --git a/hw/iommu.c b/hw/iommu.c
index abf517f1d..d73dad3e1 100644
--- a/hw/iommu.c
+++ b/hw/iommu.c
@@ -406,7 +406,7 @@ static SysBusDeviceInfo iommu_info = {
.qdev.props = (Property[]) {
{
.name = "version",
- .info = &qdev_prop_uint32,
+ .info = &qdev_prop_hex32,
.offset = offsetof(IOMMUState, version),
},
{/* end of property list */}
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 516a46842..f749a45f6 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -10,6 +10,8 @@
/* ??? Need to check if the {read,write}[wl] routines work properly on
big-endian targets. */
+#include <assert.h> \
+
#include "hw.h"
#include "pci.h"
#include "scsi-disk.h"
@@ -1981,6 +1983,174 @@ void lsi_scsi_attach(DeviceState *host, BlockDriverState *bd, int id)
bd->private = &s->pci_dev;
}
+static void lsi_scsi_save(QEMUFile *f, void *opaque)
+{
+ LSIState *s = opaque;
+
+ assert(s->dma_buf == NULL);
+ assert(s->current_dma_len == 0);
+ assert(s->active_commands == 0);
+
+ pci_device_save(&s->pci_dev, f);
+
+ qemu_put_sbe32s(f, &s->carry);
+ qemu_put_sbe32s(f, &s->sense);
+ qemu_put_sbe32s(f, &s->msg_action);
+ qemu_put_sbe32s(f, &s->msg_len);
+ qemu_put_buffer(f, s->msg, sizeof (s->msg));
+ qemu_put_sbe32s(f, &s->waiting);
+
+ qemu_put_be32s(f, &s->dsa);
+ qemu_put_be32s(f, &s->temp);
+ qemu_put_be32s(f, &s->dnad);
+ qemu_put_be32s(f, &s->dbc);
+ qemu_put_8s(f, &s->istat0);
+ qemu_put_8s(f, &s->istat1);
+ qemu_put_8s(f, &s->dcmd);
+ qemu_put_8s(f, &s->dstat);
+ qemu_put_8s(f, &s->dien);
+ qemu_put_8s(f, &s->sist0);
+ qemu_put_8s(f, &s->sist1);
+ qemu_put_8s(f, &s->sien0);
+ qemu_put_8s(f, &s->sien1);
+ qemu_put_8s(f, &s->mbox0);
+ qemu_put_8s(f, &s->mbox1);
+ qemu_put_8s(f, &s->dfifo);
+ qemu_put_8s(f, &s->ctest2);
+ qemu_put_8s(f, &s->ctest3);
+ qemu_put_8s(f, &s->ctest4);
+ qemu_put_8s(f, &s->ctest5);
+ qemu_put_8s(f, &s->ccntl0);
+ qemu_put_8s(f, &s->ccntl1);
+ qemu_put_be32s(f, &s->dsp);
+ qemu_put_be32s(f, &s->dsps);
+ qemu_put_8s(f, &s->dmode);
+ qemu_put_8s(f, &s->dcntl);
+ qemu_put_8s(f, &s->scntl0);
+ qemu_put_8s(f, &s->scntl1);
+ qemu_put_8s(f, &s->scntl2);
+ qemu_put_8s(f, &s->scntl3);
+ qemu_put_8s(f, &s->sstat0);
+ qemu_put_8s(f, &s->sstat1);
+ qemu_put_8s(f, &s->scid);
+ qemu_put_8s(f, &s->sxfer);
+ qemu_put_8s(f, &s->socl);
+ qemu_put_8s(f, &s->sdid);
+ qemu_put_8s(f, &s->ssid);
+ qemu_put_8s(f, &s->sfbr);
+ qemu_put_8s(f, &s->stest1);
+ qemu_put_8s(f, &s->stest2);
+ qemu_put_8s(f, &s->stest3);
+ qemu_put_8s(f, &s->sidl);
+ qemu_put_8s(f, &s->stime0);
+ qemu_put_8s(f, &s->respid0);
+ qemu_put_8s(f, &s->respid1);
+ qemu_put_be32s(f, &s->mmrs);
+ qemu_put_be32s(f, &s->mmws);
+ qemu_put_be32s(f, &s->sfs);
+ qemu_put_be32s(f, &s->drs);
+ qemu_put_be32s(f, &s->sbms);
+ qemu_put_be32s(f, &s->dbms);
+ qemu_put_be32s(f, &s->dnad64);
+ qemu_put_be32s(f, &s->pmjad1);
+ qemu_put_be32s(f, &s->pmjad2);
+ qemu_put_be32s(f, &s->rbc);
+ qemu_put_be32s(f, &s->ua);
+ qemu_put_be32s(f, &s->ia);
+ qemu_put_be32s(f, &s->sbc);
+ qemu_put_be32s(f, &s->csbc);
+ qemu_put_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch));
+ qemu_put_8s(f, &s->sbr);
+
+ qemu_put_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram));
+}
+
+static int lsi_scsi_load(QEMUFile *f, void *opaque, int version_id)
+{
+ LSIState *s = opaque;
+ int ret;
+
+ if (version_id > 0) {
+ return -EINVAL;
+ }
+
+ if ((ret = pci_device_load(&s->pci_dev, f)) < 0)
+ return ret;
+
+ qemu_get_sbe32s(f, &s->carry);
+ qemu_get_sbe32s(f, &s->sense);
+ qemu_get_sbe32s(f, &s->msg_action);
+ qemu_get_sbe32s(f, &s->msg_len);
+ qemu_get_buffer(f, s->msg, sizeof (s->msg));
+ qemu_get_sbe32s(f, &s->waiting);
+
+ qemu_get_be32s(f, &s->dsa);
+ qemu_get_be32s(f, &s->temp);
+ qemu_get_be32s(f, &s->dnad);
+ qemu_get_be32s(f, &s->dbc);
+ qemu_get_8s(f, &s->istat0);
+ qemu_get_8s(f, &s->istat1);
+ qemu_get_8s(f, &s->dcmd);
+ qemu_get_8s(f, &s->dstat);
+ qemu_get_8s(f, &s->dien);
+ qemu_get_8s(f, &s->sist0);
+ qemu_get_8s(f, &s->sist1);
+ qemu_get_8s(f, &s->sien0);
+ qemu_get_8s(f, &s->sien1);
+ qemu_get_8s(f, &s->mbox0);
+ qemu_get_8s(f, &s->mbox1);
+ qemu_get_8s(f, &s->dfifo);
+ qemu_get_8s(f, &s->ctest2);
+ qemu_get_8s(f, &s->ctest3);
+ qemu_get_8s(f, &s->ctest4);
+ qemu_get_8s(f, &s->ctest5);
+ qemu_get_8s(f, &s->ccntl0);
+ qemu_get_8s(f, &s->ccntl1);
+ qemu_get_be32s(f, &s->dsp);
+ qemu_get_be32s(f, &s->dsps);
+ qemu_get_8s(f, &s->dmode);
+ qemu_get_8s(f, &s->dcntl);
+ qemu_get_8s(f, &s->scntl0);
+ qemu_get_8s(f, &s->scntl1);
+ qemu_get_8s(f, &s->scntl2);
+ qemu_get_8s(f, &s->scntl3);
+ qemu_get_8s(f, &s->sstat0);
+ qemu_get_8s(f, &s->sstat1);
+ qemu_get_8s(f, &s->scid);
+ qemu_get_8s(f, &s->sxfer);
+ qemu_get_8s(f, &s->socl);
+ qemu_get_8s(f, &s->sdid);
+ qemu_get_8s(f, &s->ssid);
+ qemu_get_8s(f, &s->sfbr);
+ qemu_get_8s(f, &s->stest1);
+ qemu_get_8s(f, &s->stest2);
+ qemu_get_8s(f, &s->stest3);
+ qemu_get_8s(f, &s->sidl);
+ qemu_get_8s(f, &s->stime0);
+ qemu_get_8s(f, &s->respid0);
+ qemu_get_8s(f, &s->respid1);
+ qemu_get_be32s(f, &s->mmrs);
+ qemu_get_be32s(f, &s->mmws);
+ qemu_get_be32s(f, &s->sfs);
+ qemu_get_be32s(f, &s->drs);
+ qemu_get_be32s(f, &s->sbms);
+ qemu_get_be32s(f, &s->dbms);
+ qemu_get_be32s(f, &s->dnad64);
+ qemu_get_be32s(f, &s->pmjad1);
+ qemu_get_be32s(f, &s->pmjad2);
+ qemu_get_be32s(f, &s->rbc);
+ qemu_get_be32s(f, &s->ua);
+ qemu_get_be32s(f, &s->ia);
+ qemu_get_be32s(f, &s->sbc);
+ qemu_get_be32s(f, &s->csbc);
+ qemu_get_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch));
+ qemu_get_8s(f, &s->sbr);
+
+ qemu_get_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram));
+
+ return 0;
+}
+
static int lsi_scsi_uninit(PCIDevice *d)
{
LSIState *s = (LSIState *) d;
@@ -2033,6 +2203,8 @@ static void lsi_scsi_init(PCIDevice *dev)
lsi_soft_reset(s);
scsi_bus_new(&dev->qdev, lsi_scsi_attach);
+
+ register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
}
static PCIDeviceInfo lsi_info = {
diff --git a/hw/openpic.c b/hw/openpic.c
index baa7ecc28..f50031dd5 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -592,7 +592,7 @@ static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t v
IRQ_dst_t *dst;
int idx;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
#if defined TARGET_WORDS_BIGENDIAN
@@ -651,7 +651,7 @@ static uint32_t openpic_gbl_read (void *opaque, target_phys_addr_t addr)
openpic_t *opp = opaque;
uint32_t retval;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -824,7 +824,7 @@ static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t v
IRQ_dst_t *dst;
int idx, s_IRQ, n_IRQ;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
#if defined TARGET_WORDS_BIGENDIAN
@@ -886,7 +886,7 @@ static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx, n_IRQ;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -1264,8 +1264,7 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
{
int n_ci = IDR_CI0 - n_CPU;
- DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
- n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
+
if(test_bit(&src->ide, n_ci)) {
qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
}
@@ -1313,7 +1312,7 @@ static void mpic_timer_write (void *opaque, target_phys_addr_t addr, uint32_t va
openpic_t *mpp = opaque;
int idx, cpu;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
addr &= 0xFFFF;
@@ -1347,7 +1346,7 @@ static uint32_t mpic_timer_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx, cpu;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -1382,7 +1381,7 @@ static void mpic_src_ext_write (void *opaque, target_phys_addr_t addr,
openpic_t *mpp = opaque;
int idx = MPIC_EXT_IRQ;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
@@ -1405,7 +1404,7 @@ static uint32_t mpic_src_ext_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx = MPIC_EXT_IRQ;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -1432,7 +1431,7 @@ static void mpic_src_int_write (void *opaque, target_phys_addr_t addr,
openpic_t *mpp = opaque;
int idx = MPIC_INT_IRQ;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
@@ -1455,7 +1454,7 @@ static uint32_t mpic_src_int_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx = MPIC_INT_IRQ;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -1482,7 +1481,7 @@ static void mpic_src_msg_write (void *opaque, target_phys_addr_t addr,
openpic_t *mpp = opaque;
int idx = MPIC_MSG_IRQ;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
@@ -1505,7 +1504,7 @@ static uint32_t mpic_src_msg_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx = MPIC_MSG_IRQ;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
@@ -1532,7 +1531,7 @@ static void mpic_src_msi_write (void *opaque, target_phys_addr_t addr,
openpic_t *mpp = opaque;
int idx = MPIC_MSI_IRQ;
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
@@ -1554,7 +1553,7 @@ static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr)
uint32_t retval;
int idx = MPIC_MSI_IRQ;
- DPRINTF("%s: addr %08x\n", __func__, addr);
+ DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
diff --git a/hw/pci.c b/hw/pci.c
index a575d4a97..9b86d992b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -148,11 +148,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
return bus;
}
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
+static PCIBus *pci_register_secondary_bus(PCIDevice *dev,
+ pci_map_irq_fn map_irq,
+ const char *name)
{
PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus));
+ bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
bus->map_irq = map_irq;
bus->parent_dev = dev;
bus->next = dev->bus->next;
@@ -1011,7 +1013,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
s->dev.config[0x1E] = 0xa0; // secondary status
- s->bus = pci_register_secondary_bus(&s->dev, map_irq);
+ s->bus = pci_register_secondary_bus(&s->dev, map_irq, name);
return s->bus;
}
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 7181181be..7a219778c 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -60,7 +60,8 @@ do { \
} \
} while (0)
#elif defined (DEBUG_PPC_IO)
-#define PPC_IO_DPRINTF(fmt, ...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
+#define PPC_IO_DPRINTF(fmt, ...) \
+qemu_log_mask(CPU_LOG_IOPORT, fmt, ## __VA_ARGS__)
#else
#define PPC_IO_DPRINTF(fmt, ...) do { } while (0)
#endif
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 1a8a6c995..5b4673a82 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -89,8 +89,8 @@ static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
{
PPCE500PCIState *pci = opaque;
- pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
- pci->pci_state.config_reg);
+ pci_debug("%s: (addr:" TARGET_FMT_plx ") -> value:%x\n", __func__, addr,
+ pci->pci_state.config_reg);
return pci->pci_state.config_reg;
}
@@ -105,7 +105,8 @@ static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
{
PPCE500PCIState *controller = opaque;
- pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
+ pci_debug("%s: value:%x -> (addr:" TARGET_FMT_plx ")\n", __func__, value,
+ addr);
controller->pci_state.config_reg = value & ~0x3;
}
@@ -169,7 +170,8 @@ static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
break;
}
- pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
+ pci_debug("%s: win:%lx(addr:" TARGET_FMT_plx ") -> value:%x\n", __func__,
+ win, addr, value);
return value;
}
@@ -187,7 +189,8 @@ static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
win = addr & 0xfe0;
- pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
+ pci_debug("%s: value:%x -> win:%lx(addr:" TARGET_FMT_plx ")\n",
+ __func__, value, win, addr);
switch (win) {
case PPCE500_PCI_OW1:
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 06c25aff7..4f35f0662 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -88,6 +88,59 @@ PropertyInfo qdev_prop_hex32 = {
.print = print_hex32,
};
+/* --- 64bit integer --- */
+
+static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
+{
+ uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ const char *fmt;
+
+ /* accept both hex and decimal */
+ fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx64 : "%" PRIu64;
+ if (sscanf(str, fmt, ptr) != 1)
+ return -1;
+ return 0;
+}
+
+static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "%" PRIu64, *ptr);
+}
+
+PropertyInfo qdev_prop_uint64 = {
+ .name = "uint64",
+ .type = PROP_TYPE_UINT64,
+ .size = sizeof(uint64_t),
+ .parse = parse_uint64,
+ .print = print_uint64,
+};
+
+/* --- 64bit hex value --- */
+
+static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
+{
+ uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (sscanf(str, "%" PRIx64, ptr) != 1)
+ return -1;
+ return 0;
+}
+
+static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "0x%" PRIx64, *ptr);
+}
+
+PropertyInfo qdev_prop_hex64 = {
+ .name = "hex64",
+ .type = PROP_TYPE_UINT64,
+ .size = sizeof(uint64_t),
+ .parse = parse_hex64,
+ .print = print_hex64,
+};
+
/* --- pointer --- */
static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -117,9 +170,9 @@ static int parse_mac(DeviceState *dev, Property *prop, const char *str)
char *p;
for (i = 0, pos = 0; i < 6; i++, pos += 3) {
- if (!isxdigit(str[pos]))
+ if (!qemu_isxdigit(str[pos]))
return -1;
- if (!isxdigit(str[pos+1]))
+ if (!qemu_isxdigit(str[pos+1]))
return -1;
if (i == 5 && str[pos+2] != '\0')
return -1;
@@ -224,6 +277,11 @@ void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
}
+void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
+{
+ qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
+}
+
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
{
qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
diff --git a/hw/qdev.c b/hw/qdev.c
index 001c74ce0..faecc767a 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -32,7 +32,6 @@
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
static BusState *main_system_bus;
-extern struct BusInfo system_bus_info;
static DeviceInfo *device_info_list;
diff --git a/hw/qdev.h b/hw/qdev.h
index 11744fa53..2e196e1c1 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -58,6 +58,7 @@ enum PropertyType {
PROP_TYPE_UNSPEC = 0,
PROP_TYPE_UINT16,
PROP_TYPE_UINT32,
+ PROP_TYPE_UINT64,
PROP_TYPE_TADDR,
PROP_TYPE_MACADDR,
PROP_TYPE_PTR,
@@ -145,7 +146,9 @@ void do_info_qtree(Monitor *mon);
extern PropertyInfo qdev_prop_uint16;
extern PropertyInfo qdev_prop_uint32;
+extern PropertyInfo qdev_prop_uint64;
extern PropertyInfo qdev_prop_hex32;
+extern PropertyInfo qdev_prop_hex64;
extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
@@ -155,6 +158,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value);
+void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_set_defaults(DeviceState *dev, Property *props);
@@ -162,4 +166,7 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
void qdev_prop_register_compat(CompatProperty *props);
void qdev_prop_set_compat(DeviceState *dev);
+/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
+extern struct BusInfo system_bus_info;
+
#endif
diff --git a/hw/sbi.c b/hw/sbi.c
index 32c8fa944..101fba5ae 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -21,9 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include "hw.h"
#include "sun4m.h"
#include "console.h"
+#include "sysbus.h"
//#define DEBUG_IRQ
@@ -39,9 +41,10 @@
#define SBI_NREGS 16
typedef struct SBIState {
+ SysBusDevice busdev;
uint32_t regs[SBI_NREGS];
uint32_t intreg_pending[MAX_CPUS];
- qemu_irq *cpu_irqs[MAX_CPUS];
+ qemu_irq cpu_irqs[MAX_CPUS];
uint32_t pil_out[MAX_CPUS];
} SBIState;
@@ -51,10 +54,6 @@ static void sbi_set_irq(void *opaque, int irq, int level)
{
}
-static void sbi_set_timer_irq_cpu(void *opaque, int cpu, int level)
-{
-}
-
static uint32_t sbi_mem_readl(void *opaque, target_phys_addr_t addr)
{
SBIState *s = opaque;
@@ -132,27 +131,54 @@ static void sbi_reset(void *opaque)
}
}
-void *sbi_init(target_phys_addr_t addr, qemu_irq **irq, qemu_irq **cpu_irq,
- qemu_irq **parent_irq)
+DeviceState *sbi_init(target_phys_addr_t addr, qemu_irq **parent_irq)
{
+ DeviceState *dev;
+ SysBusDevice *s;
unsigned int i;
- int sbi_io_memory;
- SBIState *s;
- s = qemu_mallocz(sizeof(SBIState));
+ dev = qdev_create(NULL, "sbi");
+ qdev_init(dev);
+
+ s = sysbus_from_qdev(dev);
for (i = 0; i < MAX_CPUS; i++) {
- s->cpu_irqs[i] = parent_irq[i];
+ sysbus_connect_irq(s, i, *parent_irq[i]);
+ }
+
+ sysbus_mmio_map(s, 0, addr);
+
+ return dev;
+}
+
+static void sbi_init1(SysBusDevice *dev)
+{
+ SBIState *s = FROM_SYSBUS(SBIState, dev);
+ int sbi_io_memory;
+ unsigned int i;
+
+ qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS);
+ for (i = 0; i < MAX_CPUS; i++) {
+ sysbus_init_irq(dev, &s->cpu_irqs[i]);
}
sbi_io_memory = cpu_register_io_memory(sbi_mem_read, sbi_mem_write, s);
- cpu_register_physical_memory(addr, SBI_SIZE, sbi_io_memory);
+ sysbus_init_mmio(dev, SBI_SIZE, sbi_io_memory);
- register_savevm("sbi", addr, 1, sbi_save, sbi_load, s);
+ register_savevm("sbi", -1, 1, sbi_save, sbi_load, s);
qemu_register_reset(sbi_reset, s);
- *irq = qemu_allocate_irqs(sbi_set_irq, s, 32);
- *cpu_irq = qemu_allocate_irqs(sbi_set_timer_irq_cpu, s, MAX_CPUS);
sbi_reset(s);
+}
+
+static SysBusDeviceInfo sbi_info = {
+ .init = sbi_init1,
+ .qdev.name = "sbi",
+ .qdev.size = sizeof(SBIState),
+};
- return s;
+static void sbi_register_devices(void)
+{
+ sysbus_register_withprop(&sbi_info);
}
+
+device_init(sbi_register_devices)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a0485dbeb..8b6426fd8 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -172,7 +172,7 @@ static void scsi_read_complete(void * opaque, int ret)
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
return;
}
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->iov.iov_len);
+ DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->tag, r->iov.iov_len);
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
}
@@ -192,7 +192,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
return;
}
if (r->sector_count == (uint32_t)-1) {
- DPRINTF("Read buf_len=%d\n", r->iov.iov_len);
+ DPRINTF("Read buf_len=%" PRId64 "\n", r->iov.iov_len);
r->sector_count = 0;
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
return;
@@ -777,7 +777,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
case 0x08:
case 0x28:
case 0x88:
- DPRINTF("Read (sector %lld, count %d)\n", lba, len);
+ DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
if (lba > s->max_lba)
goto illegal_lba;
r->sector = lba * s->cluster_size;
@@ -786,7 +786,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
case 0x0a:
case 0x2a:
case 0x8a:
- DPRINTF("Write (sector %lld, count %d)\n", lba, len);
+ DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
if (lba > s->max_lba)
goto illegal_lba;
r->sector = lba * s->cluster_size;
@@ -794,7 +794,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
is_write = 1;
break;
case 0x35:
- DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
+ DPRINTF("Synchronise cache (sector %" PRId64 ", count %d)\n", lba, len);
bdrv_flush(s->bdrv);
break;
case 0x43:
@@ -896,7 +896,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->iov.iov_len = 16;
break;
case 0x2f:
- DPRINTF("Verify (sector %d, count %d)\n", lba, len);
+ DPRINTF("Verify (sector %" PRId64 ", count %d)\n", lba, len);
break;
default:
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 21924f871..69c9f3b67 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -197,8 +197,8 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
s->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
s->reached = 0;
count = ((uint64_t)s->counthigh << 32) | s->count;
- DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
- count);
+ DPRINTF("processor %d user timer set to %016" PRIx64 "\n",
+ s->slave_index, count);
if (s->timer)
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
} else {
@@ -223,8 +223,8 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
s->count = val & TIMER_MAX_COUNT64;
s->reached = 0;
count = ((uint64_t)s->counthigh) << 32 | s->count;
- DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
- count);
+ DPRINTF("processor %d user timer set to %016" PRIx64 "\n",
+ s->slave_index, count);
if (s->timer)
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
} else
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index 7eb84596b..c9867da45 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -21,9 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include "hw.h"
#include "sun4m.h"
#include "monitor.h"
+#include "sysbus.h"
+
//#define DEBUG_IRQ_COUNT
//#define DEBUG_IRQ
@@ -42,10 +45,11 @@
#define MAX_PILS 16
typedef struct Sun4c_INTCTLState {
+ SysBusDevice busdev;
#ifdef DEBUG_IRQ_COUNT
uint64_t irq_count;
#endif
- qemu_irq *cpu_irqs;
+ qemu_irq cpu_irqs[MAX_PILS];
const uint32_t *intbit_to_level;
uint32_t pil_out;
uint8_t reg;
@@ -107,9 +111,9 @@ void sun4c_irq_info(Monitor *mon, void *opaque)
int64_t count;
monitor_printf(mon, "IRQ statistics:\n");
- count = s->irq_count[i];
+ count = s->irq_count;
if (count > 0)
- monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
+ monitor_printf(mon, " %" PRId64 "\n", count);
#endif
}
@@ -121,7 +125,6 @@ static void sun4c_check_interrupts(void *opaque)
uint32_t pil_pending;
unsigned int i;
- DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled);
pil_pending = 0;
if (s->pending && !(s->reg & 0x80000000)) {
for (i = 0; i < 8; i++) {
@@ -156,7 +159,7 @@ static void sun4c_set_irq(void *opaque, int irq, int level)
if (pil > 0) {
if (level) {
#ifdef DEBUG_IRQ_COUNT
- s->irq_count[pil]++;
+ s->irq_count++;
#endif
s->pending |= mask;
} else {
@@ -195,25 +198,54 @@ static void sun4c_intctl_reset(void *opaque)
s->pending = 0;
}
-void *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq **irq,
- qemu_irq *parent_irq)
+DeviceState *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq *parent_irq)
{
- int sun4c_intctl_io_memory;
- Sun4c_INTCTLState *s;
+ DeviceState *dev;
+ SysBusDevice *s;
+ unsigned int i;
- s = qemu_mallocz(sizeof(Sun4c_INTCTLState));
+ dev = qdev_create(NULL, "sun4c_intctl");
+ qdev_init(dev);
- sun4c_intctl_io_memory = cpu_register_io_memory(sun4c_intctl_mem_read,
- sun4c_intctl_mem_write, s);
- cpu_register_physical_memory(addr, INTCTL_SIZE, sun4c_intctl_io_memory);
- s->cpu_irqs = parent_irq;
+ s = sysbus_from_qdev(dev);
- register_savevm("sun4c_intctl", addr, 1, sun4c_intctl_save,
- sun4c_intctl_load, s);
+ for (i = 0; i < MAX_PILS; i++) {
+ sysbus_connect_irq(s, i, parent_irq[i]);
+ }
+ sysbus_mmio_map(s, 0, addr);
- qemu_register_reset(sun4c_intctl_reset, s);
- *irq = qemu_allocate_irqs(sun4c_set_irq, s, 8);
+ return dev;
+}
+
+static void sun4c_intctl_init1(SysBusDevice *dev)
+{
+ Sun4c_INTCTLState *s = FROM_SYSBUS(Sun4c_INTCTLState, dev);
+ int io_memory;
+ unsigned int i;
+ io_memory = cpu_register_io_memory(sun4c_intctl_mem_read,
+ sun4c_intctl_mem_write, s);
+ sysbus_init_mmio(dev, INTCTL_SIZE, io_memory);
+ qdev_init_gpio_in(&dev->qdev, sun4c_set_irq, 8);
+
+ for (i = 0; i < MAX_PILS; i++) {
+ sysbus_init_irq(dev, &s->cpu_irqs[i]);
+ }
+ register_savevm("sun4c_intctl", -1, 1, sun4c_intctl_save,
+ sun4c_intctl_load, s);
+ qemu_register_reset(sun4c_intctl_reset, s);
sun4c_intctl_reset(s);
- return s;
}
+
+static SysBusDeviceInfo sun4c_intctl_info = {
+ .init = sun4c_intctl_init1,
+ .qdev.name = "sun4c_intctl",
+ .qdev.size = sizeof(Sun4c_INTCTLState),
+};
+
+static void sun4c_intctl_register_devices(void)
+{
+ sysbus_register_withprop(&sun4c_intctl_info);
+}
+
+device_init(sun4c_intctl_register_devices)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 4954ba37d..1e668fca1 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -374,6 +374,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
dev = qdev_create(NULL, "lance");
dev->nd = nd;
+ qdev_prop_set_ptr(dev, "dma", dma_opaque);
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, leaddr);
@@ -479,7 +480,7 @@ device_init(prom_register_devices);
typedef struct RamDevice
{
SysBusDevice busdev;
- uint32_t size;
+ uint64_t size;
} RamDevice;
/* System RAM */
@@ -510,11 +511,11 @@ static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
exit(1);
}
dev = qdev_create(NULL, "memory");
- qdev_init(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(RamDevice, s);
d->size = RAM_size;
+ qdev_init(dev);
sysbus_mmio_map(s, 0, addr);
}
@@ -526,7 +527,7 @@ static SysBusDeviceInfo ram_info = {
.qdev.props = (Property[]) {
{
.name = "size",
- .info = &qdev_prop_uint32,
+ .info = &qdev_prop_uint64,
.offset = offsetof(RamDevice, size),
},
{/* end of property list */}
@@ -1321,12 +1322,13 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
{
CPUState *envs[MAX_CPUS];
unsigned int i;
- void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram, *sbi;
- qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq,
+ void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
+ qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
espdma_irq, ledma_irq;
qemu_irq *esp_reset, *le_reset;
unsigned long kernel_size;
void *fw_cfg;
+ DeviceState *dev;
/* init CPUs */
if (!cpu_model)
@@ -1344,7 +1346,14 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
prom_init(hwdef->slavio_base, bios_name);
- sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs);
+ dev = sbi_init(hwdef->sbi_base, cpu_irqs);
+
+ for (i = 0; i < 32; i++) {
+ sbi_irq[i] = qdev_get_gpio_in(dev, i);
+ }
+ for (i = 0; i < MAX_CPUS; i++) {
+ sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
+ }
for (i = 0; i < MAX_IOUNITS; i++)
if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
@@ -1493,13 +1502,15 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
{
CPUState *env;
void *iommu, *espdma, *ledma, *nvram;
- qemu_irq *cpu_irqs, *slavio_irq, espdma_irq, ledma_irq;
+ qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
qemu_irq *esp_reset, *le_reset;
qemu_irq fdc_tc;
unsigned long kernel_size;
BlockDriverState *fd[MAX_FD];
int drive_index;
void *fw_cfg;
+ DeviceState *dev;
+ unsigned int i;
/* init CPU */
if (!cpu_model)
@@ -1512,8 +1523,11 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
prom_init(hwdef->slavio_base, bios_name);
- slavio_intctl = sun4c_intctl_init(hwdef->intctl_base,
- &slavio_irq, cpu_irqs);
+ dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs);
+
+ for (i = 0; i < 8; i++) {
+ slavio_irq[i] = qdev_get_gpio_in(dev, i);
+ }
iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
slavio_irq[hwdef->me_irq]);
diff --git a/hw/sun4m.h b/hw/sun4m.h
index d818fb184..33d5010da 100644
--- a/hw/sun4m.h
+++ b/hw/sun4m.h
@@ -36,12 +36,10 @@ void slavio_pic_info(Monitor *mon, void *opaque);
void slavio_irq_info(Monitor *mon, void *opaque);
/* sbi.c */
-void *sbi_init(target_phys_addr_t addr, qemu_irq **irq, qemu_irq **cpu_irq,
- qemu_irq **parent_irq);
+DeviceState *sbi_init(target_phys_addr_t addr, qemu_irq **parent_irq);
/* sun4c_intctl.c */
-void *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq **irq,
- qemu_irq *parent_irq);
+DeviceState *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq *parent_irq);
void sun4c_pic_info(Monitor *mon, void *opaque);
void sun4c_irq_info(Monitor *mon, void *opaque);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 9d2a7f59e..c49e34542 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -32,6 +32,7 @@
#include "boards.h"
#include "firmware_abi.h"
#include "fw_cfg.h"
+#include "sysbus.h"
//#define DEBUG_IRQ
@@ -147,6 +148,56 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
return 0;
}
+static unsigned long sun4u_load_kernel(const char *kernel_filename,
+ const char *initrd_filename,
+ ram_addr_t RAM_size, long *initrd_size)
+{
+ int linux_boot;
+ unsigned int i;
+ long kernel_size;
+
+ linux_boot = (kernel_filename != NULL);
+
+ kernel_size = 0;
+ if (linux_boot) {
+ kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
+ if (kernel_size < 0)
+ kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
+ RAM_size - KERNEL_LOAD_ADDR);
+ if (kernel_size < 0)
+ kernel_size = load_image_targphys(kernel_filename,
+ KERNEL_LOAD_ADDR,
+ RAM_size - KERNEL_LOAD_ADDR);
+ if (kernel_size < 0) {
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ kernel_filename);
+ exit(1);
+ }
+
+ /* load initrd */
+ *initrd_size = 0;
+ if (initrd_filename) {
+ *initrd_size = load_image_targphys(initrd_filename,
+ INITRD_LOAD_ADDR,
+ RAM_size - INITRD_LOAD_ADDR);
+ if (*initrd_size < 0) {
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ initrd_filename);
+ exit(1);
+ }
+ }
+ if (*initrd_size > 0) {
+ for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
+ if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
+ stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
+ stl_phys(KERNEL_LOAD_ADDR + i + 20, *initrd_size);
+ break;
+ }
+ }
+ }
+ }
+ return kernel_size;
+}
void pic_info(Monitor *mon)
{
@@ -342,34 +393,129 @@ static void pci_ebus_register(void)
device_init(pci_ebus_register);
-static void sun4uv_init(ram_addr_t RAM_size,
- const char *boot_devices,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model,
- const struct hwdef *hwdef)
+/* Boot PROM (OpenBIOS) */
+static void prom_init(target_phys_addr_t addr, const char *bios_name)
{
- CPUState *env;
+ DeviceState *dev;
+ SysBusDevice *s;
char *filename;
- m48t59_t *nvram;
- int ret, linux_boot;
- unsigned int i;
- ram_addr_t ram_offset, prom_offset;
- long initrd_size, kernel_size;
- PCIBus *pci_bus, *pci_bus2, *pci_bus3;
+ int ret;
+
+ dev = qdev_create(NULL, "openprom");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+
+ sysbus_mmio_map(s, 0, addr);
+
+ /* load boot prom */
+ if (bios_name == NULL) {
+ bios_name = PROM_FILENAME;
+ }
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (filename) {
+ ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
+ if (ret < 0 || ret > PROM_SIZE_MAX) {
+ ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
+ }
+ qemu_free(filename);
+ } else {
+ ret = -1;
+ }
+ if (ret < 0 || ret > PROM_SIZE_MAX) {
+ fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name);
+ exit(1);
+ }
+}
+
+static void prom_init1(SysBusDevice *dev)
+{
+ ram_addr_t prom_offset;
+
+ prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
+ sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
+}
+
+static SysBusDeviceInfo prom_info = {
+ .init = prom_init1,
+ .qdev.name = "openprom",
+ .qdev.size = sizeof(SysBusDevice),
+ .qdev.props = (Property[]) {
+ {/* end of property list */}
+ }
+};
+
+static void prom_register_devices(void)
+{
+ sysbus_register_withprop(&prom_info);
+}
+
+device_init(prom_register_devices);
+
+
+typedef struct RamDevice
+{
+ SysBusDevice busdev;
+ uint64_t size;
+} RamDevice;
+
+/* System RAM */
+static void ram_init1(SysBusDevice *dev)
+{
+ ram_addr_t RAM_size, ram_offset;
+ RamDevice *d = FROM_SYSBUS(RamDevice, dev);
+
+ RAM_size = d->size;
+
+ ram_offset = qemu_ram_alloc(RAM_size);
+ sysbus_init_mmio(dev, RAM_size, ram_offset);
+}
+
+static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ RamDevice *d;
+
+ /* allocate RAM */
+ dev = qdev_create(NULL, "memory");
+ s = sysbus_from_qdev(dev);
+
+ d = FROM_SYSBUS(RamDevice, s);
+ d->size = RAM_size;
+ qdev_init(dev);
+
+ sysbus_mmio_map(s, 0, addr);
+}
+
+static SysBusDeviceInfo ram_info = {
+ .init = ram_init1,
+ .qdev.name = "memory",
+ .qdev.size = sizeof(RamDevice),
+ .qdev.props = (Property[]) {
+ {
+ .name = "size",
+ .info = &qdev_prop_uint64,
+ .offset = offsetof(RamDevice, size),
+ },
+ {/* end of property list */}
+ }
+};
+
+static void ram_register_devices(void)
+{
+ sysbus_register_withprop(&ram_info);
+}
+
+device_init(ram_register_devices);
+
+static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
+{
+ CPUState *env;
QEMUBH *bh;
- qemu_irq *irq;
- int drive_index;
- BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- BlockDriverState *fd[MAX_FD];
- void *fw_cfg;
ResetData *reset_info;
- linux_boot = (kernel_filename != NULL);
-
- /* init CPUs */
if (!cpu_model)
cpu_model = hwdef->default_cpu_model;
-
env = cpu_init(cpu_model);
if (!env) {
fprintf(stderr, "Unable to find Sparc CPU definition\n");
@@ -396,76 +542,34 @@ static void sun4uv_init(ram_addr_t RAM_size,
env->pc = hwdef->prom_addr + 0x20ULL;
env->npc = env->pc + 4;
- /* allocate RAM */
- ram_offset = qemu_ram_alloc(RAM_size);
- cpu_register_physical_memory(0, RAM_size, ram_offset);
+ return env;
+}
- prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
- cpu_register_physical_memory(hwdef->prom_addr,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
- TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
+static void sun4uv_init(ram_addr_t RAM_size,
+ const char *boot_devices,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model,
+ const struct hwdef *hwdef)
+{
+ CPUState *env;
+ m48t59_t *nvram;
+ unsigned int i;
+ long initrd_size, kernel_size;
+ PCIBus *pci_bus, *pci_bus2, *pci_bus3;
+ qemu_irq *irq;
+ int drive_index;
+ BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+ BlockDriverState *fd[MAX_FD];
+ void *fw_cfg;
- if (bios_name == NULL)
- bios_name = PROM_FILENAME;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (filename) {
- ret = load_elf(filename, hwdef->prom_addr - PROM_VADDR,
- NULL, NULL, NULL);
- if (ret < 0) {
- ret = load_image_targphys(filename, hwdef->prom_addr,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
- TARGET_PAGE_MASK);
- }
- qemu_free(filename);
- } else {
- ret = -1;
- }
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- bios_name);
- exit(1);
- }
+ /* init CPUs */
+ env = cpu_devinit(cpu_model, hwdef);
- kernel_size = 0;
- initrd_size = 0;
- if (linux_boot) {
- /* XXX: put correct offset */
- kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
- if (kernel_size < 0)
- kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
- ram_size - KERNEL_LOAD_ADDR);
- if (kernel_size < 0)
- kernel_size = load_image_targphys(kernel_filename,
- KERNEL_LOAD_ADDR,
- ram_size - KERNEL_LOAD_ADDR);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
+ /* set up devices */
+ ram_init(0, RAM_size);
+
+ prom_init(hwdef->prom_addr, bios_name);
- /* load initrd */
- if (initrd_filename) {
- initrd_size = load_image_targphys(initrd_filename,
- INITRD_LOAD_ADDR,
- ram_size - INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- }
- if (initrd_size > 0) {
- for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
- stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
- stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
- break;
- }
- }
- }
- }
irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,
@@ -525,6 +629,11 @@ static void sun4uv_init(ram_addr_t RAM_size,
}
floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
+
+ initrd_size = 0;
+ kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
+ ram_size, &initrd_size);
+
sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
KERNEL_LOAD_ADDR, kernel_size,
kernel_cmdline,
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 28ab3a915..4c42ec0de 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -905,7 +905,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
flag_r = (td.flags & OHCI_TD_R) != 0;
#ifdef DEBUG_PACKET
- dprintf(" TD @ 0x%.8x %u bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
+ dprintf(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
addr, len, str, flag_r, td.cbp, td.be);
if (len > 0 && dir != OHCI_TD_DIR_IN) {
@@ -1677,7 +1677,7 @@ static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
usb_bit_time = 1;
}
#endif
- dprintf("usb-ohci: usb_bit_time=%lli usb_frame_time=%lli\n",
+ dprintf("usb-ohci: usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64 "\n",
usb_frame_time, usb_bit_time);
}
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 7b74207b5..a61887b44 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -72,7 +72,7 @@
#ifdef DEBUG
#define dprintf printf
-const char *pid2str(int pid)
+static const char *pid2str(int pid)
{
switch (pid) {
case USB_TOKEN_SETUP: return "SETUP";
diff --git a/hw/vga.c b/hw/vga.c
index dc851ce6b..6aeb6b8f1 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -800,7 +800,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
uint32_t write_mask, bit_mask, set_mask;
#ifdef DEBUG_VGA_MEM
- printf("vga: [0x%x] = 0x%02x\n", addr, val);
+ printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
#endif
/* convert to VGA memory offset */
memory_map_mode = (s->gr[6] >> 2) & 3;
@@ -833,7 +833,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
if (s->sr[2] & mask) {
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
- printf("vga: chain4: [0x%x]\n", addr);
+ printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
cpu_physical_memory_set_dirty(s->vram_offset + addr);
@@ -846,7 +846,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
addr = ((addr & ~1) << 1) | plane;
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
- printf("vga: odd/even: [0x%x]\n", addr);
+ printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
cpu_physical_memory_set_dirty(s->vram_offset + addr);
@@ -920,10 +920,10 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
(val & write_mask);
#ifdef DEBUG_VGA_MEM
- printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
- addr * 4, write_mask, val);
+ printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
+ addr * 4, write_mask, val);
#endif
- cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+ cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
}
}
diff --git a/kvm-all.c b/kvm-all.c
index b4b5a35f4..60c7b2f01 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -154,6 +154,15 @@ static void kvm_reset_vcpu(void *opaque)
}
}
+static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
+{
+ if (env == cpu_single_env) {
+ func(data);
+ return;
+ }
+ abort();
+}
+
int kvm_init_vcpu(CPUState *env)
{
KVMState *s = kvm_state;
@@ -227,7 +236,7 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,
if (mem == NULL) {
fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
TARGET_FMT_plx "\n", __func__, phys_addr,
- phys_addr + size - 1);
+ (target_phys_addr_t)(phys_addr + size - 1));
return -EINVAL;
}
@@ -301,6 +310,7 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
KVMDirtyLog d;
KVMSlot *mem;
int ret = 0;
+ int r;
d.dirty_bitmap = NULL;
while (start_addr < end_addr) {
@@ -309,6 +319,11 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
break;
}
+ /* We didn't activate dirty logging? Don't care then. */
+ if(!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) {
+ continue;
+ }
+
size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
if (!d.dirty_bitmap) {
d.dirty_bitmap = qemu_malloc(size);
@@ -320,7 +335,8 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
d.slot = mem->slot;
- if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
+ r = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
+ if (r == -EINVAL) {
dprintf("ioctl failed %d\n", errno);
ret = -1;
break;
@@ -336,6 +352,10 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
if ((bitmap[word] >> bit) & 1) {
cpu_physical_memory_set_dirty(addr);
+ } else if (r < 0) {
+ /* When our KVM implementation doesn't know about dirty logging
+ * we can just assume it's always dirty and be fine. */
+ cpu_physical_memory_set_dirty(addr);
}
}
start_addr = phys_addr;
@@ -898,18 +918,33 @@ int kvm_sw_breakpoints_active(CPUState *env)
}
#ifdef KVM_UPSTREAM
+
+struct kvm_set_guest_debug_data {
+ struct kvm_guest_debug dbg;
+ CPUState *env;
+ int err;
+};
+
+static void kvm_invoke_set_guest_debug(void *data)
+{
+ struct kvm_set_guest_debug_data *dbg_data = data;
+ dbg_data->err = kvm_vcpu_ioctl(dbg_data->env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
+}
+
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
{
- struct kvm_guest_debug dbg;
+ struct kvm_set_guest_debug_data data;
- dbg.control = 0;
+ data.dbg.control = 0;
if (env->singlestep_enabled)
- dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
+ data.dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
- kvm_arch_update_guest_debug(env, &dbg);
- dbg.control |= reinject_trap;
+ kvm_arch_update_guest_debug(env, &data.dbg);
+ data.dbg.control |= reinject_trap;
+ data.env = env;
- return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg);
+ on_vcpu(env, kvm_invoke_set_guest_debug, &data);
+ return data.err;
}
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d31cca71d..63d0ae4e9 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -134,13 +134,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->rip = infop->entry;
}
-typedef target_ulong elf_greg_t;
+typedef target_ulong target_elf_greg_t;
typedef uint32_t target_uid_t;
typedef uint32_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 27
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
/*
* Note that ELF_NREG should be 29 as there should be place for
@@ -149,7 +149,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG];
*
* See linux kernel: arch/x86/include/asm/elf.h
*/
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[15];
(*regs)[1] = env->regs[14];
@@ -211,13 +211,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->edx = 0;
}
-typedef target_ulong elf_greg_t;
+typedef target_ulong target_elf_greg_t;
typedef uint16_t target_uid_t;
typedef uint16_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 17
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
/*
* Note that ELF_NREG should be 19 as there should be place for
@@ -226,7 +226,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG];
*
* See linux kernel: arch/x86/include/asm/elf.h
*/
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[R_EBX];
(*regs)[1] = env->regs[R_ECX];
@@ -286,15 +286,15 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->ARM_r10 = infop->start_data;
}
-typedef uint32_t elf_greg_t;
+typedef uint32_t target_elf_greg_t;
typedef uint16_t target_uid_t;
typedef uint16_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 18
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[0];
(*regs)[1] = env->regs[1];
@@ -422,35 +422,35 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
/* Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP).
See arch/powerpc/include/asm/cputable.h. */
enum {
- PPC_FEATURE_32 = 0x80000000,
- PPC_FEATURE_64 = 0x40000000,
- PPC_FEATURE_601_INSTR = 0x20000000,
- PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
- PPC_FEATURE_HAS_FPU = 0x08000000,
- PPC_FEATURE_HAS_MMU = 0x04000000,
- PPC_FEATURE_HAS_4xxMAC = 0x02000000,
- PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
- PPC_FEATURE_HAS_SPE = 0x00800000,
- PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
- PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
- PPC_FEATURE_NO_TB = 0x00100000,
- PPC_FEATURE_POWER4 = 0x00080000,
- PPC_FEATURE_POWER5 = 0x00040000,
- PPC_FEATURE_POWER5_PLUS = 0x00020000,
- PPC_FEATURE_CELL = 0x00010000,
- PPC_FEATURE_BOOKE = 0x00008000,
- PPC_FEATURE_SMT = 0x00004000,
- PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
- PPC_FEATURE_ARCH_2_05 = 0x00001000,
- PPC_FEATURE_PA6T = 0x00000800,
- PPC_FEATURE_HAS_DFP = 0x00000400,
- PPC_FEATURE_POWER6_EXT = 0x00000200,
- PPC_FEATURE_ARCH_2_06 = 0x00000100,
- PPC_FEATURE_HAS_VSX = 0x00000080,
- PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
-
- PPC_FEATURE_TRUE_LE = 0x00000002,
- PPC_FEATURE_PPC_LE = 0x00000001,
+ QEMU_PPC_FEATURE_32 = 0x80000000,
+ QEMU_PPC_FEATURE_64 = 0x40000000,
+ QEMU_PPC_FEATURE_601_INSTR = 0x20000000,
+ QEMU_PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
+ QEMU_PPC_FEATURE_HAS_FPU = 0x08000000,
+ QEMU_PPC_FEATURE_HAS_MMU = 0x04000000,
+ QEMU_PPC_FEATURE_HAS_4xxMAC = 0x02000000,
+ QEMU_PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
+ QEMU_PPC_FEATURE_HAS_SPE = 0x00800000,
+ QEMU_PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
+ QEMU_PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
+ QEMU_PPC_FEATURE_NO_TB = 0x00100000,
+ QEMU_PPC_FEATURE_POWER4 = 0x00080000,
+ QEMU_PPC_FEATURE_POWER5 = 0x00040000,
+ QEMU_PPC_FEATURE_POWER5_PLUS = 0x00020000,
+ QEMU_PPC_FEATURE_CELL = 0x00010000,
+ QEMU_PPC_FEATURE_BOOKE = 0x00008000,
+ QEMU_PPC_FEATURE_SMT = 0x00004000,
+ QEMU_PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
+ QEMU_PPC_FEATURE_ARCH_2_05 = 0x00001000,
+ QEMU_PPC_FEATURE_PA6T = 0x00000800,
+ QEMU_PPC_FEATURE_HAS_DFP = 0x00000400,
+ QEMU_PPC_FEATURE_POWER6_EXT = 0x00000200,
+ QEMU_PPC_FEATURE_ARCH_2_06 = 0x00000100,
+ QEMU_PPC_FEATURE_HAS_VSX = 0x00000080,
+ QEMU_PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
+
+ QEMU_PPC_FEATURE_TRUE_LE = 0x00000002,
+ QEMU_PPC_FEATURE_PPC_LE = 0x00000001,
};
#define ELF_HWCAP get_elf_hwcap()
@@ -464,14 +464,14 @@ static uint32_t get_elf_hwcap(void)
Altivec/FP/SPE support. Anything else is just a bonus. */
#define GET_FEATURE(flag, feature) \
do {if (e->insns_flags & flag) features |= feature; } while(0)
- GET_FEATURE(PPC_64B, PPC_FEATURE_64);
- GET_FEATURE(PPC_FLOAT, PPC_FEATURE_HAS_FPU);
- GET_FEATURE(PPC_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC);
- GET_FEATURE(PPC_SPE, PPC_FEATURE_HAS_SPE);
- GET_FEATURE(PPC_SPE_SINGLE, PPC_FEATURE_HAS_EFP_SINGLE);
- GET_FEATURE(PPC_SPE_DOUBLE, PPC_FEATURE_HAS_EFP_DOUBLE);
- GET_FEATURE(PPC_BOOKE, PPC_FEATURE_BOOKE);
- GET_FEATURE(PPC_405_MAC, PPC_FEATURE_HAS_4xxMAC);
+ GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64);
+ GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU);
+ GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC);
+ GET_FEATURE(PPC_SPE, QEMU_PPC_FEATURE_HAS_SPE);
+ GET_FEATURE(PPC_SPE_SINGLE, QEMU_PPC_FEATURE_HAS_EFP_SINGLE);
+ GET_FEATURE(PPC_SPE_DOUBLE, QEMU_PPC_FEATURE_HAS_EFP_DOUBLE);
+ GET_FEATURE(PPC_BOOKE, QEMU_PPC_FEATURE_BOOKE);
+ GET_FEATURE(PPC_405_MAC, QEMU_PPC_FEATURE_HAS_4xxMAC);
#undef GET_FEATURE
return features;
@@ -798,9 +798,9 @@ static int elf_core_dump(int, const CPUState *);
#ifdef BSWAP_NEEDED
static void bswap_note(struct elf_note *en)
{
- bswaptls(&en->n_namesz);
- bswaptls(&en->n_descsz);
- bswaptls(&en->n_type);
+ bswap32s(&en->n_namesz);
+ bswap32s(&en->n_descsz);
+ bswap32s(&en->n_type);
}
#endif /* BSWAP_NEEDED */
@@ -1545,6 +1545,29 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
info->mmap = 0;
elf_entry = (abi_ulong) elf_ex.e_entry;
+#if defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * In case where user has not explicitly set the guest_base, we
+ * probe here that should we set it automatically.
+ */
+ if (!have_guest_base) {
+ /*
+ * Go through ELF program header table and find out whether
+ * any of the segments drop below our current mmap_min_addr and
+ * in that case set guest_base to corresponding address.
+ */
+ for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum;
+ i++, elf_ppnt++) {
+ if (elf_ppnt->p_type != PT_LOAD)
+ continue;
+ if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) {
+ guest_base = HOST_PAGE_ALIGN(mmap_min_addr);
+ break;
+ }
+ }
+ }
+#endif /* CONFIG_USE_GUEST_BASE */
+
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
info->rss = 0;
@@ -1725,7 +1748,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
/*
* Definitions to generate Intel SVR4-like core files.
- * These mostly have the same names as the SVR4 types with "elf_"
+ * These mostly have the same names as the SVR4 types with "target_elf_"
* tacked on the front to prevent clashes with linux definitions,
* and the typedef forms have been avoided. This is mostly like
* the SVR4 structure, but more Linuxy, with things that Linux does
@@ -1745,9 +1768,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
* Next you define type of register set used for dumping. ELF specification
* says that it needs to be array of elf_greg_t that has size of ELF_NREG.
*
- * typedef <target_regtype> elf_greg_t;
+ * typedef <target_regtype> target_elf_greg_t;
* #define ELF_NREG <number of registers>
- * typedef elf_greg_t elf_gregset_t[ELF_NREG];
+ * typedef taret_elf_greg_t target_elf_gregset_t[ELF_NREG];
*
* Then define following types to match target types. Actual types can
* be found from linux kernel (arch/<ARCH>/include/asm/posix_types.h):
@@ -1759,7 +1782,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
* Last step is to implement target specific function that copies registers
* from given cpu into just specified register set. Prototype is:
*
- * static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env);
+ * static void elf_core_copy_regs(taret_elf_gregset_t *regs,
+ * const CPUState *env);
*
* Parameters:
* regs - copy register values into here (allocated and zeroed by caller)
@@ -1779,14 +1803,14 @@ struct memelfnote {
size_t notesz;
};
-struct elf_siginfo {
+struct target_elf_siginfo {
int si_signo; /* signal number */
int si_code; /* extra code */
int si_errno; /* errno */
};
-struct elf_prstatus {
- struct elf_siginfo pr_info; /* Info associated with signal */
+struct target_elf_prstatus {
+ struct target_elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
target_ulong pr_sigpend; /* XXX */
target_ulong pr_sighold; /* XXX */
@@ -1798,13 +1822,13 @@ struct elf_prstatus {
struct target_timeval pr_stime; /* XXX System time */
struct target_timeval pr_cutime; /* XXX Cumulative user time */
struct target_timeval pr_cstime; /* XXX Cumulative system time */
- elf_gregset_t pr_reg; /* GP registers */
+ target_elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* XXX */
};
#define ELF_PRARGSZ (80) /* Number of chars for args */
-struct elf_prpsinfo {
+struct target_elf_prpsinfo {
char pr_state; /* numeric process state */
char pr_sname; /* char for pr_state */
char pr_zomb; /* zombie */
@@ -1821,7 +1845,7 @@ struct elf_prpsinfo {
/* Here is the structure in which status of each thread is captured. */
struct elf_thread_status {
TAILQ_ENTRY(elf_thread_status) ets_link;
- struct elf_prstatus prstatus; /* NT_PRSTATUS */
+ struct target_elf_prstatus prstatus; /* NT_PRSTATUS */
#if 0
elf_fpregset_t fpu; /* NT_PRFPREG */
struct task_struct *thread;
@@ -1833,8 +1857,8 @@ struct elf_thread_status {
struct elf_note_info {
struct memelfnote *notes;
- struct elf_prstatus *prstatus; /* NT_PRSTATUS */
- struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
+ struct target_elf_prstatus *prstatus; /* NT_PRSTATUS */
+ struct target_elf_prpsinfo *psinfo; /* NT_PRPSINFO */
TAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
#if 0
@@ -1876,8 +1900,8 @@ static int vma_walker(void *priv, unsigned long start, unsigned long end,
static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
static void fill_note(struct memelfnote *, const char *, int,
unsigned int, void *);
-static void fill_prstatus(struct elf_prstatus *, const TaskState *, int);
-static int fill_psinfo(struct elf_prpsinfo *, const TaskState *);
+static void fill_prstatus(struct target_elf_prstatus *, const TaskState *, int);
+static int fill_psinfo(struct target_elf_prpsinfo *, const TaskState *);
static void fill_auxv_note(struct memelfnote *, const TaskState *);
static void fill_elf_note_phdr(struct elf_phdr *, int, off_t);
static size_t note_size(const struct memelfnote *);
@@ -1891,10 +1915,10 @@ static int write_note(struct memelfnote *, int);
static int write_note_info(struct elf_note_info *, int);
#ifdef BSWAP_NEEDED
-static void bswap_prstatus(struct elf_prstatus *);
-static void bswap_psinfo(struct elf_prpsinfo *);
+static void bswap_prstatus(struct target_elf_prstatus *);
+static void bswap_psinfo(struct target_elf_prpsinfo *);
-static void bswap_prstatus(struct elf_prstatus *prstatus)
+static void bswap_prstatus(struct target_elf_prstatus *prstatus)
{
prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo);
prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code);
@@ -1911,7 +1935,7 @@ static void bswap_prstatus(struct elf_prstatus *prstatus)
prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
}
-static void bswap_psinfo(struct elf_prpsinfo *psinfo)
+static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
{
psinfo->pr_flag = tswapl(psinfo->pr_flag);
psinfo->pr_uid = tswap16(psinfo->pr_uid);
@@ -2105,7 +2129,7 @@ static size_t note_size(const struct memelfnote *note)
return (note->notesz);
}
-static void fill_prstatus(struct elf_prstatus *prstatus,
+static void fill_prstatus(struct target_elf_prstatus *prstatus,
const TaskState *ts, int signr)
{
(void) memset(prstatus, 0, sizeof (*prstatus));
@@ -2120,7 +2144,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
#endif
}
-static int fill_psinfo(struct elf_prpsinfo *psinfo, const TaskState *ts)
+static int fill_psinfo(struct target_elf_prpsinfo *psinfo, const TaskState *ts)
{
char *filename, *base_filename;
unsigned int i, len;
diff --git a/linux-user/main.c b/linux-user/main.c
index 9038b58e7..4388c04c9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,11 @@
char *exec_path;
int singlestep;
+#if defined(CONFIG_USE_GUEST_BASE)
+unsigned long mmap_min_addr;
+unsigned long guest_base;
+int have_guest_base;
+#endif
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
@@ -2320,6 +2325,9 @@ static void usage(void)
"-E var=value sets/modifies targets environment variable(s)\n"
"-U var unsets targets environment variable(s)\n"
"-0 argv0 forces target process argv[0] to be argv0\n"
+#if defined(CONFIG_USE_GUEST_BASE)
+ "-B address set guest_base address to address\n"
+#endif
"\n"
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
@@ -2495,6 +2503,11 @@ int main(int argc, char **argv, char **envp)
#endif
exit(1);
}
+#if defined(CONFIG_USE_GUEST_BASE)
+ } else if (!strcmp(r, "B")) {
+ guest_base = strtol(argv[optind++], NULL, 0);
+ have_guest_base = 1;
+#endif
} else if (!strcmp(r, "drop-ld-preload")) {
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
} else if (!strcmp(r, "singlestep")) {
@@ -2572,6 +2585,35 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
+#if defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Now that page sizes are configured in cpu_init() we can do
+ * proper page alignment for guest_base.
+ */
+ guest_base = HOST_PAGE_ALIGN(guest_base);
+
+ /*
+ * Read in mmap_min_addr kernel parameter. This value is used
+ * When loading the ELF image to determine whether guest_base
+ * is needed.
+ *
+ * When user has explicitly set the quest base, we skip this
+ * test.
+ */
+ if (!have_guest_base) {
+ FILE *fp;
+
+ if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
+ unsigned long tmp;
+ if (fscanf(fp, "%lu", &tmp) == 1) {
+ mmap_min_addr = tmp;
+ qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
+ }
+ fclose(fp);
+ }
+ }
+#endif /* CONFIG_USE_GUEST_BASE */
+
/*
* Prepare copy of argv vector for target.
*/
@@ -2622,6 +2664,9 @@ int main(int argc, char **argv, char **envp)
free(target_environ);
if (qemu_log_enabled()) {
+#if defined(CONFIG_USE_GUEST_BASE)
+ qemu_log("guest_base 0x%lx\n", guest_base);
+#endif
log_page_dump();
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 79cb4e605..e05caa0a1 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -145,8 +145,8 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
int prot1, ret;
#ifdef DEBUG_MMAP
- printf("mprotect: start=0x" TARGET_FMT_lx
- "len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
+ printf("mprotect: start=0x" TARGET_ABI_FMT_lx
+ "len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
@@ -331,8 +331,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
mmap_lock();
#ifdef DEBUG_MMAP
{
- printf("mmap: start=0x" TARGET_FMT_lx
- " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
+ printf("mmap: start=0x" TARGET_ABI_FMT_lx
+ " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=",
start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
@@ -352,7 +352,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE);
break;
}
- printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset);
+ printf("fd=%d offset=" TARGET_ABI_FMT_lx "\n", fd, offset);
}
#endif
@@ -523,7 +523,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
page_set_flags(start, start + len, prot | PAGE_VALID);
the_end:
#ifdef DEBUG_MMAP
- printf("ret=0x" TARGET_FMT_lx "\n", start);
+ printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);
page_dump(stdout);
printf("\n");
#endif
@@ -540,7 +540,9 @@ int target_munmap(abi_ulong start, abi_ulong len)
int prot, ret;
#ifdef DEBUG_MMAP
- printf("munmap: start=0x%lx len=0x%lx\n", start, len);
+ printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x"
+ TARGET_ABI_FMT_lx "\n",
+ start, len);
#endif
if (start & ~TARGET_PAGE_MASK)
return -EINVAL;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 83ad443c2..8e728a3d2 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -133,6 +133,9 @@ void init_task_state(TaskState *ts);
void task_settid(TaskState *);
void stop_all_tasks(void);
extern const char *qemu_uname_release;
+#if defined(CONFIG_USE_GUEST_BASE)
+extern unsigned long mmap_min_addr;
+#endif
/* ??? See if we can avoid exposing so much of the loader internals. */
/*
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 93c2ebe1e..b2c0623a4 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -584,8 +584,8 @@ int do_sigaction(int sig, const struct target_sigaction *act,
return -EINVAL;
k = &sigact_table[sig - 1];
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
- sig, (int)act, (int)oact);
+ fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
+ sig, act, oact);
#endif
if (oact) {
oact->_sa_handler = tswapl(k->_sa_handler);
@@ -3533,12 +3533,12 @@ struct target_mcontext {
varies depending on whether we're PPC64 or not: PPC64 splits
them apart; PPC32 stuffs them together. */
#if defined(TARGET_PPC64)
-#define NVRREG 34
+#define QEMU_NVRREG 34
#else
-#define NVRREG 33
+#define QEMU_NVRREG 33
#endif
- ppc_avr_t altivec[NVRREG];
-#undef NVRREG
+ ppc_avr_t altivec[QEMU_NVRREG];
+#undef QEMU_NVRREG
} mc_vregs __attribute__((__aligned__(16)));
};
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8b0a5fa3f..7b5732388 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6977,7 +6977,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
fail:
#ifdef DEBUG
- gemu_log(" = %ld\n", ret);
+ gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
#endif
if(do_strace)
print_syscall_ret(num, ret);
diff --git a/loader.c b/loader.c
index 54580e4c5..b5c5914c2 100644
--- a/loader.c
+++ b/loader.c
@@ -272,6 +272,9 @@ static void *load_at(int fd, int offset, int size)
return ptr;
}
+#ifdef ELF_CLASS
+#undef ELF_CLASS
+#endif
#define ELF_CLASS ELFCLASS32
#include "elf.h"
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 7747e2733..68a684277 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2026,7 +2026,7 @@ qemu-i386 /usr/local/qemu-i386/wine/bin/wine \
@subsection Command line options
@example
-usage: qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g port] program [arguments...]
+usage: qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g port] [-B offset] program [arguments...]
@end example
@table @option
@@ -2038,6 +2038,10 @@ Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
Set the x86 stack size in bytes (default=524288)
@item -cpu model
Select CPU model (-cpu ? for list and additional feature selection)
+@item -B offset
+Offset guest address by the specified number of bytes. This is useful when
+the address region rewuired by guest applications is reserved on the host.
+Ths option is currently only supported on some hosts.
@end table
Debug options:
diff --git a/qemu-img.c b/qemu-img.c
index d806cfa19..070fe2e22 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -747,14 +747,20 @@ static int img_convert(int argc, char **argv)
n = bs_offset + bs_sectors - sector_num;
if (strcmp(drv->format_name, "host_device")) {
- if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
- n, &n1)) {
- sector_num += n1;
- continue;
+ /* If the output image is being created as a copy on write image,
+ assume that sectors which are unallocated in the input image
+ are present in both the output's and input's base images (no
+ need to copy them). */
+ if (out_baseimg) {
+ if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
+ n, &n1)) {
+ sector_num += n1;
+ continue;
+ }
+ /* The next 'n1' sectors are allocated in the input image. Copy
+ only those as they may be followed by unallocated sectors. */
+ n = n1;
}
- /* The next 'n1' sectors are allocated in the input image. Copy
- only those as they may be followed by unallocated sectors. */
- n = n1;
} else {
n1 = n;
}
diff --git a/qemu-io.c b/qemu-io.c
index 6c35a071c..029ee0b6e 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -26,6 +26,26 @@ static BlockDriverState *bs;
static int misalign;
/*
+ * Parse the pattern argument to various sub-commands.
+ *
+ * Because the pattern is used as an argument to memset it must evaluate
+ * to an unsigned integer that fits into a single byte.
+ */
+static int parse_pattern(const char *arg)
+{
+ char *endptr = NULL;
+ long pattern;
+
+ pattern = strtol(arg, &endptr, 0);
+ if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
+ printf("%s is not a valid pattern byte\n", arg);
+ return -1;
+ }
+
+ return pattern;
+}
+
+/*
* Memory allocation helpers.
*
* Make sure memory is aligned by default, or purposefully misaligned if
@@ -304,7 +324,9 @@ read_f(int argc, char **argv)
break;
case 'P':
Pflag = 1;
- pattern = atoi(optarg);
+ pattern = parse_pattern(optarg);
+ if (pattern < 0)
+ return 0;
break;
case 'q':
qflag = 1;
@@ -469,7 +491,9 @@ readv_f(int argc, char **argv)
break;
case 'P':
Pflag = 1;
- pattern = atoi(optarg);
+ pattern = parse_pattern(optarg);
+ if (pattern < 0)
+ return 0;
break;
case 'q':
qflag = 1;
@@ -594,7 +618,9 @@ write_f(int argc, char **argv)
pflag = 1;
break;
case 'P':
- pattern = atoi(optarg);
+ pattern = parse_pattern(optarg);
+ if (pattern < 0)
+ return 0;
break;
case 'q':
qflag = 1;
@@ -721,7 +747,9 @@ writev_f(int argc, char **argv)
qflag = 1;
break;
case 'P':
- pattern = atoi(optarg);
+ pattern = parse_pattern(optarg);
+ if (pattern < 0)
+ return 0;
break;
default:
return command_usage(&writev_cmd);
@@ -895,7 +923,9 @@ aio_read_f(int argc, char **argv)
break;
case 'P':
ctx->Pflag = 1;
- ctx->pattern = atoi(optarg);
+ ctx->pattern = parse_pattern(optarg);
+ if (ctx->pattern < 0)
+ return 0;
break;
case 'q':
ctx->qflag = 1;
@@ -995,7 +1025,9 @@ aio_write_f(int argc, char **argv)
ctx->qflag = 1;
break;
case 'P':
- pattern = atoi(optarg);
+ pattern = parse_pattern(optarg);
+ if (pattern < 0)
+ return 0;
break;
default:
free(ctx);
@@ -1170,11 +1202,10 @@ static int
alloc_f(int argc, char **argv)
{
int64_t offset;
- int nb_sectors;
+ int nb_sectors, remaining;
char s1[64];
- int num;
+ int num, sum_alloc;
int ret;
- const char *retstr;
offset = cvtnum(argv[1]);
if (offset & 0x1ff) {
@@ -1188,16 +1219,23 @@ alloc_f(int argc, char **argv)
else
nb_sectors = 1;
- ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
+ remaining = nb_sectors;
+ sum_alloc = 0;
+ while (remaining) {
+ ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
+ remaining -= num;
+ if (ret) {
+ sum_alloc += num;
+ }
+ }
cvtstr(offset, s1, sizeof(s1));
- retstr = ret ? "allocated" : "not allocated";
if (nb_sectors == 1)
- printf("sector %s at offset %s\n", retstr, s1);
+ printf("sector allocated at offset %s\n", s1);
else
- printf("%d/%d sectors %s at offset %s\n",
- num, nb_sectors, retstr, s1);
+ printf("%d/%d sectors allocated at offset %s\n",
+ sum_alloc, nb_sectors, s1);
return 0;
}
diff --git a/qemu-tool.c b/qemu-tool.c
index c08f061be..ba24aa2a1 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -15,11 +15,14 @@
#include "monitor.h"
#include "sysemu.h"
#include "qemu-timer.h"
+#include "qemu-log.h"
#include <sys/time.h>
QEMUClock *rt_clock;
+FILE *logfile;
+
struct QEMUBH
{
QEMUBHFunc *cb;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c819ef2c0..4785ff0d7 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -299,7 +299,7 @@ static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
static int cpu_x86_fill_model_id(char *str)
{
- uint32_t eax, ebx, ecx, edx;
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
int i;
for (i = 0; i < 3; i++) {
@@ -360,11 +360,10 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
break;
}
}
- if (!def) {
- if (strcmp(name, "host") != 0) {
- goto error;
- }
+ if (kvm_enabled() && strcmp(name, "host") == 0) {
cpu_x86_fill_host(x86_cpu_def);
+ } else if (!def) {
+ goto error;
} else {
memcpy(x86_cpu_def, def, sizeof(*def));
}
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 91bdaf3d1..6ffe9ce1c 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -559,18 +559,18 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
}
if (ret < 0) {
#if defined(DEBUG_BATS)
- if (IS_LOGGING) {
- QEMU_LOG0("no BAT match for " ADDRX ":\n", virtual);
+ if (qemu_log_enabled()) {
+ LOG_BATS("no BAT match for " ADDRX ":\n", virtual);
for (i = 0; i < 4; i++) {
BATu = &BATut[i];
BATl = &BATlt[i];
BEPIu = *BATu & 0xF0000000;
BEPIl = *BATu & 0x0FFE0000;
bl = (*BATu & 0x00001FFC) << 15;
- QEMU_LOG0("%s: %cBAT%d v " ADDRX " BATu " ADDRX
- " BATl " ADDRX " \n\t" ADDRX " " ADDRX " " ADDRX "\n",
- __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
- *BATu, *BATl, BEPIu, BEPIl, bl);
+ LOG_BATS("%s: %cBAT%d v " ADDRX " BATu " ADDRX
+ " BATl " ADDRX " \n\t" ADDRX " " ADDRX " " ADDRX "\n",
+ __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
+ *BATu, *BATl, BEPIu, BEPIl, bl);
}
}
#endif
@@ -861,8 +861,8 @@ void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
slb->tmp = (vsid << 8) | (flags << 3);
LOG_SLB("%s: %d " ADDRX " - " ADDRX " => %016" PRIx64
- " %08" PRIx32 "\n", __func__,
- slb_nr, rb, rs, tmp64, tmp);
+ " %08" PRIx32 "\n", __func__,
+ slb_nr, rb, rs, slb->tmp64, slb->tmp);
slb_set_entry(env, slb_nr, slb);
}
@@ -2446,7 +2446,7 @@ static always_inline void powerpc_excp (CPUState *env,
tlb_miss:
#if defined (DEBUG_SOFTWARE_TLB)
if (qemu_log_enabled()) {
- const unsigned char *es;
+ const char *es;
target_ulong *miss, *cmp;
int en;
if (excp == POWERPC_EXCP_IFTLB) {
@@ -2479,7 +2479,7 @@ static always_inline void powerpc_excp (CPUState *env,
tlb_miss_74xx:
#if defined (DEBUG_SOFTWARE_TLB)
if (qemu_log_enabled()) {
- const unsigned char *es;
+ const char *es;
target_ulong *miss, *cmp;
int en;
if (excp == POWERPC_EXCP_IFTLB) {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index acbb1abd2..b53d6e99a 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -44,7 +44,13 @@ int kvm_arch_init(KVMState *s, int smp_cpus)
int kvm_arch_init_vcpu(CPUState *cenv)
{
- return 0;
+ int ret = 0;
+ struct kvm_sregs sregs;
+
+ sregs.pvr = cenv->spr[SPR_PVR];
+ ret = kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
+
+ return ret;
}
int kvm_arch_put_registers(CPUState *env)
@@ -118,6 +124,14 @@ int kvm_arch_get_registers(CPUState *env)
return 0;
}
+#if defined(TARGET_PPCEMB)
+#define PPC_INPUT_INT PPC40x_INPUT_INT
+#elif defined(TARGET_PPC64)
+#define PPC_INPUT_INT PPC970_INPUT_INT
+#else
+#define PPC_INPUT_INT PPC6xx_INPUT_INT
+#endif
+
int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
{
int r;
@@ -127,7 +141,7 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
* interrupt, reset, etc) in PPC-specific env->irq_input_state. */
if (run->ready_for_interrupt_injection &&
(env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->irq_input_state & (1<<PPC40x_INPUT_INT)))
+ (env->irq_input_state & (1<<PPC_INPUT_INT)))
{
/* For now KVM disregards the 'irq' argument. However, in the
* future KVM could cache it in-kernel to avoid a heavyweight exit
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 04513f82d..5951e6b5c 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -583,15 +583,15 @@ void dump_mmu(CPUState *env)
break;
}
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
- printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
+ printf("VA: %" PRIx64 ", PA: %" PRIx64
", %s, %s, %s, %s, ctx %" PRId64 "\n",
- env->dtlb_tag[i] & ~0x1fffULL,
- env->dtlb_tte[i] & 0x1ffffffe000ULL,
+ env->dtlb_tag[i] & (uint64_t)~0x1fffULL,
+ env->dtlb_tte[i] & (uint64_t)0x1ffffffe000ULL,
mask,
env->dtlb_tte[i] & 0x4? "priv": "user",
env->dtlb_tte[i] & 0x2? "RW": "RO",
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
- env->dtlb_tag[i] & 0x1fffULL);
+ env->dtlb_tag[i] & (uint64_t)0x1fffULL);
}
}
}
@@ -616,14 +616,14 @@ void dump_mmu(CPUState *env)
break;
}
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
- printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
+ printf("VA: %" PRIx64 ", PA: %" PRIx64
", %s, %s, %s, ctx %" PRId64 "\n",
- env->itlb_tag[i] & ~0x1fffULL,
- env->itlb_tte[i] & 0x1ffffffe000ULL,
+ env->itlb_tag[i] & (uint64_t)~0x1fffULL,
+ env->itlb_tte[i] & (uint64_t)0x1ffffffe000ULL,
mask,
env->itlb_tte[i] & 0x4? "priv": "user",
env->itlb_tte[i] & 0x40? "locked": "unlocked",
- env->itlb_tag[i] & 0x1fffULL);
+ env->itlb_tag[i] & (uint64_t)0x1fffULL);
}
}
}
@@ -1314,7 +1314,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
}
cpu_def->fpu_version = fpu_version;
#ifdef DEBUG_FEATURES
- fprintf(stderr, "fpu_version %llx\n", fpu_version);
+ fprintf(stderr, "fpu_version %x\n", fpu_version);
#endif
} else if (!strcmp(featurestr, "mmu_version")) {
char *err;
@@ -1326,7 +1326,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
}
cpu_def->mmu_version = mmu_version;
#ifdef DEBUG_FEATURES
- fprintf(stderr, "mmu_version %llx\n", mmu_version);
+ fprintf(stderr, "mmu_version %x\n", mmu_version);
#endif
} else if (!strcmp(featurestr, "nwindows")) {
char *err;
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index d25b642c0..739ed9abd 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1212,11 +1212,14 @@ GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
defined(DEBUG_MXCC)
static void dump_mxcc(CPUState *env)
{
- printf("mxccdata: %016llx %016llx %016llx %016llx\n",
+ printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
+ "\n",
env->mxccdata[0], env->mxccdata[1],
env->mxccdata[2], env->mxccdata[3]);
- printf("mxccregs: %016llx %016llx %016llx %016llx\n"
- " %016llx %016llx %016llx %016llx\n",
+ printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
+ "\n"
+ " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
+ "\n",
env->mxccregs[0], env->mxccregs[1],
env->mxccregs[2], env->mxccregs[3],
env->mxccregs[4], env->mxccregs[5],
@@ -1455,7 +1458,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
env->mmubpregs[reg] = 0ULL;
break;
}
- DPRINTF_MMU("read breakpoint reg[%d] 0x%016llx\n", reg, ret);
+ DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg,
+ ret);
}
break;
case 8: /* User code access, XXX */
@@ -1808,7 +1812,7 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
env->mmubpregs[reg] = (val & 0xfULL);
break;
}
- DPRINTF_MMU("write breakpoint reg[%d] 0x%016llx\n", reg,
+ DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
env->mmuregs[reg]);
}
break;
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 8139da10c..7ef2b898a 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -100,6 +100,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
ct_str = *pct_str;
switch (ct_str[0]) {
+ case 'I':
+ ct->ct |= TCG_CT_CONST_ARM;
+ break;
+
case 'r':
#ifndef CONFIG_SOFTMMU
case 'd':
@@ -175,6 +179,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
return 0;
}
+
+static inline int check_fit_imm(uint32_t imm)
+{
+ /* XXX: use rotation */
+ return (imm & ~0xff) == 0;
+}
+
/* Test if a constant matches the constraint.
* TODO: define constraints for:
*
@@ -190,6 +201,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
ct = arg_ct->ct;
if (ct & TCG_CT_CONST)
return 1;
+ else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val))
+ return 1;
else
return 0;
}
@@ -333,6 +346,16 @@ static inline void tcg_out_movi32(TCGContext *s,
tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) :
tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset);
+#ifdef __ARM_ARCH_7A__
+ /* use movw/movt */
+ /* movw */
+ tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
+ | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
+ if (arg & 0xffff0000)
+ /* movt */
+ tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
+ | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
+#else
tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff);
if (arg & 0x0000ff00)
tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd,
@@ -343,6 +366,7 @@ static inline void tcg_out_movi32(TCGContext *s,
if (arg & 0xff000000)
tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd,
((arg >> 24) & 0xff) | 0x400);
+#endif
}
static inline void tcg_out_mul32(TCGContext *s,
@@ -990,7 +1014,22 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
+#else /* !CONFIG_SOFTMMU */
+ if (GUEST_BASE) {
+ uint32_t offset = GUEST_BASE;
+ int i;
+ int rot;
+
+ while (offset) {
+ i = ctz32(offset) & ~1;
+ rot = ((32 - i) << 7) & 0xf00;
+
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ ((offset >> i) & 0xff) | rot);
+ addr_reg = 8;
+ offset &= ~(0xff << i);
+ }
+ }
switch (opc) {
case 0:
tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
@@ -1200,7 +1239,22 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
# endif
*label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
+#else /* !CONFIG_SOFTMMU */
+ if (GUEST_BASE) {
+ uint32_t offset = GUEST_BASE;
+ int i;
+ int rot;
+
+ while (offset) {
+ i = ctz32(offset) & ~1;
+ rot = ((32 - i) << 7) & 0xf00;
+
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
+ ((offset >> i) & 0xff) | rot);
+ addr_reg = 8;
+ offset &= ~(0xff << i);
+ }
+ }
switch (opc) {
case 0:
tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
@@ -1353,8 +1407,12 @@ static inline void tcg_out_op(TCGContext *s, int opc,
c = ARITH_EOR;
/* Fall through. */
gen_arith:
- tcg_out_dat_reg(s, COND_AL, c,
- args[0], args[1], args[2], SHIFT_IMM_LSL(0));
+ if (const_args[2])
+ tcg_out_dat_imm(s, COND_AL, c,
+ args[0], args[1], args[2]);
+ else
+ tcg_out_dat_reg(s, COND_AL, c,
+ args[0], args[1], args[2], SHIFT_IMM_LSL(0));
break;
case INDEX_op_add2_i32:
tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC,
@@ -1493,15 +1551,15 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_st_i32, { "r", "r" } },
/* TODO: "r", "r", "ri" */
- { INDEX_op_add_i32, { "r", "r", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "r" } },
+ { INDEX_op_add_i32, { "r", "r", "rI" } },
+ { INDEX_op_sub_i32, { "r", "r", "rI" } },
{ INDEX_op_mul_i32, { "r", "r", "r" } },
{ INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
{ INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } },
{ INDEX_op_divu2_i32, { "r", "r", "r", "1", "2" } },
- { INDEX_op_and_i32, { "r", "r", "r" } },
- { INDEX_op_or_i32, { "r", "r", "r" } },
- { INDEX_op_xor_i32, { "r", "r", "r" } },
+ { INDEX_op_and_i32, { "r", "r", "rI" } },
+ { INDEX_op_or_i32, { "r", "r", "rI" } },
+ { INDEX_op_xor_i32, { "r", "r", "rI" } },
{ INDEX_op_neg_i32, { "r", "r" } },
{ INDEX_op_shl_i32, { "r", "r", "ri" } },
@@ -1567,7 +1625,7 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
tcg_out_st32(s, COND_AL, arg, arg1, arg2);
}
-void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
{
if (val > 0)
if (val < 0x100)
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8f5016fc4..7ff29281b 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -51,14 +51,19 @@ enum {
TCG_REG_R12,
TCG_REG_R13,
TCG_REG_R14,
- TCG_TARGET_NB_REGS
};
+#define TCG_TARGET_NB_REGS 15
+
+#define TCG_CT_CONST_ARM 0x100
+
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_R13
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 0
+#define TCG_TARGET_HAS_GUEST_BASE
+
enum {
/* Note: must be synced with dyngen-exec.h */
TCG_AREG0 = TCG_REG_R7,
@@ -69,8 +74,7 @@ enum {
static inline void flush_icache_range(unsigned long start, unsigned long stop)
{
#if QEMU_GNUC_PREREQ(4, 1)
- void __clear_cache(char *beg, char *end);
- __clear_cache((char *) start, (char *) stop);
+ __builtin___clear_cache((char *) start, (char *) stop);
#else
register unsigned long _beg __asm ("a1") = start;
register unsigned long _end __asm ("a2") = stop;
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index e0fd43462..a95fe4c20 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -427,6 +427,10 @@ static void *qemu_st_helpers[4] = {
};
#endif
+#ifndef CONFIG_USER_ONLY
+#define GUEST_BASE 0
+#endif
+
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
EAX. It will be useful once fixed registers globals are less
common. */
@@ -572,15 +576,15 @@ 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, 0);
+ tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, GUEST_BASE);
break;
case 0 | 4:
/* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, GUEST_BASE);
break;
case 1:
/* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, GUEST_BASE);
if (bswap) {
/* rolw $8, data_reg */
tcg_out8(s, 0x66);
@@ -590,7 +594,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
break;
case 1 | 4:
/* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, GUEST_BASE);
if (bswap) {
/* rolw $8, data_reg */
tcg_out8(s, 0x66);
@@ -603,7 +607,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
break;
case 2:
/* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE);
if (bswap) {
/* bswap */
tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
@@ -619,13 +623,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
r0 = r1;
}
if (!bswap) {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4);
+ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, GUEST_BASE + 4);
} else {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4);
+ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE + 4);
tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0);
+ tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, GUEST_BASE);
/* bswap */
tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT);
}
@@ -806,7 +810,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
switch(opc) {
case 0:
/* movb */
- tcg_out_modrm_offset(s, 0x88, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x88, data_reg, r0, GUEST_BASE);
break;
case 1:
if (bswap) {
@@ -818,7 +822,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
}
/* movw */
tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
break;
case 2:
if (bswap) {
@@ -828,21 +832,21 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
data_reg = r1;
}
/* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
break;
case 3:
if (bswap) {
tcg_out_mov(s, r1, data_reg2);
/* bswap data_reg */
tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 0);
+ tcg_out_modrm_offset(s, 0x89, r1, r0, GUEST_BASE);
tcg_out_mov(s, r1, data_reg);
/* bswap data_reg */
tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 4);
+ tcg_out_modrm_offset(s, 0x89, r1, r0, GUEST_BASE + 4);
} else {
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x89, data_reg2, r0, 4);
+ tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
+ tcg_out_modrm_offset(s, 0x89, data_reg2, r0, GUEST_BASE + 4);
}
break;
default:
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 301a5bf14..461ef315c 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -53,6 +53,8 @@ enum {
#define TCG_TARGET_HAS_ext16s_i32
#define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_GUEST_BASE
+
/* Note: must be synced with dyngen-exec.h */
#define TCG_AREG0 TCG_REG_EBP
#define TCG_AREG1 TCG_REG_EBX
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index e3f4b598c..240928899 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -42,6 +42,16 @@ static uint8_t *tb_ret_addr;
#define ADDEND_OFFSET 4
#endif
+#ifndef GUEST_BASE
+#define GUEST_BASE 0
+#endif
+
+#ifdef CONFIG_USE_GUEST_BASE
+#define TCG_GUEST_BASE_REG 30
+#else
+#define TCG_GUEST_BASE_REG 0
+#endif
+
#ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"r0",
@@ -357,7 +367,7 @@ static int tcg_target_const_match(tcg_target_long val,
#define NEG XO31(104)
#define LBZX XO31( 87)
-#define LHZX XO31(276)
+#define LHZX XO31(279)
#define LHAX XO31(343)
#define LWZX XO31( 23)
#define STBX XO31(215)
@@ -501,7 +511,7 @@ static void *qemu_st_helpers[4] = {
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
+ int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
#ifdef CONFIG_SOFTMMU
int r2;
void *label1_ptr, *label2_ptr;
@@ -526,6 +536,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
r0 = 3;
r1 = 4;
r2 = 0;
+ rbase = 0;
tcg_out32 (s, (RLWINM
| RA (r0)
@@ -631,6 +642,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
#else /* !CONFIG_SOFTMMU */
r0 = addr_reg;
r1 = 3;
+ rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -638,37 +650,47 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
#else
bswap = 1;
#endif
+
switch (opc) {
default:
case 0:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
+ tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
break;
case 0|4:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
+ tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
break;
case 1:
- if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
break;
case 1|4:
if (bswap) {
- tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
+ tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
}
- else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
+ else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
break;
case 2:
- if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
+ if (bswap)
+ tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
break;
case 3:
if (bswap) {
- tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- tcg_out32 (s, LWBRX | RT (data_reg2) | RB (r1));
+ tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
+ tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
+ tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
}
else {
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
+ tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
+ tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
+#else
if (r0 == data_reg2) {
tcg_out32 (s, LWZ | RT (0) | RA (r0));
tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
@@ -678,6 +700,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
}
+#endif
}
break;
}
@@ -689,7 +712,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap;
+ int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
#ifdef CONFIG_SOFTMMU
int r2, ir;
void *label1_ptr, *label2_ptr;
@@ -713,6 +736,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
r0 = 3;
r1 = 4;
r2 = 0;
+ rbase = 0;
tcg_out32 (s, (RLWINM
| RA (r0)
@@ -819,8 +843,9 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
/* r0 = env->tlb_table[mem_index][index].addend + addr */
#else /* !CONFIG_SOFTMMU */
- r1 = 3;
r0 = addr_reg;
+ r1 = 3;
+ rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -830,25 +855,35 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
#endif
switch (opc) {
case 0:
- tcg_out32 (s, STB | RS (data_reg) | RA (r0));
+ tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
break;
case 1:
- if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
break;
case 2:
- if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
break;
case 3:
if (bswap) {
tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- tcg_out32 (s, STWBRX | RS (data_reg2) | RA (0) | RB (r1));
+ tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
+ tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
}
else {
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
+ tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
+ tcg_out32 (s, STWX | SAB (data_reg, rbase, r1));
+#else
tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
+#endif
}
break;
}
@@ -890,6 +925,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
);
tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
+#endif
+
tcg_out32 (s, MTSPR | RS (3) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
tb_ret_addr = s->code_ptr;
@@ -1532,6 +1571,9 @@ void tcg_target_init(TCGContext *s)
#ifdef __linux__
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
#endif
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+#endif
tcg_add_target_add_op_defs(ppc_op_defs);
}
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 5faf73024..0197e7993 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -85,3 +85,5 @@ enum {
#define TCG_AREG0 TCG_REG_R27
#define TCG_AREG1 TCG_REG_R24
#define TCG_AREG2 TCG_REG_R25
+
+#define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index a2f85ffc6..1bb13e6b0 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -42,6 +42,16 @@ static uint8_t *tb_ret_addr;
#define CMP_L (1<<21)
#endif
+#ifndef GUEST_BASE
+#define GUEST_BASE 0
+#endif
+
+#ifdef CONFIG_USE_GUEST_BASE
+#define TCG_GUEST_BASE_REG 30
+#else
+#define TCG_GUEST_BASE_REG 0
+#endif
+
#ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"r0",
@@ -349,7 +359,7 @@ static int tcg_target_const_match (tcg_target_long val,
#define DIVDU XO31(457)
#define LBZX XO31( 87)
-#define LHZX XO31(276)
+#define LHZX XO31(279)
#define LHAX XO31(343)
#define LWZX XO31( 23)
#define STBX XO31(215)
@@ -588,7 +598,7 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
+ int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
#ifdef CONFIG_SOFTMMU
int r2;
void *label1_ptr, *label2_ptr;
@@ -603,6 +613,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
r0 = 3;
r1 = 4;
r2 = 0;
+ rbase = 0;
tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
offsetof (CPUState, tlb_table[mem_index][0].addr_read));
@@ -663,6 +674,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
#endif
r0 = addr_reg;
r1 = 3;
+ rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -673,35 +685,48 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
switch (opc) {
default:
case 0:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
+ tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
break;
case 0|4:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
+ tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
break;
case 1:
- if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
break;
case 1|4:
if (bswap) {
- tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
+ tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
}
- else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
+ else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
break;
case 2:
- if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
+ if (bswap)
+ tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
break;
case 2|4:
if (bswap) {
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
+ tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
}
- else tcg_out32 (s, LWA | RT (data_reg)| RA (r0));
+ else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
break;
case 3:
+#ifdef CONFIG_USE_GUEST_BASE
+ if (bswap) {
+ tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
+ tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
+ tcg_out32 (s, LWBRX | TAB ( r1, rbase, r1));
+ tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
+ }
+ else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
+#else
if (bswap) {
tcg_out_movi32 (s, 0, 4);
tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
@@ -709,6 +734,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
}
else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
+#endif
break;
}
@@ -719,7 +745,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
{
- int addr_reg, r0, r1, data_reg, mem_index, bswap;
+ int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
#ifdef CONFIG_SOFTMMU
int r2;
void *label1_ptr, *label2_ptr;
@@ -733,6 +759,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
r0 = 3;
r1 = 4;
r2 = 0;
+ rbase = 0;
tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
offsetof (CPUState, tlb_table[mem_index][0].addr_write));
@@ -775,6 +802,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
#endif
r1 = 3;
r0 = addr_reg;
+ rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -784,24 +812,28 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
#endif
switch (opc) {
case 0:
- tcg_out32 (s, STB | RS (data_reg) | RA (r0));
+ tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
break;
case 1:
- if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
break;
case 2:
- if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
+ if (bswap)
+ tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
+ else
+ tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
break;
case 3:
if (bswap) {
- tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
+ tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
- tcg_out32 (s, STWBRX | RS (0) | RA (0) | RB (r1));
+ tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
}
- else tcg_out32 (s, STD | RS (data_reg) | RA (r0));
+ else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
break;
}
@@ -844,6 +876,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
);
tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
+#endif
+
tcg_out32 (s, MTSPR | RS (3) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
@@ -1498,5 +1534,9 @@ void tcg_target_init (TCGContext *s)
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
+#ifdef CONFIG_USE_GUEST_BASE
+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+#endif
+
tcg_add_target_add_op_defs (ppc_op_defs);
}
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 452bfdadc..94b800fa6 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -81,3 +81,5 @@ enum {
#define TCG_AREG0 TCG_REG_R27
#define TCG_AREG1 TCG_REG_R24
#define TCG_AREG2 TCG_REG_R25
+
+#define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index daeb025a6..f3f2f711f 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1749,7 +1749,7 @@ static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
- tcg_gen_shl_i64(t0, arg1, arg2);
+ tcg_gen_shr_i64(t0, arg1, arg2);
tcg_gen_subfi_i64(t1, 64, arg2);
tcg_gen_shl_i64(t1, arg1, t1);
tcg_gen_or_i64(ret, t0, t1);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 299bff6f0..0ba1b6a3e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -46,6 +46,7 @@
#include "qemu-common.h"
#include "cache-utils.h"
+#include "host-utils.h"
/* Note: the long term plan is to reduce the dependancies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st
@@ -57,6 +58,9 @@
#include "tcg-op.h"
#include "elf.h"
+#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
+#error GUEST_BASE not supported on this host.
+#endif
static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend);
@@ -1862,7 +1866,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
static int64_t tcg_table_op_count[NB_OPS];
-void dump_op_count(void)
+static void dump_op_count(void)
{
int i;
FILE *f;
@@ -2070,10 +2074,8 @@ void tcg_dump_info(FILE *f,
s->restore_count);
cpu_fprintf(f, " avg cycles %0.1f\n",
s->restore_count ? (double)s->restore_time / s->restore_count : 0);
- {
- extern void dump_op_count(void);
- dump_op_count();
- }
+
+ dump_op_count();
}
#else
void tcg_dump_info(FILE *f,
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c
index 5378e8510..9facb01e4 100644
--- a/tcg/x86_64/tcg-target.c
+++ b/tcg/x86_64/tcg-target.c
@@ -508,6 +508,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int opc)
{
int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
+ int32_t offset;
#if defined(CONFIG_SOFTMMU)
uint8_t *label1_ptr, *label2_ptr;
#endif
@@ -604,8 +605,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_read));
+ offset = 0;
#else
- r0 = addr_reg;
+ if (GUEST_BASE == (int32_t)GUEST_BASE) {
+ r0 = addr_reg;
+ offset = GUEST_BASE;
+ } else {
+ offset = 0;
+ /* movq $GUEST_BASE, r0 */
+ tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0);
+ tcg_out32(s, GUEST_BASE);
+ tcg_out32(s, GUEST_BASE >> 32);
+ /* addq addr_reg, r0 */
+ tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0);
+ }
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -616,15 +629,15 @@ 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, 0);
+ tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, offset);
break;
case 0 | 4:
/* movsbX */
- tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, offset);
break;
case 1:
/* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
if (bswap) {
/* rolw $8, data_reg */
tcg_out8(s, 0x66);
@@ -635,7 +648,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
case 1 | 4:
if (bswap) {
/* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
/* rolw $8, data_reg */
tcg_out8(s, 0x66);
tcg_out_modrm(s, 0xc1, 0, data_reg);
@@ -645,12 +658,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg);
} else {
/* movswX */
- tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, offset);
}
break;
case 2:
/* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
if (bswap) {
/* bswap */
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
@@ -659,19 +672,19 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
case 2 | 4:
if (bswap) {
/* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
/* bswap */
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
/* movslq */
tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg);
} else {
/* movslq */
- tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, offset);
}
break;
case 3:
/* movq (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, offset);
if (bswap) {
/* bswap */
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0);
@@ -691,6 +704,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
int opc)
{
int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
+ int32_t offset;
#if defined(CONFIG_SOFTMMU)
uint8_t *label1_ptr, *label2_ptr;
#endif
@@ -775,8 +789,20 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_write));
+ offset = 0;
#else
- r0 = addr_reg;
+ if (GUEST_BASE == (int32_t)GUEST_BASE) {
+ r0 = addr_reg;
+ offset = GUEST_BASE;
+ } else {
+ offset = 0;
+ /* movq $GUEST_BASE, r0 */
+ tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0);
+ tcg_out32(s, GUEST_BASE);
+ tcg_out32(s, GUEST_BASE >> 32);
+ /* addq addr_reg, r0 */
+ tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0);
+ }
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -787,7 +813,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
switch(opc) {
case 0:
/* movb */
- tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, offset);
break;
case 1:
if (bswap) {
@@ -799,7 +825,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
}
/* movw */
tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
break;
case 2:
if (bswap) {
@@ -809,7 +835,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
data_reg = r1;
}
/* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
break;
case 3:
if (bswap) {
@@ -819,7 +845,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
data_reg = r1;
}
/* movq */
- tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
+ tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, offset);
break;
default:
tcg_abort();
diff --git a/tcg/x86_64/tcg-target.h b/tcg/x86_64/tcg-target.h
index 8cb05c632..8d47e7873 100644
--- a/tcg/x86_64/tcg-target.h
+++ b/tcg/x86_64/tcg-target.h
@@ -73,6 +73,8 @@ enum {
#define TCG_TARGET_HAS_rot_i32
#define TCG_TARGET_HAS_rot_i64
+#define TCG_TARGET_HAS_GUEST_BASE
+
/* Note: must be synced with dyngen-exec.h */
#define TCG_AREG0 TCG_REG_R14
#define TCG_AREG1 TCG_REG_R15
diff --git a/vl.c b/vl.c
index 39e96a779..143dbb527 100644
--- a/vl.c
+++ b/vl.c
@@ -31,6 +31,8 @@
/* Needed early for HOST_BSD etc. */
#include "config-host.h"
+/* Needed early to override system queue definitions on BSD */
+#include "sys-queue.h"
#ifndef _WIN32
#include <libgen.h>