aboutsummaryrefslogtreecommitdiff
path: root/hw/core
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/qdev-properties.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 71f8aca7c6..ca7771f307 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -15,6 +15,7 @@
#include "chardev/char.h"
#include "qemu/uuid.h"
#include "qemu/units.h"
+#include "qemu/cutils.h"
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp)
@@ -578,6 +579,94 @@ const PropertyInfo qdev_prop_macaddr = {
.set = set_mac,
};
+/* --- Reserved Region --- */
+
+/*
+ * Accepted syntax:
+ * <low address>:<high address>:<type>
+ * where low/high addresses are uint64_t in hexadecimal
+ * and type is a non-negative decimal integer
+ */
+static void get_reserved_region(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+ char buffer[64];
+ char *p = buffer;
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
+ rr->low, rr->high, rr->type);
+ assert(rc < sizeof(buffer));
+
+ visit_type_str(v, name, &p, errp);
+}
+
+static void set_reserved_region(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ const char *endptr;
+ char *str;
+ int ret;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_str(v, name, &str, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ ret = qemu_strtou64(str, &endptr, 16, &rr->low);
+ if (ret) {
+ error_setg(errp, "start address of '%s'"
+ " must be a hexadecimal integer", name);
+ goto out;
+ }
+ if (*endptr != ':') {
+ goto separator_error;
+ }
+
+ ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high);
+ if (ret) {
+ error_setg(errp, "end address of '%s'"
+ " must be a hexadecimal integer", name);
+ goto out;
+ }
+ if (*endptr != ':') {
+ goto separator_error;
+ }
+
+ ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type);
+ if (ret) {
+ error_setg(errp, "type of '%s'"
+ " must be a non-negative decimal integer", name);
+ }
+ goto out;
+
+separator_error:
+ error_setg(errp, "reserved region fields must be separated with ':'");
+out:
+ g_free(str);
+ return;
+}
+
+const PropertyInfo qdev_prop_reserved_region = {
+ .name = "reserved_region",
+ .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0",
+ .get = get_reserved_region,
+ .set = set_reserved_region,
+};
+
/* --- on/off/auto --- */
const PropertyInfo qdev_prop_on_off_auto = {