Changes in boot/genarch/ofw_tree.c [e731b0d:8ea0308] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/ofw_tree.c
re731b0d r8ea0308 29 29 #include <ofw_tree.h> 30 30 #include <ofw.h> 31 #include <ofwarch.h>32 31 #include <types.h> 33 32 #include <string.h> 34 33 #include <balloc.h> 35 34 #include <asm.h> 36 #include <memstr.h> 37 38 #define MAX_PATH_LEN 256 35 36 #define MAX_PATH_LEN 256 39 37 40 38 static ofw_tree_node_t *ofw_tree_node_alloc(void) … … 51 49 static void *ofw_tree_space_alloc(size_t size) 52 50 { 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 char *addr = balloc(size + 1, size);63 addr = balloc(size + 1, size); 64 64 if (addr) 65 65 addr[size] = '\0'; 66 67 66 return addr; 68 67 } … … 76 75 * order to prevent stack from overflowing. 77 76 * 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 * 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. 84 82 */ 85 83 static void ofw_tree_node_process(ofw_tree_node_t *current_node, 86 84 ofw_tree_node_t *parent_node, phandle current) 87 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 88 94 while (current_node) { 89 95 /* 90 96 * Initialize node. 91 97 */ 92 current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node);98 current_node->parent = parent_node; 93 99 current_node->peer = NULL; 94 100 current_node->child = NULL; … … 97 103 current_node->property = NULL; 98 104 current_node->device = NULL; 99 105 100 106 /* 101 107 * Get the disambigued name. 102 108 */ 103 static char path[MAX_PATH_LEN + 1]; 104 size_t len = ofw_package_to_path(current, path, MAX_PATH_LEN); 109 len = ofw_package_to_path(current, path, MAX_PATH_LEN); 105 110 if (len == -1) 106 111 return; 107 112 108 113 path[len] = '\0'; 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++; 114 for (i = len - 1; i >= 0 && path[i] != '/'; i--) 115 ; 116 i++; /* do not include '/' */ 117 116 118 len -= i; 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 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 127 128 /* 128 129 * Recursively process the potential child node. 129 130 */ 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(); 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(); 133 136 if (child_node) { 134 137 ofw_tree_node_process(child_node, current_node, 135 138 child); 136 current_node->child = 137 (ofw_tree_node_t *) balloc_rebase(child_node); 139 current_node->child = child_node; 138 140 } 139 141 } 140 142 141 143 /* 142 144 * Count properties. 143 145 */ 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 ofw_tree_property_t *property =158 current_node->property = 159 159 ofw_tree_properties_alloc(current_node->properties); 160 if (! property)160 if (!current_node->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 165 167 if (i == current_node->properties) 166 168 break; 169 170 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; 178 if (size) { 179 void *buf; 167 180 168 memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); 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 175 if (size) { 176 void *buf = ofw_tree_space_alloc(size); 177 if (buf) { 181 buf = ofw_tree_space_alloc(size); 182 if (current_node->property[i].value = buf) { 178 183 /* 179 184 * Copy property value to memory node. 180 185 */ 181 (void) ofw_get_property(current, name, buf, size);182 property[i].value = balloc_rebase(buf);186 (void) ofw_get_property(current, name, 187 buf, size); 183 188 } 184 } else 185 property[i].value = NULL; 186 } 187 189 } else { 190 current_node->property[i].value = NULL; 191 } 192 } 193 188 194 /* Just in case we ran out of memory. */ 189 195 current_node->properties = i; 190 current_node->property = (ofw_tree_property_t *) balloc_rebase(property); 191 192 196 193 197 /* 194 198 * Iteratively process the next peer node. … … 198 202 * risk of overflowing the stack is too real. 199 203 */ 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); 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; 205 211 current_node = peer_node; 206 212 current = peer; … … 211 217 } 212 218 } 213 214 219 /* 215 220 * No more peers on this level. … … 221 226 /** Construct memory representation of OpenFirmware device tree. 222 227 * 223 * @return NULL on failure or kernel pointer to the root node. 224 * 228 * @return NULL on failure or pointer to the root node. 225 229 */ 226 230 ofw_tree_node_t *ofw_tree_build(void) 227 231 { 228 ofw_tree_node_t *root = ofw_tree_node_alloc(); 232 ofw_tree_node_t *root; 233 phandle ssm_node; 234 ofw_tree_node_t *ssm; 235 236 root = ofw_tree_node_alloc(); 229 237 if (root) 230 238 ofw_tree_node_process(root, NULL, ofw_root); 231 239 232 240 /* 233 241 * The firmware client interface does not automatically include the … … 235 243 * solution is to explicitly stick "ssm" to the OFW tree. 236 244 */ 237 phandlessm_node = ofw_find_device("/ssm@0,0");245 ssm_node = ofw_find_device("/ssm@0,0"); 238 246 if (ssm_node != -1) { 239 ofw_tree_node_t *ssm = ofw_tree_node_alloc();247 ssm = ofw_tree_node_alloc(); 240 248 if (ssm) { 241 249 ofw_tree_node_process(ssm, root, 242 250 ofw_find_device("/ssm@0,0")); 243 251 ssm->peer = root->child; 244 root->child = (ofw_tree_node_t *) balloc_rebase(ssm);252 root->child = ssm; 245 253 } 246 254 } 247 255 248 return (ofw_tree_node_t *) balloc_rebase(root);249 } 256 return root; 257 }
Note:
See TracChangeset
for help on using the changeset viewer.