dtoverlay: Support literal assignments of path strings

The dtc compiler expands &node1 (as opposed to <&node1>) to the full
path to the node with the label "node1". Note that if this label is on
a node in an overlay that the path will reflect that, even if the
node with the label eventually ends up in the base dtb.

If a parameter of a base dtb is used to make an alias point to another
node in the base dtb, it is nice to be able to specify that replacement
path using a label on that node, rather than have to write it out
longhand. Doing so requires one simple change - treating literal
assignments of empty strings as a special case:

    console_uart0 = <&aliases>, "console=", &uart0;

Prior to this commit, this would have resulted in an error when the
console_uart0 was applied because the start of the &uart0 path string
would have been interpreted as a phandle to the next override target.
With this commit, the parser sees the empty string assigment and
treats the next thing as a string to assign (rather like assigning
a phandle value to an integer property).

A consequence of this change is that intentionally assigning an empty
string (probably a very rare occurrence) requires an explicit empty
string to be added, i.e. "...=","" or that the empty assignment falls
at the end of the list of overrides for that parameter.
This commit is contained in:
Phil Elwell
2023-07-06 15:10:35 +01:00
committed by Phil Elwell
parent 44a3953fd1
commit a1c7f81143

View File

@@ -2047,6 +2047,47 @@ static int dtoverlay_extract_override(const char *override_name,
literal_value[0])
{
/* String */
if (type == DTOVERRIDE_STRING && !literal_value[0])
{
/* The empty string is a special case indicating that the literal
* string follows the NUL. This could appear as
* "foo=","bar";
* but the expecged use case is to support label paths:
* "console=",&uart1;
* which dtc will expand to something like:
* "console=","/soc/serial@7e215040";
* Note that the corollary of this is that assigning an empty
* string (not a likely scenario, and not one encountered at the
* time of writing) requires an empty string to appear
* immediately afterwards:
* <&aliases>,"console=","",<&node>,"other:0";
* or that the empty string assignment is at the end:
* <&aliases>,"console=";
* although the same effect can be achieved with:
* <&aliases>,"console[=00";
*/
len = data_end - data;
if (!len)
{
/* end-of-property case - treat as an empty string */
literal_value = data - 1;
override_len = 1;
}
else
{
override_end = memchr(data, 0, len);
if (!override_end)
{
dtoverlay_error(" override %s: string is not NUL-terminated",
override_name);
return -FDT_ERR_BADSTRUCTURE;
}
literal_value = data;
data = override_end + 1;
}
*datap = data;
}
strcpy(override_value, literal_value);
}
else