1 // See LICENSE for license details.
11 std::string
make_dts(size_t insns_per_rtc_tick
, size_t cpu_hz
,
12 std::vector
<processor_t
*> procs
,
13 std::vector
<std::pair
<reg_t
, mem_t
*>> mems
)
20 " #address-cells = <2>;\n"
21 " #size-cells = <2>;\n"
22 " compatible = \"ucbbar,spike-bare-dev\";\n"
23 " model = \"ucbbar,spike-bare\";\n"
25 " #address-cells = <1>;\n"
26 " #size-cells = <0>;\n"
27 " timebase-frequency = <" << (cpu_hz
/insns_per_rtc_tick
) << ">;\n";
28 for (size_t i
= 0; i
< procs
.size(); i
++) {
29 s
<< " CPU" << i
<< ": cpu@" << i
<< " {\n"
30 " device_type = \"cpu\";\n"
31 " reg = <" << i
<< ">;\n"
32 " status = \"okay\";\n"
33 " compatible = \"riscv\";\n"
34 " riscv,isa = \"" << procs
[i
]->get_isa_string() << "\";\n"
35 " mmu-type = \"riscv," << (procs
[i
]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n"
36 " clock-frequency = <" << cpu_hz
<< ">;\n"
37 " CPU" << i
<< "_intc: interrupt-controller {\n"
38 " #interrupt-cells = <1>;\n"
39 " interrupt-controller;\n"
40 " compatible = \"riscv,cpu-intc\";\n"
45 for (auto& m
: mems
) {
47 " memory@" << m
.first
<< " {\n"
48 " device_type = \"memory\";\n"
49 " reg = <0x" << (m
.first
>> 32) << " 0x" << (m
.first
& (uint32_t)-1) <<
50 " 0x" << (m
.second
->size() >> 32) << " 0x" << (m
.second
->size() & (uint32_t)-1) << ">;\n"
54 " #address-cells = <2>;\n"
55 " #size-cells = <2>;\n"
56 " compatible = \"ucbbar,spike-bare-soc\", \"simple-bus\";\n"
58 " clint@" << CLINT_BASE
<< " {\n"
59 " compatible = \"riscv,clint0\";\n"
60 " interrupts-extended = <" << std::dec
;
61 for (size_t i
= 0; i
< procs
.size(); i
++)
62 s
<< "&CPU" << i
<< "_intc 3 &CPU" << i
<< "_intc 7 ";
63 reg_t clintbs
= CLINT_BASE
;
64 reg_t clintsz
= CLINT_SIZE
;
65 s
<< std::hex
<< ">;\n"
66 " reg = <0x" << (clintbs
>> 32) << " 0x" << (clintbs
& (uint32_t)-1) <<
67 " 0x" << (clintsz
>> 32) << " 0x" << (clintsz
& (uint32_t)-1) << ">;\n"
71 " compatible = \"ucb,htif0\";\n"
77 std::string
dts_compile(const std::string
& dts
)
79 // Convert the DTS to DTB
83 if (pipe(dts_pipe
) != 0 || (dts_pid
= fork()) < 0) {
84 std::cerr
<< "Failed to fork dts child: " << strerror(errno
) << std::endl
;
88 // Child process to output dts
91 int step
, len
= dts
.length();
92 const char *buf
= dts
.c_str();
93 for (int done
= 0; done
< len
; done
+= step
) {
94 step
= write(dts_pipe
[1], buf
+done
, len
-done
);
96 std::cerr
<< "Failed to write dts: " << strerror(errno
) << std::endl
;
106 if (pipe(dtb_pipe
) != 0 || (dtb_pid
= fork()) < 0) {
107 std::cerr
<< "Failed to fork dtb child: " << strerror(errno
) << std::endl
;
111 // Child process to output dtb
113 dup2(dts_pipe
[0], 0);
114 dup2(dtb_pipe
[1], 1);
119 execl(DTC
, DTC
, "-O", "dtb", 0);
120 std::cerr
<< "Failed to run " DTC
": " << strerror(errno
) << std::endl
;
129 std::stringstream dtb
;
133 while ((got
= read(dtb_pipe
[0], buf
, sizeof(buf
))) > 0) {
137 std::cerr
<< "Failed to read dtb: " << strerror(errno
) << std::endl
;
144 waitpid(dts_pid
, &status
, 0);
145 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
146 std::cerr
<< "Child dts process failed" << std::endl
;
149 waitpid(dtb_pid
, &status
, 0);
150 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
151 std::cerr
<< "Child dtb process failed" << std::endl
;