#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)
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;
"};\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));