Changeset e731b0d in mainline for kernel/genarch
- Timestamp:
- 2009-08-20T16:58:55Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b9c7425
- Parents:
- a11099f
- Location:
- kernel/genarch
- Files:
-
- 8 edited
-
Makefile.inc (modified) (1 diff)
-
include/ofw/ofw_tree.h (modified) (2 diffs)
-
src/ofw/ebus.c (modified) (1 diff)
-
src/ofw/fhc.c (modified) (1 diff)
-
src/ofw/ofw_tree.c (modified) (13 diffs)
-
src/ofw/pci.c (modified) (1 diff)
-
src/ofw/sbus.c (modified) (1 diff)
-
src/ofw/upa.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/Makefile.inc
ra11099f re731b0d 130 130 ifeq ($(CONFIG_OFW_TREE),y) 131 131 GENARCH_SOURCES += \ 132 genarch/src/ofw/ofw_tree.c \ 132 genarch/src/ofw/ofw_tree.c 133 endif 134 135 ifeq ($(CONFIG_OFW_PCI),y) 136 GENARCH_SOURCES += \ 133 137 genarch/src/ofw/ebus.c \ 134 138 genarch/src/ofw/fhc.c \ 135 139 genarch/src/ofw/pci.c \ 136 140 genarch/src/ofw/sbus.c \ 137 genarch/src/ofw/upa.c 141 genarch/src/ofw/upa.c 138 142 endif 139 143 -
kernel/genarch/include/ofw/ofw_tree.h
ra11099f re731b0d 31 31 32 32 #include <arch/types.h> 33 #include <ddi/irq.h>34 33 #include <typedefs.h> 35 34 36 #define OFW_TREE_PROPERTY_MAX_NAMELEN 3235 #define OFW_TREE_PROPERTY_MAX_NAMELEN 32 37 36 38 typedef struct ofw_tree_node ofw_tree_node_t; 39 typedef struct ofw_tree_property ofw_tree_property_t; 37 /** Memory representation of OpenFirmware device tree node property. */ 38 typedef struct { 39 char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 40 size_t size; 41 void *value; 42 } ofw_tree_property_t; 40 43 41 44 /** Memory representation of OpenFirmware device tree node. */ 42 struct ofw_tree_node {43 ofw_tree_node_t*parent;44 ofw_tree_node_t*peer;45 ofw_tree_node_t*child;46 47 uint32_t node_handle; /**< Old OpenFirmware node handle. */48 49 char *da_name; /**< Disambigued name. */50 51 unsigned properties;/**< Number of properties. */45 typedef struct ofw_tree_node { 46 struct ofw_tree_node *parent; 47 struct ofw_tree_node *peer; 48 struct ofw_tree_node *child; 49 50 uint32_t node_handle; /**< Old OpenFirmware node handle. */ 51 52 char *da_name; /**< Disambigued name. */ 53 54 unsigned int properties; /**< Number of properties. */ 52 55 ofw_tree_property_t *property; 53 56 … … 57 60 */ 58 61 void *device; 59 } ;62 } ofw_tree_node_t; 60 63 61 /** Memory representation of OpenFirmware device tree node property. */ 62 struct ofw_tree_property { 63 char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 64 size_t size; 65 void *value; 66 }; 67 68 /* 69 * Definition of 'reg' and 'ranges' properties for various buses. 70 */ 71 72 struct ofw_fhc_reg { 73 uint64_t addr; 74 uint32_t size; 75 } __attribute__ ((packed)); 76 typedef struct ofw_fhc_reg ofw_fhc_reg_t; 77 78 struct ofw_fhc_range { 79 uint64_t child_base; 80 uint64_t parent_base; 81 uint32_t size; 82 } __attribute__ ((packed)); 83 typedef struct ofw_fhc_range ofw_fhc_range_t; 84 85 struct ofw_central_reg { 86 uint64_t addr; 87 uint32_t size; 88 } __attribute__ ((packed)); 89 typedef struct ofw_central_reg ofw_central_reg_t; 90 91 struct ofw_central_range { 92 uint64_t child_base; 93 uint64_t parent_base; 94 uint32_t size; 95 } __attribute__ ((packed)); 96 typedef struct ofw_central_range ofw_central_range_t; 97 98 struct ofw_ebus_reg { 99 uint32_t space; 100 uint32_t addr; 101 uint32_t size; 102 } __attribute__ ((packed)); 103 typedef struct ofw_ebus_reg ofw_ebus_reg_t; 104 105 struct ofw_ebus_range { 106 uint32_t child_space; 107 uint32_t child_base; 108 uint32_t parent_space; 109 uint64_t parent_base; /* group phys.mid and phys.lo together */ 110 uint32_t size; 111 } __attribute__ ((packed)); 112 typedef struct ofw_ebus_range ofw_ebus_range_t; 113 114 struct ofw_ebus_intr_map { 115 uint32_t space; 116 uint32_t addr; 117 uint32_t intr; 118 uint32_t controller_handle; 119 uint32_t controller_ino; 120 } __attribute__ ((packed)); 121 typedef struct ofw_ebus_intr_map ofw_ebus_intr_map_t; 122 123 struct ofw_ebus_intr_mask { 124 uint32_t space_mask; 125 uint32_t addr_mask; 126 uint32_t intr_mask; 127 } __attribute__ ((packed)); 128 typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t; 129 130 struct ofw_pci_reg { 131 uint32_t space; /* needs to be masked to obtain pure space id */ 132 uint64_t addr; /* group phys.mid and phys.lo together */ 133 uint64_t size; 134 } __attribute__ ((packed)); 135 typedef struct ofw_pci_reg ofw_pci_reg_t; 136 137 struct ofw_pci_range { 138 uint32_t space; 139 uint64_t child_base; /* group phys.mid and phys.lo together */ 140 uint64_t parent_base; 141 uint64_t size; 142 } __attribute__ ((packed)); 143 typedef struct ofw_pci_range ofw_pci_range_t; 144 145 struct ofw_sbus_reg { 146 uint64_t addr; 147 uint32_t size; 148 } __attribute__ ((packed)); 149 typedef struct ofw_sbus_reg ofw_sbus_reg_t; 150 151 struct ofw_sbus_range { 152 uint64_t child_base; 153 uint64_t parent_base; 154 uint32_t size; 155 } __attribute__ ((packed)); 156 typedef struct ofw_sbus_range ofw_sbus_range_t; 157 158 struct ofw_upa_reg { 159 uint64_t addr; 160 uint64_t size; 161 } __attribute__ ((packed)); 162 typedef struct ofw_upa_reg ofw_upa_reg_t; 64 /* Walker for visiting OpenFirmware device tree nodes. */ 65 typedef bool (* ofw_tree_walker_t)(ofw_tree_node_t *, void *); 163 66 164 67 extern void ofw_tree_init(ofw_tree_node_t *); 165 68 extern void ofw_tree_print(void); 69 166 70 extern const char *ofw_tree_node_name(const ofw_tree_node_t *); 167 71 extern ofw_tree_node_t *ofw_tree_lookup(const char *); 168 72 extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *, 169 73 const char *); 74 extern void ofw_tree_walk_by_device_type(const char *, ofw_tree_walker_t, 75 void *); 76 170 77 extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *); 171 78 extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *, 172 79 const char *); 80 173 81 extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *, 174 82 const char *); 175 extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t * node,176 const char * name);83 extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *, 84 const char *); 177 85 extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *, 178 86 uint32_t); 179 87 180 extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,181 uintptr_t *);182 extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,183 uintptr_t *);184 extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,185 uintptr_t *);186 extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,187 uintptr_t *);188 extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,189 uintptr_t *);190 extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,191 uintptr_t *);192 193 extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,194 ofw_pci_reg_t *);195 196 extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,197 uint32_t, int *, cir_t *, void **);198 extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,199 uint32_t, int *, cir_t *, void **);200 extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,201 int, int *, cir_t *, void **);202 203 88 #endif -
kernel/genarch/src/ofw/ebus.c
ra11099f re731b0d 37 37 38 38 #include <genarch/ofw/ofw_tree.h> 39 #include <genarch/ofw/ebus.h> 40 #include <genarch/ofw/pci.h> 39 41 #include <arch/memstr.h> 40 #include <arch/trap/interrupt.h>41 42 #include <string.h> 42 43 #include <panic.h> -
kernel/genarch/src/ofw/fhc.c
ra11099f re731b0d 37 37 38 38 #include <genarch/ofw/ofw_tree.h> 39 #include <genarch/ofw/fhc.h> 39 40 #include <arch/drivers/fhc.h> 40 41 #include <arch/memstr.h> -
kernel/genarch/src/ofw/ofw_tree.c
ra11099f re731b0d 32 32 /** 33 33 * @file 34 * @brief OpenFirmware device tree navigation.34 * @brief OpenFirmware device tree navigation. 35 35 * 36 36 */ … … 40 40 #include <mm/slab.h> 41 41 #include <string.h> 42 #include <panic.h> 42 43 #include <print.h> 43 #include <panic.h> 44 45 #define PATH_MAX_LEN 80 46 #define NAME_BUF_LEN 50 44 45 #define PATH_MAX_LEN 256 46 #define NAME_BUF_LEN 50 47 47 48 48 static ofw_tree_node_t *ofw_root; … … 55 55 /** Get OpenFirmware node property. 56 56 * 57 * @param node Node in which to lookup the property. 58 * @param name Name of the property. 59 * 60 * @return Pointer to the property structure or NULL if no such 61 * property. 62 */ 63 ofw_tree_property_t * 64 ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) 57 * @param node Node in which to lookup the property. 58 * @param name Name of the property. 59 * 60 * @return Pointer to the property structure or NULL if no such 61 * property. 62 * 63 */ 64 ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, 65 const char *name) 65 66 { 66 67 unsigned int i; … … 70 71 return &node->property[i]; 71 72 } 72 73 73 74 return NULL; 74 75 } … … 76 77 /** Return value of the 'name' property. 77 78 * 78 * @param node Node of interest. 79 * 80 * @return Value of the 'name' property belonging to the node. 79 * @param node Node of interest. 80 * 81 * @return Value of the 'name' property belonging to the node 82 * or NULL if the property is invalid. 83 * 81 84 */ 82 85 const char *ofw_tree_node_name(const ofw_tree_node_t *node) 83 86 { 84 ofw_tree_property_t *prop; 85 86 prop = ofw_tree_getprop(node, "name"); 87 if (!prop) 88 panic("Node without name property."); 89 90 if (prop->size < 2) 91 panic("Invalid name property."); 87 ofw_tree_property_t *prop = ofw_tree_getprop(node, "name"); 88 if ((!prop) || (prop->size < 2)) 89 return NULL; 92 90 93 91 return prop->value; … … 96 94 /** Lookup child of given name. 97 95 * 98 * @param node Node whose child is being looked up. 99 * @param name Name of the child being looked up. 100 * 101 * @return NULL if there is no such child or pointer to the 102 * matching child node. 103 */ 104 ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name) 96 * @param node Node whose child is being looked up. 97 * @param name Name of the child being looked up. 98 * 99 * @return NULL if there is no such child or pointer to the 100 * matching child node. 101 * 102 */ 103 ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, 104 const char *name) 105 105 { 106 106 ofw_tree_node_t *cur; … … 125 125 return cur; 126 126 } 127 127 128 128 return NULL; 129 129 } … … 131 131 /** Lookup first child of given device type. 132 132 * 133 * @param node Node whose child is being looked up.134 * @param nameDevice type of the child being looked up.135 * 136 * @return NULL if there is no such child or pointer to the137 * matching child node.138 * /139 ofw_tree_node_t * 140 ofw_tree_ find_child_by_device_type(ofw_tree_node_t *node, const char *name)141 { 142 ofw_tree_node_t *cur; 143 ofw_tree_ property_t *prop;133 * @param node Node whose child is being looked up. 134 * @param dtype Device type of the child being looked up. 135 * 136 * @return NULL if there is no such child or pointer to the 137 * matching child node. 138 * 139 */ 140 ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, 141 const char *dtype) 142 { 143 ofw_tree_node_t *cur; 144 144 145 145 for (cur = node->child; cur; cur = cur->peer) { 146 prop = ofw_tree_getprop(cur, "device_type"); 147 if (!prop || !prop->value) 146 ofw_tree_property_t *prop = 147 ofw_tree_getprop(cur, "device_type"); 148 149 if ((!prop) || (!prop->value)) 148 150 continue; 149 if (str_cmp(prop->value, name) == 0) 150 return cur; 151 } 152 151 152 if (str_cmp(prop->value, dtype) == 0) 153 return cur; 154 } 155 153 156 return NULL; 154 157 } … … 159 162 * are looked up iteratively to avoid stack overflow. 160 163 * 161 * @param root Root of the searched subtree. 162 * @param handle OpenFirmware handle. 163 * 164 * @return NULL if there is no such node or pointer to the matching 165 * node. 166 */ 167 ofw_tree_node_t * 168 ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) 169 { 170 ofw_tree_node_t *cur; 171 172 for (cur = root; cur; cur = cur->peer) { 164 * @param root Root of the searched subtree. 165 * @param handle OpenFirmware handle. 166 * 167 * @return NULL if there is no such node or pointer to the matching 168 * node. 169 * 170 */ 171 ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, 172 uint32_t handle) 173 { 174 ofw_tree_node_t *cur; 175 176 for (cur = root; cur; cur = cur->peer) { 173 177 if (cur->node_handle == handle) 174 178 return cur; 175 179 176 180 if (cur->child) { 177 ofw_tree_node_t *node; 178 179 node = ofw_tree_find_node_by_handle(cur->child, handle); 181 ofw_tree_node_t *node 182 = ofw_tree_find_node_by_handle(cur->child, handle); 180 183 if (node) 181 184 return node; … … 183 186 } 184 187 185 return NULL; 188 return NULL; 186 189 } 187 190 188 191 /** Lookup first peer of given device type. 189 192 * 190 * @param node Node whose peer is being looked up.191 * @param nameDevice type of the child being looked up.192 * 193 * @return NULL if there is no such child or pointer to the194 * matching child node.195 * /196 ofw_tree_node_t * 197 ofw_tree_ find_peer_by_device_type(ofw_tree_node_t *node, const char *name)198 { 199 ofw_tree_node_t *cur; 200 ofw_tree_ property_t *prop;193 * @param node Node whose peer is being looked up. 194 * @param dtype Device type of the child being looked up. 195 * 196 * @return NULL if there is no such child or pointer to the 197 * matching child node. 198 * 199 */ 200 ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, 201 const char *dtype) 202 { 203 ofw_tree_node_t *cur; 201 204 202 205 for (cur = node->peer; cur; cur = cur->peer) { 203 prop = ofw_tree_getprop(cur, "device_type"); 204 if (!prop || !prop->value) 206 ofw_tree_property_t *prop = 207 ofw_tree_getprop(cur, "device_type"); 208 209 if ((!prop) || (!prop->value)) 205 210 continue; 211 212 if (str_cmp(prop->value, dtype) == 0) 213 return cur; 214 } 215 216 return NULL; 217 } 218 219 /** Lookup first peer of given name. 220 * 221 * @param node Node whose peer is being looked up. 222 * @param name Name of the child being looked up. 223 * 224 * @return NULL if there is no such peer or pointer to the matching 225 * peer node. 226 * 227 */ 228 ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node, 229 const char *name) 230 { 231 ofw_tree_node_t *cur; 232 233 for (cur = node->peer; cur; cur = cur->peer) { 234 ofw_tree_property_t *prop 235 = ofw_tree_getprop(cur, "name"); 236 237 if ((!prop) || (!prop->value)) 238 continue; 239 206 240 if (str_cmp(prop->value, name) == 0) 207 241 return cur; 208 242 } 209 210 return NULL; 211 } 212 213 214 /** Lookup first peer of given name. 215 * 216 * @param node Node whose peer is being looked up. 217 * @param name Name of the child being looked up. 218 * 219 * @return NULL if there is no such peer or pointer to the matching 220 * peer node. 221 */ 222 ofw_tree_node_t * 223 ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name) 224 { 225 ofw_tree_node_t *cur; 226 ofw_tree_property_t *prop; 227 228 for (cur = node->peer; cur; cur = cur->peer) { 229 prop = ofw_tree_getprop(cur, "name"); 230 if (!prop || !prop->value) 231 continue; 232 if (str_cmp(prop->value, name) == 0) 233 return cur; 234 } 235 243 236 244 return NULL; 237 245 } … … 239 247 /** Lookup OpenFirmware node by its path. 240 248 * 241 * @param path Path to the node. 242 * 243 * @return NULL if there is no such node or pointer to the leaf 244 * node. 249 * @param path Path to the node. 250 * 251 * @return NULL if there is no such node or pointer to the leaf 252 * node. 253 * 245 254 */ 246 255 ofw_tree_node_t *ofw_tree_lookup(const char *path) 247 256 { 248 char buf[NAME_BUF_LEN + 1]; 257 if (path[0] != '/') 258 return NULL; 259 249 260 ofw_tree_node_t *node = ofw_root; 250 261 size_t i; 251 262 size_t j; 252 263 253 if (path[0] != '/')254 return NULL;255 256 264 for (i = 1; (i < str_size(path)) && (node); i = j + 1) { 257 265 for (j = i; (j < str_size(path)) && (path[j] != '/'); j++); … … 261 269 continue; 262 270 271 char buf[NAME_BUF_LEN + 1]; 263 272 memcpy(buf, &path[i], j - i); 264 273 buf[j - i] = 0; … … 269 278 } 270 279 271 /** PrintOpenFirmware device subtree rooted in a node.280 /** Walk the OpenFirmware device subtree rooted in a node. 272 281 * 273 282 * Child nodes are processed recursively and peer nodes are processed 274 283 * iteratively in order to avoid stack overflow. 275 284 * 276 * @param node Root of the subtree. 277 * @param path Current path, NULL for the very root of the entire tree. 278 */ 279 static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path) 280 { 281 char *p; 282 const ofw_tree_node_t *cur; 283 284 p = (char *) malloc(PATH_MAX_LEN, 0); 285 285 * @param node Root of the subtree. 286 * @param dtype Device type to look for. 287 * @param walker Routine to be invoked on found device. 288 * @param arg User argument to the walker. 289 * 290 * @return True if the walk should continue. 291 * 292 */ 293 static bool ofw_tree_walk_by_device_type_internal(ofw_tree_node_t *node, 294 const char *dtype, ofw_tree_walker_t walker, void *arg) 295 { 296 ofw_tree_node_t *cur; 297 286 298 for (cur = node; cur; cur = cur->peer) { 287 if (cur->parent) { 288 snprintf(p, PATH_MAX_LEN, "%s/%s", path, cur->da_name); 289 printf("%s\n", p); 299 ofw_tree_property_t *prop = 300 ofw_tree_getprop(cur, "device_type"); 301 302 if ((prop) && (prop->value) && (str_cmp(prop->value, dtype) == 0)) { 303 bool ret = walker(cur, arg); 304 if (!ret) 305 return false; 306 } 307 308 if (cur->child) { 309 bool ret = 310 ofw_tree_walk_by_device_type_internal(cur->child, dtype, walker, arg); 311 if (!ret) 312 return false; 313 } 314 } 315 316 return true; 317 } 318 319 /** Walk the OpenFirmware device tree and find devices by type. 320 * 321 * Walk the whole OpenFirmware device tree and if any node has 322 * the property "device_type" equal to dtype, run a walker on it. 323 * If the walker returns false, the walk does not continue. 324 * 325 * @param dtype Device type to look for. 326 * @param walker Routine to be invoked on found device. 327 * @param arg User argument to the walker. 328 * 329 */ 330 void ofw_tree_walk_by_device_type(const char *dtype, ofw_tree_walker_t walker, 331 void *arg) 332 { 333 (void) ofw_tree_walk_by_device_type_internal(ofw_root, dtype, walker, arg); 334 } 335 336 /** Print OpenFirmware device subtree rooted in a node. 337 * 338 * Child nodes are processed recursively and peer nodes are processed 339 * iteratively in order to avoid stack overflow. 340 * 341 * @param node Root of the subtree. 342 * @param path Current path, NULL for the very root of the entire tree. 343 * 344 */ 345 static void ofw_tree_node_print(ofw_tree_node_t *node, const char *path) 346 { 347 char *cur_path = (char *) malloc(PATH_MAX_LEN, 0); 348 ofw_tree_node_t *cur; 349 350 for (cur = node; cur; cur = cur->peer) { 351 if ((cur->parent) && (path)) { 352 snprintf(cur_path, PATH_MAX_LEN, "%s/%s", path, cur->da_name); 353 printf("%s\n", cur_path); 290 354 } else { 291 snprintf( p, PATH_MAX_LEN, "%s", cur->da_name);355 snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name); 292 356 printf("/\n"); 293 357 } 294 358 295 359 if (cur->child) 296 ofw_tree_node_print(cur->child, p);297 } 298 299 free( p);360 ofw_tree_node_print(cur->child, cur_path); 361 } 362 363 free(cur_path); 300 364 } 301 365 -
kernel/genarch/src/ofw/pci.c
ra11099f re731b0d 37 37 38 38 #include <genarch/ofw/ofw_tree.h> 39 #include <genarch/ofw/pci.h> 39 40 #include <arch/drivers/pci.h> 40 41 #include <arch/trap/interrupt.h> -
kernel/genarch/src/ofw/sbus.c
ra11099f re731b0d 37 37 38 38 #include <genarch/ofw/ofw_tree.h> 39 #include <genarch/ofw/sbus.h> 39 40 #include <macros.h> 40 41 -
kernel/genarch/src/ofw/upa.c
ra11099f re731b0d 37 37 38 38 #include <genarch/ofw/ofw_tree.h> 39 #include <genarch/ofw/upa.h> 39 40 #include <arch/memstr.h> 40 41 #include <func.h>
Note:
See TracChangeset
for help on using the changeset viewer.
