|
13 | 13 | #include <sys/types.h>
|
14 | 14 |
|
15 | 15 | std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
|
16 |
| - reg_t initrd_start, reg_t initrd_end, |
17 |
| - const char* bootargs, |
18 |
| - size_t pmpregions, |
19 |
| - size_t pmpgranularity, |
20 |
| - std::vector<processor_t*> procs, |
| 16 | + const cfg_t* cfg, |
21 | 17 | std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
|
22 | 18 | std::string device_nodes)
|
23 | 19 | {
|
| 20 | + reg_t initrd_start = cfg->initrd_bounds.first; |
| 21 | + reg_t initrd_end = cfg->initrd_bounds.second; |
| 22 | + const char* bootargs = cfg->bootargs; |
| 23 | + reg_t pmpregions = cfg->pmpregions; |
| 24 | + reg_t pmpgranularity = cfg->pmpgranularity; |
| 25 | + isa_parser_t isa(cfg->isa, cfg->priv); |
| 26 | + |
24 | 27 | std::stringstream s;
|
25 | 28 | s << std::dec <<
|
26 | 29 | "/dts-v1/;\n"
|
@@ -54,14 +57,14 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
|
54 | 57 | " #address-cells = <1>;\n"
|
55 | 58 | " #size-cells = <0>;\n"
|
56 | 59 | " timebase-frequency = <" << (cpu_hz/insns_per_rtc_tick) << ">;\n";
|
57 |
| - for (size_t i = 0; i < procs.size(); i++) { |
| 60 | + for (size_t i = 0; i < cfg->nprocs(); i++) { |
58 | 61 | s << " CPU" << i << ": cpu@" << i << " {\n"
|
59 | 62 | " device_type = \"cpu\";\n"
|
60 |
| - " reg = <" << i << ">;\n" |
| 63 | + " reg = <" << cfg->hartids[i] << ">;\n" |
61 | 64 | " status = \"okay\";\n"
|
62 | 65 | " compatible = \"riscv\";\n"
|
63 |
| - " riscv,isa = \"" << procs[i]->get_isa().get_isa_string() << "\";\n" |
64 |
| - " mmu-type = \"riscv," << (procs[i]->get_isa().get_max_xlen() <= 32 ? "sv32" : "sv57") << "\";\n" |
| 66 | + " riscv,isa = \"" << isa.get_isa_string() << "\";\n" |
| 67 | + " mmu-type = \"riscv," << (isa.get_max_xlen() <= 32 ? "sv32" : "sv57") << "\";\n" |
65 | 68 | " riscv,pmpregions = <" << pmpregions << ">;\n"
|
66 | 69 | " riscv,pmpgranularity = <" << pmpgranularity << ">;\n"
|
67 | 70 | " clock-frequency = <" << cpu_hz << ">;\n"
|
@@ -96,86 +99,91 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
|
96 | 99 | return s.str();
|
97 | 100 | }
|
98 | 101 |
|
99 |
| -std::string dts_compile(const std::string& dts) |
| 102 | +std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type) |
100 | 103 | {
|
101 |
| - // Convert the DTS to DTB |
102 |
| - int dts_pipe[2]; |
103 |
| - pid_t dts_pid; |
| 104 | + if (input_type == output_type) |
| 105 | + std::cerr << "Must have differing {in,out}put types for running " DTC << std::endl; |
| 106 | + |
| 107 | + if (!((input_type == "dts" && output_type == "dtb") || (input_type == "dtb" && output_type == "dts"))) |
| 108 | + std::cerr << "Invalid {in,out}put types for running " DTC ": Must convert from 'dts' to 'dtb' (or vice versa)" << std::endl; |
| 109 | + |
| 110 | + int dtc_input_pipe[2]; |
| 111 | + pid_t dtc_input_pid; |
104 | 112 |
|
105 | 113 | fflush(NULL); // flush stdout/stderr before forking
|
106 |
| - if (pipe(dts_pipe) != 0 || (dts_pid = fork()) < 0) { |
107 |
| - std::cerr << "Failed to fork dts child: " << strerror(errno) << std::endl; |
| 114 | + if (pipe(dtc_input_pipe) != 0 || (dtc_input_pid = fork()) < 0) { |
| 115 | + std::cerr << "Failed to fork dtc_input child: " << strerror(errno) << std::endl; |
108 | 116 | exit(1);
|
109 | 117 | }
|
110 | 118 |
|
111 |
| - // Child process to output dts |
112 |
| - if (dts_pid == 0) { |
113 |
| - close(dts_pipe[0]); |
114 |
| - int step, len = dts.length(); |
115 |
| - const char *buf = dts.c_str(); |
| 119 | + // Child process to output dtc_input |
| 120 | + if (dtc_input_pid == 0) { |
| 121 | + close(dtc_input_pipe[0]); |
| 122 | + int step, len = dtc_input.length(); |
| 123 | + const char *buf = dtc_input.c_str(); |
116 | 124 | for (int done = 0; done < len; done += step) {
|
117 |
| - step = write(dts_pipe[1], buf+done, len-done); |
| 125 | + step = write(dtc_input_pipe[1], buf+done, len-done); |
118 | 126 | if (step == -1) {
|
119 |
| - std::cerr << "Failed to write dts: " << strerror(errno) << std::endl; |
| 127 | + std::cerr << "Failed to write dtc_input: " << strerror(errno) << std::endl; |
120 | 128 | exit(1);
|
121 | 129 | }
|
122 | 130 | }
|
123 |
| - close(dts_pipe[1]); |
| 131 | + close(dtc_input_pipe[1]); |
124 | 132 | exit(0);
|
125 | 133 | }
|
126 | 134 |
|
127 |
| - pid_t dtb_pid; |
128 |
| - int dtb_pipe[2]; |
129 |
| - if (pipe(dtb_pipe) != 0 || (dtb_pid = fork()) < 0) { |
130 |
| - std::cerr << "Failed to fork dtb child: " << strerror(errno) << std::endl; |
| 135 | + pid_t dtc_output_pid; |
| 136 | + int dtc_output_pipe[2]; |
| 137 | + if (pipe(dtc_output_pipe) != 0 || (dtc_output_pid = fork()) < 0) { |
| 138 | + std::cerr << "Failed to fork dtc_output child: " << strerror(errno) << std::endl; |
131 | 139 | exit(1);
|
132 | 140 | }
|
133 | 141 |
|
134 |
| - // Child process to output dtb |
135 |
| - if (dtb_pid == 0) { |
136 |
| - dup2(dts_pipe[0], 0); |
137 |
| - dup2(dtb_pipe[1], 1); |
138 |
| - close(dts_pipe[0]); |
139 |
| - close(dts_pipe[1]); |
140 |
| - close(dtb_pipe[0]); |
141 |
| - close(dtb_pipe[1]); |
142 |
| - execlp(DTC, DTC, "-O", "dtb", (char *)0); |
| 142 | + // Child process to output dtc_output |
| 143 | + if (dtc_output_pid == 0) { |
| 144 | + dup2(dtc_input_pipe[0], 0); |
| 145 | + dup2(dtc_output_pipe[1], 1); |
| 146 | + close(dtc_input_pipe[0]); |
| 147 | + close(dtc_input_pipe[1]); |
| 148 | + close(dtc_output_pipe[0]); |
| 149 | + close(dtc_output_pipe[1]); |
| 150 | + execlp(DTC, DTC, "-O", output_type.c_str(), "-I", input_type.c_str(), (char *)0); |
143 | 151 | std::cerr << "Failed to run " DTC ": " << strerror(errno) << std::endl;
|
144 | 152 | exit(1);
|
145 | 153 | }
|
146 | 154 |
|
147 |
| - close(dts_pipe[1]); |
148 |
| - close(dts_pipe[0]); |
149 |
| - close(dtb_pipe[1]); |
| 155 | + close(dtc_input_pipe[1]); |
| 156 | + close(dtc_input_pipe[0]); |
| 157 | + close(dtc_output_pipe[1]); |
150 | 158 |
|
151 |
| - // Read-out dtb |
152 |
| - std::stringstream dtb; |
| 159 | + // Read-out dtc_output |
| 160 | + std::stringstream dtc_output; |
153 | 161 |
|
154 | 162 | int got;
|
155 | 163 | char buf[4096];
|
156 |
| - while ((got = read(dtb_pipe[0], buf, sizeof(buf))) > 0) { |
157 |
| - dtb.write(buf, got); |
| 164 | + while ((got = read(dtc_output_pipe[0], buf, sizeof(buf))) > 0) { |
| 165 | + dtc_output.write(buf, got); |
158 | 166 | }
|
159 | 167 | if (got == -1) {
|
160 |
| - std::cerr << "Failed to read dtb: " << strerror(errno) << std::endl; |
| 168 | + std::cerr << "Failed to read dtc_output: " << strerror(errno) << std::endl; |
161 | 169 | exit(1);
|
162 | 170 | }
|
163 |
| - close(dtb_pipe[0]); |
| 171 | + close(dtc_output_pipe[0]); |
164 | 172 |
|
165 | 173 | // Reap children
|
166 | 174 | int status;
|
167 |
| - waitpid(dts_pid, &status, 0); |
| 175 | + waitpid(dtc_input_pid, &status, 0); |
168 | 176 | if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
169 |
| - std::cerr << "Child dts process failed" << std::endl; |
| 177 | + std::cerr << "Child dtc_input process failed" << std::endl; |
170 | 178 | exit(1);
|
171 | 179 | }
|
172 |
| - waitpid(dtb_pid, &status, 0); |
| 180 | + waitpid(dtc_output_pid, &status, 0); |
173 | 181 | if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
174 |
| - std::cerr << "Child dtb process failed" << std::endl; |
| 182 | + std::cerr << "Child dtc_output process failed" << std::endl; |
175 | 183 | exit(1);
|
176 | 184 | }
|
177 | 185 |
|
178 |
| - return dtb.str(); |
| 186 | + return dtc_output.str(); |
179 | 187 | }
|
180 | 188 |
|
181 | 189 | int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr,
|
@@ -386,3 +394,44 @@ int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type)
|
386 | 394 |
|
387 | 395 | return 0;
|
388 | 396 | }
|
| 397 | + |
| 398 | +int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa) |
| 399 | +{ |
| 400 | + assert(isa); |
| 401 | + |
| 402 | + int len, rc; |
| 403 | + const void *prop; |
| 404 | + |
| 405 | + if ((rc = check_cpu_node(fdt, cpu_offset)) < 0) |
| 406 | + return rc; |
| 407 | + |
| 408 | + prop = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len); |
| 409 | + if (!prop || !len) |
| 410 | + return -EINVAL; |
| 411 | + |
| 412 | + *isa = (const char *)prop; |
| 413 | + |
| 414 | + return 0; |
| 415 | +} |
| 416 | + |
| 417 | +int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid) |
| 418 | +{ |
| 419 | + int len, rc; |
| 420 | + const void *prop; |
| 421 | + const fdt32_t *val; |
| 422 | + |
| 423 | + if ((rc = check_cpu_node(fdt, cpu_offset)) < 0) |
| 424 | + return rc; |
| 425 | + |
| 426 | + val = (fdt32_t*) fdt_getprop(fdt, cpu_offset, "reg", &len); |
| 427 | + if (!val || len < (int) sizeof(fdt32_t)) |
| 428 | + return -EINVAL; |
| 429 | + |
| 430 | + if (len > (int) sizeof(fdt32_t)) |
| 431 | + val++; |
| 432 | + |
| 433 | + if (hartid) |
| 434 | + *hartid = fdt32_to_cpu(*val); |
| 435 | + |
| 436 | + return 0; |
| 437 | +} |
0 commit comments