summaryrefslogtreecommitdiff
path: root/hw/core
diff options
context:
space:
mode:
authorhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
committerhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
commit2a84d37c88d606fda46a565bcc80e173b4d0a80a (patch)
tree8b755bb78271e76e13fb7db38b670dbc443479e7 /hw/core
parentbd54c25035217800f3b1d39f6472d599cd602d5a (diff)
downloadqemu-upstream.tar.gz
qemu-upstream.tar.bz2
qemu-upstream.zip
Imported Upstream version 2.6.1upstream/2.6.1upstream
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/Makefile.objs4
-rw-r--r--hw/core/bus.c251
-rw-r--r--hw/core/hotplug.c11
-rw-r--r--hw/core/loader.c6
-rw-r--r--hw/core/machine.c70
-rw-r--r--hw/core/nmi.c19
-rw-r--r--hw/core/ptimer.c83
-rw-r--r--hw/core/qdev-properties-system.c75
-rw-r--r--hw/core/qdev-properties.c42
-rw-r--r--hw/core/qdev.c278
-rw-r--r--hw/core/register.c287
-rw-r--r--hw/core/sysbus.c4
-rw-r--r--hw/core/uboot_image.h6
13 files changed, 351 insertions, 785 deletions
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index cfd484039..abb3560be 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -1,11 +1,10 @@
# core qdev-related obj files, also used by *-user:
common-obj-y += qdev.o qdev-properties.o
-common-obj-y += bus.o
common-obj-y += fw-path-provider.o
# irq.o needed for qdev GPIO handling:
common-obj-y += irq.o
common-obj-y += hotplug.o
-obj-y += nmi.o
+common-obj-y += nmi.o
common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_XILINX_AXI) += stream.o
@@ -15,5 +14,4 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
common-obj-$(CONFIG_SOFTMMU) += loader.o
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
-common-obj-$(CONFIG_SOFTMMU) += register.o
common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
diff --git a/hw/core/bus.c b/hw/core/bus.c
deleted file mode 100644
index 3e3f8ac74..000000000
--- a/hw/core/bus.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Dynamic device configuration and creation -- buses.
- *
- * Copyright (c) 2009 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "hw/qdev.h"
-#include "qapi/error.h"
-
-static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
- Error **errp)
-{
-
- object_property_set_link(OBJECT(bus), OBJECT(handler),
- QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
-}
-
-void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
-{
- qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
-}
-
-void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
-{
- qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
-}
-
-int qbus_walk_children(BusState *bus,
- qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
- qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
- void *opaque)
-{
- BusChild *kid;
- int err;
-
- if (pre_busfn) {
- err = pre_busfn(bus, opaque);
- if (err) {
- return err;
- }
- }
-
- QTAILQ_FOREACH(kid, &bus->children, sibling) {
- err = qdev_walk_children(kid->child,
- pre_devfn, pre_busfn,
- post_devfn, post_busfn, opaque);
- if (err < 0) {
- return err;
- }
- }
-
- if (post_busfn) {
- err = post_busfn(bus, opaque);
- if (err) {
- return err;
- }
- }
-
- return 0;
-}
-
-static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
-{
- const char *typename = object_get_typename(OBJECT(bus));
- BusClass *bc;
- char *buf;
- int i, len, bus_id;
-
- bus->parent = parent;
-
- if (name) {
- bus->name = g_strdup(name);
- } else if (bus->parent && bus->parent->id) {
- /* parent device has id -> use it plus parent-bus-id for bus name */
- bus_id = bus->parent->num_child_bus;
-
- len = strlen(bus->parent->id) + 16;
- buf = g_malloc(len);
- snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
- bus->name = buf;
- } else {
- /* no id -> use lowercase bus type plus global bus-id for bus name */
- bc = BUS_GET_CLASS(bus);
- bus_id = bc->automatic_ids++;
-
- len = strlen(typename) + 16;
- buf = g_malloc(len);
- len = snprintf(buf, len, "%s.%d", typename, bus_id);
- for (i = 0; i < len; i++) {
- buf[i] = qemu_tolower(buf[i]);
- }
- bus->name = buf;
- }
-
- if (bus->parent) {
- QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
- bus->parent->num_child_bus++;
- object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
- object_unref(OBJECT(bus));
- } else if (bus != sysbus_get_default()) {
- /* TODO: once all bus devices are qdevified,
- only reset handler for main_system_bus should be registered here. */
- qemu_register_reset(qbus_reset_all_fn, bus);
- }
-}
-
-static void bus_unparent(Object *obj)
-{
- BusState *bus = BUS(obj);
- BusChild *kid;
-
- while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
- DeviceState *dev = kid->child;
- object_unparent(OBJECT(dev));
- }
- if (bus->parent) {
- QLIST_REMOVE(bus, sibling);
- bus->parent->num_child_bus--;
- bus->parent = NULL;
- } else {
- assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
- qemu_unregister_reset(qbus_reset_all_fn, bus);
- }
-}
-
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
- DeviceState *parent, const char *name)
-{
- object_initialize(bus, size, typename);
- qbus_realize(bus, parent, name);
-}
-
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
-{
- BusState *bus;
-
- bus = BUS(object_new(typename));
- qbus_realize(bus, parent, name);
-
- return bus;
-}
-
-static bool bus_get_realized(Object *obj, Error **errp)
-{
- BusState *bus = BUS(obj);
-
- return bus->realized;
-}
-
-static void bus_set_realized(Object *obj, bool value, Error **errp)
-{
- BusState *bus = BUS(obj);
- BusClass *bc = BUS_GET_CLASS(bus);
- BusChild *kid;
- Error *local_err = NULL;
-
- if (value && !bus->realized) {
- if (bc->realize) {
- bc->realize(bus, &local_err);
- }
-
- /* TODO: recursive realization */
- } else if (!value && bus->realized) {
- QTAILQ_FOREACH(kid, &bus->children, sibling) {
- DeviceState *dev = kid->child;
- object_property_set_bool(OBJECT(dev), false, "realized",
- &local_err);
- if (local_err != NULL) {
- break;
- }
- }
- if (bc->unrealize && local_err == NULL) {
- bc->unrealize(bus, &local_err);
- }
- }
-
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- bus->realized = value;
-}
-
-static void qbus_initfn(Object *obj)
-{
- BusState *bus = BUS(obj);
-
- QTAILQ_INIT(&bus->children);
- object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
- TYPE_HOTPLUG_HANDLER,
- (Object **)&bus->hotplug_handler,
- object_property_allow_set_link,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- NULL);
- object_property_add_bool(obj, "realized",
- bus_get_realized, bus_set_realized, NULL);
-}
-
-static char *default_bus_get_fw_dev_path(DeviceState *dev)
-{
- return g_strdup(object_get_typename(OBJECT(dev)));
-}
-
-static void bus_class_init(ObjectClass *class, void *data)
-{
- BusClass *bc = BUS_CLASS(class);
-
- class->unparent = bus_unparent;
- bc->get_fw_dev_path = default_bus_get_fw_dev_path;
-}
-
-static void qbus_finalize(Object *obj)
-{
- BusState *bus = BUS(obj);
-
- g_free((char *)bus->name);
-}
-
-static const TypeInfo bus_info = {
- .name = TYPE_BUS,
- .parent = TYPE_OBJECT,
- .instance_size = sizeof(BusState),
- .abstract = true,
- .class_size = sizeof(BusClass),
- .instance_init = qbus_initfn,
- .instance_finalize = qbus_finalize,
- .class_init = bus_class_init,
-};
-
-static void bus_register_types(void)
-{
- type_register_static(&bus_info);
-}
-
-type_init(bus_register_types)
diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c
index 17ac98668..645cfca1b 100644
--- a/hw/core/hotplug.c
+++ b/hw/core/hotplug.c
@@ -13,17 +13,6 @@
#include "hw/hotplug.h"
#include "qemu/module.h"
-void hotplug_handler_pre_plug(HotplugHandler *plug_handler,
- DeviceState *plugged_dev,
- Error **errp)
-{
- HotplugHandlerClass *hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler);
-
- if (hdc->pre_plug) {
- hdc->pre_plug(plug_handler, plugged_dev, errp);
- }
-}
-
void hotplug_handler_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev,
Error **errp)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 53e0e4155..c0499571c 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -914,16 +914,10 @@ int rom_add_file(const char *file, const char *fw_dir,
err:
if (fd != -1)
close(fd);
-
g_free(rom->data);
g_free(rom->path);
g_free(rom->name);
- if (fw_dir) {
- g_free(rom->fw_dir);
- g_free(rom->fw_file);
- }
g_free(rom);
-
return -1;
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index e5a456f21..6dbbc85b9 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -65,9 +65,6 @@ static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
ms->kernel_irqchip_split = true;
break;
default:
- /* The value was checked in visit_type_OnOffSplit() above. If
- * we get here, then something is wrong in QEMU.
- */
abort();
}
}
@@ -260,47 +257,47 @@ static void machine_set_usb(Object *obj, bool value, Error **errp)
ms->usb_disabled = !value;
}
-static bool machine_get_graphics(Object *obj, Error **errp)
+static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
- return ms->enable_graphics;
+ return ms->igd_gfx_passthru;
}
-static void machine_set_graphics(Object *obj, bool value, Error **errp)
+static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
{
MachineState *ms = MACHINE(obj);
- ms->enable_graphics = value;
+ ms->igd_gfx_passthru = value;
}
-static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
+static char *machine_get_firmware(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
- return ms->igd_gfx_passthru;
+ return g_strdup(ms->firmware);
}
-static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
+static void machine_set_firmware(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
- ms->igd_gfx_passthru = value;
+ g_free(ms->firmware);
+ ms->firmware = g_strdup(value);
}
-static char *machine_get_firmware(Object *obj, Error **errp)
+static bool machine_get_iommu(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
- return g_strdup(ms->firmware);
+ return ms->iommu;
}
-static void machine_set_firmware(Object *obj, const char *value, Error **errp)
+static void machine_set_iommu(Object *obj, bool value, Error **errp)
{
MachineState *ms = MACHINE(obj);
- g_free(ms->firmware);
- ms->firmware = g_strdup(value);
+ ms->iommu = value;
}
static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
@@ -385,7 +382,6 @@ static void machine_initfn(Object *obj)
ms->kvm_shadow_mem = -1;
ms->dump_guest_core = true;
ms->mem_merge = true;
- ms->enable_graphics = true;
object_property_add_str(obj, "accel",
machine_get_accel, machine_set_accel, NULL);
@@ -464,12 +460,6 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "usb",
"Set on/off to enable/disable usb",
NULL);
- object_property_add_bool(obj, "graphics",
- machine_get_graphics,
- machine_set_graphics, NULL);
- object_property_set_description(obj, "graphics",
- "Set on/off to enable/disable graphics emulation",
- NULL);
object_property_add_bool(obj, "igd-passthru",
machine_get_igd_gfx_passthru,
machine_set_igd_gfx_passthru, NULL);
@@ -482,6 +472,12 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "firmware",
"Firmware image",
NULL);
+ object_property_add_bool(obj, "iommu",
+ machine_get_iommu,
+ machine_set_iommu, NULL);
+ object_property_set_description(obj, "iommu",
+ "Set on/off to enable/disable Intel IOMMU (VT-d)",
+ NULL);
object_property_add_bool(obj, "suppress-vmdesc",
machine_get_suppress_vmdesc,
machine_set_suppress_vmdesc, NULL);
@@ -554,33 +550,6 @@ bool machine_mem_merge(MachineState *machine)
return machine->mem_merge;
}
-static void machine_class_finalize(ObjectClass *klass, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(klass);
-
- if (mc->compat_props) {
- g_array_free(mc->compat_props, true);
- }
-}
-
-void machine_register_compat_props(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- int i;
- GlobalProperty *p;
-
- if (!mc->compat_props) {
- return;
- }
-
- for (i = 0; i < mc->compat_props->len; i++) {
- p = g_array_index(mc->compat_props, GlobalProperty *, i);
- /* Machine compat_props must never cause errors: */
- p->errp = &error_abort;
- qdev_prop_register_global(p);
- }
-}
-
static const TypeInfo machine_info = {
.name = TYPE_MACHINE,
.parent = TYPE_OBJECT,
@@ -588,7 +557,6 @@ static const TypeInfo machine_info = {
.class_size = sizeof(MachineClass),
.class_init = machine_class_init,
.class_base_init = machine_class_base_init,
- .class_finalize = machine_class_finalize,
.instance_size = sizeof(MachineState),
.instance_init = machine_initfn,
.instance_finalize = machine_finalize,
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index bfd0896da..e8bcc4177 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -73,6 +73,25 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
}
}
+void inject_nmi(void)
+{
+#if defined(TARGET_I386)
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ X86CPU *cpu = X86_CPU(cs);
+
+ if (!cpu->apic_state) {
+ cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+ } else {
+ apic_deliver_nmi(cpu->apic_state);
+ }
+ }
+#else
+ nmi_monitor_handle(0, NULL);
+#endif
+}
+
static const TypeInfo nmi_info = {
.name = TYPE_NMI,
.parent = TYPE_INTERFACE,
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index 30829ee97..153c83513 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -35,9 +35,6 @@ static void ptimer_trigger(ptimer_state *s)
static void ptimer_reload(ptimer_state *s)
{
- uint32_t period_frac = s->period_frac;
- uint64_t period = s->period;
-
if (s->delta == 0) {
ptimer_trigger(s);
s->delta = s->limit;
@@ -48,24 +45,10 @@ static void ptimer_reload(ptimer_state *s)
return;
}
- /*
- * Artificially limit timeout rate to something
- * achievable under QEMU. Otherwise, QEMU spends all
- * its time generating timer interrupts, and there
- * is no forward progress.
- * About ten microseconds is the fastest that really works
- * on the current generation of host machines.
- */
-
- if (s->enabled == 1 && (s->delta * period < 10000) && !use_icount) {
- period = 10000 / s->delta;
- period_frac = 0;
- }
-
s->last_event = s->next_event;
- s->next_event = s->last_event + s->delta * period;
- if (period_frac) {
- s->next_event += ((int64_t)period_frac * s->delta) >> 32;
+ s->next_event = s->last_event + s->delta * s->period;
+ if (s->period_frac) {
+ s->next_event += ((int64_t)s->period_frac * s->delta) >> 32;
}
timer_mod(s->timer, s->next_event);
}
@@ -84,16 +67,14 @@ static void ptimer_tick(void *opaque)
uint64_t ptimer_get_count(ptimer_state *s)
{
+ int64_t now;
uint64_t counter;
if (s->enabled) {
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t next = s->next_event;
- bool expired = (now - next >= 0);
- bool oneshot = (s->enabled == 2);
-
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Figure out the current counter value. */
- if (expired) {
+ if (now - s->next_event > 0
+ || s->period == 0) {
/* Prevent timer underflowing if it should already have
triggered. */
counter = 0;
@@ -102,13 +83,6 @@ uint64_t ptimer_get_count(ptimer_state *s)
uint64_t div;
int clz1, clz2;
int shift;
- uint32_t period_frac = s->period_frac;
- uint64_t period = s->period;
-
- if (!oneshot && (s->delta * period < 10000) && !use_icount) {
- period = 10000 / s->delta;
- period_frac = 0;
- }
/* We need to divide time by period, where time is stored in
rem (64-bit integer) and period is stored in period/period_frac
@@ -120,8 +94,8 @@ uint64_t ptimer_get_count(ptimer_state *s)
backwards.
*/
- rem = next - now;
- div = period;
+ rem = s->next_event - now;
+ div = s->period;
clz1 = clz64(rem);
clz2 = clz64(div);
@@ -130,13 +104,13 @@ uint64_t ptimer_get_count(ptimer_state *s)
rem <<= shift;
div <<= shift;
if (shift >= 32) {
- div |= ((uint64_t)period_frac << (shift - 32));
+ div |= ((uint64_t)s->period_frac << (shift - 32));
} else {
if (shift != 0)
- div |= (period_frac >> (32 - shift));
+ div |= (s->period_frac >> (32 - shift));
/* Look at remaining bits of period_frac and round div up if
necessary. */
- if ((uint32_t)(period_frac << shift))
+ if ((uint32_t)(s->period_frac << shift))
div += 1;
}
counter = rem / div;
@@ -158,17 +132,16 @@ void ptimer_set_count(ptimer_state *s, uint64_t count)
void ptimer_run(ptimer_state *s, int oneshot)
{
- bool was_disabled = !s->enabled;
-
- if (was_disabled && s->period == 0) {
+ if (s->enabled) {
+ return;
+ }
+ if (s->period == 0) {
fprintf(stderr, "Timer with period zero, disabling\n");
return;
}
s->enabled = oneshot ? 2 : 1;
- if (was_disabled) {
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- ptimer_reload(s);
- }
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ ptimer_reload(s);
}
/* Pause a timer. Note that this may cause it to "lose" time, even if it
@@ -186,7 +159,6 @@ void ptimer_stop(ptimer_state *s)
/* Set counter increment interval in nanoseconds. */
void ptimer_set_period(ptimer_state *s, int64_t period)
{
- s->delta = ptimer_get_count(s);
s->period = period;
s->period_frac = 0;
if (s->enabled) {
@@ -198,7 +170,6 @@ void ptimer_set_period(ptimer_state *s, int64_t period)
/* Set counter frequency in Hz. */
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
{
- s->delta = ptimer_get_count(s);
s->period = 1000000000ll / freq;
s->period_frac = (1000000000ll << 32) / freq;
if (s->enabled) {
@@ -211,6 +182,19 @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
count = limit. */
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
{
+ /*
+ * Artificially limit timeout rate to something
+ * achievable under QEMU. Otherwise, QEMU spends all
+ * its time generating timer interrupts, and there
+ * is no forward progress.
+ * About ten microseconds is the fastest that really works
+ * on the current generation of host machines.
+ */
+
+ if (!use_icount && limit * s->period < 10000 && s->period) {
+ limit = 10000 / s->period;
+ }
+
s->limit = limit;
if (reload)
s->delta = limit;
@@ -220,11 +204,6 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
}
}
-uint64_t ptimer_get_limit(ptimer_state *s)
-{
- return s->limit;
-}
-
const VMStateDescription vmstate_ptimer = {
.name = "ptimer",
.version_id = 1,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index e55afe6bf..891219ae0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -1,5 +1,5 @@
/*
- * qdev property parsing
+ * qdev property parsing and global properties
* (parts specific for qemu-system-*)
*
* This file is based on code from hw/qdev-properties.c from
@@ -72,26 +72,17 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
const char *propname, Error **errp)
{
BlockBackend *blk;
- bool blk_created = false;
blk = blk_by_name(str);
if (!blk) {
- BlockDriverState *bs = bdrv_lookup_bs(NULL, str, NULL);
- if (bs) {
- blk = blk_new();
- blk_insert_bs(blk, bs);
- blk_created = true;
- }
- }
- if (!blk) {
error_setg(errp, "Property '%s.%s' can't find value '%s'",
object_get_typename(OBJECT(dev)), propname, str);
- goto fail;
+ return;
}
if (blk_attach_dev(blk, dev) < 0) {
DriveInfo *dinfo = blk_legacy_dinfo(blk);
- if (dinfo && dinfo->type != IF_NONE) {
+ if (dinfo->type != IF_NONE) {
error_setg(errp, "Drive '%s' is already in use because "
"it has been automatically connected to another "
"device (did you need 'if=none' in the drive options?)",
@@ -100,16 +91,9 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
error_setg(errp, "Drive '%s' is already in use by another device",
str);
}
- goto fail;
+ return;
}
-
*ptr = blk;
-
-fail:
- if (blk_created) {
- /* If we need to keep a reference, blk_attach_dev() took it */
- blk_unref(blk);
- }
}
static void release_drive(Object *obj, const char *name, void *opaque)
@@ -119,23 +103,14 @@ static void release_drive(Object *obj, const char *name, void *opaque)
BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) {
- blockdev_auto_del(*ptr);
blk_detach_dev(*ptr, dev);
+ blockdev_auto_del(*ptr);
}
}
static char *print_drive(void *ptr)
{
- const char *name;
-
- name = blk_name(ptr);
- if (!*name) {
- BlockDriverState *bs = blk_bs(ptr);
- if (bs) {
- name = bdrv_get_node_name(bs);
- }
- }
- return g_strdup(name);
+ return g_strdup(blk_name(ptr));
}
static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
@@ -152,7 +127,7 @@ static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
PropertyInfo qdev_prop_drive = {
.name = "str",
- .description = "Node name or ID of a block device to use as a backend",
+ .description = "ID of a drive to use as a backend",
.get = get_drive,
.set = set_drive,
.release = release_drive,
@@ -256,7 +231,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
}
queues = qemu_find_net_clients_except(str, peers,
- NET_CLIENT_DRIVER_NIC,
+ NET_CLIENT_OPTIONS_KIND_NIC,
MAX_QUEUE_NUM);
if (queues == 0) {
err = -ENOENT;
@@ -387,19 +362,8 @@ PropertyInfo qdev_prop_vlan = {
void qdev_prop_set_drive(DeviceState *dev, const char *name,
BlockBackend *value, Error **errp)
{
- const char *ref = "";
-
- if (value) {
- ref = blk_name(value);
- if (!*ref) {
- BlockDriverState *bs = blk_bs(value);
- if (bs) {
- ref = bdrv_get_node_name(bs);
- }
- }
- }
-
- object_property_set_str(OBJECT(dev), ref, name, errp);
+ object_property_set_str(OBJECT(dev), value ? blk_name(value) : "",
+ name, errp);
}
void qdev_prop_set_chr(DeviceState *dev, const char *name,
@@ -430,3 +394,22 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
}
nd->instantiated = 1;
}
+
+static int qdev_add_one_global(void *opaque, QemuOpts *opts, Error **errp)
+{
+ GlobalProperty *g;
+
+ g = g_malloc0(sizeof(*g));
+ g->driver = qemu_opt_get(opts, "driver");
+ g->property = qemu_opt_get(opts, "property");
+ g->value = qemu_opt_get(opts, "value");
+ g->user_provided = true;
+ qdev_prop_register_global(g);
+ return 0;
+}
+
+void qemu_add_globals(void)
+{
+ qemu_opts_foreach(qemu_find_opts("global"),
+ qdev_add_one_global, NULL, NULL);
+}
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 311af6da7..737d29c63 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -539,19 +539,6 @@ PropertyInfo qdev_prop_losttickpolicy = {
.set = set_enum,
};
-/* --- Block device error handling policy --- */
-
-QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
-
-PropertyInfo qdev_prop_blockdev_on_error = {
- .name = "BlockdevOnError",
- .description = "Error handling policy, "
- "report/ignore/enospc/stop/auto",
- .enum_table = BlockdevOnError_lookup,
- .get = get_enum,
- .set = set_enum,
-};
-
/* --- BIOS CHS translation */
QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
@@ -1033,11 +1020,12 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
*ptr = value;
}
-static GList *global_props;
+static QTAILQ_HEAD(, GlobalProperty) global_props =
+ QTAILQ_HEAD_INITIALIZER(global_props);
void qdev_prop_register_global(GlobalProperty *prop)
{
- global_props = g_list_append(global_props, prop);
+ QTAILQ_INSERT_TAIL(&global_props, prop, next);
}
void qdev_prop_register_global_list(GlobalProperty *props)
@@ -1051,11 +1039,10 @@ void qdev_prop_register_global_list(GlobalProperty *props)
int qdev_prop_check_globals(void)
{
- GList *l;
+ GlobalProperty *prop;
int ret = 0;
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
+ QTAILQ_FOREACH(prop, &global_props, next) {
ObjectClass *oc;
DeviceClass *dc;
if (prop->used) {
@@ -1084,12 +1071,11 @@ int qdev_prop_check_globals(void)
}
static void qdev_prop_set_globals_for_type(DeviceState *dev,
- const char *typename)
+ const char *typename)
{
- GList *l;
+ GlobalProperty *prop;
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
+ QTAILQ_FOREACH(prop, &global_props, next) {
Error *err = NULL;
if (strcmp(typename, prop->driver) != 0) {
@@ -1098,14 +1084,10 @@ static void qdev_prop_set_globals_for_type(DeviceState *dev,
prop->used = true;
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
if (err != NULL) {
- error_prepend(&err, "can't apply global %s.%s=%s: ",
- prop->driver, prop->property, prop->value);
- if (!dev->hotplugged && prop->errp) {
- error_propagate(prop->errp, err);
- } else {
- assert(prop->user_provided);
- error_reportf_err(err, "Warning: ");
- }
+ assert(prop->user_provided);
+ error_reportf_err(err, "Warning: global %s.%s=%s ignored: ",
+ prop->driver, prop->property, prop->value);
+ return;
}
}
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 57834423b..db41aa1f2 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -35,7 +35,6 @@
#include "qemu/error-report.h"
#include "hw/hotplug.h"
#include "hw/boards.h"
-#include "hw/sysbus.h"
#include "qapi-event.h"
int qdev_hotplug = 0;
@@ -59,6 +58,9 @@ const char *qdev_fw_name(DeviceState *dev)
return object_get_typename(OBJECT(dev));
}
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+ Error **errp);
+
static void bus_remove_child(BusState *bus, DeviceState *child)
{
BusChild *kid;
@@ -107,6 +109,24 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
bus_add_child(bus, dev);
}
+static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
+ Error **errp)
+{
+
+ object_property_set_link(OBJECT(bus), OBJECT(handler),
+ QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
+}
+
+void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
+{
+ qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
+}
+
+void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
+{
+ qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
+}
+
/* Create a new device. This only initializes the device state
structure and allows properties to be set. The device still needs
to be realized. See qdev-core.h. */
@@ -141,12 +161,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
}
if (!bus) {
- /* Assert that the device really is a SysBusDevice before
- * we put it onto the sysbus. Non-sysbus devices which aren't
- * being put onto a bus should be created with object_new(TYPE_FOO),
- * not qdev_create(NULL, TYPE_FOO).
- */
- g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
bus = sysbus_get_default();
}
@@ -354,14 +368,12 @@ void qdev_init_nofail(DeviceState *dev)
assert(!dev->realized);
- object_ref(OBJECT(dev));
object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (err) {
error_reportf_err(err, "Initialization of device %s failed: ",
object_get_typename(OBJECT(dev)));
exit(1);
}
- object_unref(OBJECT(dev));
}
void qdev_machine_creation_done(void)
@@ -583,6 +595,40 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
return NULL;
}
+int qbus_walk_children(BusState *bus,
+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+ void *opaque)
+{
+ BusChild *kid;
+ int err;
+
+ if (pre_busfn) {
+ err = pre_busfn(bus, opaque);
+ if (err) {
+ return err;
+ }
+ }
+
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ err = qdev_walk_children(kid->child,
+ pre_devfn, pre_busfn,
+ post_devfn, post_busfn, opaque);
+ if (err < 0) {
+ return err;
+ }
+ }
+
+ if (post_busfn) {
+ err = post_busfn(bus, opaque);
+ if (err) {
+ return err;
+ }
+ }
+
+ return 0;
+}
+
int qdev_walk_children(DeviceState *dev,
qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
@@ -639,6 +685,129 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
return NULL;
}
+static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
+{
+ const char *typename = object_get_typename(OBJECT(bus));
+ BusClass *bc;
+ char *buf;
+ int i, len, bus_id;
+
+ bus->parent = parent;
+
+ if (name) {
+ bus->name = g_strdup(name);
+ } else if (bus->parent && bus->parent->id) {
+ /* parent device has id -> use it plus parent-bus-id for bus name */
+ bus_id = bus->parent->num_child_bus;
+
+ len = strlen(bus->parent->id) + 16;
+ buf = g_malloc(len);
+ snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
+ bus->name = buf;
+ } else {
+ /* no id -> use lowercase bus type plus global bus-id for bus name */
+ bc = BUS_GET_CLASS(bus);
+ bus_id = bc->automatic_ids++;
+
+ len = strlen(typename) + 16;
+ buf = g_malloc(len);
+ len = snprintf(buf, len, "%s.%d", typename, bus_id);
+ for (i = 0; i < len; i++) {
+ buf[i] = qemu_tolower(buf[i]);
+ }
+ bus->name = buf;
+ }
+
+ if (bus->parent) {
+ QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+ bus->parent->num_child_bus++;
+ object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+ object_unref(OBJECT(bus));
+ } else if (bus != sysbus_get_default()) {
+ /* TODO: once all bus devices are qdevified,
+ only reset handler for main_system_bus should be registered here. */
+ qemu_register_reset(qbus_reset_all_fn, bus);
+ }
+}
+
+static void bus_unparent(Object *obj)
+{
+ BusState *bus = BUS(obj);
+ BusChild *kid;
+
+ while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+ DeviceState *dev = kid->child;
+ object_unparent(OBJECT(dev));
+ }
+ if (bus->parent) {
+ QLIST_REMOVE(bus, sibling);
+ bus->parent->num_child_bus--;
+ bus->parent = NULL;
+ } else {
+ assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+ qemu_unregister_reset(qbus_reset_all_fn, bus);
+ }
+}
+
+static bool bus_get_realized(Object *obj, Error **errp)
+{
+ BusState *bus = BUS(obj);
+
+ return bus->realized;
+}
+
+static void bus_set_realized(Object *obj, bool value, Error **errp)
+{
+ BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ BusChild *kid;
+ Error *local_err = NULL;
+
+ if (value && !bus->realized) {
+ if (bc->realize) {
+ bc->realize(bus, &local_err);
+ }
+
+ /* TODO: recursive realization */
+ } else if (!value && bus->realized) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ object_property_set_bool(OBJECT(dev), false, "realized",
+ &local_err);
+ if (local_err != NULL) {
+ break;
+ }
+ }
+ if (bc->unrealize && local_err == NULL) {
+ bc->unrealize(bus, &local_err);
+ }
+ }
+
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ bus->realized = value;
+}
+
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
+ DeviceState *parent, const char *name)
+{
+ object_initialize(bus, size, typename);
+ qbus_realize(bus, parent, name);
+}
+
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
+{
+ BusState *bus;
+
+ bus = BUS(object_new(typename));
+ qbus_realize(bus, parent, name);
+
+ return bus;
+}
+
static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
{
BusClass *bc = BUS_GET_CLASS(bus);
@@ -739,20 +908,13 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v,
}
/**
- * qdev_property_add_legacy:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- * @errp: location to store error information.
+ * @qdev_add_legacy_property - adds a legacy property
*
- * Add a legacy QOM property to @dev for qdev property @prop.
- * On error, store error in @errp.
+ * Do not use this is new code! Properties added through this interface will
+ * be given names and types in the "legacy" namespace.
*
- * Legacy properties are string versions of QOM properties. The format of
- * the string depends on the property type. Legacy properties are only
- * needed for "info qtree".
- *
- * Do not use this is new code! QOM Properties added through this interface
- * will be given names in the "legacy" namespace.
+ * Legacy properties are string versions of other OOM properties. The format
+ * of the string depends on the property type.
*/
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
@@ -775,14 +937,10 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
}
/**
- * qdev_property_add_static:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- * @errp: location to store error information.
+ * @qdev_property_add_static - add a @Property to a device.
*
- * Add a static QOM property to @dev for qdev property @prop.
- * On error, store error in @errp. Static properties access data in a struct.
- * The type of the QOM property is derived from prop->info.
+ * Static properties access data in a struct. The actual type of the
+ * property and the field depends on the property type.
*/
void qdev_property_add_static(DeviceState *dev, Property *prop,
Error **errp)
@@ -887,8 +1045,6 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
HotplugHandler *hotplug_ctrl;
BusState *bus;
Error *local_err = NULL;
- bool unattached_parent = false;
- static int unattached_count;
if (dev->hotplugged && !dc->hotpluggable) {
error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
@@ -897,23 +1053,15 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
if (value && !dev->realized) {
if (!obj->parent) {
+ static int unattached_count;
gchar *name = g_strdup_printf("device[%d]", unattached_count++);
object_property_add_child(container_get(qdev_get_machine(),
"/unattached"),
name, obj, &error_abort);
- unattached_parent = true;
g_free(name);
}
- hotplug_ctrl = qdev_get_hotplug_handler(dev);
- if (hotplug_ctrl) {
- hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
- if (local_err != NULL) {
- goto fail;
- }
- }
-
if (dc->realize) {
dc->realize(dev, &local_err);
}
@@ -924,6 +1072,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
DEVICE_LISTENER_CALL(realize, Forward, dev);
+ hotplug_ctrl = qdev_get_hotplug_handler(dev);
if (hotplug_ctrl) {
hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
}
@@ -991,10 +1140,6 @@ post_realize_fail:
fail:
error_propagate(errp, local_err);
- if (unattached_parent) {
- object_unparent(OBJECT(dev));
- unattached_count--;
- }
}
static bool device_get_hotpluggable(Object *obj, Error **errp)
@@ -1170,8 +1315,55 @@ static const TypeInfo device_type_info = {
.class_size = sizeof(DeviceClass),
};
+static void qbus_initfn(Object *obj)
+{
+ BusState *bus = BUS(obj);
+
+ QTAILQ_INIT(&bus->children);
+ object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
+ TYPE_HOTPLUG_HANDLER,
+ (Object **)&bus->hotplug_handler,
+ object_property_allow_set_link,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
+ NULL);
+ object_property_add_bool(obj, "realized",
+ bus_get_realized, bus_set_realized, NULL);
+}
+
+static char *default_bus_get_fw_dev_path(DeviceState *dev)
+{
+ return g_strdup(object_get_typename(OBJECT(dev)));
+}
+
+static void bus_class_init(ObjectClass *class, void *data)
+{
+ BusClass *bc = BUS_CLASS(class);
+
+ class->unparent = bus_unparent;
+ bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+}
+
+static void qbus_finalize(Object *obj)
+{
+ BusState *bus = BUS(obj);
+
+ g_free((char *)bus->name);
+}
+
+static const TypeInfo bus_info = {
+ .name = TYPE_BUS,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(BusState),
+ .abstract = true,
+ .class_size = sizeof(BusClass),
+ .instance_init = qbus_initfn,
+ .instance_finalize = qbus_finalize,
+ .class_init = bus_class_init,
+};
+
static void qdev_register_types(void)
{
+ type_register_static(&bus_info);
type_register_static(&device_type_info);
}
diff --git a/hw/core/register.c b/hw/core/register.c
deleted file mode 100644
index 4bfbc508d..000000000
--- a/hw/core/register.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Register Definition API
- *
- * Copyright (c) 2016 Xilinx Inc.
- * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "qemu/osdep.h"
-#include "hw/register.h"
-#include "hw/qdev.h"
-#include "qemu/log.h"
-
-static inline void register_write_val(RegisterInfo *reg, uint64_t val)
-{
- g_assert(reg->data);
-
- switch (reg->data_size) {
- case 1:
- *(uint8_t *)reg->data = val;
- break;
- case 2:
- *(uint16_t *)reg->data = val;
- break;
- case 4:
- *(uint32_t *)reg->data = val;
- break;
- case 8:
- *(uint64_t *)reg->data = val;
- break;
- default:
- g_assert_not_reached();
- }
-}
-
-static inline uint64_t register_read_val(RegisterInfo *reg)
-{
- switch (reg->data_size) {
- case 1:
- return *(uint8_t *)reg->data;
- case 2:
- return *(uint16_t *)reg->data;
- case 4:
- return *(uint32_t *)reg->data;
- case 8:
- return *(uint64_t *)reg->data;
- default:
- g_assert_not_reached();
- }
- return 0; /* unreachable */
-}
-
-void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
- const char *prefix, bool debug)
-{
- uint64_t old_val, new_val, test, no_w_mask;
- const RegisterAccessInfo *ac;
-
- assert(reg);
-
- ac = reg->access;
-
- if (!ac || !ac->name) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
- "(written value: %#" PRIx64 ")\n", prefix, val);
- return;
- }
-
- old_val = reg->data ? register_read_val(reg) : ac->reset;
-
- test = (old_val ^ val) & ac->rsvd;
- if (test) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
- "fields: %#" PRIx64 ")\n", prefix, test);
- }
-
- test = val & ac->unimp;
- if (test) {
- qemu_log_mask(LOG_UNIMP,
- "%s:%s writing %#" PRIx64 " to unimplemented bits:" \
- " %#" PRIx64 "",
- prefix, reg->access->name, val, ac->unimp);
- }
-
- /* Create the no write mask based on the read only, write to clear and
- * reserved bit masks.
- */
- no_w_mask = ac->ro | ac->w1c | ac->rsvd | ~we;
- new_val = (val & ~no_w_mask) | (old_val & no_w_mask);
- new_val &= ~(val & ac->w1c);
-
- if (ac->pre_write) {
- new_val = ac->pre_write(reg, new_val);
- }
-
- if (debug) {
- qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name,
- new_val);
- }
-
- register_write_val(reg, new_val);
-
- if (ac->post_write) {
- ac->post_write(reg, new_val);
- }
-}
-
-uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
- bool debug)
-{
- uint64_t ret;
- const RegisterAccessInfo *ac;
-
- assert(reg);
-
- ac = reg->access;
- if (!ac || !ac->name) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n",
- prefix);
- return 0;
- }
-
- ret = reg->data ? register_read_val(reg) : ac->reset;
-
- register_write_val(reg, ret & ~(ac->cor & re));
-
- /* Mask based on the read enable size */
- ret &= re;
-
- if (ac->post_read) {
- ret = ac->post_read(reg, ret);
- }
-
- if (debug) {
- qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix,
- ac->name, ret);
- }
-
- return ret;
-}
-
-void register_reset(RegisterInfo *reg)
-{
- g_assert(reg);
-
- if (!reg->data || !reg->access) {
- return;
- }
-
- register_write_val(reg, reg->access->reset);
-}
-
-void register_init(RegisterInfo *reg)
-{
- assert(reg);
-
- if (!reg->data || !reg->access) {
- return;
- }
-
- object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
-}
-
-void register_write_memory(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- RegisterInfoArray *reg_array = opaque;
- RegisterInfo *reg = NULL;
- uint64_t we;
- int i;
-
- for (i = 0; i < reg_array->num_elements; i++) {
- if (reg_array->r[i]->access->addr == addr) {
- reg = reg_array->r[i];
- break;
- }
- }
-
- if (!reg) {
- qemu_log_mask(LOG_GUEST_ERROR, "Write to unimplemented register at " \
- "address: %#" PRIx64 "\n", addr);
- return;
- }
-
- /* Generate appropriate write enable mask */
- if (reg->data_size < size) {
- we = MAKE_64BIT_MASK(0, reg->data_size * 8);
- } else {
- we = MAKE_64BIT_MASK(0, size * 8);
- }
-
- register_write(reg, value, we, reg_array->prefix,
- reg_array->debug);
-}
-
-uint64_t register_read_memory(void *opaque, hwaddr addr,
- unsigned size)
-{
- RegisterInfoArray *reg_array = opaque;
- RegisterInfo *reg = NULL;
- uint64_t read_val;
- int i;
-
- for (i = 0; i < reg_array->num_elements; i++) {
- if (reg_array->r[i]->access->addr == addr) {
- reg = reg_array->r[i];
- break;
- }
- }
-
- if (!reg) {
- qemu_log_mask(LOG_GUEST_ERROR, "Read to unimplemented register at " \
- "address: %#" PRIx64 "\n", addr);
- return 0;
- }
-
- read_val = register_read(reg, size * 8, reg_array->prefix,
- reg_array->debug);
-
- return extract64(read_val, 0, size * 8);
-}
-
-RegisterInfoArray *register_init_block32(DeviceState *owner,
- const RegisterAccessInfo *rae,
- int num, RegisterInfo *ri,
- uint32_t *data,
- const MemoryRegionOps *ops,
- bool debug_enabled,
- uint64_t memory_size)
-{
- const char *device_prefix = object_get_typename(OBJECT(owner));
- RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
- int i;
-
- r_array->r = g_new0(RegisterInfo *, num);
- r_array->num_elements = num;
- r_array->debug = debug_enabled;
- r_array->prefix = device_prefix;
-
- for (i = 0; i < num; i++) {
- int index = rae[i].addr / 4;
- RegisterInfo *r = &ri[index];
-
- *r = (RegisterInfo) {
- .data = &data[index],
- .data_size = sizeof(uint32_t),
- .access = &rae[i],
- .opaque = owner,
- };
- register_init(r);
-
- r_array->r[i] = r;
- }
-
- memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array,
- device_prefix, memory_size);
-
- return r_array;
-}
-
-void register_finalize_block(RegisterInfoArray *r_array)
-{
- object_unparent(OBJECT(&r_array->mem));
- g_free(r_array->r);
- g_free(r_array);
-}
-
-static const TypeInfo register_info = {
- .name = TYPE_REGISTER,
- .parent = TYPE_DEVICE,
-};
-
-static void register_register_types(void)
-{
- type_register_static(&register_info);
-}
-
-type_init(register_register_types)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index c0f560b28..a7dbe2b32 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -190,9 +190,9 @@ MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n)
return dev->mmio[n].memory;
}
-void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size)
+void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
{
- uint32_t i;
+ pio_addr_t i;
for (i = 0; i < size; i++) {
assert(dev->num_pio < QDEV_MAX_PIO);
diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
index 34c11a70a..9fc2760b5 100644
--- a/hw/core/uboot_image.h
+++ b/hw/core/uboot_image.h
@@ -26,8 +26,8 @@
********************************************************************
*/
-#ifndef UBOOT_IMAGE_H
-#define UBOOT_IMAGE_H
+#ifndef __UBOOT_IMAGE_H__
+#define __UBOOT_IMAGE_H__
/*
* Operating System Codes
@@ -155,4 +155,4 @@ typedef struct uboot_image_header {
} uboot_image_header_t;
-#endif /* UBOOT_IMAGE_H */
+#endif /* __IMAGE_H__ */