aboutsummaryrefslogtreecommitdiff
path: root/riscv/sim.cc
diff options
context:
space:
mode:
authorWesley W. Terpstra <wesley@sifive.com>2017-03-21 16:06:49 -0700
committerWesley W. Terpstra <wesley@sifive.com>2017-03-21 16:08:22 -0700
commitf7a7557273b050ddc50dbff09c0c4bf8505e4ac7 (patch)
treed42e564f22996e1e7c4cc02ff3011a476b7c7848 /riscv/sim.cc
parent4198bc7c62a59ca62fdd8deb84affb32978ba986 (diff)
downloadspike-f7a7557273b050ddc50dbff09c0c4bf8505e4ac7.zip
spike-f7a7557273b050ddc50dbff09c0c4bf8505e4ac7.tar.gz
spike-f7a7557273b050ddc50dbff09c0c4bf8505e4ac7.tar.bz2
bootrom: include compiled dtb
Diffstat (limited to 'riscv/sim.cc')
-rw-r--r--riscv/sim.cc88
1 files changed, 87 insertions, 1 deletions
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 49b0336..004ccaa 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -10,6 +10,9 @@
#include <cstdlib>
#include <cassert>
#include <signal.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
volatile bool ctrlc_pressed = false;
static void handle_signal(int sig)
@@ -150,6 +153,87 @@ bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
return bus.store(addr, len, bytes);
}
+static std::string dts_compile(const std::string& dts)
+{
+ // Convert the DTS to DTB
+ int dts_pipe[2];
+ pid_t dts_pid;
+
+ if (pipe(dts_pipe) != 0 || (dts_pid = fork()) < 0) {
+ std::cerr << "Failed to fork dts child: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+
+ // Child process to output dts
+ if (dts_pid == 0) {
+ close(dts_pipe[0]);
+ int step, len = dts.length();
+ const char *buf = dts.c_str();
+ for (int done = 0; done < len; done += step) {
+ step = write(dts_pipe[1], buf+done, len-done);
+ if (step == -1) {
+ std::cerr << "Failed to write dts: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+ }
+ close(dts_pipe[1]);
+ exit(0);
+ }
+
+ pid_t dtb_pid;
+ int dtb_pipe[2];
+ if (pipe(dtb_pipe) != 0 || (dtb_pid = fork()) < 0) {
+ std::cerr << "Failed to fork dtb child: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+
+ // Child process to output dtb
+ if (dtb_pid == 0) {
+ dup2(dts_pipe[0], 0);
+ dup2(dtb_pipe[1], 1);
+ close(dts_pipe[0]);
+ close(dts_pipe[1]);
+ close(dtb_pipe[0]);
+ close(dtb_pipe[1]);
+ execl(DTC, DTC, "-O", "dtb", 0);
+ std::cerr << "Failed to run " DTC ": " << strerror(errno) << std::endl;
+ exit(1);
+ }
+
+ close(dts_pipe[1]);
+ close(dts_pipe[0]);
+ close(dtb_pipe[1]);
+
+ // Read-out dtb
+ std::stringstream dtb;
+
+ int got;
+ char buf[4096];
+ while ((got = read(dtb_pipe[0], buf, sizeof(buf))) > 0) {
+ dtb.write(buf, got);
+ }
+ if (got == -1) {
+ std::cerr << "Failed to read dtb: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+ close(dtb_pipe[0]);
+
+ // Reap children
+ int status;
+ waitpid(dts_pid, &status, 0);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ std::cerr << "Child dts process failed" << std::endl;
+ exit(1);
+ }
+ waitpid(dtb_pid, &status, 0);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ std::cerr << "Child dtb process failed" << std::endl;
+ exit(1);
+ }
+
+ return dtb.str();
+}
+
void sim_t::make_config_string()
{
reg_t rtc_addr = EXT_IO_BASE;
@@ -220,7 +304,9 @@ void sim_t::make_config_string()
"};\n";
config_string = s.str();
- rom.insert(rom.end(), config_string.begin(), config_string.end());
+ std::string dtb = dts_compile(config_string);
+
+ rom.insert(rom.end(), dtb.begin(), dtb.end());
rom.resize((rom.size() / align + 1) * align);
boot_rom.reset(new rom_device_t(rom));