Changeset 1787e527 in mainline for boot/genarch/ofw_tree.c


Ignore:
Timestamp:
2009-11-16T21:22:54Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5ebdf94
Parents:
fcbd1be (diff), 9c70ed6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merged with head (unstable)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/genarch/ofw_tree.c

    rfcbd1be r1787e527  
    2929#include <ofw_tree.h>
    3030#include <ofw.h>
     31#include <ofwarch.h>
    3132#include <types.h>
    3233#include <string.h>
    3334#include <balloc.h>
    3435#include <asm.h>
    35 
    36 #define MAX_PATH_LEN    256
     36#include <memstr.h>
    3737
    3838static ofw_tree_node_t *ofw_tree_node_alloc(void)
     
    4949static void *ofw_tree_space_alloc(size_t size)
    5050{
    51         char *addr;
    52 
    5351        /*
    5452         * What we do here is a nasty hack :-)
     
    6159         * behind the requested memory.
    6260         */
    63         addr = balloc(size + 1, size);
     61        char *addr = balloc(size + 1, size);
    6462        if (addr)
    6563                addr[size] = '\0';
     64       
    6665        return addr;
    6766}
     
    7574 * order to prevent stack from overflowing.
    7675 *
    77  * @param current_node  Pointer to uninitialized ofw_tree_node structure that
    78  *                      will become the memory represenation of 'current'.
    79  * @param parent_node   Parent ofw_tree_node structure or NULL in case of root
    80  *                      node.
    81  * @param current       OpenFirmware phandle to the current device tree node.
     76 * @param current_node Pointer to uninitialized ofw_tree_node structure that
     77 *                     will become the memory represenation of 'current'.
     78 * @param parent_node  Parent ofw_tree_node structure or NULL in case of root
     79 *                     node.
     80 * @param current      OpenFirmware phandle to the current device tree node.
     81 *
    8282 */
    8383static void ofw_tree_node_process(ofw_tree_node_t *current_node,
    8484    ofw_tree_node_t *parent_node, phandle current)
    8585{
    86         static char path[MAX_PATH_LEN + 1];
    87         static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
    88         static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
    89         phandle peer;
    90         phandle child;
    91         size_t len;
    92         int i;
    93 
    9486        while (current_node) {
    9587                /*
    9688                 * Initialize node.
    9789                 */
    98                 current_node->parent = parent_node;
     90                current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node);
    9991                current_node->peer = NULL;
    10092                current_node->child = NULL;
     
    10395                current_node->property = NULL;
    10496                current_node->device = NULL;
    105        
     97               
    10698                /*
    10799                 * Get the disambigued name.
    108100                 */
    109                 len = ofw_package_to_path(current, path, MAX_PATH_LEN);
     101                static char path[OFW_TREE_PATH_MAX_LEN + 1];
     102                size_t len = ofw_package_to_path(current, path, OFW_TREE_PATH_MAX_LEN);
    110103                if (len == -1)
    111104                        return;
    112        
     105               
    113106                path[len] = '\0';
    114                 for (i = len - 1; i >= 0 && path[i] != '/'; i--)
    115                         ;
    116                 i++;    /* do not include '/' */
    117        
     107               
     108                /* Find last slash */
     109                int i;
     110                for (i = len - 1; (i >= 0) && (path[i] != '/'); i--);
     111               
     112                /* Do not include the slash */
     113                i++;
    118114                len -= i;
    119 
    120                 /* add space for trailing '\0' */
    121                 current_node->da_name = ofw_tree_space_alloc(len + 1);
    122                 if (!current_node->da_name)
    123                         return;
    124        
    125                 memcpy(current_node->da_name, &path[i], len);
    126                 current_node->da_name[len] = '\0';
    127        
     115               
     116                /* Add space for trailing '\0' */
     117                char *da_name = ofw_tree_space_alloc(len + 1);
     118                if (!da_name)
     119                        return;
     120               
     121                memcpy(da_name, &path[i], len);
     122                da_name[len] = '\0';
     123                current_node->da_name = (char *) balloc_rebase(da_name);
     124               
    128125                /*
    129126                 * Recursively process the potential child node.
    130127                 */
    131                 child = ofw_get_child_node(current);
    132                 if (child != 0 && child != -1) {
    133                         ofw_tree_node_t *child_node;
    134                
    135                         child_node = ofw_tree_node_alloc();
     128                phandle child = ofw_get_child_node(current);
     129                if ((child != 0) && (child != -1)) {
     130                        ofw_tree_node_t *child_node = ofw_tree_node_alloc();
    136131                        if (child_node) {
    137132                                ofw_tree_node_process(child_node, current_node,
    138133                                    child);
    139                                 current_node->child = child_node;
     134                                current_node->child =
     135                                    (ofw_tree_node_t *) balloc_rebase(child_node);
    140136                        }
    141137                }
    142        
     138               
    143139                /*
    144140                 * Count properties.
    145141                 */
     142                static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
     143                static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
    146144                name[0] = '\0';
    147145                while (ofw_next_property(current, name, name2) == 1) {
     
    149147                        memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
    150148                }
    151 
     149               
    152150                if (!current_node->properties)
    153151                        return;
    154        
     152               
    155153                /*
    156154                 * Copy properties.
    157155                 */
    158                 current_node->property =
     156                ofw_tree_property_t *property =
    159157                    ofw_tree_properties_alloc(current_node->properties);
    160                 if (!current_node->property)
     158                if (!property)
    161159                        return;
    162160               
    163161                name[0] = '\0';
    164162                for (i = 0; ofw_next_property(current, name, name2) == 1; i++) {
    165                         size_t size;
    166                
    167163                        if (i == current_node->properties)
    168164                                break;
    169                
     165                       
    170166                        memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
    171                         memcpy(current_node->property[i].name, name,
    172                             OFW_TREE_PROPERTY_MAX_NAMELEN);
    173                         current_node->property[i].name[
    174                             OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
    175 
    176                         size = ofw_get_proplen(current, name);
    177                         current_node->property[i].size = size;
     167                        memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN);
     168                        property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN - 1] = '\0';
     169                       
     170                        size_t size = ofw_get_proplen(current, name);
     171                        property[i].size = size;
     172                       
    178173                        if (size) {
    179                                 void *buf;
    180                        
    181                                 buf = ofw_tree_space_alloc(size);
    182                                 if (current_node->property[i].value = buf) {
     174                                void *buf = ofw_tree_space_alloc(size);
     175                                if (buf) {
    183176                                        /*
    184177                                         * Copy property value to memory node.
    185178                                         */
    186                                         (void) ofw_get_property(current, name,
    187                                             buf, size);
     179                                        (void) ofw_get_property(current, name, buf, size);
     180                                        property[i].value = balloc_rebase(buf);
    188181                                }
    189                         } else {
    190                                 current_node->property[i].value = NULL;
    191                         }
    192                 }
    193 
     182                        } else
     183                                property[i].value = NULL;
     184                }
     185               
    194186                /* Just in case we ran out of memory. */
    195187                current_node->properties = i;
    196 
     188                current_node->property = (ofw_tree_property_t *) balloc_rebase(property);
     189               
     190               
    197191                /*
    198192                 * Iteratively process the next peer node.
     
    202196                 * risk of overflowing the stack is too real.
    203197                 */
    204                 peer = ofw_get_peer_node(current);
    205                 if (peer != 0 && peer != -1) {
    206                         ofw_tree_node_t *peer_node;
    207                
    208                         peer_node = ofw_tree_node_alloc();
    209                         if (peer_node) {
    210                                 current_node->peer = peer_node;
     198                phandle peer = ofw_get_peer_node(current);
     199                if ((peer != 0) && (peer != -1)) {
     200                        ofw_tree_node_t *peer_node = ofw_tree_node_alloc();
     201                        if (peer_node) {
     202                                current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node);
    211203                                current_node = peer_node;
    212204                                current = peer;
     
    217209                        }
    218210                }
     211               
    219212                /*
    220213                 * No more peers on this level.
     
    226219/** Construct memory representation of OpenFirmware device tree.
    227220 *
    228  * @return              NULL on failure or pointer to the root node.
     221 * @return NULL on failure or kernel pointer to the root node.
     222 *
    229223 */
    230224ofw_tree_node_t *ofw_tree_build(void)
    231225{
    232         ofw_tree_node_t *root;
    233         phandle ssm_node;
    234         ofw_tree_node_t *ssm;
    235        
    236         root = ofw_tree_node_alloc();
     226        ofw_tree_node_t *root = ofw_tree_node_alloc();
    237227        if (root)
    238228                ofw_tree_node_process(root, NULL, ofw_root);
    239 
     229       
    240230        /*
    241231         * The firmware client interface does not automatically include the
     
    243233         * solution is to explicitly stick "ssm" to the OFW tree.
    244234         */
    245         ssm_node = ofw_find_device("/ssm@0,0");
     235        phandle ssm_node = ofw_find_device("/ssm@0,0");
    246236        if (ssm_node != -1) {
    247                 ssm = ofw_tree_node_alloc();
     237                ofw_tree_node_t *ssm = ofw_tree_node_alloc();
    248238                if (ssm) {
    249239                        ofw_tree_node_process(ssm, root,
    250240                            ofw_find_device("/ssm@0,0"));
    251241                        ssm->peer = root->child;
    252                         root->child = ssm;
     242                        root->child = (ofw_tree_node_t *) balloc_rebase(ssm);
    253243                }
    254244        }
    255245       
    256         return root;
    257 }
     246        return (ofw_tree_node_t *) balloc_rebase(root);
     247}
Note: See TracChangeset for help on using the changeset viewer.