From 398101b53f46c0dfdfa3c4540a8a8492aad725c0 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Wed, 3 Jul 2024 11:59:23 -0700 Subject: [PATCH] Generalize DTC compilation to support both DTS/B --- riscv/dts.cc | 87 +++++++++++++++++++++++++++------------------------- riscv/dts.h | 2 +- riscv/sim.cc | 3 +- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/riscv/dts.cc b/riscv/dts.cc index 7f50dd82..7ca7c4e3 100644 --- a/riscv/dts.cc +++ b/riscv/dts.cc @@ -99,86 +99,91 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, return s.str(); } -std::string dts_compile(const std::string& dts) +std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type) { - // Convert the DTS to DTB - int dts_pipe[2]; - pid_t dts_pid; + if (input_type == output_type) + std::cerr << "Must have differing {in,out}put types for running " DTC << std::endl; + + if (!((input_type == "dts" && output_type == "dtb") || (input_type == "dtb" && output_type == "dts"))) + std::cerr << "Invalid {in,out}put types for running " DTC ": Must convert from 'dts' to 'dtb' (or vice versa)" << std::endl; + + int dtc_input_pipe[2]; + pid_t dtc_input_pid; fflush(NULL); // flush stdout/stderr before forking - if (pipe(dts_pipe) != 0 || (dts_pid = fork()) < 0) { - std::cerr << "Failed to fork dts child: " << strerror(errno) << std::endl; + if (pipe(dtc_input_pipe) != 0 || (dtc_input_pid = fork()) < 0) { + std::cerr << "Failed to fork dtc_input 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(); + // Child process to output dtc_input + if (dtc_input_pid == 0) { + close(dtc_input_pipe[0]); + int step, len = dtc_input.length(); + const char *buf = dtc_input.c_str(); for (int done = 0; done < len; done += step) { - step = write(dts_pipe[1], buf+done, len-done); + step = write(dtc_input_pipe[1], buf+done, len-done); if (step == -1) { - std::cerr << "Failed to write dts: " << strerror(errno) << std::endl; + std::cerr << "Failed to write dtc_input: " << strerror(errno) << std::endl; exit(1); } } - close(dts_pipe[1]); + close(dtc_input_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; + pid_t dtc_output_pid; + int dtc_output_pipe[2]; + if (pipe(dtc_output_pipe) != 0 || (dtc_output_pid = fork()) < 0) { + std::cerr << "Failed to fork dtc_output 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]); - execlp(DTC, DTC, "-O", "dtb", (char *)0); + // Child process to output dtc_output + if (dtc_output_pid == 0) { + dup2(dtc_input_pipe[0], 0); + dup2(dtc_output_pipe[1], 1); + close(dtc_input_pipe[0]); + close(dtc_input_pipe[1]); + close(dtc_output_pipe[0]); + close(dtc_output_pipe[1]); + execlp(DTC, DTC, "-O", output_type.c_str(), "-I", input_type.c_str(), (char *)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]); + close(dtc_input_pipe[1]); + close(dtc_input_pipe[0]); + close(dtc_output_pipe[1]); - // Read-out dtb - std::stringstream dtb; + // Read-out dtc_output + std::stringstream dtc_output; int got; char buf[4096]; - while ((got = read(dtb_pipe[0], buf, sizeof(buf))) > 0) { - dtb.write(buf, got); + while ((got = read(dtc_output_pipe[0], buf, sizeof(buf))) > 0) { + dtc_output.write(buf, got); } if (got == -1) { - std::cerr << "Failed to read dtb: " << strerror(errno) << std::endl; + std::cerr << "Failed to read dtc_output: " << strerror(errno) << std::endl; exit(1); } - close(dtb_pipe[0]); + close(dtc_output_pipe[0]); // Reap children int status; - waitpid(dts_pid, &status, 0); + waitpid(dtc_input_pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - std::cerr << "Child dts process failed" << std::endl; + std::cerr << "Child dtc_input process failed" << std::endl; exit(1); } - waitpid(dtb_pid, &status, 0); + waitpid(dtc_output_pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - std::cerr << "Child dtb process failed" << std::endl; + std::cerr << "Child dtc_output process failed" << std::endl; exit(1); } - return dtb.str(); + return dtc_output.str(); } int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr, diff --git a/riscv/dts.h b/riscv/dts.h index d58093be..987f2698 100644 --- a/riscv/dts.h +++ b/riscv/dts.h @@ -11,7 +11,7 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, std::vector> mems, std::string device_nodes); -std::string dts_compile(const std::string& dts); +std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type); int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr, unsigned long *size, const char *field); diff --git a/riscv/sim.cc b/riscv/sim.cc index b0355ae4..e9928f5c 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -133,6 +133,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, std::stringstream strstream; strstream << fin.rdbuf(); dtb = strstream.str(); + dts = dtc_compile(dtb, "dtb", "dts"); } else { std::pair initrd_bounds = cfg->initrd_bounds; std::string device_nodes; @@ -142,7 +143,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, device_nodes.append(factory->generate_dts(this, sargs)); } dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, cfg, mems, device_nodes); - dtb = dts_compile(dts); + dtb = dtc_compile(dts, "dts", "dtb"); } int fdt_code = fdt_check_header(dtb.c_str());