aboutsummaryrefslogtreecommitdiff
path: root/fesvr/htif.cc
diff options
context:
space:
mode:
authorJames Clarke <jrtc27@jrtc27.com>2020-01-31 20:57:51 +0000
committerJames Clarke <jrtc27@jrtc27.com>2020-01-31 20:57:51 +0000
commit725a0190770b0094f18d0fdc22660fa6845841f7 (patch)
treeac5fbaccc655ef86be0ba401a423bb4dfea3517c /fesvr/htif.cc
parentc050d113fe4d5a0554b9ece58aa352a065e6a70c (diff)
downloadspike-725a0190770b0094f18d0fdc22660fa6845841f7.zip
spike-725a0190770b0094f18d0fdc22660fa6845841f7.tar.gz
spike-725a0190770b0094f18d0fdc22660fa6845841f7.tar.bz2
Support loading multiple ELF files via a new payload HTIF option
Firmware implementations, such as OpenSBI's fw_jump, make use of this feature on other targets to avoid having to be rebuilt every time the payload is updated.
Diffstat (limited to 'fesvr/htif.cc')
-rw-r--r--fesvr/htif.cc32
1 files changed, 25 insertions, 7 deletions
diff --git a/fesvr/htif.cc b/fesvr/htif.cc
index 2309f12..be70394 100644
--- a/fesvr/htif.cc
+++ b/fesvr/htif.cc
@@ -83,21 +83,21 @@ void htif_t::start()
reset();
}
-void htif_t::load_program()
+std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry)
{
std::string path;
- if (access(targs[0].c_str(), F_OK) == 0)
- path = targs[0];
- else if (targs[0].find('/') == std::string::npos)
+ if (access(payload.c_str(), F_OK) == 0)
+ path = payload;
+ else if (payload.find('/') == std::string::npos)
{
- std::string test_path = PREFIX TARGET_DIR + targs[0];
+ std::string test_path = PREFIX TARGET_DIR + payload;
if (access(test_path.c_str(), F_OK) == 0)
path = test_path;
}
if (path.empty())
throw std::runtime_error(
- "could not open " + targs[0] +
+ "could not open " + payload +
" (did you misspell it? If VCS, did you forget +permissive/+permissive-off?)");
// temporarily construct a memory interface that skips writing bytes
@@ -116,7 +116,12 @@ void htif_t::load_program()
htif_t* htif;
} preload_aware_memif(this);
- std::map<std::string, uint64_t> symbols = load_elf(path.c_str(), &preload_aware_memif, &entry);
+ return load_elf(path.c_str(), &preload_aware_memif, entry);
+}
+
+void htif_t::load_program()
+{
+ std::map<std::string, uint64_t> symbols = load_payload(targs[0], &entry);
if (symbols.count("tohost") && symbols.count("fromhost")) {
tohost_addr = symbols["tohost"];
@@ -131,6 +136,12 @@ void htif_t::load_program()
sig_addr = symbols["begin_signature"];
sig_len = symbols["end_signature"] - sig_addr;
}
+
+ for (auto payload : payloads)
+ {
+ reg_t dummy_entry;
+ load_payload(payload, &dummy_entry);
+ }
}
void htif_t::stop()
@@ -243,6 +254,9 @@ void htif_t::parse_arguments(int argc, char ** argv)
case HTIF_LONG_OPTIONS_OPTIND + 3:
syscall_proxy.set_chroot(optarg);
break;
+ case HTIF_LONG_OPTIONS_OPTIND + 4:
+ payloads.push_back(optarg);
+ break;
case '?':
if (!opterr)
break;
@@ -273,6 +287,10 @@ void htif_t::parse_arguments(int argc, char ** argv)
c = HTIF_LONG_OPTIONS_OPTIND + 3;
optarg = optarg + 8;
}
+ else if (arg.find("+payload=") == 0) {
+ c = HTIF_LONG_OPTIONS_OPTIND + 4;
+ optarg = optarg + 9;
+ }
else if (arg.find("+permissive-off") == 0) {
if (opterr)
throw std::invalid_argument("Found +permissive-off when not parsing permissively");