|
|
|
@ -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)); |
|
|
|
|