linux/scripts/dtc/livetree.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
   3 *
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of the
   8 * License, or (at your option) any later version.
   9 *
  10 *  This program is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 *  General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU General Public License
  16 *  along with this program; if not, write to the Free Software
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  18 *                                                                   USA
  19 */
  20
  21#include "dtc.h"
  22
  23/*
  24 * Tree building functions
  25 */
  26
  27struct property *build_property(char *name, struct data val, char *label)
  28{
  29        struct property *new = xmalloc(sizeof(*new));
  30
  31        new->name = name;
  32        new->val = val;
  33
  34        new->next = NULL;
  35
  36        new->label = label;
  37
  38        return new;
  39}
  40
  41struct property *chain_property(struct property *first, struct property *list)
  42{
  43        assert(first->next == NULL);
  44
  45        first->next = list;
  46        return first;
  47}
  48
  49struct property *reverse_properties(struct property *first)
  50{
  51        struct property *p = first;
  52        struct property *head = NULL;
  53        struct property *next;
  54
  55        while (p) {
  56                next = p->next;
  57                p->next = head;
  58                head = p;
  59                p = next;
  60        }
  61        return head;
  62}
  63
  64struct node *build_node(struct property *proplist, struct node *children)
  65{
  66        struct node *new = xmalloc(sizeof(*new));
  67        struct node *child;
  68
  69        memset(new, 0, sizeof(*new));
  70
  71        new->proplist = reverse_properties(proplist);
  72        new->children = children;
  73
  74        for_each_child(new, child) {
  75                child->parent = new;
  76        }
  77
  78        return new;
  79}
  80
  81struct node *name_node(struct node *node, char *name, char * label)
  82{
  83        assert(node->name == NULL);
  84
  85        node->name = name;
  86
  87        node->label = label;
  88
  89        return node;
  90}
  91
  92struct node *chain_node(struct node *first, struct node *list)
  93{
  94        assert(first->next_sibling == NULL);
  95
  96        first->next_sibling = list;
  97        return first;
  98}
  99
 100void add_property(struct node *node, struct property *prop)
 101{
 102        struct property **p;
 103
 104        prop->next = NULL;
 105
 106        p = &node->proplist;
 107        while (*p)
 108                p = &((*p)->next);
 109
 110        *p = prop;
 111}
 112
 113void add_child(struct node *parent, struct node *child)
 114{
 115        struct node **p;
 116
 117        child->next_sibling = NULL;
 118        child->parent = parent;
 119
 120        p = &parent->children;
 121        while (*p)
 122                p = &((*p)->next_sibling);
 123
 124        *p = child;
 125}
 126
 127struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
 128                                         char *label)
 129{
 130        struct reserve_info *new = xmalloc(sizeof(*new));
 131
 132        new->re.address = address;
 133        new->re.size = size;
 134
 135        new->next = NULL;
 136
 137        new->label = label;
 138
 139        return new;
 140}
 141
 142struct reserve_info *chain_reserve_entry(struct reserve_info *first,
 143                                        struct reserve_info *list)
 144{
 145        assert(first->next == NULL);
 146
 147        first->next = list;
 148        return first;
 149}
 150
 151struct reserve_info *add_reserve_entry(struct reserve_info *list,
 152                                      struct reserve_info *new)
 153{
 154        struct reserve_info *last;
 155
 156        new->next = NULL;
 157
 158        if (! list)
 159                return new;
 160
 161        for (last = list; last->next; last = last->next)
 162                ;
 163
 164        last->next = new;
 165
 166        return list;
 167}
 168
 169struct boot_info *build_boot_info(struct reserve_info *reservelist,
 170                                  struct node *tree, uint32_t boot_cpuid_phys)
 171{
 172        struct boot_info *bi;
 173
 174        bi = xmalloc(sizeof(*bi));
 175        bi->reservelist = reservelist;
 176        bi->dt = tree;
 177        bi->boot_cpuid_phys = boot_cpuid_phys;
 178
 179        return bi;
 180}
 181
 182/*
 183 * Tree accessor functions
 184 */
 185
 186const char *get_unitname(struct node *node)
 187{
 188        if (node->name[node->basenamelen] == '\0')
 189                return "";
 190        else
 191                return node->name + node->basenamelen + 1;
 192}
 193
 194struct property *get_property(struct node *node, const char *propname)
 195{
 196        struct property *prop;
 197
 198        for_each_property(node, prop)
 199                if (streq(prop->name, propname))
 200                        return prop;
 201
 202        return NULL;
 203}
 204
 205cell_t propval_cell(struct property *prop)
 206{
 207        assert(prop->val.len == sizeof(cell_t));
 208        return fdt32_to_cpu(*((cell_t *)prop->val.val));
 209}
 210
 211struct node *get_subnode(struct node *node, const char *nodename)
 212{
 213        struct node *child;
 214
 215        for_each_child(node, child)
 216                if (streq(child->name, nodename))
 217                        return child;
 218
 219        return NULL;
 220}
 221
 222struct node *get_node_by_path(struct node *tree, const char *path)
 223{
 224        const char *p;
 225        struct node *child;
 226
 227        if (!path || ! (*path))
 228                return tree;
 229
 230        while (path[0] == '/')
 231                path++;
 232
 233        p = strchr(path, '/');
 234
 235        for_each_child(tree, child) {
 236                if (p && strneq(path, child->name, p-path))
 237                        return get_node_by_path(child, p+1);
 238                else if (!p && streq(path, child->name))
 239                        return child;
 240        }
 241
 242        return NULL;
 243}
 244
 245struct node *get_node_by_label(struct node *tree, const char *label)
 246{
 247        struct node *child, *node;
 248
 249        assert(label && (strlen(label) > 0));
 250
 251        if (tree->label && streq(tree->label, label))
 252                return tree;
 253
 254        for_each_child(tree, child) {
 255                node = get_node_by_label(child, label);
 256                if (node)
 257                        return node;
 258        }
 259
 260        return NULL;
 261}
 262
 263struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
 264{
 265        struct node *child, *node;
 266
 267        assert((phandle != 0) && (phandle != -1));
 268
 269        if (tree->phandle == phandle)
 270                return tree;
 271
 272        for_each_child(tree, child) {
 273                node = get_node_by_phandle(child, phandle);
 274                if (node)
 275                        return node;
 276        }
 277
 278        return NULL;
 279}
 280
 281struct node *get_node_by_ref(struct node *tree, const char *ref)
 282{
 283        if (ref[0] == '/')
 284                return get_node_by_path(tree, ref);
 285        else
 286                return get_node_by_label(tree, ref);
 287}
 288
 289cell_t get_node_phandle(struct node *root, struct node *node)
 290{
 291        static cell_t phandle = 1; /* FIXME: ick, static local */
 292
 293        if ((node->phandle != 0) && (node->phandle != -1))
 294                return node->phandle;
 295
 296        assert(! get_property(node, "linux,phandle"));
 297
 298        while (get_node_by_phandle(root, phandle))
 299                phandle++;
 300
 301        node->phandle = phandle;
 302        add_property(node,
 303                     build_property("linux,phandle",
 304                                    data_append_cell(empty_data, phandle),
 305                                    NULL));
 306
 307        return node->phandle;
 308}
 309