[Skiboot] [PATCH v9 05/11] dt: Add phandle fixup helpers
Stewart Smith
stewart at linux.vnet.ibm.com
Tue May 2 14:24:44 AEST 2017
Madhavan Srinivasan <maddy at linux.vnet.ibm.com> writes:
> On Monday 01 May 2017 12:28 PM, Stewart Smith wrote:
>> Anju T Sudhakar <anju at linux.vnet.ibm.com> writes:
>>> Patch to add a phandle fixup function for a new
>> You don't need to say "patch to add". You can drop the whole first
>> sentence.
>>
>>> incoming subtree. When attaching a "subtree" to
>>> main dt, subtree could have "property" referring
>>> different nodes or multiple nodes via phandle as
>>> "labels". For this reason, new subtree will have
>>> "phandle" already assigned to some of it's nodes.
>>> If this new subtree is attached to main dt without
>>> phandle fixup, could lead to duplicate phandle errors
>>>
>>> dt_fixup_populate_hash() does two main things. It first
>>> uses a hash primitive to create a hashtable using phandle
>>> as key. It then loops through the list of properties specified
>>> as an input to this function (which needs to be fixed up),
>>> and calls the fixup "handler".
>>>
>>> Signed-off-by: Anju T Sudhakar <anju at linux.vnet.ibm.com>
>>> Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
>>> ---
>>> core/device.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>>> include/device.h | 19 +++++++++++++++++++
>>> 2 files changed, 66 insertions(+)
>>>
>>> diff --git a/core/device.c b/core/device.c
>>> index 170e0ee..e933c27 100644
>>> --- a/core/device.c
>>> +++ b/core/device.c
>>> @@ -17,6 +17,7 @@
>>> #include <device.h>
>>> #include <stdlib.h>
>>> #include <skiboot.h>
>>> +#include <hash.h>
>>> #include <libfdt/libfdt.h>
>>> #include <libfdt/libfdt_internal.h>
>>> #include <ccan/str/str.h>
>>> @@ -849,6 +850,52 @@ void dt_expand(const void *fdt)
>>> abort();
>>> }
>>>
>>> +/* dt_fixup_populate_hash: populate the hash table, and invoke the fixup-handler
>>> + * to fixup the phandle value of the nodes.
>>> + */
>>> +int dt_fixup_populate_hash(struct dt_node *dev, hash_table_p hash, phandle_fixup_p list_prop )
>>> +{
>>> + struct dt_node *node;
>>> + hash_entry_p entry;
>>> + fixup_prop_list *list_pp;
>>> + u32 phandle;
>>> + phandle_fixup_n *val;
>>> +
>>> + /* Initialize the hashtable */
>>> + hash_init(hash);
>>> +
>>> + /* For each node of 'dev', insert the node-phandle pair into hashtable */
>>> + dt_for_each_node(dev, node) {
>>> + if (node->phandle > 0) {
>>> + val = (phandle_fixup_n *)malloc(sizeof(phandle_fixup_n));
>>> + if(!val) {
>>> + prerror("Failed to allocate memory");
>>> + return -1;
>>> + }
>>> + val->node = node;
>>> + val->fixed = false;
>>> + entry = hash_insert_entry(hash, node->phandle, val);
>>> + if(!entry) {
>>> + prerror("Failed to make hash table entry");
>>> + return -1;
>>> + }
>>> + }
>>> + }
>>> + list_for_each(&list_prop->list, list_pp, list) {
>>> + phandle = dt_prop_get_u32(list_pp->node, list_pp->prop->name);
>>> + /* look for the entry, with phandle as the key to hashtable */
>>> + entry = hash_lookup_entry(hash, phandle);
>>> + if (entry) {
>>> + /* If find a valid entry in the hashtable, do the fixup */
>>> + list_prop->fixup(entry, list_pp->prop);
>>> + } else {
>>> + prerror("%s: Missing hash entry phandle = %x\n", __FUNCTION__, phandle);
>>> + return -1;
>>> + }
>>> + }
>>> + return 0;
>>> +}
>>> +
>> This looks overly complex for what needs to be done.
>>
>> If we're importing a subtree that uses phandles say 1-100, and our
>> existing last_phandle=42, then all we need to do is go through and add
>> 42 to all of the phandles in the subtree, and at the end, set
>> last_phandle=42+100.
>
> Basically this function does two things.
> 1)Fix the phandle
> 2)properties that refers to the phandle
>
> For example (from imc dtb), node here carries the events supported by
> "mcs" unit.
> And this node is common and referred by all "mcs" units supported.
>
> + nest-mcs-events {
> + #address-cells = <0x1>;
> + #size-cells = <0x1>;
> + phandle = <0x10000242>;
> +
>
> Here is the "mcs" unit node which refers to the above event node via
> a property called "events". "events" property contains the phandle.
>
> + mcs3 {
> + compatible = "ibm,imc-counters-nest";
> + events-prefix = "PM_MCS3_"; /* denotes event name to be prefixed to get complete event name supported by this device */
> +
> + phandle = <0x10000241>;
> + events = <0x10000242>; /* phandle of the events node supported by this device */
>
>
> So when we fix the incoming dtb for the phandles, we also need to
> look for any property that refers that phandle.
>
> Now my initial implementation was using llist from the
> current ccan lib in the skiboot, But benh suggested to
> have a simple hash primitive. Since this is a generic
> function, he suggested to have a list of properties from
> the caller along with a "handler" function which knows to fix.
>
> Hope this clarifies.
I don't see why any of that would require anything more complex than a
single pass through the subtree we're adding though.
We just need a function like this:
int dt_adjust_subtree_phandle(dt_node *subtree,
const char** (get_properties_to_fix*)(dt_node *n))
{
phandle_import_start = ++last_phandle;
foreach node and subnode {
phandle += phandle_import_start;
const char **properties_to_update;
props_to_update = get_properties_to_fix(node);
if (props_to_update) {
for (const char* p = props_to_update; *p != NULL; p++) {
set_value(prop, get_value(prop) + phandle_import_start);
}
}
}
}
With this for IMC:
const char** imc_properties_to_fix(dt_node *node)
{
if (node_is_compatible("ibm,imc-counters-nest"))
return { "events" , NULL };
else
return NULL;
}
?
--
Stewart Smith
OPAL Architect, IBM.
More information about the Skiboot
mailing list