1 // See LICENSE for license details.
3 #ifndef _RISCV_DEVICETREE_H
4 #define _RISCV_DEVICETREE_H
11 #include <arpa/inet.h>
13 #define FDT_MAGIC 0xd00dfeedU
14 #define FDT_VERSION 17
15 #define FDT_COMP_VERSION 16
16 #define FDT_BEGIN_NODE 1
17 #define FDT_END_NODE 2
24 uint32_t off_dt_struct
;
25 uint32_t off_dt_strings
;
28 uint32_t last_comp_version
;
29 uint32_t boot_cpuid_phys
;
30 uint32_t size_dt_strings
;
31 uint32_t size_dt_struct
;
34 struct fdt_reserve_entry
{
40 std::map
<std::string
, size_t> strings
;
41 std::vector
<char> data
;
43 size_t add(std::string s
) {
44 if (!strings
.count(s
)) {
45 strings
[s
] = data
.size();
46 data
.insert(data
.end(), s
.begin(), s
.end());
55 memset(rsvmap
, 0, sizeof(rsvmap
));
58 void begin_node(std::string s
) {
59 std::vector
<uint32_t> name
= s2v(s
);
60 sblock
.push_back(FDT_BEGIN_NODE
);
61 sblock
.insert(sblock
.end(), name
.begin(), name
.end());
65 sblock
.push_back(FDT_END_NODE
);
68 std::vector
<char> finalize() {
69 sblock
.push_back(FDT_END
);
72 h
.size_dt_struct
= sblock
.size() * sizeof(sblock
[0]);
73 h
.size_dt_strings
= strings
.data
.size();
75 h
.off_rsvmap
= sizeof(h
);
76 h
.off_dt_struct
= h
.off_rsvmap
+ sizeof(rsvmap
);
77 h
.off_dt_strings
= h
.off_dt_struct
+ h
.size_dt_struct
;
78 h
.totalsize
= h
.off_dt_strings
+ h
.size_dt_strings
;
79 h
.version
= FDT_VERSION
;
80 h
.last_comp_version
= FDT_COMP_VERSION
;
81 h
.boot_cpuid_phys
= 0;
83 for (uint32_t* p
= &h
.magic
; p
< &h
.magic
+ sizeof(h
)/sizeof(uint32_t); p
++)
85 for (uint32_t& p
: sblock
)
88 std::vector
<char> res
;
89 res
.insert(res
.end(), (char*)&h
, (char*)&h
+ sizeof(h
));
90 res
.insert(res
.end(), (char*)&rsvmap
, (char*)&rsvmap
+ sizeof(rsvmap
));
91 res
.insert(res
.end(), (char*)&sblock
[0],
92 (char*)&sblock
[0] + sblock
.size() * sizeof(sblock
[0]));
93 res
.insert(res
.end(), strings
.data
.begin(), strings
.data
.end());
97 void add_prop(std::string name
, uint32_t data
)
99 add_prop(name
, std::vector
<uint32_t>(1, data
), sizeof(data
));
102 void add_reg(std::vector
<uint64_t> values
)
104 std::vector
<uint32_t> v
;
105 for (auto x
: values
) {
106 v
.push_back(x
>> 32);
109 add_prop("reg", v
, v
.size() * sizeof(v
[0]));
112 void add_prop(std::string name
, std::string data
)
114 add_prop(name
, s2v(data
), data
.size()+1);
118 struct string_table strings
;
119 std::vector
<uint32_t> sblock
;
120 struct fdt_reserve_entry rsvmap
[1];
122 std::vector
<uint32_t> s2v(std::string data
) {
123 std::vector
<char> v(data
.begin(), data
.end());
126 } while (v
.size() % 4);
128 std::vector
<uint32_t> words
;
129 for (size_t i
= 0; i
< v
.size(); i
+= 4)
130 words
.push_back((v
[i
] << 24) | (v
[i
+1] << 16) | (v
[i
+2] << 8) | v
[i
+3]);
134 void add_prop(std::string name
, std::vector
<uint32_t> data
, size_t len
) {
135 sblock
.push_back(FDT_PROP
);
136 sblock
.push_back(len
);
137 sblock
.push_back(strings
.add(name
));
138 sblock
.insert(sblock
.end(), data
.begin(), data
.end());