Skip to content

Commit fdd2570

Browse files
authored
Merge pull request #1721 from abejgonzalez/dts_parsing
Enable more configuration using the DTB
2 parents 62a2dd1 + deeda9a commit fdd2570

File tree

8 files changed

+195
-136
lines changed

8 files changed

+195
-136
lines changed

riscv/dts.cc

Lines changed: 99 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@
1313
#include <sys/types.h>
1414

1515
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,
2117
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
2218
std::string device_nodes)
2319
{
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+
2427
std::stringstream s;
2528
s << std::dec <<
2629
"/dts-v1/;\n"
@@ -54,14 +57,14 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
5457
" #address-cells = <1>;\n"
5558
" #size-cells = <0>;\n"
5659
" 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++) {
5861
s << " CPU" << i << ": cpu@" << i << " {\n"
5962
" device_type = \"cpu\";\n"
60-
" reg = <" << i << ">;\n"
63+
" reg = <" << cfg->hartids[i] << ">;\n"
6164
" status = \"okay\";\n"
6265
" 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"
6568
" riscv,pmpregions = <" << pmpregions << ">;\n"
6669
" riscv,pmpgranularity = <" << pmpgranularity << ">;\n"
6770
" clock-frequency = <" << cpu_hz << ">;\n"
@@ -96,86 +99,91 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
9699
return s.str();
97100
}
98101

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)
100103
{
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;
104112

105113
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;
108116
exit(1);
109117
}
110118

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();
116124
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);
118126
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;
120128
exit(1);
121129
}
122130
}
123-
close(dts_pipe[1]);
131+
close(dtc_input_pipe[1]);
124132
exit(0);
125133
}
126134

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;
131139
exit(1);
132140
}
133141

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);
143151
std::cerr << "Failed to run " DTC ": " << strerror(errno) << std::endl;
144152
exit(1);
145153
}
146154

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]);
150158

151-
// Read-out dtb
152-
std::stringstream dtb;
159+
// Read-out dtc_output
160+
std::stringstream dtc_output;
153161

154162
int got;
155163
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);
158166
}
159167
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;
161169
exit(1);
162170
}
163-
close(dtb_pipe[0]);
171+
close(dtc_output_pipe[0]);
164172

165173
// Reap children
166174
int status;
167-
waitpid(dts_pid, &status, 0);
175+
waitpid(dtc_input_pid, &status, 0);
168176
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;
170178
exit(1);
171179
}
172-
waitpid(dtb_pid, &status, 0);
180+
waitpid(dtc_output_pid, &status, 0);
173181
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;
175183
exit(1);
176184
}
177185

178-
return dtb.str();
186+
return dtc_output.str();
179187
}
180188

181189
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)
386394

387395
return 0;
388396
}
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+
}

riscv/dts.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,11 @@
77
#include <string>
88

99
std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
10-
reg_t initrd_start, reg_t initrd_end,
11-
const char* bootargs,
12-
size_t pmpregions,
13-
size_t pmpgranularity,
14-
std::vector<processor_t*> procs,
10+
const cfg_t* cfg,
1511
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
1612
std::string device_nodes);
1713

18-
std::string dts_compile(const std::string& dts);
14+
std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type);
1915

2016
int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr,
2117
unsigned long *size, const char *field);
@@ -33,4 +29,6 @@ int fdt_parse_ns16550(const void *fdt, reg_t *ns16550_addr,
3329
int fdt_parse_pmp_num(const void *fdt, int cpu_offset, reg_t *pmp_num);
3430
int fdt_parse_pmp_alignment(const void *fdt, int cpu_offset, reg_t *pmp_align);
3531
int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type);
32+
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa_str);
33+
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid);
3634
#endif

riscv/interactive.cc

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,10 @@ void sim_t::interactive()
342342
(this->*funcs[cmd])(cmd, args);
343343
else
344344
out << "Unknown command " << cmd << std::endl;
345-
} catch(trap_t& t) {
345+
} catch(trap_interactive& t) {
346346
out << "Bad or missing arguments for command " << cmd << std::endl;
347+
} catch(trap_t& t){
348+
out << "Received trap: " << t.name() << std::endl;
347349
}
348350
#ifdef HAVE_BOOST_ASIO
349351
if (socketif)
@@ -473,15 +475,9 @@ void sim_t::interactive_insn(const std::string& cmd, const std::vector<std::stri
473475
int max_xlen = p->get_isa().get_max_xlen();
474476

475477
std::ostream out(sout_.rdbuf());
476-
try
477-
{
478-
insn_t insn(get_insn(args));
479-
out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4)
480-
<< zext(insn.bits(), max_xlen) << " " << p->get_disassembler()->disassemble(insn) << std::endl;
481-
}
482-
catch (trap_t& t) {
483-
out << "Unable to obtain insn due to " << t.name() << std::endl;
484-
}
478+
insn_t insn(get_insn(args)); // ensure this is outside of ostream to not pollute output on non-interactive trap
479+
out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4)
480+
<< zext(insn.bits(), max_xlen) << " " << p->get_disassembler()->disassemble(insn) << std::endl;
485481
}
486482

487483
void sim_t::interactive_priv(const std::string& cmd, const std::vector<std::string>& args)
@@ -717,8 +713,9 @@ void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::strin
717713
int max_xlen = procs[0]->get_isa().get_max_xlen();
718714

719715
std::ostream out(sout_.rdbuf());
716+
reg_t mem_val = get_mem(args); // ensure this is outside of ostream to not pollute output on non-interactive trap
720717
out << std::hex << "0x" << std::setfill('0') << std::setw(max_xlen/4)
721-
<< zext(get_mem(args), max_xlen) << std::endl;
718+
<< zext(mem_val, max_xlen) << std::endl;
722719
}
723720

724721
void sim_t::interactive_str(const std::string& cmd, const std::vector<std::string>& args)

0 commit comments

Comments
 (0)