Update tt-atlantis to, when the RCPU is enabled and bootrom binary is
provided, load the provided bootrom binary for the RCPU to execute.

This adds a tt-atlantis machine property 'bootrom' that takes a file
name. qemu_find_file() tries the filename before the search path, so both
full file paths and filenames relative to -L work:

    -M tt-atlantis,rcpu=on,bootrom=out/bootrom.bin

Signed-off-by: Portia Stephens <[email protected]>
---
 hw/riscv/tt_atlantis.c         | 63 ++++++++++++++++++++++++++++++++--
 include/hw/riscv/tt_atlantis.h |  4 +++
 2 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
index f778091e91..f3e35c63ea 100644
--- a/hw/riscv/tt_atlantis.c
+++ b/hw/riscv/tt_atlantis.c
@@ -9,6 +9,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/cutils.h"
+#include "qemu/datadir.h"
 #include "qemu/error-report.h"
 #include "qemu/guest-random.h"
 #include "qemu/units.h"
@@ -663,15 +664,36 @@ static void tt_rcpu_cluster_realize(DeviceState *dev, 
Error **errp)
 
     create_unimplemented_devices(OBJECT(rc), &rc->memory, rcpu_unimp_dev);
 
-    /* no bootrom image is provided, don't let the core run */
-    CPU(&rc->cpus.harts[0])->start_powered_off = true;
+    if (rc->bootrom_image) {
+        ssize_t rom_size;
+
+        g_autofree char *rom_file = qemu_find_file(QEMU_FILE_TYPE_BIOS, 
rc->bootrom_image);
+        if (!rom_file) {
+            error_setg(errp, "could not find bootrom image '%s'", 
rc->bootrom_image);
+            return;
+        }
+
+        rom_size = load_image_mr(rom_file, &rc->bootrom);
+        if (rom_size <= 0) {
+            error_setg(errp, "could not load bootrom image '%s'", 
rc->bootrom_image);
+            return;
+        }
+    } else {
+        /* no bootrom image is provided, don't let the core run */
+        CPU(&rc->cpus.harts[0])->start_powered_off = true;
+    }
 }
 
+static const Property tt_rcpu_cluster_props[] = {
+    DEFINE_PROP_STRING("bootrom-name", TTRCPUClusterState, bootrom_image),
+};
+
 static void tt_rcpu_cluster_class_init(ObjectClass *oc, const void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->realize = tt_rcpu_cluster_realize;
+    device_class_set_props(dc, tt_rcpu_cluster_props);
     /* The cluster must be instantiated by a machine or SoC */
     dc->user_creatable = false;
 }
@@ -830,6 +852,13 @@ static void tt_atlantis_soc_realize(DeviceState *dev, 
Error **errp)
     if (s->has_rcpu) {
         /* Only create the RCPU if it is enabled */
         object_initialize_child(OBJECT(s), "rcpu", &s->rcpu, 
TYPE_TT_RCPU_CLUSTER);
+
+        if (s->rcpu_bootrom_image) {
+            object_property_set_str(OBJECT(rc), "bootrom-name",
+                                    s->rcpu_bootrom_image,
+                                    &error_abort);
+        }
+
         if (!qdev_realize(DEVICE(&s->rcpu), NULL, errp)) {
             return;
         }
@@ -1008,7 +1037,8 @@ static void tt_atlantis_soc_realize(DeviceState *dev, 
Error **errp)
 static const Property tt_atlantis_soc_props[] = {
     DEFINE_PROP_LINK("dram", TTAtlantisSoCState, dram,
                      TYPE_MEMORY_REGION, MemoryRegion *),
-    DEFINE_PROP_BOOL("has-rcpu", TTAtlantisSoCState, has_rcpu, false)
+    DEFINE_PROP_BOOL("has-rcpu", TTAtlantisSoCState, has_rcpu, false),
+    DEFINE_PROP_STRING("bootrom-name", TTAtlantisSoCState, rcpu_bootrom_image)
 };
 
 static void tt_atlantis_soc_class_init(ObjectClass *oc, const void *data)
@@ -1060,6 +1090,13 @@ static void tt_atlantis_machine_init(MachineState 
*machine)
                             num_asc_harts,
                             &error_abort);
 
+    if (ams->has_rcpu && ams->rcpu_bootrom_image) {
+        /* Set the RCPU bootrom file name provided on the command line */
+        object_property_set_str(OBJECT(s), "bootrom-name",
+                                ams->rcpu_bootrom_image,
+                                &error_abort);
+    }
+
     object_property_set_link(OBJECT(s), "dram", OBJECT(machine->ram),
                              &error_abort);
     object_property_set_bool(OBJECT(&ams->soc), "has-rcpu", ams->has_rcpu,
@@ -1096,6 +1133,22 @@ static void tt_atlantis_machine_set_rcpu(Object *obj, 
bool value, Error **errp)
     s->has_rcpu = value;
 }
 
+static char *tt_atlantis_get_bootrom(Object *obj, Error **errp)
+{
+    TTAtlantisState *s = TT_ATLANTIS_MACHINE(obj);
+
+    return g_strdup(s->rcpu_bootrom_image);
+}
+
+static void tt_atlantis_set_bootrom(Object *obj, const char *value,
+                                   Error **errp)
+{
+    TTAtlantisState *s = TT_ATLANTIS_MACHINE(obj);
+
+    g_free(s->rcpu_bootrom_image);
+    s->rcpu_bootrom_image = g_strdup(value);
+}
+
 static void tt_atlantis_machine_class_init(ObjectClass *oc, const void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -1123,6 +1176,10 @@ static void tt_atlantis_machine_class_init(ObjectClass 
*oc, const void *data)
                                           "Set to enable/disable modeling the 
RCPU.");
     object_property_set_default_bool(prop, false);
 
+    object_class_property_add_str(oc, "bootrom",
+                                  tt_atlantis_get_bootrom,
+                                  tt_atlantis_set_bootrom);
+    object_class_property_set_description(oc, "bootrom", "RCPU bootrom image");
 }
 
 static const TypeInfo tt_atlantis_types[] = {
diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h
index 5a200410f3..e9cc147060 100644
--- a/include/hw/riscv/tt_atlantis.h
+++ b/include/hw/riscv/tt_atlantis.h
@@ -64,6 +64,8 @@ struct TTRCPUClusterState {
     CPUClusterState cluster;
     MemoryRegion bootrom;
     MemoryRegion sram;
+
+    char *bootrom_image;
 };
 
 struct TTAtlantisSoCState {
@@ -84,6 +86,7 @@ struct TTAtlantisSoCState {
     TTAtlantisPRCMState prcm[TT_ATL_NUM_PRCM];
 
     bool has_rcpu;              /* Enable RCPU */
+    char *rcpu_bootrom_image;    /* RCPU boot ROM image */
 };
 
 struct TTAtlantisState {
@@ -96,6 +99,7 @@ struct TTAtlantisState {
     TTAtlantisSoCState soc;
 
     bool has_rcpu;              /* Enable RCPU */
+    char *rcpu_bootrom_image;    /* RCPU boot ROM image */
 };
 
 enum {
-- 
2.43.0


Reply via email to