Skip to content

Commit

Permalink
Merge pull request #1522 from ucb-bar/device-plugin-api
Browse files Browse the repository at this point in the history
Fix Spike --device option to pass on args to downstream plugins
  • Loading branch information
jerryz123 authored Dec 8, 2023
2 parents d94fe56 + b98e922 commit 1f466df
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 11 deletions.
2 changes: 1 addition & 1 deletion ci-tests/testlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ int main()
hartids,
false,
4);
std::vector<const device_factory_t*> plugin_devices;
std::vector<device_factory_t*> plugin_devices;
std::vector<std::string> htif_args {"pk", "hello"};
debug_module_config_t dm_config = {
.progbufsize = 2,
Expand Down
12 changes: 9 additions & 3 deletions riscv/abstract_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>
#include <map>
#include <stdexcept>
#include <vector>

class sim_t;

Expand All @@ -26,10 +27,15 @@ class device_factory_t {
virtual abstract_device_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const = 0;
virtual std::string generate_dts(const sim_t* sim) const = 0;
virtual ~device_factory_t() {}
void set_sargs(std::vector<std::string> sargs) { this->sargs = sargs; }
std::vector<std::string> get_sargs() { return sargs; }

protected:
std::vector<std::string> sargs;
};

// Type for holding all registered MMIO plugins by name.
using mmio_device_map_t = std::map<std::string, const device_factory_t*>;
using mmio_device_map_t = std::map<std::string, device_factory_t*>;

mmio_device_map_t& mmio_device_map();

Expand All @@ -40,8 +46,8 @@ mmio_device_map_t& mmio_device_map();
std::string str(#name); \
if (!mmio_device_map().emplace(str, this).second) throw std::runtime_error("Plugin \"" + str + "\" already registered"); \
}; \
name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const override { return parse(fdt, sim, base); } \
name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const override { return parse(fdt, sim, base, sargs); } \
std::string generate_dts(const sim_t* sim) const override { return generate(sim); } \
}; const device_factory_t *name##_factory = new name##_factory_t();
}; device_factory_t *name##_factory = new name##_factory_t();

#endif
3 changes: 2 additions & 1 deletion riscv/clint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ void clint_t::tick(reg_t rtc_ticks)
}
}

clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) {
clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base,
const std::vector<std::string>& sargs) {
if (fdt_parse_clint(fdt, base, "riscv,clint0") == 0)
return new clint_t(sim,
sim->CPU_HZ / sim->INSNS_PER_RTC_TICK,
Expand Down
2 changes: 1 addition & 1 deletion riscv/ns16550.cc
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ std::string ns16550_generate_dts(const sim_t* sim)
return s.str();
}

ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base)
ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector<std::string>& sargs)
{
uint32_t ns16550_shift, ns16550_io_width, ns16550_int_id;
if (fdt_parse_ns16550(fdt, base,
Expand Down
2 changes: 1 addition & 1 deletion riscv/plic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ std::string plic_generate_dts(const sim_t* sim)
return s.str();
}

plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base)
plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector<std::string>& sargs)
{
uint32_t plic_ndev;
if (fdt_parse_plic(fdt, base, &plic_ndev, "riscv,plic0") == 0)
Expand Down
2 changes: 1 addition & 1 deletion riscv/sim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extern device_factory_t* ns16550_factory;

sim_t::sim_t(const cfg_t *cfg, bool halted,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
std::vector<const device_factory_t*> plugin_device_factories,
std::vector<device_factory_t*> plugin_device_factories,
const std::vector<std::string>& args,
const debug_module_config_t &dm_config,
const char *log_path,
Expand Down
2 changes: 1 addition & 1 deletion riscv/sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class sim_t : public htif_t, public simif_t
public:
sim_t(const cfg_t *cfg, bool halted,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
std::vector<const device_factory_t*> plugin_device_factories,
std::vector<device_factory_t*> plugin_device_factories,
const std::vector<std::string>& args,
const debug_module_config_t &dm_config, const char *log_path,
bool dtb_enabled, const char *dtb_file,
Expand Down
20 changes: 18 additions & 2 deletions spike_main/spike.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "extension.h"
#include <dlfcn.h>
#include <fesvr/option_parser.h>
#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
Expand All @@ -18,6 +19,7 @@
#include <fstream>
#include <limits>
#include <cinttypes>
#include <sstream>
#include "../VERSION"

static void help(int exit_code = 1)
Expand Down Expand Up @@ -332,7 +334,7 @@ int main(int argc, char** argv)
bool dtb_enabled = true;
const char* kernel = NULL;
reg_t kernel_offset, kernel_size;
std::vector<const device_factory_t*> plugin_device_factories;
std::vector<device_factory_t*> plugin_device_factories;
std::unique_ptr<icache_sim_t> ic;
std::unique_ptr<dcache_sim_t> dc;
std::unique_ptr<cache_sim_t> l2;
Expand Down Expand Up @@ -374,10 +376,24 @@ int main(int argc, char** argv)
/*default_trigger_count=*/4);

auto const device_parser = [&plugin_device_factories](const char *s) {
const std::string name(s);
const std::string device_args(s);
std::vector<std::string> parsed_args;
std::stringstream sstr(device_args);
while (sstr.good()) {
std::string substr;
getline(sstr, substr, ',');
parsed_args.push_back(substr);
}
if (parsed_args.empty()) throw std::runtime_error("Plugin argument is empty.");

const std::string name = parsed_args[0];
if (name.empty()) throw std::runtime_error("Plugin name is empty.");

auto it = mmio_device_map().find(name);
if (it == mmio_device_map().end()) throw std::runtime_error("Plugin \"" + name + "\" not found in loaded extlibs.");

parsed_args.erase(parsed_args.begin());
it->second->set_sargs(parsed_args);
plugin_device_factories.push_back(it->second);
};

Expand Down

0 comments on commit 1f466df

Please sign in to comment.