From c61e4bccce9d5324db316ded33923cb8b8e396ac Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 30 Jul 2025 13:04:12 -0700 Subject: [PATCH 1/2] Remove brittle reliance on ordering of factory table --- riscv/sim.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/riscv/sim.cc b/riscv/sim.cc index 2776e33d..fb643d6f 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -118,8 +118,8 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, // particular, the default device tree configuration that you get without // setting the dtb_file argument has one. std::vector device_factories = { - {clint_factory, {}}, // clint must be element 0 - {plic_factory, {}}, // plic must be element 1 + {clint_factory, {}}, + {plic_factory, {}}, {ns16550_factory, {}}}; device_factories.insert(device_factories.end(), plugin_device_factories.begin(), @@ -253,10 +253,15 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, std::shared_ptr dev_ptr(device); add_device(device_base, dev_ptr); - if (i == 0) // clint_factory + if (dynamic_cast(&*dev_ptr)) { + assert(!clint); clint = std::static_pointer_cast(dev_ptr); - else if (i == 1) // plic_factory + } + + if (dynamic_cast(&*dev_ptr)) { + assert(!plic); plic = std::static_pointer_cast(dev_ptr); + } } } } From 8da8b6a34d86384bcce482e2414d5341e2af87df Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 30 Jul 2025 13:46:04 -0700 Subject: [PATCH 2/2] Don't include built-in devices in mmio_device_map Only use mmio_device_map for plugin devices. This fixes a collision caused by multiple static initializers if Spike depends on a library that depends on libriscv.so. --- riscv/abstract_device.h | 7 +++++++ riscv/clint.cc | 2 +- riscv/ns16550.cc | 2 +- riscv/plic.cc | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/riscv/abstract_device.h b/riscv/abstract_device.h index d8ddbabe..41f5c3f1 100644 --- a/riscv/abstract_device.h +++ b/riscv/abstract_device.h @@ -46,4 +46,11 @@ mmio_device_map_t& mmio_device_map(); std::string generate_dts(const sim_t* sim, const std::vector& sargs) const override { return generate(sim, sargs); } \ }; device_factory_t *name##_factory = new name##_factory_t(); +#define REGISTER_BUILTIN_DEVICE(name, parse, generate) \ + class name##_factory_t : public device_factory_t { \ + public: \ + name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector& sargs) const override { return parse(fdt, sim, base, sargs); } \ + std::string generate_dts(const sim_t* sim, const std::vector& sargs) const override { return generate(sim, sargs); } \ + }; device_factory_t *name##_factory = new name##_factory_t(); + #endif diff --git a/riscv/clint.cc b/riscv/clint.cc index 3d5c9841..e16ebddc 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -145,4 +145,4 @@ std::string clint_generate_dts(const sim_t* sim, const std::vector& return s.str(); } -REGISTER_DEVICE(clint, clint_parse_from_fdt, clint_generate_dts) +REGISTER_BUILTIN_DEVICE(clint, clint_parse_from_fdt, clint_generate_dts) diff --git a/riscv/ns16550.cc b/riscv/ns16550.cc index 15e08733..4bda6f4a 100644 --- a/riscv/ns16550.cc +++ b/riscv/ns16550.cc @@ -361,4 +361,4 @@ ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base } } -REGISTER_DEVICE(ns16550, ns16550_parse_from_fdt, ns16550_generate_dts) +REGISTER_BUILTIN_DEVICE(ns16550, ns16550_parse_from_fdt, ns16550_generate_dts) diff --git a/riscv/plic.cc b/riscv/plic.cc index b6d204b2..03105385 100644 --- a/riscv/plic.cc +++ b/riscv/plic.cc @@ -436,4 +436,4 @@ plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, cons return nullptr; } -REGISTER_DEVICE(plic, plic_parse_from_fdt, plic_generate_dts) +REGISTER_BUILTIN_DEVICE(plic, plic_parse_from_fdt, plic_generate_dts)