aboutsummaryrefslogtreecommitdiff
path: root/spike_main
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-04-30 22:03:15 -0700
committerAndrew Waterman <andrew@sifive.com>2017-04-30 22:03:15 -0700
commitabb7dddfdfd6ec5070c26c1824e4f5801e6bb12d (patch)
treec20479a56197fe8bcc6b886a0454af028444ac4c /spike_main
parent1d2892407fed141d20607ae9c49e50673e2c5c11 (diff)
downloadspike-abb7dddfdfd6ec5070c26c1824e4f5801e6bb12d.zip
spike-abb7dddfdfd6ec5070c26c1824e4f5801e6bb12d.tar.gz
spike-abb7dddfdfd6ec5070c26c1824e4f5801e6bb12d.tar.bz2
Support more flexible main memory allocation
Diffstat (limited to 'spike_main')
-rw-r--r--spike_main/spike.cc58
1 files changed, 54 insertions, 4 deletions
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index dde6f5a..80c5fa6 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -18,7 +18,9 @@ static void help()
fprintf(stderr, "usage: spike [host options] <target program> [target options]\n");
fprintf(stderr, "Host Options:\n");
fprintf(stderr, " -p<n> Simulate <n> processors [default 1]\n");
- fprintf(stderr, " -m<n> Provide <n> MiB of target memory [default 4096]\n");
+ fprintf(stderr, " -m<n> Provide <n> MiB of target memory [default 2048]\n");
+ fprintf(stderr, " -m<a:m,b:n,...> Provide memory regions of size m and n bytes\n");
+ fprintf(stderr, " at base addresses a and b (with 4 KiB alignment)\n");
fprintf(stderr, " -d Interactive debug mode\n");
fprintf(stderr, " -g Track histogram of PCs\n");
fprintf(stderr, " -l Generate a log of execution\n");
@@ -35,6 +37,51 @@ static void help()
exit(1);
}
+static std::vector<std::pair<reg_t, mem_t*>> make_mems(const char* arg)
+{
+ // handle legacy mem argument
+ char* p;
+ auto mb = strtoull(arg, &p, 0);
+ if (*p == 0) {
+ reg_t size = reg_t(mb) << 20;
+ return std::vector<std::pair<reg_t, mem_t*>>(1, std::make_pair(reg_t(DRAM_BASE), new mem_t(size)));
+ }
+
+ // handle base/size tuples
+ std::vector<std::pair<reg_t, mem_t*>> res;
+ while (true) {
+ auto base = strtoull(arg, &p, 0);
+ if (!*p || *p != ':')
+ help();
+ auto size = strtoull(p + 1, &p, 0);
+ if ((size | base) % PGSIZE != 0)
+ help();
+ res.push_back(std::make_pair(reg_t(base), new mem_t(size)));
+ if (!*p)
+ break;
+ if (*p != ',')
+ help();
+ arg = p + 1;
+ }
+ return res;
+#if 0
+ // allocate target machine's memory, shrinking it as necessary
+ // until the allocation succeeds
+ size_t memsz0 = (size_t)mem_mb << 20;
+ size_t quantum = 1L << 20;
+ if (memsz0 == 0)
+ memsz0 = (size_t)2048 << 20;
+
+ memsz = memsz0;
+ while ((mem = (char*)calloc(1, memsz)) == NULL)
+ memsz = (size_t)(memsz*0.9)/quantum*quantum;
+
+ if (memsz != memsz0)
+ fprintf(stderr, "warning: only got %zu bytes of target mem (wanted %zu)\n",
+ memsz, memsz0);
+#endif
+}
+
int main(int argc, char** argv)
{
bool debug = false;
@@ -43,7 +90,7 @@ int main(int argc, char** argv)
bool log = false;
bool dump_dts = false;
size_t nprocs = 1;
- size_t mem_mb = 0;
+ std::vector<std::pair<reg_t, mem_t*>> mems;
std::unique_ptr<icache_sim_t> ic;
std::unique_ptr<dcache_sim_t> dc;
std::unique_ptr<cache_sim_t> l2;
@@ -58,7 +105,7 @@ int main(int argc, char** argv)
parser.option('g', 0, 0, [&](const char* s){histogram = true;});
parser.option('l', 0, 0, [&](const char* s){log = true;});
parser.option('p', 0, 1, [&](const char* s){nprocs = atoi(s);});
- parser.option('m', 0, 1, [&](const char* s){mem_mb = atoi(s);});
+ parser.option('m', 0, 1, [&](const char* s){mems = make_mems(s);});
// I wanted to use --halted, but for some reason that doesn't work.
parser.option('H', 0, 0, [&](const char* s){halted = true;});
parser.option(0, "gdb-port", 1, [&](const char* s){gdb_port = atoi(s);});
@@ -78,7 +125,10 @@ int main(int argc, char** argv)
auto argv1 = parser.parse(argv);
std::vector<std::string> htif_args(argv1, (const char*const*)argv + argc);
- sim_t s(isa, nprocs, mem_mb, halted, htif_args);
+ if (mems.empty())
+ mems = make_mems("2048");
+
+ sim_t s(isa, nprocs, halted, mems, htif_args);
std::unique_ptr<gdbserver_t> gdbserver;
if (gdb_port) {
gdbserver = std::unique_ptr<gdbserver_t>(new gdbserver_t(gdb_port, &s));