diff options
author | Andrew Waterman <andrew@sifive.com> | 2020-01-31 15:05:31 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-31 15:05:31 -0800 |
commit | 39fd6f33e03540f25665cd99edd111ef1cf110b0 (patch) | |
tree | e1376b5f77b8019ef96625fbceff3d0dac5d9a1d | |
parent | b93262af831cdfb416d19ee6fa808c5d767c9ceb (diff) | |
parent | 725a0190770b0094f18d0fdc22660fa6845841f7 (diff) | |
download | spike-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
-rw-r--r-- | fesvr/htif.cc | 38 | ||||
-rw-r--r-- | fesvr/htif.h | 7 |
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 |