aboutsummaryrefslogtreecommitdiff
path: root/fesvr
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-01-31 15:05:31 -0800
committerGitHub <noreply@github.com>2020-01-31 15:05:31 -0800
commit39fd6f33e03540f25665cd99edd111ef1cf110b0 (patch)
treee1376b5f77b8019ef96625fbceff3d0dac5d9a1d /fesvr
parentb93262af831cdfb416d19ee6fa808c5d767c9ceb (diff)
parent725a0190770b0094f18d0fdc22660fa6845841f7 (diff)
downloadspike-39fd6f33e03540f25665cd99edd111ef1cf110b0.zip
spike-39fd6f33e03540f25665cd99edd111ef1cf110b0.tar.gz
spike-39fd6f33e03540f25665cd99edd111ef1cf110b0.tar.bz2
Merge pull request #390 from jrtc27/payload
Support loading multiple ELF files via a new payload HTIF option
Diffstat (limited to 'fesvr')
-rw-r--r--fesvr/htif.cc38
-rw-r--r--fesvr/htif.h7
2 files changed, 37 insertions, 8 deletions
diff --git a/fesvr/htif.cc b/fesvr/htif.cc
index d9e884f..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,13 +254,20 @@ 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;
throw std::invalid_argument("Unknown argument (did you mean to enable +permissive parsing?)");
case 1: {
std::string arg = optarg;
- if (arg == "+rfb") {
+ if (arg == "+h" || arg == "+help") {
+ c = 'h';
+ optarg = nullptr;
+ }
+ else if (arg == "+rfb") {
c = HTIF_LONG_OPTIONS_OPTIND;
optarg = nullptr;
}
@@ -269,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");
diff --git a/fesvr/htif.h b/fesvr/htif.h
index d312c77..d69bd42 100644
--- a/fesvr/htif.h
+++ b/fesvr/htif.h
@@ -7,6 +7,7 @@
#include "syscall.h"
#include "device.h"
#include <string.h>
+#include <map>
#include <vector>
class htif_t : public chunked_memif_t
@@ -36,6 +37,7 @@ class htif_t : public chunked_memif_t
virtual size_t chunk_align() = 0;
virtual size_t chunk_max_size() = 0;
+ virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry);
virtual void load_program();
virtual void idle() {}
@@ -69,6 +71,7 @@ class htif_t : public chunked_memif_t
syscall_t syscall_proxy;
bcd_t bcd;
std::vector<device_t*> dynamic_devices;
+ std::vector<std::string> payloads;
const std::vector<std::string>& target_args() { return targs; }
@@ -83,6 +86,7 @@ class htif_t : public chunked_memif_t
#define HTIF_USAGE_OPTIONS \
"HOST OPTIONS\n\
-h, --help Display this help and exit\n\
+ +h, +help\n\
+permissive The host will ignore any unparsed options up until\n\
+permissive-off (Only needed for VCS)\n\
+permissive-off Stop ignoring options. This is mandatory if using\n\
@@ -93,6 +97,8 @@ class htif_t : public chunked_memif_t
+signature=FILE\n\
--chroot=PATH Use PATH as location of syscall-servicing binaries\n\
+chroot=PATH\n\
+ --payload=PATH Load PATH memory as an additional ELF payload\n\
+ +payload=PATH\n\
\n\
HOST OPTIONS (currently unsupported)\n\
--disk=DISK Add DISK device. Use a ramdisk since this isn't\n\
@@ -109,6 +115,7 @@ TARGET (RISC-V BINARY) OPTIONS\n\
{"disk", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 1 }, \
{"signature", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 2 }, \
{"chroot", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 3 }, \
+{"payload", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 4 }, \
{0, 0, 0, 0}
#endif // __HTIF_H