dtc(1): Update to 97d2d5715eeb45108cc60367fdf6bd5b2046b050
Notable fixes: - Overlays may now be generated properly without -@ - /__local_fixups__ were not including unit address in their structure - The error reporting a magic token was misleading, reporting "Bad magic token in header. Got d00dfeed expected 0xd00dfeed" if the token was missing. This has been split out into a separate message. MFC after: 1 week
This commit is contained in:
parent
624b46f401
commit
c1f14ac369
@ -262,9 +262,14 @@ header::write(output_writer &out)
|
||||
bool
|
||||
header::read_dtb(input_buffer &input)
|
||||
{
|
||||
if (!(input.consume_binary(magic) && magic == 0xd00dfeed))
|
||||
if (!input.consume_binary(magic))
|
||||
{
|
||||
fprintf(stderr, "Missing magic token in header. Got %" PRIx32
|
||||
fprintf(stderr, "Missing magic token in header.");
|
||||
return false;
|
||||
}
|
||||
if (magic != 0xd00dfeed)
|
||||
{
|
||||
fprintf(stderr, "Bad magic token in header. Got %" PRIx32
|
||||
" expected 0xd00dfeed\n", magic);
|
||||
return false;
|
||||
}
|
||||
|
@ -1337,7 +1337,7 @@ device_tree::resolve_cross_references(uint32_t &phandle)
|
||||
phandle_set.insert({&i.val, i});
|
||||
}
|
||||
std::vector<std::reference_wrapper<fixup>> sorted_phandles;
|
||||
root->visit([&](node &n, node *parent) {
|
||||
root->visit([&](node &n, node *) {
|
||||
for (auto &p : n.properties())
|
||||
{
|
||||
for (auto &v : *p)
|
||||
@ -1917,117 +1917,122 @@ device_tree::parse_dts(const string &fn, FILE *depfile)
|
||||
symbols.push_back(prop);
|
||||
}
|
||||
root->add_child(node::create_special_node("__symbols__", symbols));
|
||||
// If this is a plugin, then we also need to create two extra nodes.
|
||||
// Internal phandles will need to be renumbered to avoid conflicts with
|
||||
// already-loaded nodes and external references will need to be
|
||||
// resolved.
|
||||
if (is_plugin)
|
||||
}
|
||||
// If this is a plugin, then we also need to create two extra nodes.
|
||||
// Internal phandles will need to be renumbered to avoid conflicts with
|
||||
// already-loaded nodes and external references will need to be
|
||||
// resolved.
|
||||
if (is_plugin)
|
||||
{
|
||||
std::vector<property_ptr> symbols;
|
||||
// Create the fixups entry. This is of the form:
|
||||
// {target} = {path}:{property name}:{offset}
|
||||
auto create_fixup_entry = [&](fixup &i, string target)
|
||||
{
|
||||
string value = i.path.to_string();
|
||||
value += ':';
|
||||
value += i.prop->get_key();
|
||||
value += ':';
|
||||
value += std::to_string(i.prop->offset_of_value(i.val));
|
||||
property_value v;
|
||||
v.string_data = value;
|
||||
v.type = property_value::STRING;
|
||||
auto prop = std::make_shared<property>(std::move(target));
|
||||
prop->add_value(v);
|
||||
return prop;
|
||||
};
|
||||
// If we have any unresolved phandle references in this plugin,
|
||||
// then we must update them to 0xdeadbeef and leave a property in
|
||||
// the /__fixups__ node whose key is the label and whose value is
|
||||
// as described above.
|
||||
if (!unresolved_fixups.empty())
|
||||
{
|
||||
// Create the fixups entry. This is of the form:
|
||||
// {target} = {path}:{property name}:{offset}
|
||||
auto create_fixup_entry = [&](fixup &i, string target)
|
||||
{
|
||||
string value = i.path.to_string();
|
||||
value += ':';
|
||||
value += i.prop->get_key();
|
||||
value += ':';
|
||||
value += std::to_string(i.prop->offset_of_value(i.val));
|
||||
property_value v;
|
||||
v.string_data = value;
|
||||
v.type = property_value::STRING;
|
||||
auto prop = std::make_shared<property>(std::move(target));
|
||||
prop->add_value(v);
|
||||
return prop;
|
||||
};
|
||||
// If we have any unresolved phandle references in this plugin,
|
||||
// then we must update them to 0xdeadbeef and leave a property in
|
||||
// the /__fixups__ node whose key is the label and whose value is
|
||||
// as described above.
|
||||
if (!unresolved_fixups.empty())
|
||||
for (auto &i : unresolved_fixups)
|
||||
{
|
||||
symbols.clear();
|
||||
for (auto &i : unresolved_fixups)
|
||||
{
|
||||
auto &val = i.get().val;
|
||||
symbols.push_back(create_fixup_entry(i, val.string_data));
|
||||
val.byte_data.push_back(0xde);
|
||||
val.byte_data.push_back(0xad);
|
||||
val.byte_data.push_back(0xbe);
|
||||
val.byte_data.push_back(0xef);
|
||||
val.type = property_value::BINARY;
|
||||
}
|
||||
root->add_child(node::create_special_node("__fixups__", symbols));
|
||||
auto &val = i.get().val;
|
||||
symbols.push_back(create_fixup_entry(i, val.string_data));
|
||||
val.byte_data.push_back(0xde);
|
||||
val.byte_data.push_back(0xad);
|
||||
val.byte_data.push_back(0xbe);
|
||||
val.byte_data.push_back(0xef);
|
||||
val.type = property_value::BINARY;
|
||||
}
|
||||
symbols.clear();
|
||||
// If we have any resolved phandle references in this plugin, then
|
||||
// we must create a child in the __local_fixups__ node whose path
|
||||
// matches the node path from the root and whose value contains the
|
||||
// location of the reference within a property.
|
||||
|
||||
// Create a local_fixups node that is initially empty.
|
||||
node_ptr local_fixups = node::create_special_node("__local_fixups__", symbols);
|
||||
for (auto &i : fixups)
|
||||
root->add_child(node::create_special_node("__fixups__", symbols));
|
||||
}
|
||||
symbols.clear();
|
||||
// If we have any resolved phandle references in this plugin, then
|
||||
// we must create a child in the __local_fixups__ node whose path
|
||||
// matches the node path from the root and whose value contains the
|
||||
// location of the reference within a property.
|
||||
|
||||
// Create a local_fixups node that is initially empty.
|
||||
node_ptr local_fixups = node::create_special_node("__local_fixups__", symbols);
|
||||
for (auto &i : fixups)
|
||||
{
|
||||
if (!i.val.is_phandle())
|
||||
{
|
||||
if (!i.val.is_phandle())
|
||||
continue;
|
||||
}
|
||||
node *n = local_fixups.get();
|
||||
for (auto &p : i.path)
|
||||
{
|
||||
// Skip the implicit root
|
||||
if (p.first.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node *n = local_fixups.get();
|
||||
for (auto &p : i.path)
|
||||
bool found = false;
|
||||
for (auto &c : n->child_nodes())
|
||||
{
|
||||
// Skip the implicit root
|
||||
if (p.first.empty())
|
||||
if (c->name == p.first)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
for (auto &c : n->child_nodes())
|
||||
{
|
||||
if (c->name == p.first)
|
||||
string path = p.first;
|
||||
if (!(p.second.empty()))
|
||||
{
|
||||
n = c.get();
|
||||
found = true;
|
||||
break;
|
||||
path += '@';
|
||||
path += p.second;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
n->add_child(node::create_special_node(p.first, symbols));
|
||||
n->add_child(node::create_special_node(path, symbols));
|
||||
n = (--n->child_end())->get();
|
||||
}
|
||||
}
|
||||
assert(n);
|
||||
property_value pv;
|
||||
push_big_endian(pv.byte_data, static_cast<uint32_t>(i.prop->offset_of_value(i.val)));
|
||||
pv.type = property_value::BINARY;
|
||||
auto key = i.prop->get_key();
|
||||
property_ptr prop = n->get_property(key);
|
||||
// If we don't have an existing property then create one and
|
||||
// use this property value
|
||||
if (!prop)
|
||||
if (!found)
|
||||
{
|
||||
n->add_child(node::create_special_node(p.first, symbols));
|
||||
n = (--n->child_end())->get();
|
||||
}
|
||||
}
|
||||
assert(n);
|
||||
property_value pv;
|
||||
push_big_endian(pv.byte_data, static_cast<uint32_t>(i.prop->offset_of_value(i.val)));
|
||||
pv.type = property_value::BINARY;
|
||||
auto key = i.prop->get_key();
|
||||
property_ptr prop = n->get_property(key);
|
||||
// If we don't have an existing property then create one and
|
||||
// use this property value
|
||||
if (!prop)
|
||||
{
|
||||
prop = std::make_shared<property>(std::move(key));
|
||||
n->add_property(prop);
|
||||
prop->add_value(pv);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we do have an existing property value, try to append
|
||||
// this value.
|
||||
property_value &old_val = *(--prop->end());
|
||||
if (!old_val.try_to_merge(pv))
|
||||
{
|
||||
prop = std::make_shared<property>(std::move(key));
|
||||
n->add_property(prop);
|
||||
prop->add_value(pv);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we do have an existing property value, try to append
|
||||
// this value.
|
||||
property_value &old_val = *(--prop->end());
|
||||
if (!old_val.try_to_merge(pv))
|
||||
{
|
||||
prop->add_value(pv);
|
||||
}
|
||||
}
|
||||
}
|
||||
// We've iterated over all fixups, but only emit the
|
||||
// __local_fixups__ if we found some that were resolved internally.
|
||||
if (local_fixups->child_begin() != local_fixups->child_end())
|
||||
{
|
||||
root->add_child(std::move(local_fixups));
|
||||
}
|
||||
}
|
||||
// We've iterated over all fixups, but only emit the
|
||||
// __local_fixups__ if we found some that were resolved internally.
|
||||
if (local_fixups->child_begin() != local_fixups->child_end())
|
||||
{
|
||||
root->add_child(std::move(local_fixups));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user