aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.objs6
-rw-r--r--VERSION2
-rw-r--r--arch_init.c11
-rw-r--r--block/sheepdog.c1
-rwxr-xr-xconfigure113
-rw-r--r--dma-helpers.c4
-rw-r--r--exec.c21
-rw-r--r--hw/alpha_typhoon.c26
-rw-r--r--hw/boards.h3
-rw-r--r--hw/bonito.c152
-rw-r--r--hw/dec_pci.c31
-rw-r--r--hw/dec_pci.h2
-rw-r--r--hw/grackle_pci.c65
-rw-r--r--hw/gt64xxx.c67
-rw-r--r--hw/i82378.c1
-rw-r--r--hw/msix.c8
-rw-r--r--hw/pc.c31
-rw-r--r--hw/pc_piix.c4
-rw-r--r--hw/pci_host.c12
-rw-r--r--hw/pci_host.h5
-rw-r--r--hw/piix_pci.c22
-rw-r--r--hw/ppc440_bamboo.c3
-rw-r--r--hw/ppc4xx.h2
-rw-r--r--hw/ppc4xx_pci.c27
-rw-r--r--hw/ppc_mac.h1
-rw-r--r--hw/ppc_prep.c4
-rw-r--r--hw/ppce500_pci.c24
-rw-r--r--hw/prep_pci.c33
-rw-r--r--hw/scsi-bus.c2
-rw-r--r--hw/spapr.c13
-rw-r--r--hw/spapr_pci.c94
-rw-r--r--hw/spapr_pci.h7
-rw-r--r--hw/unin_pci.c185
-rw-r--r--hw/virtio-blk.c1
-rw-r--r--hw/virtio-blk.h3
-rw-r--r--iohandler.c1
-rw-r--r--json-parser.c230
-rw-r--r--linux-user/syscall.c4
-rw-r--r--osdep.c8
-rw-r--r--osdep.h7
-rw-r--r--pc-bios/README2
-rw-r--r--pc-bios/openbios-ppcbin729876 -> 729876 bytes
-rw-r--r--pc-bios/openbios-sparc32bin381764 -> 381764 bytes
-rw-r--r--pc-bios/openbios-sparc64bin1598648 -> 1598648 bytes
-rw-r--r--qapi-schema.json39
-rw-r--r--qemu-char.c7
-rw-r--r--qemu-config.c18
-rw-r--r--qemu-config.h1
-rw-r--r--qemu-ga.c3
-rw-r--r--qemu-options.hx15
-rw-r--r--qemu-seccomp.c141
-rw-r--r--qemu-seccomp.h22
-rw-r--r--qlist.c13
-rw-r--r--qlist.h1
-rw-r--r--qmp-commands.hx5
-rw-r--r--rules.mak2
-rw-r--r--softmmu-semi.h5
-rw-r--r--sysemu.h1
-rw-r--r--target-arm/arm-semi.c13
-rw-r--r--tests/check-qjson.c53
-rw-r--r--vl.c53
61 files changed, 1146 insertions, 484 deletions
diff --git a/Makefile.objs b/Makefile.objs
index 309d066286..4412757309 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -97,6 +97,12 @@ common-obj-y += qemu-timer.o qemu-timer-common.o
common-obj-$(CONFIG_SLIRP) += slirp/
######################################################################
+# libseccomp
+ifeq ($(CONFIG_SECCOMP),y)
+common-obj-y += qemu-seccomp.o
+endif
+
+######################################################################
# libuser
user-obj-y =
diff --git a/VERSION b/VERSION
index da44c7f348..69658cdda2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.50
+1.1.90
diff --git a/arch_init.c b/arch_init.c
index 9b46bfcaa5..5a1173e29a 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -44,6 +44,7 @@
#include "exec-memory.h"
#include "hw/pcspk.h"
#include "qemu/page_cache.h"
+#include "qmp-commands.h"
#ifdef DEBUG_ARCH_INIT
#define DPRINTF(fmt, ...) \
@@ -1080,3 +1081,13 @@ int xen_available(void)
return 0;
#endif
}
+
+
+TargetInfo *qmp_query_target(Error **errp)
+{
+ TargetInfo *info = g_malloc0(sizeof(*info));
+
+ info->arch = TARGET_TYPE;
+
+ return info;
+}
diff --git a/block/sheepdog.c b/block/sheepdog.c
index a04ad99ead..df4f44107b 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -485,6 +485,7 @@ static int connect_to_sdog(const char *addr, const char *port)
if (errno == EINTR) {
goto reconnect;
}
+ close(fd);
break;
}
diff --git a/configure b/configure
index edf9da44b5..d97fd81709 100755
--- a/configure
+++ b/configure
@@ -218,6 +218,7 @@ zlib="yes"
guest_agent="yes"
libiscsi=""
coroutine=""
+seccomp=""
# parse CC options first
for opt do
@@ -298,6 +299,41 @@ EOF
compile_object
}
+if check_define __linux__ ; then
+ targetos="Linux"
+elif check_define _WIN32 ; then
+ targetos='MINGW32'
+elif check_define __OpenBSD__ ; then
+ targetos='OpenBSD'
+elif check_define __sun__ ; then
+ targetos='SunOS'
+elif check_define __HAIKU__ ; then
+ targetos='Haiku'
+else
+ targetos=`uname -s`
+fi
+
+# Some host OSes need non-standard checks for which CPU to use.
+# Note that these checks are broken for cross-compilation: if you're
+# cross-compiling to one of these OSes then you'll need to specify
+# the correct CPU with the --cpu option.
+case $targetos in
+Darwin)
+ # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
+ # run 64-bit userspace code.
+ # If the user didn't specify a CPU explicitly and the kernel says this is
+ # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
+ if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
+ cpu="x86_64"
+ fi
+ ;;
+SunOS)
+ # `uname -m` returns i86pc even on an x86_64 box, so default based on isainfo
+ if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
+ cpu="x86_64"
+ fi
+esac
+
if test ! -z "$cpu" ; then
# command line argument
:
@@ -372,19 +408,6 @@ if test -z "$ARCH"; then
fi
# OS specific
-if check_define __linux__ ; then
- targetos="Linux"
-elif check_define _WIN32 ; then
- targetos='MINGW32'
-elif check_define __OpenBSD__ ; then
- targetos='OpenBSD'
-elif check_define __sun__ ; then
- targetos='SunOS'
-elif check_define __HAIKU__ ; then
- targetos='Haiku'
-else
- targetos=`uname -s`
-fi
case $targetos in
CYGWIN*)
@@ -434,12 +457,6 @@ OpenBSD)
Darwin)
bsd="yes"
darwin="yes"
- # on Leopard most of the system is 32-bit, so we have to ask the kernel it if we can
- # run 64-bit userspace code
- if [ "$cpu" = "i386" ] ; then
- is_x86_64=`sysctl -n hw.optional.x86_64`
- [ "$is_x86_64" = "1" ] && cpu=x86_64
- fi
if [ "$cpu" = "x86_64" ] ; then
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
LDFLAGS="-arch x86_64 $LDFLAGS"
@@ -451,6 +468,9 @@ Darwin)
audio_possible_drivers="coreaudio sdl fmod"
LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
+ # Disable attempts to use ObjectiveC features in os/object.h since they
+ # won't work when we're compiling with gcc as a C compiler.
+ QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
;;
SunOS)
solaris="yes"
@@ -460,12 +480,6 @@ SunOS)
smbd="${SMBD-/usr/sfw/sbin/smbd}"
needs_libsunmath="no"
solarisrev=`uname -r | cut -f2 -d.`
- # have to select again, because `uname -m` returns i86pc
- # even on an x86_64 box.
- solariscpu=`isainfo -k`
- if test "${solariscpu}" = "amd64" ; then
- cpu="x86_64"
- fi
if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
if test "$solarisrev" -le 9 ; then
if test -f /opt/SUNWspro/prod/lib/libsunmath.so.1; then
@@ -530,6 +544,13 @@ fi
: ${python=${PYTHON-python}}
: ${smbd=${SMBD-/usr/sbin/smbd}}
+# Default objcc to clang if available, otherwise use CC
+if has clang; then
+ objcc=clang
+else
+ objcc="$cc"
+fi
+
if test "$mingw32" = "yes" ; then
EXESUF=".exe"
QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS"
@@ -573,6 +594,8 @@ for opt do
;;
--host-cc=*) host_cc="$optarg"
;;
+ --objcc=*) objcc="$optarg"
+ ;;
--make=*) make="$optarg"
;;
--install=*) install="$optarg"
@@ -842,6 +865,10 @@ for opt do
;;
--disable-guest-agent) guest_agent="no"
;;
+ --enable-seccomp) seccomp="yes"
+ ;;
+ --disable-seccomp) seccomp="no"
+ ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -1015,6 +1042,7 @@ echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
echo " --cc=CC use C compiler CC [$cc]"
echo " --host-cc=CC use C compiler CC [$host_cc] for code run at"
echo " build time"
+echo " --objcc=OBJCC use Objective-C compiler OBJCC [$objcc]"
echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS"
echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS"
echo " --make=MAKE use specified make [$make]"
@@ -1129,6 +1157,8 @@ echo " --disable-usb-redir disable usb network redirection support"
echo " --enable-usb-redir enable usb network redirection support"
echo " --disable-guest-agent disable building of the QEMU Guest Agent"
echo " --enable-guest-agent enable building of the QEMU Guest Agent"
+echo " --disable-seccomp disable seccomp support"
+echo " --enable-seccomp enables seccomp support"
echo " --with-coroutine=BACKEND coroutine backend. Supported options:"
echo " gthread, ucontext, sigaltstack, windows"
echo ""
@@ -1391,6 +1421,20 @@ EOF
fi
##########################################
+# libseccomp check
+
+if test "$seccomp" != "no" ; then
+ if $pkg_config libseccomp --modversion >/dev/null 2>&1; then
+ LIBS=`$pkg_config --libs libseccomp`
+ seccomp="yes"
+ else
+ seccomp="no"
+ if test "$seccomp" = "yes"; then
+ feature_not_found "libseccomp"
+ fi
+ fi
+fi
+##########################################
# xen probe
if test "$xen" != "no" ; then
@@ -3045,6 +3089,7 @@ fi
echo "Source path $source_path"
echo "C compiler $cc"
echo "Host C compiler $host_cc"
+echo "Objective-C compiler $objcc"
echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS"
echo "LDFLAGS $LDFLAGS"
@@ -3119,6 +3164,7 @@ echo "usb net redir $usb_redir"
echo "OpenGL support $opengl"
echo "libiscsi support $libiscsi"
echo "build guest agent $guest_agent"
+echo "seccomp support $seccomp"
echo "coroutine backend $coroutine_backend"
if test "$sdl_too_old" = "yes"; then
@@ -3414,6 +3460,10 @@ if test "$libiscsi" = "yes" ; then
echo "CONFIG_LIBISCSI=y" >> $config_host_mak
fi
+if test "$seccomp" = "yes"; then
+ echo "CONFIG_SECCOMP=y" >> $config_host_mak
+fi
+
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "CONFIG_BSD=y" >> $config_host_mak
@@ -3508,6 +3558,7 @@ echo "PYTHON=$python" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak
echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak
+echo "OBJCC=$objcc" >> $config_host_mak
echo "AR=$ar" >> $config_host_mak
echo "OBJCOPY=$objcopy" >> $config_host_mak
echo "LD=$ld" >> $config_host_mak
@@ -3783,14 +3834,19 @@ case "$target_arch2" in
;;
esac
+upper() {
+ echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
+}
+
echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak
echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak
echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak
echo "TARGET_LLONG_ALIGNMENT=$target_llong_alignment" >> $config_target_mak
echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
-target_arch_name="`echo $TARGET_ARCH | LC_ALL=C tr '[a-z]' '[A-Z]'`"
+target_arch_name="`upper $TARGET_ARCH`"
echo "TARGET_$target_arch_name=y" >> $config_target_mak
echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak
+echo "TARGET_TYPE=TARGET_TYPE_`upper $target_arch2`" >> $config_target_mak
echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
if [ "$TARGET_ABI_DIR" = "" ]; then
TARGET_ABI_DIR=$TARGET_ARCH
@@ -3881,6 +3937,11 @@ if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=y" >> $config_target_mak
fi
+# the static way of configuring available audio cards requires this workaround
+if test "$target_user_only" != "yes" && grep -q CONFIG_PCSPK $source_path/default-configs/$target.mak; then
+ echo "CONFIG_PCSPK=y" >> $config_target_mak
+fi
+
# generate QEMU_CFLAGS/LDFLAGS for targets
cflags=""
diff --git a/dma-helpers.c b/dma-helpers.c
index 13593d1b42..433d8b21b3 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -24,8 +24,8 @@ static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
while (len > 0) {
l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
cpu_physical_memory_rw(addr, fillbuf, l, true);
- len -= len;
- addr += len;
+ len -= l;
+ addr += l;
}
}
diff --git a/exec.c b/exec.c
index 929db5cf0a..58347664b2 100644
--- a/exec.c
+++ b/exec.c
@@ -2475,6 +2475,24 @@ static ram_addr_t last_ram_offset(void)
return last;
}
+static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
+{
+ int ret;
+ QemuOpts *machine_opts;
+
+ /* Use MADV_DONTDUMP, if user doesn't want the guest memory in the core */
+ machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
+ if (machine_opts &&
+ !qemu_opt_get_bool(machine_opts, "dump-guest-core", true)) {
+ ret = qemu_madvise(addr, size, QEMU_MADV_DONTDUMP);
+ if (ret) {
+ perror("qemu_madvise");
+ fprintf(stderr, "madvise doesn't support MADV_DONTDUMP, "
+ "but dump_guest_core=off specified\n");
+ }
+ }
+}
+
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
{
RAMBlock *new_block, *block;
@@ -2554,6 +2572,8 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
0, size >> TARGET_PAGE_BITS);
cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);
+ qemu_ram_setup_dump(new_block->host, size);
+
if (kvm_enabled())
kvm_setup_guest_memory(new_block->host, size);
@@ -2670,6 +2690,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
exit(1);
}
qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE);
+ qemu_ram_setup_dump(vaddr, length);
}
return;
}
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index 872e1122e8..b7cf4e2900 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -15,6 +15,8 @@
#include "exec-memory.h"
+#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
+
typedef struct TyphoonCchip {
MemoryRegion region;
uint64_t misc;
@@ -40,8 +42,12 @@ typedef struct TyphoonPchip {
TyphoonWindow win[4];
} TyphoonPchip;
+#define TYPHOON_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
+
typedef struct TyphoonState {
- PCIHostState host;
+ PCIHostState parent_obj;
+
TyphoonCchip cchip;
TyphoonPchip pchip;
MemoryRegion dchip_region;
@@ -700,16 +706,16 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
MemoryRegion *addr_space = get_system_memory();
MemoryRegion *addr_space_io = get_system_io();
DeviceState *dev;
- PCIHostState *p;
TyphoonState *s;
+ PCIHostState *phb;
PCIBus *b;
int i;
- dev = qdev_create(NULL, "typhoon-pcihost");
+ dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
- p = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
- s = container_of(p, TyphoonState, host);
+ s = TYPHOON_PCI_HOST_BRIDGE(dev);
+ phb = PCI_HOST_BRIDGE(dev);
/* Remember the CPUs so that we can deliver interrupts to them. */
for (i = 0; i < 4; i++) {
@@ -763,10 +769,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);
- b = pci_register_bus(&s->host.busdev.qdev, "pci",
+ b = pci_register_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, addr_space_io, 0, 64);
- s->host.bus = b;
+ phb->bus = b;
/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
memory_region_init_io(&s->pchip.reg_iack, &alpha_pci_iack_ops, b,
@@ -817,9 +823,9 @@ static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo typhoon_pcihost_info = {
- .name = "typhoon-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo typhoon_pcihost_info = {
+ .name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(TyphoonState),
.class_init = typhoon_pcihost_class_init,
};
diff --git a/hw/boards.h b/hw/boards.h
index 59c01d0367..a2e0a54497 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -12,11 +12,14 @@ typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
const char *initrd_filename,
const char *cpu_model);
+typedef void QEMUMachineResetFunc(void);
+
typedef struct QEMUMachine {
const char *name;
const char *alias;
const char *desc;
QEMUMachineInitFunc *init;
+ QEMUMachineResetFunc *reset;
int use_scsi;
int max_cpus;
unsigned int no_serial:1,
diff --git a/hw/bonito.c b/hw/bonito.c
index 77786f8883..6084ac48fa 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -180,11 +180,14 @@
#define PCI_ADDR(busno,devno,funno,regno) \
((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno))
-typedef PCIHostState BonitoState;
+#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
+
+typedef struct BonitoState BonitoState;
typedef struct PCIBonitoState
{
PCIDevice dev;
+
BonitoState *pcihost;
uint32_t regs[BONITO_REGS];
@@ -218,7 +221,16 @@ typedef struct PCIBonitoState
} PCIBonitoState;
-PCIBonitoState * bonito_state;
+#define BONITO_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(BonitoState, (obj), TYPE_BONITO_PCI_HOST_BRIDGE)
+
+struct BonitoState {
+ PCIHostState parent_obj;
+
+ qemu_irq *pic;
+
+ PCIBonitoState *pci_dev;
+};
static void bonito_writel(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
@@ -314,9 +326,10 @@ static void bonito_pciconf_writel(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
- s->dev.config_write(&s->dev, addr, val, 4);
+ d->config_write(d, addr, val, 4);
}
static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
@@ -324,9 +337,10 @@ static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
DPRINTF("bonito_pciconf_readl "TARGET_FMT_plx"\n", addr);
- return s->dev.config_read(&s->dev, addr, 4);
+ return d->config_read(d, addr, 4);
}
/* north bridge PCI configure space. 0x1fe0 0000 - 0x1fe0 00ff */
@@ -402,6 +416,7 @@ static const MemoryRegionOps bonito_cop_ops = {
static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t cfgaddr;
uint32_t idsel;
uint32_t devno;
@@ -423,13 +438,13 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
if (idsel == 0) {
- fprintf(stderr, "error in bonito pci config address" TARGET_FMT_plx
+ fprintf(stderr, "error in bonito pci config address " TARGET_FMT_plx
",pcimap_cfg=%x\n", addr, s->regs[BONITO_PCIMAP_CFG]);
exit(1);
}
- pciaddr = PCI_ADDR(pci_bus_num(s->pcihost->bus), devno, funno, regno);
+ pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno);
DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n",
- cfgaddr, pciaddr, pci_bus_num(s->pcihost->bus), devno, funno, regno);
+ cfgaddr, pciaddr, pci_bus_num(phb->bus), devno, funno, regno);
return pciaddr;
}
@@ -438,6 +453,8 @@ static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
@@ -449,24 +466,26 @@ static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
- pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val & 0xff, 1);
+ phb->config_reg = (pciaddr) | (1u << 31);
+ pci_data_write(phb->bus, phb->config_reg, val & 0xff, 1);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
}
static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x\n", addr, val);
- assert((addr&0x1)==0);
+ assert((addr & 0x1) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -475,24 +494,26 @@ static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
- pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 2);
+ phb->config_reg = (pciaddr) | (1u << 31);
+ pci_data_write(phb->bus, phb->config_reg, val, 2);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
}
static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
- assert((addr&0x3)==0);
+ assert((addr & 0x3) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -501,18 +522,20 @@ static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
- pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 4);
+ phb->config_reg = (pciaddr) | (1u << 31);
+ pci_data_write(phb->bus, phb->config_reg, val, 4);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
}
static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
@@ -524,24 +547,26 @@ static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
+ phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
- return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 1);
+ return pci_data_read(phb->bus, phb->config_reg, 1);
}
static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx"\n", addr);
- assert((addr&0x1)==0);
+ assert((addr & 0x1) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -550,24 +575,26 @@ static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
+ phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
- return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 2);
+ return pci_data_read(phb->bus, phb->config_reg, 2);
}
static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
+ PCIDevice *d = PCI_DEVICE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr);
- assert((addr&0x3) == 0);
+ assert((addr & 0x3) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -576,14 +603,14 @@ static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
- s->pcihost->config_reg = (pciaddr) | (1u << 31);
+ phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(s->dev.config + PCI_STATUS);
+ status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(s->dev.config + PCI_STATUS, status);
+ pci_set_word(d->config + PCI_STATUS, status);
- return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 4);
+ return pci_data_read(phb->bus, phb->config_reg, 4);
}
/* south bridge PCI configure space. 0x1fe8 0000 - 0x1fef ffff */
@@ -607,13 +634,15 @@ static const MemoryRegionOps bonito_spciconf_ops = {
static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
{
- qemu_irq *pic = opaque;
+ BonitoState *s = opaque;
+ qemu_irq *pic = s->pic;
+ PCIBonitoState *bonito_state = s->pci_dev;
int internal_irq = irq_num - BONITO_IRQ_BASE;
- if (bonito_state->regs[BONITO_INTEDGE] & (1<<internal_irq)) {
+ if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
qemu_irq_pulse(*pic);
} else { /* level triggered */
- if (bonito_state->regs[BONITO_INTPOL] & (1<<internal_irq)) {
+ if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
qemu_irq_raise(*pic);
} else {
qemu_irq_lower(*pic);
@@ -673,13 +702,21 @@ static const VMStateDescription vmstate_bonito = {
static int bonito_pcihost_initfn(SysBusDevice *dev)
{
+ PCIHostState *phb = PCI_HOST_BRIDGE(dev);
+
+ phb->bus = pci_register_bus(DEVICE(dev), "pci",
+ pci_bonito_set_irq, pci_bonito_map_irq, dev,
+ get_system_memory(), get_system_io(),
+ 0x28, 32);
+
return 0;
}
static int bonito_initfn(PCIDevice *dev)
{
PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
- SysBusDevice *sysbus = &s->pcihost->busdev;
+ SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
/* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */
pci_config_set_prog_interface(dev->config, 0x00);
@@ -691,15 +728,15 @@ static int bonito_initfn(PCIDevice *dev)
sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
/* set the north bridge pci configure mapping */
- memory_region_init_io(&s->pcihost->conf_mem, &bonito_pciconf_ops, s,
+ memory_region_init_io(&phb->conf_mem, &bonito_pciconf_ops, s,
"north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
- sysbus_init_mmio(sysbus, &s->pcihost->conf_mem);
+ sysbus_init_mmio(sysbus, &phb->conf_mem);
sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE);
/* set the south bridge pci configure mapping */
- memory_region_init_io(&s->pcihost->data_mem, &bonito_spciconf_ops, s,
+ memory_region_init_io(&phb->data_mem, &bonito_spciconf_ops, s,
"south-bridge-pci-config", BONITO_SPCICONFIG_SIZE);
- sysbus_init_mmio(sysbus, &s->pcihost->data_mem);
+ sysbus_init_mmio(sysbus, &phb->data_mem);
sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE);
memory_region_init_io(&s->iomem_ldma, &bonito_ldma_ops, s,
@@ -742,28 +779,25 @@ static int bonito_initfn(PCIDevice *dev)
PCIBus *bonito_init(qemu_irq *pic)
{
DeviceState *dev;
- PCIBus *b;
BonitoState *pcihost;
+ PCIHostState *phb;
PCIBonitoState *s;
PCIDevice *d;
- dev = qdev_create(NULL, "Bonito-pcihost");
- pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
- b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
- pci_bonito_map_irq, pic, get_system_memory(),
- get_system_io(),
- 0x28, 32);
- pcihost->bus = b;
+ dev = qdev_create(NULL, TYPE_BONITO_PCI_HOST_BRIDGE);
+ phb = PCI_HOST_BRIDGE(dev);
+ pcihost = BONITO_PCI_HOST_BRIDGE(dev);
+ pcihost->pic = pic;
qdev_init_nofail(dev);
/* set the pcihost pointer before bonito_initfn is called */
- d = pci_create(b, PCI_DEVFN(0, 0), "Bonito");
+ d = pci_create(phb->bus, PCI_DEVFN(0, 0), "Bonito");
s = DO_UPCAST(PCIBonitoState, dev, d);
s->pcihost = pcihost;
- bonito_state = s;
- qdev_init_nofail(&d->qdev);
+ pcihost->pci_dev = s;
+ qdev_init_nofail(DEVICE(d));
- return b;
+ return phb->bus;
}
static void bonito_class_init(ObjectClass *klass, void *data)
@@ -781,7 +815,7 @@ static void bonito_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bonito;
}
-static TypeInfo bonito_info = {
+static const TypeInfo bonito_info = {
.name = "Bonito",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBonitoState),
@@ -797,9 +831,9 @@ static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo bonito_pcihost_info = {
- .name = "Bonito-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo bonito_pcihost_info = {
+ .name = TYPE_BONITO_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(BonitoState),
.class_init = bonito_pcihost_class_init,
};
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 37337bf4b6..c30ade38bd 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -40,9 +40,10 @@
#define DEC_DPRINTF(fmt, ...)
#endif
+#define DEC_21154(obj) OBJECT_CHECK(DECState, (obj), TYPE_DEC_21154)
+
typedef struct DECState {
- SysBusDevice busdev;
- PCIHostState host_state;
+ PCIHostState parent_obj;
} DECState;
static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -66,7 +67,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pci_device;
}
-static TypeInfo dec_21154_pci_bridge_info = {
+static const TypeInfo dec_21154_pci_bridge_info = {
.name = "dec-21154-p2p-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBridge),
@@ -88,16 +89,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
static int pci_dec_21154_device_init(SysBusDevice *dev)
{
- DECState *s;
+ PCIHostState *phb;
- s = FROM_SYSBUS(DECState, dev);
+ phb = PCI_HOST_BRIDGE(dev);
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
- &s->host_state, "pci-data-idx", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
+ dev, "pci-data-idx", 0x1000);
+ sysbus_init_mmio(dev, &phb->conf_mem);
+ sysbus_init_mmio(dev, &phb->data_mem);
return 0;
}
@@ -119,7 +120,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
k->is_bridge = 1;
}
-static TypeInfo dec_21154_pci_host_info = {
+static const TypeInfo dec_21154_pci_host_info = {
.name = "dec-21154",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -133,9 +134,9 @@ static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
sdc->init = pci_dec_21154_device_init;
}
-static TypeInfo pci_dec_21154_device_info = {
- .name = "dec-21154-sysbus",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo pci_dec_21154_device_info = {
+ .name = TYPE_DEC_21154,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(DECState),
.class_init = pci_dec_21154_device_class_init,
};
diff --git a/hw/dec_pci.h b/hw/dec_pci.h
index 79264bac84..17dc0c2b0a 100644
--- a/hw/dec_pci.h
+++ b/hw/dec_pci.h
@@ -3,6 +3,8 @@
#include "qemu-common.h"
+#define TYPE_DEC_21154 "dec-21154-sysbus"
+
PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn);
#endif
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 81ff3a339a..67da307284 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -23,10 +23,9 @@
* THE SOFTWARE.
*/
-#include "sysbus.h"
+#include "pci_host.h"
#include "ppc_mac.h"
#include "pci.h"
-#include "pci_host.h"
/* debug Grackle */
//#define DEBUG_GRACKLE
@@ -38,9 +37,12 @@
#define GRACKLE_DPRINTF(fmt, ...)
#endif
+#define GRACKLE_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(GrackleState, (obj), TYPE_GRACKLE_PCI_HOST_BRIDGE)
+
typedef struct GrackleState {
- SysBusDevice busdev;
- PCIHostState host_state;
+ PCIHostState parent_obj;
+
MemoryRegion pci_mmio;
MemoryRegion pci_hole;
} GrackleState;
@@ -59,22 +61,20 @@ static void pci_grackle_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num + 0x15], level);
}
-static void pci_grackle_reset(void *opaque)
-{
-}
-
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io)
{
DeviceState *dev;
SysBusDevice *s;
+ PCIHostState *phb;
GrackleState *d;
- dev = qdev_create(NULL, "grackle-pcihost");
+ dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
- d = FROM_SYSBUS(GrackleState, s);
+ s = SYS_BUS_DEVICE(dev);
+ phb = PCI_HOST_BRIDGE(dev);
+ d = GRACKLE_PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
@@ -82,36 +82,35 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
- pci_grackle_set_irq,
- pci_grackle_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- 0, 4);
+ phb->bus = pci_register_bus(dev, "pci",
+ pci_grackle_set_irq,
+ pci_grackle_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ 0, 4);
- pci_create_simple(d->host_state.bus, 0, "grackle");
+ pci_create_simple(phb->bus, 0, "grackle");
sysbus_mmio_map(s, 0, base);
sysbus_mmio_map(s, 1, base + 0x00200000);
- return d->host_state.bus;
+ return phb->bus;
}
static int pci_grackle_init_device(SysBusDevice *dev)
{
- GrackleState *s;
+ PCIHostState *phb;
- s = FROM_SYSBUS(GrackleState, dev);
+ phb = PCI_HOST_BRIDGE(dev);
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
- &s->host_state, "pci-data-idx", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
+ dev, "pci-data-idx", 0x1000);
+ sysbus_init_mmio(dev, &phb->conf_mem);
+ sysbus_init_mmio(dev, &phb->data_mem);
- qemu_register_reset(pci_grackle_reset, &s->host_state);
return 0;
}
@@ -134,7 +133,7 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo grackle_pci_info = {
+static const TypeInfo grackle_pci_info = {
.name = "grackle",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -150,9 +149,9 @@ static void pci_grackle_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo grackle_pci_host_info = {
- .name = "grackle-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo grackle_pci_host_info = {
+ .name = TYPE_GRACKLE_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(GrackleState),
.class_init = pci_grackle_class_init,
};
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index a2d0e5a2c3..e95e664833 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -229,9 +229,14 @@
target_phys_addr_t regname ##_length; \
MemoryRegion regname ##_mem
+#define TYPE_GT64120_PCI_HOST_BRIDGE "gt64120"
+
+#define GT64120_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(GT64120State, (obj), TYPE_GT64120_PCI_HOST_BRIDGE)
+
typedef struct GT64120State {
- SysBusDevice busdev;
- PCIHostState pci;
+ PCIHostState parent_obj;
+
uint32_t regs[GT_REGS];
PCI_MAPPING_ENTRY(PCI0IO);
PCI_MAPPING_ENTRY(ISD);
@@ -310,6 +315,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
GT64120State *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t saddr;
if (!(s->regs[GT_CPU] & 0x00001000))
@@ -530,13 +536,15 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
/* not implemented */
break;
case GT_PCI0_CFGADDR:
- s->pci.config_reg = val & 0x80fffffc;
+ phb->config_reg = val & 0x80fffffc;
break;
case GT_PCI0_CFGDATA:
- if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci.config_reg & 0x00fff800))
+ if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
val = bswap32(val);
- if (s->pci.config_reg & (1u << 31))
- pci_data_write(s->pci.bus, s->pci.config_reg, val, 4);
+ }
+ if (phb->config_reg & (1u << 31)) {
+ pci_data_write(phb->bus, phb->config_reg, val, 4);
+ }
break;
/* Interrupts */
@@ -589,6 +597,7 @@ static uint64_t gt64120_readl (void *opaque,
target_phys_addr_t addr, unsigned size)
{
GT64120State *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t val;
uint32_t saddr;
@@ -770,15 +779,17 @@ static uint64_t gt64120_readl (void *opaque,
/* PCI Internal */
case GT_PCI0_CFGADDR:
- val = s->pci.config_reg;
+ val = phb->config_reg;
break;
case GT_PCI0_CFGDATA:
- if (!(s->pci.config_reg & (1 << 31)))
+ if (!(phb->config_reg & (1 << 31))) {
val = 0xffffffff;
- else
- val = pci_data_read(s->pci.bus, s->pci.config_reg, 4);
- if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci.config_reg & 0x00fff800))
+ } else {
+ val = pci_data_read(phb->bus, phb->config_reg, 4);
+ }
+ if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
val = bswap32(val);
+ }
break;
case GT_PCI0_CMD:
@@ -1083,31 +1094,31 @@ static void gt64120_reset(void *opaque)
PCIBus *gt64120_register(qemu_irq *pic)
{
- SysBusDevice *s;
GT64120State *d;
+ PCIHostState *phb;
DeviceState *dev;
- dev = qdev_create(NULL, "gt64120");
+ dev = qdev_create(NULL, TYPE_GT64120_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
- d = FROM_SYSBUS(GT64120State, s);
- d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
- gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic,
- get_system_memory(),
- get_system_io(),
- PCI_DEVFN(18, 0), 4);
+ d = GT64120_PCI_HOST_BRIDGE(dev);
+ phb = PCI_HOST_BRIDGE(dev);
+ phb->bus = pci_register_bus(dev, "pci",
+ gt64120_pci_set_irq, gt64120_pci_map_irq,
+ pic,
+ get_system_memory(),
+ get_system_io(),
+ PCI_DEVFN(18, 0), 4);
memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000);
- pci_create_simple(d->pci.bus, PCI_DEVFN(0, 0), "gt64120_pci");
- return d->pci.bus;
+ pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
+ return phb->bus;
}
static int gt64120_init(SysBusDevice *dev)
{
GT64120State *s;
- s = FROM_SYSBUS(GT64120State, dev);
+ s = GT64120_PCI_HOST_BRIDGE(dev);
/* FIXME: This value is computed from registers during reset, but some
devices (e.g. VGA card) need to know it when they are registered.
@@ -1147,7 +1158,7 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo gt64120_pci_info = {
+static const TypeInfo gt64120_pci_info = {
.name = "gt64120_pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -1161,9 +1172,9 @@ static void gt64120_class_init(ObjectClass *klass, void *data)
sdc->init = gt64120_init;
}
-static TypeInfo gt64120_info = {
- .name = "gt64120",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo gt64120_info = {
+ .name = TYPE_GT64120_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(GT64120State),
.class_init = gt64120_class_init,
};
diff --git a/hw/i82378.c b/hw/i82378.c
index 9b11d907eb..2123c142aa 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -225,7 +225,6 @@ static int pci_i82378_init(PCIDevice *dev)
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io);
memory_region_init_io(&s->mem, &i82378_mem_ops, s, "i82378-mem", 0x01000000);
- memory_region_set_coalescing(&s->mem);
pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
/* Make I/O address read only */
diff --git a/hw/msix.c b/hw/msix.c
index 800fc32f0b..aea340b7c7 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -307,13 +307,9 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
return -EINVAL;
}
- if (asprintf(&name, "%s-msix", dev->name) == -1) {
- return -ENOMEM;
- }
-
+ name = g_strdup_printf("%s-msix", dev->name);
memory_region_init(&dev->msix_exclusive_bar, name, MSIX_EXCLUSIVE_BAR_SIZE);
-
- free(name);
+ g_free(name);
ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar,
diff --git a/hw/pc.c b/hw/pc.c
index 3ed1a3caa2..112739a278 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -338,32 +338,37 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
/* various important CMOS locations needed by PC/Bochs bios */
/* memory size */
- val = 640; /* base memory in K */
+ /* base memory (first MiB) */
+ val = MIN(ram_size / 1024, 640);
rtc_set_memory(s, 0x15, val);
rtc_set_memory(s, 0x16, val >> 8);
-
- val = (ram_size / 1024) - 1024;
+ /* extended memory (next 64MiB) */
+ if (ram_size > 1024 * 1024) {
+ val = (ram_size - 1024 * 1024) / 1024;
+ } else {
+ val = 0;
+ }
if (val > 65535)
val = 65535;
rtc_set_memory(s, 0x17, val);
rtc_set_memory(s, 0x18, val >> 8);
rtc_set_memory(s, 0x30, val);
rtc_set_memory(s, 0x31, val >> 8);
-
- if (above_4g_mem_size) {
- rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16);
- rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24);
- rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32);
- }
-
- if (ram_size > (16 * 1024 * 1024))
- val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
- else
+ /* memory between 16MiB and 4GiB */
+ if (ram_size > 16 * 1024 * 1024) {
+ val = (ram_size - 16 * 1024 * 1024) / 65536;
+ } else {
val = 0;
+ }
if (val > 65535)
val = 65535;
rtc_set_memory(s, 0x34, val);
rtc_set_memory(s, 0x35, val >> 8);
+ /* memory above 4GiB */
+ val = above_4g_mem_size / 65536;
+ rtc_set_memory(s, 0x5b, val);
+ rtc_set_memory(s, 0x5c, val >> 8);
+ rtc_set_memory(s, 0x5d, val >> 16);
/* set the number of CPU */
rtc_set_memory(s, 0x5f, smp_cpus - 1);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 0c0096fd7e..d68dbb2320 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -375,6 +375,10 @@ static QEMUMachine pc_machine_v1_2 = {
.driver = "qxl",\
.property = "vgamem_mb",\
.value = stringify(8),\
+ },{\
+ .driver = "virtio-blk-pci",\
+ .property = "config-wce",\
+ .value = "off",\
}
static QEMUMachine pc_machine_v1_1 = {
diff --git a/hw/pci_host.c b/hw/pci_host.c
index 804177891a..3950e943c0 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -165,4 +165,16 @@ const MemoryRegionOps pci_host_data_be_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+static const TypeInfo pci_host_type_info = {
+ .name = TYPE_PCI_HOST_BRIDGE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .abstract = true,
+ .instance_size = sizeof(PCIHostState),
+};
+
+static void pci_host_register_types(void)
+{
+ type_register_static(&pci_host_type_info);
+}
+type_init(pci_host_register_types)
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 359e38f63b..4b9c300fcf 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -30,8 +30,13 @@
#include "sysbus.h"
+#define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
+#define PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
+
struct PCIHostState {
SysBusDevice busdev;
+
MemoryRegion conf_mem;
MemoryRegion data_mem;
MemoryRegion mmcfg;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index c497a014af..537fc1973c 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -36,7 +36,9 @@
* http://download.intel.com/design/chipsets/datashts/29054901.pdf
*/
-typedef PCIHostState I440FXState;
+typedef struct I440FXState {
+ PCIHostState parent_obj;
+} I440FXState;
#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */
#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */
@@ -225,7 +227,7 @@ static const VMStateDescription vmstate_i440fx = {
static int i440fx_pcihost_initfn(SysBusDevice *dev)
{
- I440FXState *s = FROM_SYSBUS(I440FXState, dev);
+ PCIHostState *s = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
"pci-conf-idx", 4);
@@ -267,14 +269,14 @@ static PCIBus *i440fx_common_init(const char *device_name,
DeviceState *dev;
PCIBus *b;
PCIDevice *d;
- I440FXState *s;
+ PCIHostState *s;
PIIX3State *piix3;
PCII440FXState *f;
dev = qdev_create(NULL, "i440FX-pcihost");
- s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
+ s = PCI_HOST_BRIDGE(dev);
s->address_space = address_space_mem;
- b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
+ b = pci_bus_new(dev, NULL, pci_address_space,
address_space_io, 0);
s->bus = b;
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
@@ -537,7 +539,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
}
-static TypeInfo piix3_info = {
+static const TypeInfo piix3_info = {
.name = "PIIX3",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX3State),
@@ -560,7 +562,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
};
-static TypeInfo piix3_xen_info = {
+static const TypeInfo piix3_xen_info = {
.name = "PIIX3-xen",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX3State),
@@ -584,7 +586,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_i440fx;
}
-static TypeInfo i440fx_info = {
+static const TypeInfo i440fx_info = {
.name = "i440FX",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCII440FXState),
@@ -601,9 +603,9 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo i440fx_pcihost_info = {
+static const TypeInfo i440fx_pcihost_info = {
.name = "i440FX-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(I440FXState),
.class_init = i440fx_pcihost_class_init,
};
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 0dd4dab318..c198071170 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -216,7 +216,8 @@ static void bamboo_init(ram_addr_t ram_size,
ram_bases, ram_sizes, 1);
/* PCI */
- dev = sysbus_create_varargs("ppc4xx-pcihost", PPC440EP_PCI_CONFIG,
+ dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST_BRIDGE,
+ PPC440EP_PCI_CONFIG,
pic[pci_irq_nrs[0]], pic[pci_irq_nrs[1]],
pic[pci_irq_nrs[2]], pic[pci_irq_nrs[3]],
NULL);
diff --git a/hw/ppc4xx.h b/hw/ppc4xx.h
index b511020aeb..5cd78b6291 100644
--- a/hw/ppc4xx.h
+++ b/hw/ppc4xx.h
@@ -53,6 +53,8 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
target_phys_addr_t *ram_sizes,
int do_init);
+#define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost"
+
PCIBus *ppc4xx_pci_init(CPUPPCState *env, qemu_irq pci_irqs[4],
target_phys_addr_t config_space,
target_phys_addr_t int_ack,
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 203c3cdc47..a14fd426c1 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -45,11 +45,14 @@ struct PCITargetMap {
uint32_t la;
};
+#define PPC4xx_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(PPC4xxPCIState, (obj), TYPE_PPC4xx_PCI_HOST_BRIDGE)
+
#define PPC4xx_PCI_NR_PMMS 3
#define PPC4xx_PCI_NR_PTMS 2
struct PPC4xxPCIState {
- PCIHostState pci_state;
+ PCIHostState parent_obj;
struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS];
struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS];
@@ -93,16 +96,18 @@ static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
PPC4xxPCIState *ppc4xx_pci = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
- return ppc4xx_pci->pci_state.config_reg;
+ return phb->config_reg;
}
static void pci4xx_cfgaddr_write(void *opaque, target_phys_addr_t addr,
uint64_t value, unsigned size)
{
PPC4xxPCIState *ppc4xx_pci = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
- ppc4xx_pci->pci_state.config_reg = value & ~0x3;
+ phb->config_reg = value & ~0x3;
}
static const MemoryRegionOps pci4xx_cfgaddr_ops = {
@@ -335,17 +340,17 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
PCIBus *b;
int i;
- h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
- s = DO_UPCAST(PPC4xxPCIState, pci_state, h);
+ h = PCI_HOST_BRIDGE(dev);
+ s = PPC4xx_PCI_HOST_BRIDGE(dev);
for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
- b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, ppc4xx_pci_set_irq,
+ b = pci_register_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
ppc4xx_pci_map_irq, s->irq, get_system_memory(),
get_system_io(), 0, 4);
- s->pci_state.bus = b;
+ h->bus = b;
pci_create_simple(b, 0, "ppc4xx-host-bridge");
@@ -377,7 +382,7 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_OTHER;
}
-static TypeInfo ppc4xx_host_bridge_info = {
+static const TypeInfo ppc4xx_host_bridge_info = {
.name = "ppc4xx-host-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -393,9 +398,9 @@ static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ppc4xx_pci;
}
-static TypeInfo ppc4xx_pcihost_info = {
- .name = "ppc4xx-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo ppc4xx_pcihost_info = {
+ .name = TYPE_PPC4xx_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PPC4xxPCIState),
.class_init = ppc4xx_pcihost_class_init,
};
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index af75e45cc2..7d084184fc 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -55,6 +55,7 @@ qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
int nb_cpus, qemu_irq **irqs);
/* Grackle PCI */
+#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 7a876164c9..592b7b255f 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -471,7 +471,6 @@ static void ppc_prep_init (ram_addr_t ram_size,
uint32_t kernel_base, initrd_base;
long kernel_size, initrd_size;
DeviceState *dev;
- SysBusDevice *sys;
PCIHostState *pcihost;
PCIBus *pci_bus;
PCIDevice *pci;
@@ -584,8 +583,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
}
dev = qdev_create(NULL, "raven-pcihost");
- sys = sysbus_from_qdev(dev);
- pcihost = DO_UPCAST(PCIHostState, busdev, sys);
+ pcihost = PCI_HOST_BRIDGE(dev);
pcihost->address_space = get_system_memory();
object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
qdev_init_nofail(dev);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 0f60b24134..92b1dc0534 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -72,8 +72,14 @@ struct pci_inbound {
uint32_t piwar;
};
+#define TYPE_PPC_E500_PCI_HOST_BRIDGE "e500-pcihost"
+
+#define PPC_E500_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(PPCE500PCIState, (obj), TYPE_PPC_E500_PCI_HOST_BRIDGE)
+
struct PPCE500PCIState {
- PCIHostState pci_state;
+ PCIHostState parent_obj;
+
struct pci_outbound pob[PPCE500_PCI_NR_POBS];
struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
uint32_t gasket_time;
@@ -310,17 +316,17 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *address_space_io = get_system_io();
- h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
- s = DO_UPCAST(PPCE500PCIState, pci_state, h);
+ h = PCI_HOST_BRIDGE(dev);
+ s = PPC_E500_PCI_HOST_BRIDGE(dev);
for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
- b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
+ b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
mpc85xx_pci_map_irq, s->irq, address_space_mem,
address_space_io, PCI_DEVFN(0x11, 0), 4);
- s->pci_state.bus = b;
+ h->bus = b;
pci_create_simple(b, 0, "e500-host-bridge");
@@ -350,7 +356,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
dc->desc = "Host bridge";
}
-static TypeInfo e500_host_bridge_info = {
+static const TypeInfo e500_host_bridge_info = {
.name = "e500-host-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -366,9 +372,9 @@ static void e500_pcihost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ppce500_pci;
}
-static TypeInfo e500_pcihost_info = {
- .name = "e500-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo e500_pcihost_info = {
+ .name = TYPE_PPC_E500_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PPCE500PCIState),
.class_init = e500_pcihost_class_init,
};
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 38dbff44a1..cc44e61987 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -28,8 +28,14 @@
#include "pc.h"
#include "exec-memory.h"
+#define TYPE_RAVEN_PCI_HOST_BRIDGE "raven-pcihost"
+
+#define RAVEN_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(PREPPCIState, (obj), TYPE_RAVEN_PCI_HOST_BRIDGE)
+
typedef struct PRePPCIState {
- PCIHostState host_state;
+ PCIHostState parent_obj;
+
MemoryRegion intack;
qemu_irq irq[4];
} PREPPCIState;
@@ -42,9 +48,10 @@ static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr)
{
int i;
- for(i = 0; i < 11; i++) {
- if ((addr & (1 << (11 + i))) != 0)
+ for (i = 0; i < 11; i++) {
+ if ((addr & (1 << (11 + i))) != 0) {
break;
+ }
}
return (addr & 0x7ff) | (i << 11);
}
@@ -53,14 +60,16 @@ static void ppc_pci_io_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned int size)
{
PREPPCIState *s = opaque;
- pci_data_write(s->host_state.bus, PPC_PCIIO_config(addr), val, size);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
+ pci_data_write(phb->bus, PPC_PCIIO_config(addr), val, size);
}
static uint64_t ppc_pci_io_read(void *opaque, target_phys_addr_t addr,
unsigned int size)
{
PREPPCIState *s = opaque;
- return pci_data_read(s->host_state.bus, PPC_PCIIO_config(addr), size);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
+ return pci_data_read(phb->bus, PPC_PCIIO_config(addr), size);
}
static const MemoryRegionOps PPC_PCIIO_ops = {
@@ -96,8 +105,8 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
static int raven_pcihost_init(SysBusDevice *dev)
{
- PCIHostState *h = FROM_SYSBUS(PCIHostState, dev);
- PREPPCIState *s = DO_UPCAST(PREPPCIState, host_state, h);
+ PCIHostState *h = PCI_HOST_BRIDGE(dev);
+ PREPPCIState *s = RAVEN_PCI_HOST_BRIDGE(dev);
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *address_space_io = get_system_io();
PCIBus *bus;
@@ -107,7 +116,7 @@ static int raven_pcihost_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq[i]);
}
- bus = pci_register_bus(&h->busdev.qdev, NULL,
+ bus = pci_register_bus(DEVICE(dev), NULL,
prep_set_irq, prep_map_irq, s->irq,
address_space_mem, address_space_io, 0, 4);
h->bus = bus;
@@ -166,7 +175,7 @@ static void raven_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo raven_info = {
+static const TypeInfo raven_info = {
.name = "raven",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RavenPCIState),
@@ -183,9 +192,9 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo raven_pcihost_info = {
- .name = "raven-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo raven_pcihost_info = {
+ .name = TYPE_RAVEN_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PREPPCIState),
.class_init = raven_pcihost_class_init,
};
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index b8a857d145..4981a02436 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -761,6 +761,7 @@ static int ata_passthrough_12_xfer_size(SCSIDevice *dev, uint8_t *buf)
switch (length) {
case 0:
case 3: /* USB-specific. */
+ default:
xfer = 0;
break;
case 1:
@@ -784,6 +785,7 @@ static int ata_passthrough_16_xfer_size(SCSIDevice *dev, uint8_t *buf)
switch (length) {
case 0:
case 3: /* USB-specific. */
+ default:
xfer = 0;
break;
case 1:
diff --git a/hw/spapr.c b/hw/spapr.c
index 5178721d49..c34b767c6e 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -49,6 +49,7 @@
#include "vga-pci.h"
#include "exec-memory.h"
+#include "hw/usb.h"
#include <libfdt.h>
@@ -611,6 +612,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
{
PowerPCCPU *cpu;
CPUPPCState *env;
+ PCIHostState *phb;
int i;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
@@ -741,6 +743,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
SPAPR_PCI_MEM_WIN_SIZE,
SPAPR_PCI_IO_WIN_ADDR,
SPAPR_PCI_MSI_WIN_ADDR);
+ phb = PCI_HOST_BRIDGE(QLIST_FIRST(&spapr->phbs));
for (i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
@@ -761,10 +764,18 @@ static void ppc_spapr_init(ram_addr_t ram_size,
}
/* Graphics */
- if (spapr_vga_init(QLIST_FIRST(&spapr->phbs)->host_state.bus)) {
+ if (spapr_vga_init(phb->bus)) {
spapr->has_graphics = true;
}
+ if (usb_enabled) {
+ pci_create_simple(phb->bus, -1, "pci-ohci");
+ if (spapr->has_graphics) {
+ usbdevice_create("keyboard");
+ usbdevice_create("mouse");
+ }
+ }
+
if (rma_size < (MIN_RMA_SLOF << 20)) {
fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
"%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index b92583a991..661c05bc30 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -48,13 +48,13 @@
static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid)
{
- sPAPRPHBState *phb;
+ sPAPRPHBState *sphb;
- QLIST_FOREACH(phb, &spapr->phbs, list) {
- if (phb->buid != buid) {
+ QLIST_FOREACH(sphb, &spapr->phbs, list) {
+ if (sphb->buid != buid) {
continue;
}
- return phb;
+ return sphb;
}
return NULL;
@@ -63,7 +63,9 @@ static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid)
static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
uint32_t config_addr)
{
- sPAPRPHBState *phb = find_phb(spapr, buid);
+ sPAPRPHBState *sphb = find_phb(spapr, buid);
+ PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
+ BusState *bus = BUS(phb->bus);
BusChild *kid;
int devfn = (config_addr >> 8) & 0xFF;
@@ -71,7 +73,7 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
return NULL;
}
- QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
PCIDevice *dev = (PCIDevice *)kid->child;
if (dev->devfn == devfn) {
return dev;
@@ -514,23 +516,24 @@ static DMAContext *spapr_pci_dma_context_fn(PCIBus *bus, void *opaque,
static int spapr_phb_init(SysBusDevice *s)
{
- sPAPRPHBState *phb = DO_UPCAST(sPAPRPHBState, host_state.busdev, s);
+ sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
char *namebuf;
int i;
PCIBus *bus;
- phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid);
- namebuf = alloca(strlen(phb->dtbusname) + 32);
+ sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
+ namebuf = alloca(strlen(sphb->dtbusname) + 32);
/* Initialize memory regions */
- sprintf(namebuf, "%s.mmio", phb->dtbusname);
- memory_region_init(&phb->memspace, namebuf, INT64_MAX);
+ sprintf(namebuf, "%s.mmio", sphb->dtbusname);
+ memory_region_init(&sphb->memspace, namebuf, INT64_MAX);
- sprintf(namebuf, "%s.mmio-alias", phb->dtbusname);
- memory_region_init_alias(&phb->memwindow, namebuf, &phb->memspace,
- SPAPR_PCI_MEM_WIN_BUS_OFFSET, phb->mem_win_size);
- memory_region_add_subregion(get_system_memory(), phb->mem_win_addr,
- &phb->memwindow);
+ sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname);
+ memory_region_init_alias(&sphb->memwindow, namebuf, &sphb->memspace,
+ SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
+ memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
+ &sphb->memwindow);
/* On ppc, we only have MMIO no specific IO space from the CPU
* perspective. In theory we ought to be able to embed the PCI IO
@@ -540,42 +543,42 @@ static int spapr_phb_init(SysBusDevice *s)
* system io address space. This hack to bounce things via
* system_io works around the problem until all the users of
* old_portion are updated */
- sprintf(namebuf, "%s.io", phb->dtbusname);
- memory_region_init(&phb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
+ sprintf(namebuf, "%s.io", sphb->dtbusname);
+ memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
/* FIXME: fix to support multiple PHBs */
- memory_region_add_subregion(get_system_io(), 0, &phb->iospace);
+ memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);
- sprintf(namebuf, "%s.io-alias", phb->dtbusname);
- memory_region_init_io(&phb->iowindow, &spapr_io_ops, phb,
+ sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
+ memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,
namebuf, SPAPR_PCI_IO_WIN_SIZE);
- memory_region_add_subregion(get_system_memory(), phb->io_win_addr,
- &phb->iowindow);
+ memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
+ &sphb->iowindow);
/* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
* we need to allocate some memory to catch those writes coming
* from msi_notify()/msix_notify() */
if (msi_supported) {
- sprintf(namebuf, "%s.msi", phb->dtbusname);
- memory_region_init_io(&phb->msiwindow, &spapr_msi_ops, phb,
+ sprintf(namebuf, "%s.msi", sphb->dtbusname);
+ memory_region_init_io(&sphb->msiwindow, &spapr_msi_ops, sphb,
namebuf, SPAPR_MSIX_MAX_DEVS * 0x10000);
- memory_region_add_subregion(get_system_memory(), phb->msi_win_addr,
- &phb->msiwindow);
+ memory_region_add_subregion(get_system_memory(), sphb->msi_win_addr,
+ &sphb->msiwindow);
}
- bus = pci_register_bus(&phb->host_state.busdev.qdev,
- phb->busname ? phb->busname : phb->dtbusname,
- pci_spapr_set_irq, pci_spapr_map_irq, phb,
- &phb->memspace, &phb->iospace,
+ bus = pci_register_bus(DEVICE(s),
+ sphb->busname ? sphb->busname : sphb->dtbusname,
+ pci_spapr_set_irq, pci_spapr_map_irq, sphb,
+ &sphb->memspace, &sphb->iospace,
PCI_DEVFN(0, 0), PCI_NUM_PINS);
- phb->host_state.bus = bus;
+ phb->bus = bus;
- phb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);
- phb->dma_window_start = 0;
- phb->dma_window_size = 0x40000000;
- phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, phb->dma_window_size);
- pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb);
+ sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);
+ sphb->dma_window_start = 0;
+ sphb->dma_window_size = 0x40000000;
+ sphb->dma = spapr_tce_new_dma_context(sphb->dma_liobn, sphb->dma_window_size);
+ pci_setup_iommu(bus, spapr_pci_dma_context_fn, sphb);
- QLIST_INSERT_HEAD(&spapr->phbs, phb, list);
+ QLIST_INSERT_HEAD(&spapr->phbs, sphb, list);
/* Initialize the LSI table */
for (i = 0; i < PCI_NUM_PINS; i++) {
@@ -586,7 +589,7 @@ static int spapr_phb_init(SysBusDevice *s)
return -1;
}
- phb->lsi_table[i].irq = irq;
+ sphb->lsi_table[i].irq = irq;
}
return 0;
@@ -612,9 +615,9 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
dc->props = spapr_phb_properties;
}
-static TypeInfo spapr_phb_info = {
- .name = "spapr-pci-host-bridge",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo spapr_phb_info = {
+ .name = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_class_init,
};
@@ -626,7 +629,7 @@ void spapr_create_phb(sPAPREnvironment *spapr,
{
DeviceState *dev;
- dev = qdev_create(NULL, spapr_phb_info.name);
+ dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
if (busname) {
qdev_prop_set_string(dev, "busname", g_strdup(busname));
@@ -750,8 +753,9 @@ void spapr_pci_rtas_init(void)
}
}
-static void register_types(void)
+static void spapr_pci_register_types(void)
{
type_register_static(&spapr_phb_info);
}
-type_init(register_types)
+
+type_init(spapr_pci_register_types)
diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h
index 7518899b85..670dc62a19 100644
--- a/hw/spapr_pci.h
+++ b/hw/spapr_pci.h
@@ -29,8 +29,13 @@
#define SPAPR_MSIX_MAX_DEVS 32
+#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
+
+#define SPAPR_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
+
typedef struct sPAPRPHBState {
- PCIHostState host_state;
+ PCIHostState parent_obj;
uint64_t buid;
char *busname;
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 409bcd4cc6..d1cc68062b 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -38,8 +38,23 @@
static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
+#define TYPE_UNI_NORTH_PCI_HOST_BRIDGE "uni-north-pci-pcihost"
+#define TYPE_UNI_NORTH_AGP_HOST_BRIDGE "uni-north-agp-pcihost"
+#define TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE "uni-north-internal-pci-pcihost"
+#define TYPE_U3_AGP_HOST_BRIDGE "u3-agp-pcihost"
+
+#define UNI_NORTH_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_PCI_HOST_BRIDGE)
+#define UNI_NORTH_AGP_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_AGP_HOST_BRIDGE)
+#define UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE)
+#define U3_AGP_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(UNINState, (obj), TYPE_U3_AGP_HOST_BRIDGE)
+
typedef struct UNINState {
- PCIHostState host_state;
+ PCIHostState parent_obj;
+
MemoryRegion pci_mmio;
MemoryRegion pci_hole;
} UNINState;
@@ -100,10 +115,11 @@ static void unin_data_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned len)
{
UNINState *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
addr, len, val);
- pci_data_write(s->host_state.bus,
- unin_get_config_reg(s->host_state.config_reg, addr),
+ pci_data_write(phb->bus,
+ unin_get_config_reg(phb->config_reg, addr),
val, len);
}
@@ -111,10 +127,11 @@ static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
unsigned len)
{
UNINState *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t val;
- val = pci_data_read(s->host_state.bus,
- unin_get_config_reg(s->host_state.config_reg, addr),
+ val = pci_data_read(phb->bus,
+ unin_get_config_reg(phb->config_reg, addr),
len);
UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
addr, len, val);
@@ -130,19 +147,17 @@ static const MemoryRegionOps unin_data_ops = {
static int pci_unin_main_init_device(SysBusDevice *dev)
{
PCIHostState *h;
- UNINState *s;
/* Use values found on a real PowerMac */
/* Uninorth main bus */
- h = FROM_SYSBUS(PCIHostState, dev);
- s = DO_UPCAST(UNINState, host_state, h);
+ h = PCI_HOST_BRIDGE(dev);
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
+ memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&h->data_mem, &unin_data_ops, dev,
"pci-conf-data", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ sysbus_init_mmio(dev, &h->conf_mem);
+ sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -151,18 +166,16 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
static int pci_u3_agp_init_device(SysBusDevice *dev)
{
PCIHostState *h;
- UNINState *s;
/* Uninorth U3 AGP bus */
- h = FROM_SYSBUS(PCIHostState, dev);
- s = DO_UPCAST(UNINState, host_state, h);
+ h = PCI_HOST_BRIDGE(dev);
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
+ memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&h->data_mem, &unin_data_ops, dev,
"pci-conf-data", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ sysbus_init_mmio(dev, &h->conf_mem);
+ sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -170,36 +183,32 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
static int pci_unin_agp_init_device(SysBusDevice *dev)
{
PCIHostState *h;
- UNINState *s;
/* Uninorth AGP bus */
- h = FROM_SYSBUS(PCIHostState, dev);
- s = DO_UPCAST(UNINState, host_state, h);
-
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
- &s->host_state, "pci-conf-data", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ h = PCI_HOST_BRIDGE(dev);
+
+ memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&h->data_mem, &pci_host_data_le_ops,
+ dev, "pci-conf-data", 0x1000);
+ sysbus_init_mmio(dev, &h->conf_mem);
+ sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
static int pci_unin_internal_init_device(SysBusDevice *dev)
{
PCIHostState *h;
- UNINState *s;
/* Uninorth internal bus */
- h = FROM_SYSBUS(PCIHostState, dev);
- s = DO_UPCAST(UNINState, host_state, h);
-
- memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
- &s->host_state, "pci-conf-idx", 0x1000);
- memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
- &s->host_state, "pci-conf-data", 0x1000);
- sysbus_init_mmio(dev, &s->host_state.conf_mem);
- sysbus_init_mmio(dev, &s->host_state.data_mem);
+ h = PCI_HOST_BRIDGE(dev);
+
+ memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
+ dev, "pci-conf-idx", 0x1000);
+ memory_region_init_io(&h->data_mem, &pci_host_data_le_ops,
+ dev, "pci-conf-data", 0x1000);
+ sysbus_init_mmio(dev, &h->conf_mem);
+ sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -214,26 +223,26 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
/* Use values found on a real PowerMac */
/* Uninorth main bus */
- dev = qdev_create(NULL, "uni-north-pci-pcihost");
+ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
- h = FROM_SYSBUS(PCIHostState, s);
- d = DO_UPCAST(UNINState, host_state, h);
+ s = SYS_BUS_DEVICE(dev);
+ h = PCI_HOST_BRIDGE(s);
+ d = UNI_NORTH_PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
0x80000000ULL, 0x70000000ULL);
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- d->host_state.bus = pci_register_bus(dev, "pci",
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4);
+ h->bus = pci_register_bus(dev, "pci",
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4);
#if 0
- pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north");
+ pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");
#endif
sysbus_mmio_map(s, 0, 0xf2800000);
@@ -242,30 +251,30 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
/* DEC 21154 bridge */
#if 0
/* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */
- pci_create_simple(d->host_state.bus, PCI_DEVFN(12, 0), "dec-21154");
+ pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154");
#endif
/* Uninorth AGP bus */
- pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north-agp");
- dev = qdev_create(NULL, "uni-north-agp-pcihost");
+ pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp");
+ dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
+ s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
/* Uninorth internal bus */
#if 0
/* XXX: not needed for now */
- pci_create_simple(d->host_state.bus, PCI_DEVFN(14, 0),
+ pci_create_simple(h->bus, PCI_DEVFN(14, 0),
"uni-north-internal-pci");
- dev = qdev_create(NULL, "uni-north-internal-pci-pcihost");
+ dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
+ s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, 0xf4800000);
sysbus_mmio_map(s, 1, 0xf4c00000);
#endif
- return d->host_state.bus;
+ return h->bus;
}
PCIBus *pci_pmac_u3_init(qemu_irq *pic,
@@ -279,11 +288,11 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
/* Uninorth AGP bus */
- dev = qdev_create(NULL, "u3-agp-pcihost");
+ dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE);
qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
- h = FROM_SYSBUS(PCIHostState, s);
- d = DO_UPCAST(UNINState, host_state, h);
+ s = SYS_BUS_DEVICE(dev);
+ h = PCI_HOST_BRIDGE(dev);
+ d = U3_AGP_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
@@ -291,19 +300,19 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- d->host_state.bus = pci_register_bus(dev, "pci",
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4);
+ h->bus = pci_register_bus(dev, "pci",
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
- pci_create_simple(d->host_state.bus, 11 << 3, "u3-agp");
+ pci_create_simple(h->bus, 11 << 3, "u3-agp");
- return d->host_state.bus;
+ return h->bus;
}
static int unin_main_pci_host_init(PCIDevice *d)
@@ -350,7 +359,7 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo unin_main_pci_host_info = {
+static const TypeInfo unin_main_pci_host_info = {
.name = "uni-north-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -368,7 +377,7 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo u3_agp_pci_host_info = {
+static const TypeInfo u3_agp_pci_host_info = {
.name = "u3-agp",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -386,7 +395,7 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo unin_agp_pci_host_info = {
+static const TypeInfo unin_agp_pci_host_info = {
.name = "uni-north-agp",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -404,7 +413,7 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
-static TypeInfo unin_internal_pci_host_info = {
+static const TypeInfo unin_internal_pci_host_info = {
.name = "uni-north-internal-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -418,9 +427,9 @@ static void pci_unin_main_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_main_init_device;
}
-static TypeInfo pci_unin_main_info = {
- .name = "uni-north-pci-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo pci_unin_main_info = {
+ .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_main_class_init,
};
@@ -432,9 +441,9 @@ static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
sbc->init = pci_u3_agp_init_device;
}
-static TypeInfo pci_u3_agp_info = {
- .name = "u3-agp-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo pci_u3_agp_info = {
+ .name = TYPE_U3_AGP_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_u3_agp_class_init,
};
@@ -446,9 +455,9 @@ static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_agp_init_device;
}
-static TypeInfo pci_unin_agp_info = {
- .name = "uni-north-agp-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo pci_unin_agp_info = {
+ .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_agp_class_init,
};
@@ -460,9 +469,9 @@ static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_internal_init_device;
}
-static TypeInfo pci_unin_internal_info = {
- .name = "uni-north-internal-pci-pcihost",
- .parent = TYPE_SYS_BUS_DEVICE,
+static const TypeInfo pci_unin_internal_info = {
+ .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_internal_class_init,
};
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index fd8fa90792..6f6d172fd0 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -533,7 +533,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
features |= (1 << VIRTIO_BLK_F_SCSI);
- features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
if (bdrv_enable_write_cache(s->bs))
features |= (1 << VIRTIO_BLK_F_WCE);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 35834cf493..651a000b9f 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -107,6 +107,7 @@ struct VirtIOBlkConf
};
#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
- DEFINE_VIRTIO_COMMON_FEATURES(_state, _field)
+ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
+ DEFINE_PROP_BIT("config-wce", _state, _field, VIRTIO_BLK_F_CONFIG_WCE, true)
#endif
diff --git a/iohandler.c b/iohandler.c
index 3c74de612b..dea43552d2 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -77,6 +77,7 @@ int qemu_set_fd_handler2(int fd,
ioh->fd_write = fd_write;
ioh->opaque = opaque;
ioh->deleted = 0;
+ qemu_notify_event();
}
return 0;
}
diff --git a/json-parser.c b/json-parser.c
index 849e2156da..457291b161 100644
--- a/json-parser.c
+++ b/json-parser.c
@@ -27,6 +27,11 @@
typedef struct JSONParserContext
{
Error *err;
+ struct {
+ QObject **buf;
+ size_t pos;
+ size_t count;
+ } tokens;
} JSONParserContext;
#define BUG_ON(cond) assert(!(cond))
@@ -40,7 +45,7 @@ typedef struct JSONParserContext
* 4) deal with premature EOI
*/
-static QObject *parse_value(JSONParserContext *ctxt, QList **tokens, va_list *ap);
+static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
/**
* Token manipulators
@@ -270,27 +275,111 @@ out:
return NULL;
}
+static QObject *parser_context_pop_token(JSONParserContext *ctxt)
+{
+ QObject *token;
+ g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+ token = ctxt->tokens.buf[ctxt->tokens.pos];
+ ctxt->tokens.pos++;
+ return token;
+}
+
+/* Note: parser_context_{peek|pop}_token do not increment the
+ * token object's refcount. In both cases the references will continue
+ * to be tracked and cleaned up in parser_context_free(), so do not
+ * attempt to free the token object.
+ */
+static QObject *parser_context_peek_token(JSONParserContext *ctxt)
+{
+ QObject *token;
+ g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+ token = ctxt->tokens.buf[ctxt->tokens.pos];
+ return token;
+}
+
+static JSONParserContext parser_context_save(JSONParserContext *ctxt)
+{
+ JSONParserContext saved_ctxt = {0};
+ saved_ctxt.tokens.pos = ctxt->tokens.pos;
+ saved_ctxt.tokens.count = ctxt->tokens.count;
+ saved_ctxt.tokens.buf = ctxt->tokens.buf;
+ return saved_ctxt;
+}
+
+static void parser_context_restore(JSONParserContext *ctxt,
+ JSONParserContext saved_ctxt)
+{
+ ctxt->tokens.pos = saved_ctxt.tokens.pos;
+ ctxt->tokens.count = saved_ctxt.tokens.count;
+ ctxt->tokens.buf = saved_ctxt.tokens.buf;
+}
+
+static void tokens_append_from_iter(QObject *obj, void *opaque)
+{
+ JSONParserContext *ctxt = opaque;
+ g_assert(ctxt->tokens.pos < ctxt->tokens.count);
+ ctxt->tokens.buf[ctxt->tokens.pos++] = obj;
+ qobject_incref(obj);
+}
+
+static JSONParserContext *parser_context_new(QList *tokens)
+{
+ JSONParserContext *ctxt;
+ size_t count;
+
+ if (!tokens) {
+ return NULL;
+ }
+
+ count = qlist_size(tokens);
+ if (count == 0) {
+ return NULL;
+ }
+
+ ctxt = g_malloc0(sizeof(JSONParserContext));
+ ctxt->tokens.pos = 0;
+ ctxt->tokens.count = count;
+ ctxt->tokens.buf = g_malloc(count * sizeof(QObject *));
+ qlist_iter(tokens, tokens_append_from_iter, ctxt);
+ ctxt->tokens.pos = 0;
+
+ return ctxt;
+}
+
+/* to support error propagation, ctxt->err must be freed separately */
+static void parser_context_free(JSONParserContext *ctxt)
+{
+ int i;
+ if (ctxt) {
+ for (i = 0; i < ctxt->tokens.count; i++) {
+ qobject_decref(ctxt->tokens.buf[i]);
+ }
+ g_free(ctxt->tokens.buf);
+ g_free(ctxt);
+ }
+}
+
/**
* Parsing rules
*/
-static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap)
+static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
{
QObject *key = NULL, *token = NULL, *value, *peek;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
- peek = qlist_peek(working);
+ peek = parser_context_peek_token(ctxt);
if (peek == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
}
- key = parse_value(ctxt, &working, ap);
+ key = parse_value(ctxt, ap);
if (!key || qobject_type(key) != QTYPE_QSTRING) {
parse_error(ctxt, peek, "key is not a string in object");
goto out;
}
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
@@ -301,7 +390,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_l
goto out;
}
- value = parse_value(ctxt, &working, ap);
+ value = parse_value(ctxt, ap);
if (value == NULL) {
parse_error(ctxt, token, "Missing value in dict");
goto out;
@@ -309,28 +398,24 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_l
qdict_put_obj(dict, qstring_get_str(qobject_to_qstring(key)), value);
- qobject_decref(token);
qobject_decref(key);
- QDECREF(*tokens);
- *tokens = working;
return 0;
out:
- qobject_decref(token);
+ parser_context_restore(ctxt, saved_ctxt);
qobject_decref(key);
- QDECREF(working);
return -1;
}
-static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
{
QDict *dict = NULL;
QObject *token, *peek;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
goto out;
}
@@ -338,23 +423,22 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a
if (!token_is_operator(token, '{')) {
goto out;
}
- qobject_decref(token);
token = NULL;
dict = qdict_new();
- peek = qlist_peek(working);
+ peek = parser_context_peek_token(ctxt);
if (peek == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
}
if (!token_is_operator(peek, '}')) {
- if (parse_pair(ctxt, dict, &working, ap) == -1) {
+ if (parse_pair(ctxt, dict, ap) == -1) {
goto out;
}
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
@@ -365,59 +449,52 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a
parse_error(ctxt, token, "expected separator in dict");
goto out;
}
- qobject_decref(token);
token = NULL;
- if (parse_pair(ctxt, dict, &working, ap) == -1) {
+ if (parse_pair(ctxt, dict, ap) == -1) {
goto out;
}
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
}
}
- qobject_decref(token);
token = NULL;
} else {
- token = qlist_pop(working);
- qobject_decref(token);
+ token = parser_context_pop_token(ctxt);
token = NULL;
}
- QDECREF(*tokens);
- *tokens = working;
-
return QOBJECT(dict);
out:
- qobject_decref(token);
- QDECREF(working);
+ parser_context_restore(ctxt, saved_ctxt);
QDECREF(dict);
return NULL;
}
-static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
{
QList *list = NULL;
QObject *token, *peek;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
goto out;
}
if (!token_is_operator(token, '[')) {
+ token = NULL;
goto out;
}
- qobject_decref(token);
token = NULL;
list = qlist_new();
- peek = qlist_peek(working);
+ peek = parser_context_peek_token(ctxt);
if (peek == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
@@ -426,7 +503,7 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
if (!token_is_operator(peek, ']')) {
QObject *obj;
- obj = parse_value(ctxt, &working, ap);
+ obj = parse_value(ctxt, ap);
if (obj == NULL) {
parse_error(ctxt, token, "expecting value");
goto out;
@@ -434,7 +511,7 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
qlist_append_obj(list, obj);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
@@ -446,10 +523,9 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
goto out;
}
- qobject_decref(token);
token = NULL;
- obj = parse_value(ctxt, &working, ap);
+ obj = parse_value(ctxt, ap);
if (obj == NULL) {
parse_error(ctxt, token, "expecting value");
goto out;
@@ -457,39 +533,33 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap
qlist_append_obj(list, obj);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
parse_error(ctxt, NULL, "premature EOI");
goto out;
}
}
- qobject_decref(token);
token = NULL;
} else {
- token = qlist_pop(working);
- qobject_decref(token);
+ token = parser_context_pop_token(ctxt);
token = NULL;
}
- QDECREF(*tokens);
- *tokens = working;
-
return QOBJECT(list);
out:
- qobject_decref(token);
- QDECREF(working);
+ parser_context_restore(ctxt, saved_ctxt);
QDECREF(list);
return NULL;
}
-static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens)
+static QObject *parse_keyword(JSONParserContext *ctxt)
{
QObject *token, *ret;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
goto out;
}
@@ -507,29 +577,24 @@ static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens)
goto out;
}
- qobject_decref(token);
- QDECREF(*tokens);
- *tokens = working;
-
return ret;
out:
- qobject_decref(token);
- QDECREF(working);
+ parser_context_restore(ctxt, saved_ctxt);
return NULL;
}
-static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
{
QObject *token = NULL, *obj;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
if (ap == NULL) {
goto out;
}
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
goto out;
}
@@ -553,25 +618,20 @@ static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *a
goto out;
}
- qobject_decref(token);
- QDECREF(*tokens);
- *tokens = working;
-
return obj;
out:
- qobject_decref(token);
- QDECREF(working);
+ parser_context_restore(ctxt, saved_ctxt);
return NULL;
}
-static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens)
+static QObject *parse_literal(JSONParserContext *ctxt)
{
QObject *token, *obj;
- QList *working = qlist_copy(*tokens);
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
- token = qlist_pop(working);
+ token = parser_context_pop_token(ctxt);
if (token == NULL) {
goto out;
}
@@ -591,35 +651,30 @@ static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens)
goto out;
}
- qobject_decref(token);
- QDECREF(*tokens);
- *tokens = working;
-
return obj;
out:
- qobject_decref(token);
- QDECREF(working);
+ parser_context_restore(ctxt, saved_ctxt);
return NULL;
}
-static QObject *parse_value(JSONParserContext *ctxt, QList **tokens, va_list *ap)
+static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
{
QObject *obj;
- obj = parse_object(ctxt, tokens, ap);
+ obj = parse_object(ctxt, ap);
if (obj == NULL) {
- obj = parse_array(ctxt, tokens, ap);
+ obj = parse_array(ctxt, ap);
}
if (obj == NULL) {
- obj = parse_escape(ctxt, tokens, ap);
+ obj = parse_escape(ctxt, ap);
}
if (obj == NULL) {
- obj = parse_keyword(ctxt, tokens);
+ obj = parse_keyword(ctxt);
}
if (obj == NULL) {
- obj = parse_literal(ctxt, tokens);
+ obj = parse_literal(ctxt);
}
return obj;
@@ -632,19 +687,18 @@ QObject *json_parser_parse(QList *tokens, va_list *ap)
QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
{
- JSONParserContext ctxt = {};
- QList *working;
+ JSONParserContext *ctxt = parser_context_new(tokens);
QObject *result;
- if (!tokens) {
+ if (!ctxt) {
return NULL;
}
- working = qlist_copy(tokens);
- result = parse_value(&ctxt, &working, ap);
- QDECREF(working);
+ result = parse_value(ctxt, ap);
+
+ error_propagate(errp, ctxt->err);
- error_propagate(errp, ctxt.err);
+ parser_context_free(ctxt);
return result;
}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 41c869bfe0..11743065e9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2848,7 +2848,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
return -TARGET_EFAULT;
- host_mb = malloc(msgsz+sizeof(long));
+ host_mb = g_malloc(msgsz+sizeof(long));
ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
if (ret > 0) {
@@ -2863,11 +2863,11 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
}
target_mb->mtype = tswapal(host_mb->mtype);
- free(host_mb);
end:
if (target_mb)
unlock_user_struct(target_mb, msgp, 1);
+ g_free(host_mb);
return ret;
}
diff --git a/osdep.c b/osdep.c
index 5b78ceebef..3b25297a25 100644
--- a/osdep.c
+++ b/osdep.c
@@ -113,7 +113,13 @@ static int qemu_dup_flags(int fd, int flags)
}
/* Set/unset flags that we can with fcntl */
- setfl_flags = O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK;
+ setfl_flags = O_APPEND | O_ASYNC | O_NONBLOCK;
+#ifdef O_NOATIME
+ setfl_flags |= O_NOATIME;
+#endif
+#ifdef O_DIRECT
+ setfl_flags |= O_DIRECT;
+#endif
dup_flags &= ~setfl_flags;
dup_flags |= (flags & setfl_flags);
if (fcntl(ret, F_SETFL, dup_flags) == -1) {
diff --git a/osdep.h b/osdep.h
index d4b887d542..cb213e0295 100644
--- a/osdep.h
+++ b/osdep.h
@@ -103,6 +103,11 @@ void qemu_vfree(void *ptr);
#else
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
#endif
+#ifdef MADV_DONTDUMP
+#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
+#else
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+#endif
#elif defined(CONFIG_POSIX_MADVISE)
@@ -110,6 +115,7 @@ void qemu_vfree(void *ptr);
#define QEMU_MADV_DONTNEED POSIX_MADV_DONTNEED
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
#else /* no-op */
@@ -117,6 +123,7 @@ void qemu_vfree(void *ptr);
#define QEMU_MADV_DONTNEED QEMU_MADV_INVALID
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
#endif
diff --git a/pc-bios/README b/pc-bios/README
index f4b37d66dc..fc07ebc21c 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -12,7 +12,7 @@
1275-1994 (referred to as Open Firmware) compliant firmware.
The included images for PowerPC (for 32 and 64 bit PPC CPUs),
Sparc32 and Sparc64 are built from OpenBIOS SVN revision
- 1060.
+ 1062.
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
implementation for certain IBM POWER hardware. The sources are at
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index aeae265880..1c3753d3eb 100644
--- a/pc-bios/openbios-ppc
+++ b/pc-bios/openbios-ppc
Binary files differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index d90c4e59a0..6bd8e45d86 100644
--- a/pc-bios/openbios-sparc32
+++ b/pc-bios/openbios-sparc32
Binary files differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index 457d264228..7c06fcc5aa 100644
--- a/pc-bios/openbios-sparc64
+++ b/pc-bios/openbios-sparc64
Binary files differ
diff --git a/qapi-schema.json b/qapi-schema.json
index 3d2b2d175a..72b3c4d5bd 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2454,3 +2454,42 @@
#
##
{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
+
+##
+# @TargetType
+#
+# Target CPU emulation type
+#
+# These parameters correspond to the softmmu binary CPU name that is currently
+# running.
+#
+# Since: 1.2.0
+##
+{ 'enum': 'TargetType',
+ 'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',
+ 'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'or32',
+ 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4', 'sparc64',
+ 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }
+
+##
+# @TargetInfo:
+#
+# Information describing the QEMU target.
+#
+# @arch: the target architecture (eg "x86_64", "i386", etc)
+#
+# Since: 1.2.0
+##
+{ 'type': 'TargetInfo',
+ 'data': { 'arch': 'TargetType' } }
+
+##
+# @query-target:
+#
+# Return information about the target for this QEMU
+#
+# Returns: TargetInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-target', 'returns': 'TargetInfo' }
diff --git a/qemu-char.c b/qemu-char.c
index 10d1504948..398baf1e04 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2141,14 +2141,17 @@ typedef struct {
static void tcp_chr_accept(void *opaque);
+static void tcp_chr_connect(void *opaque);
+
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
TCPCharDriver *s = chr->opaque;
if (s->connected) {
return send_all(s->fd, buf, len);
} else {
- /* XXX: indicate an error ? */
- return len;
+ /* (Re-)connect for unconnected writing */
+ tcp_chr_connect(chr);
+ return 0;
}
}
diff --git a/qemu-config.c b/qemu-config.c
index 5c3296b8c6..c05ffbc444 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -362,6 +362,19 @@ static QemuOptsList qemu_global_opts = {
},
};
+QemuOptsList qemu_sandbox_opts = {
+ .name = "sandbox",
+ .implied_opt_name = "enable",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head),
+ .desc = {
+ {
+ .name = "enable",
+ .type = QEMU_OPT_BOOL,
+ },
+ { /* end of list */ }
+ },
+};
+
static QemuOptsList qemu_mon_opts = {
.name = "mon",
.implied_opt_name = "chardev",
@@ -595,6 +608,10 @@ static QemuOptsList qemu_machine_opts = {
.name = "dt_compatible",
.type = QEMU_OPT_STRING,
.help = "Overrides the \"compatible\" property of the dt root node",
+ }, {
+ .name = "dump-guest-core",
+ .type = QEMU_OPT_BOOL,
+ .help = "Include guest memory in a core dump",
},
{ /* End of list */ }
},
@@ -641,6 +658,7 @@ static QemuOptsList *vm_config_groups[32] = {
&qemu_machine_opts,
&qemu_boot_opts,
&qemu_iscsi_opts,
+ &qemu_sandbox_opts,
NULL,
};
diff --git a/qemu-config.h b/qemu-config.h
index 12ddf3ed97..5557562c33 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -6,6 +6,7 @@
extern QemuOptsList qemu_fsdev_opts;
extern QemuOptsList qemu_virtfs_opts;
extern QemuOptsList qemu_spice_opts;
+extern QemuOptsList qemu_sandbox_opts;
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
diff --git a/qemu-ga.c b/qemu-ga.c
index 8f87621ae4..26671fee3f 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -247,6 +247,9 @@ static bool ga_open_pidfile(const char *pidfile)
pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) {
g_critical("Cannot lock pid file, %s", strerror(errno));
+ if (pidfd != -1) {
+ close(pidfd);
+ }
return false;
}
diff --git a/qemu-options.hx b/qemu-options.hx
index 47cb5bd311..3c411c427e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -37,7 +37,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\n"
- " kvm_shadow_mem=size of KVM shadow MMU\n",
+ " kvm_shadow_mem=size of KVM shadow MMU\n"
+ " dump-guest-core=on|off include guest memory in a core dump (default=on)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -54,6 +55,8 @@ to initialize.
Enables in-kernel irqchip support for the chosen accelerator when available.
@item kvm_shadow_mem=size
Defines the size of the KVM shadow MMU.
+@item dump-guest-core=on|off
+Include guest memory in a core dump. The default is on.
@end table
ETEXI
@@ -2720,6 +2723,16 @@ STEXI
Old param mode (ARM only).
ETEXI
+DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \
+ "-sandbox <arg> Enable seccomp mode 2 system call filter (default 'off').\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -sandbox
+@findex -sandbox
+Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will
+disable it. The default is 'off'.
+ETEXI
+
DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
"-readconfig <file>\n", QEMU_ARCH_ALL)
STEXI
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
new file mode 100644
index 0000000000..64329a3c09
--- /dev/null
+++ b/qemu-seccomp.c
@@ -0,0 +1,141 @@
+/*
+ * QEMU seccomp mode 2 support with libseccomp
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Eduardo Otubo <eotubo@br.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#include <stdio.h>
+#include <seccomp.h>
+#include "qemu-seccomp.h"
+
+struct QemuSeccompSyscall {
+ int32_t num;
+ uint8_t priority;
+};
+
+static const struct QemuSeccompSyscall seccomp_whitelist[] = {
+ { SCMP_SYS(timer_settime), 255 },
+ { SCMP_SYS(timer_gettime), 254 },
+ { SCMP_SYS(futex), 253 },
+ { SCMP_SYS(select), 252 },
+ { SCMP_SYS(recvfrom), 251 },
+ { SCMP_SYS(sendto), 250 },
+ { SCMP_SYS(read), 249 },
+ { SCMP_SYS(brk), 248 },
+ { SCMP_SYS(clone), 247 },
+ { SCMP_SYS(mmap), 247 },
+ { SCMP_SYS(mprotect), 246 },
+ { SCMP_SYS(execve), 245 },
+ { SCMP_SYS(open), 245 },
+ { SCMP_SYS(ioctl), 245 },
+ { SCMP_SYS(recvmsg), 245 },
+ { SCMP_SYS(sendmsg), 245 },
+ { SCMP_SYS(accept), 245 },
+ { SCMP_SYS(connect), 245 },
+ { SCMP_SYS(gettimeofday), 245 },
+ { SCMP_SYS(readlink), 245 },
+ { SCMP_SYS(access), 245 },
+ { SCMP_SYS(prctl), 245 },
+ { SCMP_SYS(signalfd), 245 },
+#if defined(__i386__)
+ { SCMP_SYS(fcntl64), 245 },
+ { SCMP_SYS(fstat64), 245 },
+ { SCMP_SYS(stat64), 245 },
+ { SCMP_SYS(getgid32), 245 },
+ { SCMP_SYS(getegid32), 245 },
+ { SCMP_SYS(getuid32), 245 },
+ { SCMP_SYS(geteuid32), 245 },
+ { SCMP_SYS(sigreturn), 245 },
+ { SCMP_SYS(_newselect), 245 },
+ { SCMP_SYS(_llseek), 245 },
+ { SCMP_SYS(mmap2), 245},
+ { SCMP_SYS(sigprocmask), 245 },
+#elif defined(__x86_64__)
+ { SCMP_SYS(sched_getparam), 245},
+ { SCMP_SYS(sched_getscheduler), 245},
+ { SCMP_SYS(fstat), 245},
+ { SCMP_SYS(clock_getres), 245},
+ { SCMP_SYS(sched_get_priority_min), 245},
+ { SCMP_SYS(sched_get_priority_max), 245},
+ { SCMP_SYS(stat), 245},
+ { SCMP_SYS(socket), 245},
+ { SCMP_SYS(setsockopt), 245},
+ { SCMP_SYS(uname), 245},
+ { SCMP_SYS(semget), 245},
+#endif
+ { SCMP_SYS(eventfd2), 245 },
+ { SCMP_SYS(dup), 245 },
+ { SCMP_SYS(gettid), 245 },
+ { SCMP_SYS(timer_create), 245 },
+ { SCMP_SYS(exit), 245 },
+ { SCMP_SYS(clock_gettime), 245 },
+ { SCMP_SYS(time), 245 },
+ { SCMP_SYS(restart_syscall), 245 },
+ { SCMP_SYS(pwrite64), 245 },
+ { SCMP_SYS(chown), 245 },
+ { SCMP_SYS(openat), 245 },
+ { SCMP_SYS(getdents), 245 },
+ { SCMP_SYS(timer_delete), 245 },
+ { SCMP_SYS(exit_group), 245 },
+ { SCMP_SYS(rt_sigreturn), 245 },
+ { SCMP_SYS(sync), 245 },
+ { SCMP_SYS(pread64), 245 },
+ { SCMP_SYS(madvise), 245 },
+ { SCMP_SYS(set_robust_list), 245 },
+ { SCMP_SYS(lseek), 245 },
+ { SCMP_SYS(pselect6), 245 },
+ { SCMP_SYS(fork), 245 },
+ { SCMP_SYS(bind), 245 },
+ { SCMP_SYS(listen), 245 },
+ { SCMP_SYS(eventfd), 245 },
+ { SCMP_SYS(rt_sigprocmask), 245 },
+ { SCMP_SYS(write), 244 },
+ { SCMP_SYS(fcntl), 243 },
+ { SCMP_SYS(tgkill), 242 },
+ { SCMP_SYS(rt_sigaction), 242 },
+ { SCMP_SYS(pipe2), 242 },
+ { SCMP_SYS(munmap), 242 },
+ { SCMP_SYS(mremap), 242 },
+ { SCMP_SYS(getsockname), 242 },
+ { SCMP_SYS(getpeername), 242 },
+ { SCMP_SYS(fdatasync), 242 },
+ { SCMP_SYS(close), 242 }
+};
+
+int seccomp_start(void)
+{
+ int rc = 0;
+ unsigned int i = 0;
+ scmp_filter_ctx ctx;
+
+ ctx = seccomp_init(SCMP_ACT_KILL);
+ if (ctx == NULL) {
+ goto seccomp_return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(seccomp_whitelist); i++) {
+ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, seccomp_whitelist[i].num, 0);
+ if (rc < 0) {
+ goto seccomp_return;
+ }
+ rc = seccomp_syscall_priority(ctx, seccomp_whitelist[i].num,
+ seccomp_whitelist[i].priority);
+ if (rc < 0) {
+ goto seccomp_return;
+ }
+ }
+
+ rc = seccomp_load(ctx);
+
+ seccomp_return:
+ seccomp_release(ctx);
+ return rc;
+}
diff --git a/qemu-seccomp.h b/qemu-seccomp.h
new file mode 100644
index 0000000000..b2fc3f8c3c
--- /dev/null
+++ b/qemu-seccomp.h
@@ -0,0 +1,22 @@
+/*
+ * QEMU seccomp mode 2 support with libseccomp
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Eduardo Otubo <eotubo@br.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#ifndef QEMU_SECCOMP_H
+#define QEMU_SECCOMP_H
+
+#include <seccomp.h>
+#include "osdep.h"
+
+int seccomp_start(void);
+#endif
diff --git a/qlist.c b/qlist.c
index 88498b157f..b48ec5b914 100644
--- a/qlist.c
+++ b/qlist.c
@@ -124,6 +124,19 @@ int qlist_empty(const QList *qlist)
return QTAILQ_EMPTY(&qlist->head);
}
+static void qlist_size_iter(QObject *obj, void *opaque)
+{
+ size_t *count = opaque;
+ (*count)++;
+}
+
+size_t qlist_size(const QList *qlist)
+{
+ size_t count = 0;
+ qlist_iter(qlist, qlist_size_iter, &count);
+ return count;
+}
+
/**
* qobject_to_qlist(): Convert a QObject into a QList
*/
diff --git a/qlist.h b/qlist.h
index d426bd4a4b..ae776f99c3 100644
--- a/qlist.h
+++ b/qlist.h
@@ -49,6 +49,7 @@ void qlist_iter(const QList *qlist,
QObject *qlist_pop(QList *qlist);
QObject *qlist_peek(QList *qlist);
int qlist_empty(const QList *qlist);
+size_t qlist_size(const QList *qlist);
QList *qobject_to_qlist(const QObject *obj);
static inline const QListEntry *qlist_first(const QList *qlist)
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 2ce4ce6556..00d798fe55 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2509,3 +2509,8 @@ EQMP
.mhandler.cmd_new = qmp_marshal_input_query_cpu_definitions,
},
+ {
+ .name = "query-target",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_target,
+ },
diff --git a/rules.mak b/rules.mak
index a28494679a..1b173aa981 100644
--- a/rules.mak
+++ b/rules.mak
@@ -29,7 +29,7 @@ endif
$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," AS $(TARGET_DIR)$@")
%.o: %.m
- $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@")
+ $(call quiet-command,$(OBJCC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@")
LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(1)) $(LIBS)," LINK $(TARGET_DIR)$@")
diff --git a/softmmu-semi.h b/softmmu-semi.h
index 648cb959d8..bcb979a5b0 100644
--- a/softmmu-semi.h
+++ b/softmmu-semi.h
@@ -40,7 +40,7 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
uint8_t *p;
/* TODO: Make this something that isn't fixed size. */
p = malloc(len);
- if (copy)
+ if (p && copy)
cpu_memory_rw_debug(env, addr, p, len, 0);
return p;
}
@@ -52,6 +52,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
uint8_t c;
/* TODO: Make this something that isn't fixed size. */
s = p = malloc(1024);
+ if (!s) {
+ return NULL;
+ }
do {
cpu_memory_rw_debug(env, addr, &c, 1, 0);
addr++;
diff --git a/sysemu.h b/sysemu.h
index 4669348a12..65552acee5 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -62,6 +62,7 @@ int qemu_powerdown_requested(void);
void qemu_system_killed(int signal, pid_t pid);
void qemu_kill_report(void);
extern qemu_irq qemu_system_powerdown;
+void qemu_devices_reset(void);
void qemu_system_reset(bool report);
void qemu_add_exit_notifier(Notifier *notify);
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 24952061cf..73bde584ab 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -194,18 +194,19 @@ uint32_t do_arm_semihosting(CPUARMState *env)
if (!(s = lock_user_string(ARG(0))))
/* FIXME - should this error code be -TARGET_EFAULT ? */
return (uint32_t)-1;
- if (ARG(1) >= 12)
+ if (ARG(1) >= 12) {
+ unlock_user(s, ARG(0), 0);
return (uint32_t)-1;
+ }
if (strcmp(s, ":tt") == 0) {
- if (ARG(1) < 4)
- return STDIN_FILENO;
- else
- return STDOUT_FILENO;
+ int result_fileno = ARG(1) < 4 ? STDIN_FILENO : STDOUT_FILENO;
+ unlock_user(s, ARG(0), 0);
+ return result_fileno;
}
if (use_gdb_syscalls()) {
gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
(int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
- return env->regs[0];
+ ret = env->regs[0];
} else {
ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 526e25ef6d..3b896f5f9c 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -466,6 +466,58 @@ static void simple_dict(void)
}
}
+/*
+ * this generates json of the form:
+ * a(0,m) = [0, 1, ..., m-1]
+ * a(n,m) = {
+ * 'key0': a(0,m),
+ * 'key1': a(1,m),
+ * ...
+ * 'key(n-1)': a(n-1,m)
+ * }
+ */
+static void gen_test_json(GString *gstr, int nest_level_max,
+ int elem_count)
+{
+ int i;
+
+ g_assert(gstr);
+ if (nest_level_max == 0) {
+ g_string_append(gstr, "[");
+ for (i = 0; i < elem_count; i++) {
+ g_string_append_printf(gstr, "%d", i);
+ if (i < elem_count - 1) {
+ g_string_append_printf(gstr, ", ");
+ }
+ }
+ g_string_append(gstr, "]");
+ return;
+ }
+
+ g_string_append(gstr, "{");
+ for (i = 0; i < nest_level_max; i++) {
+ g_string_append_printf(gstr, "'key%d': ", i);
+ gen_test_json(gstr, i, elem_count);
+ if (i < nest_level_max - 1) {
+ g_string_append(gstr, ",");
+ }
+ }
+ g_string_append(gstr, "}");
+}
+
+static void large_dict(void)
+{
+ GString *gstr = g_string_new("");
+ QObject *obj;
+
+ gen_test_json(gstr, 10, 100);
+ obj = qobject_from_json(gstr->str);
+ g_assert(obj != NULL);
+
+ qobject_decref(obj);
+ g_string_free(gstr, true);
+}
+
static void simple_list(void)
{
int i;
@@ -706,6 +758,7 @@ int main(int argc, char **argv)
g_test_add_func("/literals/keyword", keyword_literal);
g_test_add_func("/dicts/simple_dict", simple_dict);
+ g_test_add_func("/dicts/large_dict", large_dict);
g_test_add_func("/lists/simple_list", simple_list);
g_test_add_func("/whitespace/simple_whitespace", simple_whitespace);
diff --git a/vl.c b/vl.c
index d01256a6a3..7c577fa544 100644
--- a/vl.c
+++ b/vl.c
@@ -63,6 +63,11 @@
#include <linux/ppdev.h>
#include <linux/parport.h>
#endif
+
+#ifdef CONFIG_SECCOMP
+#include "qemu-seccomp.h"
+#endif
+
#ifdef __sun__
#include <sys/stat.h>
#include <sys/ethernet.h>
@@ -765,6 +770,26 @@ static int bt_parse(const char *opt)
return 1;
}
+static int parse_sandbox(QemuOpts *opts, void *opaque)
+{
+ /* FIXME: change this to true for 1.3 */
+ if (qemu_opt_get_bool(opts, "enable", false)) {
+#ifdef CONFIG_SECCOMP
+ if (seccomp_start() < 0) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "failed to install seccomp syscall filter in the kernel");
+ return -1;
+ }
+#else
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "sandboxing request but seccomp is not compiled into this build");
+ return -1;
+#endif
+ }
+
+ return 0;
+}
+
/***********************************************************/
/* QEMU Block devices */
@@ -1439,7 +1464,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
}
}
-void qemu_system_reset(bool report)
+void qemu_devices_reset(void)
{
QEMUResetEntry *re, *nre;
@@ -1447,6 +1472,15 @@ void qemu_system_reset(bool report)
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
re->func(re->opaque);
}
+}
+
+void qemu_system_reset(bool report)
+{
+ if (current_machine && current_machine->reset) {
+ current_machine->reset();
+ } else {
+ qemu_devices_reset();
+ }
if (report) {
monitor_protocol_event(QEVENT_RESET, NULL);
}
@@ -2701,6 +2735,7 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_m: {
int64_t value;
+ uint64_t sz;
char *end;
value = strtosz(optarg, &end);
@@ -2708,12 +2743,12 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
exit(1);
}
-
- if (value != (uint64_t)(ram_addr_t)value) {
+ sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+ ram_size = sz;
+ if (ram_size != sz) {
fprintf(stderr, "qemu: ram size too large\n");
exit(1);
}
- ram_size = value;
break;
}
case QEMU_OPTION_mempath:
@@ -3247,6 +3282,12 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_qtest_log:
qtest_log = optarg;
break;
+ case QEMU_OPTION_sandbox:
+ opts = qemu_opts_parse(qemu_find_opts("sandbox"), optarg, 1);
+ if (!opts) {
+ exit(0);
+ }
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
@@ -3254,6 +3295,10 @@ int main(int argc, char **argv, char **envp)
}
loc_set_none();
+ if (qemu_opts_foreach(qemu_find_opts("sandbox"), parse_sandbox, NULL, 0)) {
+ exit(1);
+ }
+
if (machine == NULL) {
fprintf(stderr, "No machine found.\n");
exit(1);