Changeset b50b5af2 in mainline for boot/genarch/ofw_tree.c
- Timestamp:
- 2009-08-22T10:48:00Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 04803bf
- Parents:
- 1ea99cc (diff), a71c158 (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
r1ea99cc rb50b5af2 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 38 #define MAX_PATH_LEN 256 37 39 38 40 static ofw_tree_node_t *ofw_tree_node_alloc(void) … … 49 51 static void *ofw_tree_space_alloc(size_t size) 50 52 { 51 char *addr;52 53 53 /* 54 54 * What we do here is a nasty hack :-) … … 61 61 * behind the requested memory. 62 62 */ 63 addr = balloc(size + 1, size);63 char *addr = balloc(size + 1, size); 64 64 if (addr) 65 65 addr[size] = '\0'; 66 66 67 return addr; 67 68 } … … 75 76 * order to prevent stack from overflowing. 76 77 * 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. 78 * @param current_node Pointer to uninitialized ofw_tree_node structure that 79 * will become the memory represenation of 'current'. 80 * @param parent_node Parent ofw_tree_node structure or NULL in case of root 81 * node. 82 * @param current OpenFirmware phandle to the current device tree node. 83 * 82 84 */ 83 85 static void ofw_tree_node_process(ofw_tree_node_t *current_node, 84 86 ofw_tree_node_t *parent_node, phandle current) 85 87 { 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 88 while (current_node) { 95 89 /* 96 90 * Initialize node. 97 91 */ 98 current_node->parent = parent_node;92 current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node); 99 93 current_node->peer = NULL; 100 94 current_node->child = NULL; … … 103 97 current_node->property = NULL; 104 98 current_node->device = NULL; 105 99 106 100 /* 107 101 * Get the disambigued name. 108 102 */ 109 len = ofw_package_to_path(current, path, MAX_PATH_LEN); 103 static char path[MAX_PATH_LEN + 1]; 104 size_t len = ofw_package_to_path(current, path, MAX_PATH_LEN); 110 105 if (len == -1) 111 106 return; 112 107 113 108 path[len] = '\0'; 114 for (i = len - 1; i >= 0 && path[i] != '/'; i--) 115 ; 116 i++; /* do not include '/' */ 117 109 110 /* Find last slash */ 111 int i; 112 for (i = len - 1; (i >= 0) && (path[i] != '/'); i--); 113 114 /* Do not include the slash */ 115 i++; 118 116 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 117 118 /* Add space for trailing '\0' */ 119 char *da_name = ofw_tree_space_alloc(len + 1); 120 if (!da_name) 121 return; 122 123 memcpy(da_name, &path[i], len); 124 da_name[len] = '\0'; 125 current_node->da_name = (char *) balloc_rebase(da_name); 126 128 127 /* 129 128 * Recursively process the potential child node. 130 129 */ 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(); 130 phandle child = ofw_get_child_node(current); 131 if ((child != 0) && (child != -1)) { 132 ofw_tree_node_t *child_node = ofw_tree_node_alloc(); 136 133 if (child_node) { 137 134 ofw_tree_node_process(child_node, current_node, 138 135 child); 139 current_node->child = child_node; 136 current_node->child = 137 (ofw_tree_node_t *) balloc_rebase(child_node); 140 138 } 141 139 } 142 140 143 141 /* 144 142 * Count properties. 145 143 */ 144 static char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 145 static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN]; 146 146 name[0] = '\0'; 147 147 while (ofw_next_property(current, name, name2) == 1) { … … 149 149 memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); 150 150 } 151 151 152 152 if (!current_node->properties) 153 153 return; 154 154 155 155 /* 156 156 * Copy properties. 157 157 */ 158 current_node->property =158 ofw_tree_property_t *property = 159 159 ofw_tree_properties_alloc(current_node->properties); 160 if (! current_node->property)160 if (!property) 161 161 return; 162 162 163 163 name[0] = '\0'; 164 164 for (i = 0; ofw_next_property(current, name, name2) == 1; i++) { 165 size_t size;166 167 165 if (i == current_node->properties) 168 166 break; 169 167 170 168 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; 169 memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN); 170 property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; 171 172 size_t size = ofw_get_proplen(current, name); 173 property[i].size = size; 174 178 175 if (size) { 179 void *buf; 180 181 buf = ofw_tree_space_alloc(size); 182 if (current_node->property[i].value = buf) { 176 void *buf = ofw_tree_space_alloc(size); 177 if (buf) { 183 178 /* 184 179 * Copy property value to memory node. 185 180 */ 186 (void) ofw_get_property(current, name, 187 buf, size);181 (void) ofw_get_property(current, name, buf, size); 182 property[i].value = balloc_rebase(buf); 188 183 } 189 } else { 190 current_node->property[i].value = NULL; 191 } 192 } 193 184 } else 185 property[i].value = NULL; 186 } 187 194 188 /* Just in case we ran out of memory. */ 195 189 current_node->properties = i; 196 190 current_node->property = (ofw_tree_property_t *) balloc_rebase(property); 191 192 197 193 /* 198 194 * Iteratively process the next peer node. … … 202 198 * risk of overflowing the stack is too real. 203 199 */ 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; 200 phandle peer = ofw_get_peer_node(current); 201 if ((peer != 0) && (peer != -1)) { 202 ofw_tree_node_t *peer_node = ofw_tree_node_alloc(); 203 if (peer_node) { 204 current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node); 211 205 current_node = peer_node; 212 206 current = peer; … … 217 211 } 218 212 } 213 219 214 /* 220 215 * No more peers on this level. … … 226 221 /** Construct memory representation of OpenFirmware device tree. 227 222 * 228 * @return NULL on failure or pointer to the root node. 223 * @return NULL on failure or kernel pointer to the root node. 224 * 229 225 */ 230 226 ofw_tree_node_t *ofw_tree_build(void) 231 227 { 232 ofw_tree_node_t *root; 233 phandle ssm_node; 234 ofw_tree_node_t *ssm; 235 236 root = ofw_tree_node_alloc(); 228 ofw_tree_node_t *root = ofw_tree_node_alloc(); 237 229 if (root) 238 230 ofw_tree_node_process(root, NULL, ofw_root); 239 231 240 232 /* 241 233 * The firmware client interface does not automatically include the … … 243 235 * solution is to explicitly stick "ssm" to the OFW tree. 244 236 */ 245 ssm_node = ofw_find_device("/ssm@0,0");237 phandle ssm_node = ofw_find_device("/ssm@0,0"); 246 238 if (ssm_node != -1) { 247 ssm = ofw_tree_node_alloc();239 ofw_tree_node_t *ssm = ofw_tree_node_alloc(); 248 240 if (ssm) { 249 241 ofw_tree_node_process(ssm, root, 250 242 ofw_find_device("/ssm@0,0")); 251 243 ssm->peer = root->child; 252 root->child = ssm;244 root->child = (ofw_tree_node_t *) balloc_rebase(ssm); 253 245 } 254 246 } 255 247 256 return root;257 } 248 return (ofw_tree_node_t *) balloc_rebase(root); 249 }
Note:
See TracChangeset
for help on using the changeset viewer.