diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 6e659e986f..8d0ee8b9c4 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -34,6 +34,7 @@ #include "qemu/log.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/sysbus.h" @@ -326,6 +327,8 @@ static void sifive_u_machine_init(MachineState *machine) object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_RISCV_U_SOC, &error_abort, NULL); + object_property_set_uint(OBJECT(&s->soc), s->serial, "serial", + &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); @@ -417,6 +420,18 @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error * s->start_in_flash = value; } +static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + visit_type_uint32(v, name, (uint32_t *)opaque, errp); +} + +static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + visit_type_uint32(v, name, (uint32_t *)opaque, errp); +} + static void sifive_u_machine_instance_init(Object *obj) { SiFiveUState *s = RISCV_U_MACHINE(obj); @@ -428,6 +443,11 @@ static void sifive_u_machine_instance_init(Object *obj) "Set on to tell QEMU's ROM to jump to " "flash. Otherwise QEMU will jump to DRAM", NULL); + + s->serial = OTP_SERIAL; + object_property_add(obj, "serial", "uint32", sifive_u_machine_get_serial, + sifive_u_machine_set_serial, NULL, &s->serial, NULL); + object_property_set_description(obj, "serial", "Board serial number", NULL); } static void sifive_u_machine_class_init(ObjectClass *oc, void *data) diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index a2baa1de5f..16c297ec5f 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -61,6 +61,7 @@ typedef struct SiFiveUState { int fdt_size; bool start_in_flash; + uint32_t serial; } SiFiveUState; enum {