aboutsummaryrefslogtreecommitdiff
path: root/fesvr
diff options
context:
space:
mode:
Diffstat (limited to 'fesvr')
-rw-r--r--fesvr/context.cc2
-rw-r--r--fesvr/device.cc2
-rw-r--r--fesvr/elfloader.cc6
-rw-r--r--fesvr/elfloader.h2
-rw-r--r--fesvr/htif.cc10
-rw-r--r--fesvr/htif.h14
-rw-r--r--fesvr/htif_hexwriter.h2
-rw-r--r--fesvr/memif.h13
-rw-r--r--fesvr/rfb.cc4
-rw-r--r--fesvr/rfb.h2
-rw-r--r--fesvr/syscall.cc4
11 files changed, 39 insertions, 22 deletions
diff --git a/fesvr/context.cc b/fesvr/context.cc
index ca73813..1dceeec 100644
--- a/fesvr/context.cc
+++ b/fesvr/context.cc
@@ -49,7 +49,7 @@ void context_t::init(void (*f)(void*), void* a)
#ifdef USE_UCONTEXT
getcontext(context.get());
context->uc_link = creator->context.get();
- context->uc_stack.ss_size = 64*1024;
+ context->uc_stack.ss_size = 1024 * 1024;
context->uc_stack.ss_sp = new void*[context->uc_stack.ss_size/sizeof(void*)];
#ifndef GLIBC_64BIT_PTR_BUG
makecontext(context.get(), (void(*)(void))&context_t::wrapper, 1, this);
diff --git a/fesvr/device.cc b/fesvr/device.cc
index b149f3c..cbfdb50 100644
--- a/fesvr/device.cc
+++ b/fesvr/device.cc
@@ -33,7 +33,7 @@ void device_t::handle_command(command_t cmd)
command_handlers[cmd.cmd()](cmd);
}
-void device_t::handle_null_command(command_t cmd)
+void device_t::handle_null_command(command_t)
{
}
diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc
index 76cd6da..1bdccd3 100644
--- a/fesvr/elfloader.cc
+++ b/fesvr/elfloader.cc
@@ -16,7 +16,7 @@
#include <vector>
#include <map>
-std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry)
+std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0)
{
int fd = open(fn, O_RDONLY);
struct stat s;
@@ -32,6 +32,10 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
assert(size >= sizeof(Elf64_Ehdr));
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
assert(IS_ELF32(*eh64) || IS_ELF64(*eh64));
+ unsigned xlen = IS_ELF32(*eh64) ? 32 : 64;
+ if (required_xlen != 0 && required_xlen != xlen) {
+ throw incompat_xlen(required_xlen, xlen);
+ }
assert(IS_ELFLE(*eh64) || IS_ELFBE(*eh64));
assert(IS_ELF_EXEC(*eh64));
assert(IS_ELF_RISCV(*eh64) || IS_ELF_EM_NONE(*eh64));
diff --git a/fesvr/elfloader.h b/fesvr/elfloader.h
index 696ef47..ae4ee78 100644
--- a/fesvr/elfloader.h
+++ b/fesvr/elfloader.h
@@ -8,6 +8,6 @@
#include <string>
class memif_t;
-std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry);
+std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0);
#endif
diff --git a/fesvr/htif.cc b/fesvr/htif.cc
index ead309c..29eb7d8 100644
--- a/fesvr/htif.cc
+++ b/fesvr/htif.cc
@@ -82,8 +82,14 @@ htif_t::~htif_t()
void htif_t::start()
{
- if (!targs.empty() && targs[0] != "none")
+ if (!targs.empty() && targs[0] != "none") {
+ try {
load_program();
+ } catch (const incompat_xlen & err) {
+ fprintf(stderr, "Error: cannot execute %d-bit program on RV%d hart\n", err.actual_xlen, err.expected_xlen);
+ exit(1);
+ }
+ }
reset();
}
@@ -129,7 +135,7 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload,
} preload_aware_memif(this);
try {
- return load_elf(path.c_str(), &preload_aware_memif, entry);
+ return load_elf(path.c_str(), &preload_aware_memif, entry, expected_xlen);
} catch (mem_trap_t& t) {
bad_address("loading payload " + payload, t.get_tval());
abort();
diff --git a/fesvr/htif.h b/fesvr/htif.h
index 3cee25f..5767e31 100644
--- a/fesvr/htif.h
+++ b/fesvr/htif.h
@@ -26,31 +26,23 @@ class htif_t : public chunked_memif_t
int run();
bool done();
int exit_code();
-
+ void set_expected_xlen(unsigned int m) { expected_xlen = m; }
virtual memif_t& memif() { return mem; }
template<typename T> inline T from_target(target_endian<T> n) const
{
-#ifdef RISCV_ENABLE_DUAL_ENDIAN
memif_endianness_t endianness = get_target_endianness();
assert(endianness == memif_endianness_little || endianness == memif_endianness_big);
return endianness == memif_endianness_big? n.from_be() : n.from_le();
-#else
- return n.from_le();
-#endif
}
template<typename T> inline target_endian<T> to_target(T n) const
{
-#ifdef RISCV_ENABLE_DUAL_ENDIAN
memif_endianness_t endianness = get_target_endianness();
assert(endianness == memif_endianness_little || endianness == memif_endianness_big);
return endianness == memif_endianness_big? target_endian<T>::to_be(n) : target_endian<T>::to_le(n);
-#else
- return target_endian<T>::to_le(n);
-#endif
}
protected:
@@ -73,7 +65,7 @@ class htif_t : public chunked_memif_t
// indicates that the initial program load can skip writing this address
// range to memory, because it has already been loaded through a sideband
- virtual bool is_address_preloaded(addr_t taddr, size_t len) { return false; }
+ virtual bool is_address_preloaded(addr_t, size_t) { return false; }
// Given an address, return symbol from addr2symbol map
const char* get_symbol(uint64_t addr);
@@ -82,7 +74,7 @@ class htif_t : public chunked_memif_t
void parse_arguments(int argc, char ** argv);
void register_devices();
void usage(const char * program_name);
-
+ unsigned int expected_xlen = 0;
memif_t mem;
reg_t entry;
bool writezeros;
diff --git a/fesvr/htif_hexwriter.h b/fesvr/htif_hexwriter.h
index 7256166..0cd859b 100644
--- a/fesvr/htif_hexwriter.h
+++ b/fesvr/htif_hexwriter.h
@@ -21,7 +21,7 @@ protected:
void read_chunk(addr_t taddr, size_t len, void* dst);
void write_chunk(addr_t taddr, size_t len, const void* src);
- void clear_chunk(addr_t taddr, size_t len) {}
+ void clear_chunk(addr_t, size_t) {}
size_t chunk_max_size() { return width; }
size_t chunk_align() { return width; }
diff --git a/fesvr/memif.h b/fesvr/memif.h
index 001c425..7c73f48 100644
--- a/fesvr/memif.h
+++ b/fesvr/memif.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <stddef.h>
+#include <stdexcept>
#include "byteorder.h"
typedef uint64_t reg_t;
@@ -27,10 +28,13 @@ public:
virtual size_t chunk_align() = 0;
virtual size_t chunk_max_size() = 0;
- virtual void set_target_endianness(memif_endianness_t endianness) {}
+ virtual void set_target_endianness(memif_endianness_t) {}
+
virtual memif_endianness_t get_target_endianness() const {
return memif_endianness_undecided;
}
+
+ virtual ~chunked_memif_t() = default;
};
class memif_t
@@ -79,4 +83,11 @@ protected:
chunked_memif_t* cmemif;
};
+class incompat_xlen : public std::exception {
+public:
+ const unsigned expected_xlen;
+ const unsigned actual_xlen;
+ incompat_xlen(unsigned _expected_xlen, unsigned _actual_xlen) : expected_xlen(_expected_xlen), actual_xlen(_actual_xlen) {}
+};
+
#endif // __MEMIF_H
diff --git a/fesvr/rfb.cc b/fesvr/rfb.cc
index 2594a1b..bd72fda 100644
--- a/fesvr/rfb.cc
+++ b/fesvr/rfb.cc
@@ -119,7 +119,7 @@ void rfb_t::set_pixel_format(const std::string& s)
throw std::runtime_error("bad pixel format");
}
-void rfb_t::fb_update(const std::string& s)
+void rfb_t::fb_update()
{
std::string u;
u += str(uint8_t(0));
@@ -153,7 +153,7 @@ void rfb_t::tick()
std::swap(fb1, fb2);
if (pthread_mutex_trylock(&lock) == 0)
{
- fb_update("");
+ fb_update();
pthread_mutex_unlock(&lock);
}
}
diff --git a/fesvr/rfb.h b/fesvr/rfb.h
index 263663a..e153bc8 100644
--- a/fesvr/rfb.h
+++ b/fesvr/rfb.h
@@ -25,7 +25,7 @@ class rfb_t : public device_t
void thread_main();
friend void* rfb_thread_main(void*);
std::string pixel_format();
- void fb_update(const std::string& s);
+ void fb_update();
void set_encodings(const std::string& s);
void set_pixel_format(const std::string& s);
void write(const std::string& s);
diff --git a/fesvr/syscall.cc b/fesvr/syscall.cc
index ab7fc3b..19c9f38 100644
--- a/fesvr/syscall.cc
+++ b/fesvr/syscall.cc
@@ -17,6 +17,10 @@ using namespace std::placeholders;
#define RISCV_AT_FDCWD -100
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
struct riscv_stat
{
target_endian<uint64_t> dev;