Changeset 1787e527 in mainline for boot/genarch/ofw_tree.c
- Timestamp:
- 2009-11-16T21:22:54Z (15 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/ofw_tree.c
rfcbd1be r1787e527 29 29 #include <ofw_tree.h> 30 30 #include <ofw.h> 31 #include <ofwarch.h> 31 32 #include <types.h> 32 33 #include <string.h> 33 34 #include <balloc.h> 34 35 #include <asm.h> 35 36 #define MAX_PATH_LEN 256 36 #include <memstr.h> 37 37 38 38 static ofw_tree_node_t *ofw_tree_node_alloc(void) … … 49 49 static void *ofw_tree_space_alloc(size_t size) 50 50 { 51 char *addr;52 53 51 /* 54 52 * What we do here is a nasty hack :-) … … 61 59 * behind the requested memory. 62 60 */ 63 addr = balloc(size + 1, size);61 char *addr = balloc(size + 1, size); 64 62 if (addr) 65 63 addr[size] = '\0'; 64 66 65 return addr; 67 66 } … … 75 74 * order to prevent stack from overflowing. 76 75 * 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 * 82 82 */ 83 83 static void ofw_tree_node_process(ofw_tree_node_t *current_node, 84 84 ofw_tree_node_t *parent_node, phandle current) 85 85 { 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 94 86 while (current_node) { 95 87 /* 96 88 * Initialize node. 97 89 */ 98 current_node->parent = parent_node;90 current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node); 99 91 current_node->peer = NULL; 100 92 current_node->child = NULL; … … 103 95 current_node->property = NULL; 104 96 current_node->device = NULL; 105 97 106 98 /* 107 99 * Get the disambigued name. 108 100 */ 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); 110 103 if (len == -1) 111 104 return; 112 105 113 106 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++; 118 114 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 128 125 /* 129 126 * Recursively process the potential child node. 130 127 */ 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(); 136 131 if (child_node) { 137 132 ofw_tree_node_process(child_node, current_node, 138 133 child); 139 current_node->child = child_node; 134 current_node->child = 135 (ofw_tree_node_t *) balloc_rebase(child_node); 140 136 } 141 137 } 142 138 143 139 /* 144 140 * Count properties. 145 141 */ 142 static char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 143 static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN]; 146 144 name[0] = '\0'; 147 145 while (ofw_next_property(current, name, name2) == 1) { … … 149 147 memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); 150 148 } 151 149 152 150 if (!current_node->properties) 153 151 return; 154 152 155 153 /* 156 154 * Copy properties. 157 155 */ 158 current_node->property =156 ofw_tree_property_t *property = 159 157 ofw_tree_properties_alloc(current_node->properties); 160 if (! current_node->property)158 if (!property) 161 159 return; 162 160 163 161 name[0] = '\0'; 164 162 for (i = 0; ofw_next_property(current, name, name2) == 1; i++) { 165 size_t size;166 167 163 if (i == current_node->properties) 168 164 break; 169 165 170 166 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 178 173 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) { 183 176 /* 184 177 * Copy property value to memory node. 185 178 */ 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); 188 181 } 189 } else { 190 current_node->property[i].value = NULL; 191 } 192 } 193 182 } else 183 property[i].value = NULL; 184 } 185 194 186 /* Just in case we ran out of memory. */ 195 187 current_node->properties = i; 196 188 current_node->property = (ofw_tree_property_t *) balloc_rebase(property); 189 190 197 191 /* 198 192 * Iteratively process the next peer node. … … 202 196 * risk of overflowing the stack is too real. 203 197 */ 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); 211 203 current_node = peer_node; 212 204 current = peer; … … 217 209 } 218 210 } 211 219 212 /* 220 213 * No more peers on this level. … … 226 219 /** Construct memory representation of OpenFirmware device tree. 227 220 * 228 * @return NULL on failure or pointer to the root node. 221 * @return NULL on failure or kernel pointer to the root node. 222 * 229 223 */ 230 224 ofw_tree_node_t *ofw_tree_build(void) 231 225 { 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(); 237 227 if (root) 238 228 ofw_tree_node_process(root, NULL, ofw_root); 239 229 240 230 /* 241 231 * The firmware client interface does not automatically include the … … 243 233 * solution is to explicitly stick "ssm" to the OFW tree. 244 234 */ 245 ssm_node = ofw_find_device("/ssm@0,0");235 phandle ssm_node = ofw_find_device("/ssm@0,0"); 246 236 if (ssm_node != -1) { 247 ssm = ofw_tree_node_alloc();237 ofw_tree_node_t *ssm = ofw_tree_node_alloc(); 248 238 if (ssm) { 249 239 ofw_tree_node_process(ssm, root, 250 240 ofw_find_device("/ssm@0,0")); 251 241 ssm->peer = root->child; 252 root->child = ssm;242 root->child = (ofw_tree_node_t *) balloc_rebase(ssm); 253 243 } 254 244 } 255 245 256 return root;257 } 246 return (ofw_tree_node_t *) balloc_rebase(root); 247 }
Note:
See TracChangeset
for help on using the changeset viewer.