aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fesvr/elfloader.cc8
-rw-r--r--fesvr/memif.h5
-rw-r--r--riscv/cfg.h3
-rw-r--r--riscv/mmu.cc7
-rw-r--r--riscv/mmu.h11
-rw-r--r--riscv/processor.cc3
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/sim.cc30
-rw-r--r--riscv/sim.h1
-rw-r--r--spike_main/spike-log-parser.cc2
-rw-r--r--spike_main/spike.cc3
11 files changed, 35 insertions, 40 deletions
diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc
index 1bdccd3..7357b47 100644
--- a/fesvr/elfloader.cc
+++ b/fesvr/elfloader.cc
@@ -98,7 +98,9 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
} while (0)
if (IS_ELFLE(*eh64)) {
- memif->set_target_endianness(memif_endianness_little);
+ if (memif->get_target_endianness() != memif_endianness_little) {
+ throw std::invalid_argument("Specified ELF is little endian, but system uses a big-endian memory system. Rerun without --big-endian");
+ }
if (IS_ELF32(*eh64))
LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym, from_le);
else
@@ -107,7 +109,9 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
#ifndef RISCV_ENABLE_DUAL_ENDIAN
throw std::invalid_argument("Specified ELF is big endian. Configure with --enable-dual-endian to enable support");
#else
- memif->set_target_endianness(memif_endianness_big);
+ if (memif->get_target_endianness() != memif_endianness_big) {
+ throw std::invalid_argument("Specified ELF is big endian, but system uses a little-endian memory system. Rerun with --big-endian");
+ }
if (IS_ELF32(*eh64))
LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym, from_be);
else
diff --git a/fesvr/memif.h b/fesvr/memif.h
index 7a005f2..e641d21 100644
--- a/fesvr/memif.h
+++ b/fesvr/memif.h
@@ -27,8 +27,6 @@ public:
virtual size_t chunk_align() = 0;
virtual size_t chunk_max_size() = 0;
- virtual void set_target_endianness(memif_endianness_t) {}
-
virtual memif_endianness_t get_target_endianness() const {
return memif_endianness_little;
}
@@ -71,9 +69,6 @@ public:
virtual void write_int64(addr_t addr, target_endian<int64_t> val);
// endianness
- virtual void set_target_endianness(memif_endianness_t endianness) {
- cmemif->set_target_endianness(endianness);
- }
virtual memif_endianness_t get_target_endianness() const {
return cmemif->get_target_endianness();
}
diff --git a/riscv/cfg.h b/riscv/cfg.h
index dbdb58b..f0f88e4 100644
--- a/riscv/cfg.h
+++ b/riscv/cfg.h
@@ -61,6 +61,7 @@ public:
const char *default_bootargs,
const char *default_isa, const char *default_priv,
const char *default_varch,
+ const memif_endianness_t default_endianness,
const reg_t default_pmpregions,
const std::vector<mem_cfg_t> &default_mem_layout,
const std::vector<int> default_hartids,
@@ -70,6 +71,7 @@ public:
isa(default_isa),
priv(default_priv),
varch(default_varch),
+ endianness(default_endianness),
pmpregions(default_pmpregions),
mem_layout(default_mem_layout),
hartids(default_hartids),
@@ -82,6 +84,7 @@ public:
cfg_arg_t<const char *> isa;
cfg_arg_t<const char *> priv;
cfg_arg_t<const char *> varch;
+ memif_endianness_t endianness;
reg_t pmpregions;
cfg_arg_t<std::vector<mem_cfg_t>> mem_layout;
std::optional<reg_t> start_pc;
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 3f9b5e9..a966180 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -5,16 +5,19 @@
#include "simif.h"
#include "processor.h"
-mmu_t::mmu_t(simif_t* sim, processor_t* proc)
+mmu_t::mmu_t(simif_t* sim, memif_endianness_t endianness, processor_t* proc)
: sim(sim), proc(proc),
#ifdef RISCV_ENABLE_DUAL_ENDIAN
- target_big_endian(false),
+ target_big_endian(endianness == memif_endianness_big),
#endif
check_triggers_fetch(false),
check_triggers_load(false),
check_triggers_store(false),
matched_trigger(NULL)
{
+#ifndef RISCV_ENABLE_DUAL_ENDIAN
+ assert(endianness == memif_endianness_little);
+#endif
flush_tlb();
yield_load_reservation();
}
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 19105e3..cee93e3 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -46,7 +46,7 @@ private:
std::map<reg_t, reg_t> alloc_cache;
std::vector<std::pair<reg_t, reg_t >> addr_tbl;
public:
- mmu_t(simif_t* sim, processor_t* proc);
+ mmu_t(simif_t* sim, memif_endianness_t endianness, processor_t* proc);
~mmu_t();
#define RISCV_XLATE_VIRT (1U << 0)
@@ -298,15 +298,6 @@ public:
#endif
}
- void set_target_big_endian(bool enable)
- {
-#ifdef RISCV_ENABLE_DUAL_ENDIAN
- target_big_endian = enable;
-#else
- assert(enable == false);
-#endif
- }
-
bool is_target_big_endian()
{
return target_big_endian;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 9262199..f9a451e 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -29,6 +29,7 @@
processor_t::processor_t(const isa_parser_t *isa, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
+ memif_endianness_t endianness,
FILE* log_file, std::ostream& sout_)
: debug(false), halt_request(HR_NONE), isa(isa), sim(sim), id(id), xlen(0),
histogram_enabled(false), log_commits_enabled(false),
@@ -48,7 +49,7 @@ processor_t::processor_t(const isa_parser_t *isa, const char* varch,
parse_varch_string(varch);
register_base_instructions();
- mmu = new mmu_t(sim, this);
+ mmu = new mmu_t(sim, endianness, this);
disassembler = new disassembler_t(isa);
for (auto e : isa->get_extensions())
diff --git a/riscv/processor.h b/riscv/processor.h
index 95043ea..06a92b1 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -16,6 +16,7 @@
#include "csrs.h"
#include "isa_parser.h"
#include "triggers.h"
+#include "memif.h"
class processor_t;
class mmu_t;
@@ -225,6 +226,7 @@ class processor_t : public abstract_device_t
public:
processor_t(const isa_parser_t *isa, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
+ memif_endianness_t endianness,
FILE *log_file, std::ostream& sout_); // because of command line option --log and -s we need both
~processor_t();
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 71ac452..ffb20e4 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -74,11 +74,21 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
debug_module.add_device(&bus);
- debug_mmu = new mmu_t(this, NULL);
+#ifndef RISCV_ENABLE_DUAL_ENDIAN
+ if (cfg->endianness != memif_endianness_little) {
+ fputs("Big-endian support has not been prroperly enabled; "
+ "please rebuild the riscv-isa-sim project using "
+ "\"configure --enable-dual-endian\".\n",
+ stderr);
+ abort();
+ }
+#endif
+
+ debug_mmu = new mmu_t(this, cfg->endianness, NULL);
for (size_t i = 0; i < cfg->nprocs(); i++) {
procs[i] = new processor_t(&isa, cfg->varch(), this, cfg->hartids()[i], halted,
- log_file.get(), sout_);
+ cfg->endianness, log_file.get(), sout_);
}
make_dtb();
@@ -432,22 +442,6 @@ void sim_t::write_chunk(addr_t taddr, size_t len, const void* src)
debug_mmu->store<uint64_t>(taddr, debug_mmu->from_target(data));
}
-void sim_t::set_target_endianness(memif_endianness_t endianness)
-{
-#ifdef RISCV_ENABLE_DUAL_ENDIAN
- assert(endianness == memif_endianness_little || endianness == memif_endianness_big);
-
- bool enable = endianness == memif_endianness_big;
- debug_mmu->set_target_big_endian(enable);
- for (size_t i = 0; i < procs.size(); i++) {
- procs[i]->get_mmu()->set_target_big_endian(enable);
- procs[i]->reset();
- }
-#else
- assert(endianness == memif_endianness_little);
-#endif
-}
-
memif_endianness_t sim_t::get_target_endianness() const
{
return debug_mmu->is_target_big_endian()? memif_endianness_big : memif_endianness_little;
diff --git a/riscv/sim.h b/riscv/sim.h
index a2ffeee..8ca06fe 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -166,7 +166,6 @@ private:
void write_chunk(addr_t taddr, size_t len, const void* src);
size_t chunk_align() { return 8; }
size_t chunk_max_size() { return 8; }
- void set_target_endianness(memif_endianness_t endianness);
memif_endianness_t get_target_endianness() const;
public:
diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc
index 10a3209..efe6955 100644
--- a/spike_main/spike-log-parser.cc
+++ b/spike_main/spike-log-parser.cc
@@ -28,7 +28,7 @@ int main(int UNUSED argc, char** argv)
parser.parse(argv);
isa_parser_t isa(isa_string, DEFAULT_PRIV);
- processor_t p(&isa, DEFAULT_VARCH, 0, 0, false, nullptr, cerr);
+ processor_t p(&isa, DEFAULT_VARCH, 0, 0, false, memif_endianness_little, nullptr, cerr);
if (extension) {
p.register_extension(extension());
}
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index 20afac9..3d9da02 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -44,6 +44,7 @@ static void help(int exit_code = 1)
fprintf(stderr, " --ic=<S>:<W>:<B> Instantiate a cache model with S sets,\n");
fprintf(stderr, " --dc=<S>:<W>:<B> W ways, and B-byte blocks (with S and\n");
fprintf(stderr, " --l2=<S>:<W>:<B> B both powers of 2).\n");
+ fprintf(stderr, " --big-endian Use a big-endian memory system.\n");
fprintf(stderr, " --device=<P,B,A> Attach MMIO plugin device from an --extlib library\n");
fprintf(stderr, " P -- Name of the MMIO plugin\n");
fprintf(stderr, " B -- Base memory address of the device\n");
@@ -287,6 +288,7 @@ int main(int argc, char** argv)
/*default_isa=*/DEFAULT_ISA,
/*default_priv=*/DEFAULT_PRIV,
/*default_varch=*/DEFAULT_VARCH,
+ /*default_endianness*/memif_endianness_little,
/*default_pmpregions=*/16,
/*default_mem_layout=*/parse_mem_layout("2048"),
/*default_hartids=*/std::vector<int>(),
@@ -357,6 +359,7 @@ int main(int argc, char** argv)
parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));});
parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));});
parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));});
+ parser.option(0, "big-endian", 0, [&](const char UNUSED *s){cfg.endianness = memif_endianness_big;});
parser.option(0, "log-cache-miss", 0, [&](const char UNUSED *s){log_cache = true;});
parser.option(0, "isa", 1, [&](const char* s){cfg.isa = s;});
parser.option(0, "pmpregions", 1, [&](const char* s){cfg.pmpregions = atoul_safe(s);});