1 /* 2 * Procedures for creating, accessing and interpreting the device tree. 3 * 4 * Paul Mackerras August 1996. 5 * Copyright (C) 1996-2005 Paul Mackerras. 6 * 7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 8 * {engebret|bergner}@us.ibm.com 9 * 10 * Adapted for sparc32 by David S. Miller davem@davemloft.net 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 15 * 2 of the License, or (at your option) any later version. 16 */ 17 18 #include <linux/kernel.h> 19 #include <linux/types.h> 20 #include <linux/string.h> 21 #include <linux/mm.h> 22 #include <linux/bootmem.h> 23 #include <linux/module.h> 24 25 #include <asm/prom.h> 26 #include <asm/oplib.h> 27 28 #include "prom.h" 29 30 static unsigned int prom_early_allocated; 31 32 static void * __init prom_early_alloc(unsigned long size) 33 { 34 void *ret; 35 36 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); 37 if (ret != NULL) 38 memset(ret, 0, size); 39 40 prom_early_allocated += size; 41 42 return ret; 43 } 44 45 static int is_root_node(const struct device_node *dp) 46 { 47 if (!dp) 48 return 0; 49 50 return (dp->parent == NULL); 51 } 52 53 /* The following routines deal with the black magic of fully naming a 54 * node. 55 * 56 * Certain well known named nodes are just the simple name string. 57 * 58 * Actual devices have an address specifier appended to the base name 59 * string, like this "foo@addr". The "addr" can be in any number of 60 * formats, and the platform plus the type of the node determine the 61 * format and how it is constructed. 62 * 63 * For children of the ROOT node, the naming convention is fixed and 64 * determined by whether this is a sun4u or sun4v system. 65 * 66 * For children of other nodes, it is bus type specific. So 67 * we walk up the tree until we discover a "device_type" property 68 * we recognize and we go from there. 69 */ 70 static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf) 71 { 72 struct linux_prom_registers *regs; 73 struct property *rprop; 74 75 rprop = of_find_property(dp, "reg", NULL); 76 if (!rprop) 77 return; 78 79 regs = rprop->value; 80 sprintf(tmp_buf, "%s@%x,%x", 81 dp->name, 82 regs->which_io, regs->phys_addr); 83 } 84 85 /* "name@slot,offset" */ 86 static void __init sbus_path_component(struct device_node *dp, char *tmp_buf) 87 { 88 struct linux_prom_registers *regs; 89 struct property *prop; 90 91 prop = of_find_property(dp, "reg", NULL); 92 if (!prop) 93 return; 94 95 regs = prop->value; 96 sprintf(tmp_buf, "%s@%x,%x", 97 dp->name, 98 regs->which_io, 99 regs->phys_addr); 100 } 101 102 /* "name@devnum[,func]" */ 103 static void __init pci_path_component(struct device_node *dp, char *tmp_buf) 104 { 105 struct linux_prom_pci_registers *regs; 106 struct property *prop; 107 unsigned int devfn; 108 109 prop = of_find_property(dp, "reg", NULL); 110 if (!prop) 111 return; 112 113 regs = prop->value; 114 devfn = (regs->phys_hi >> 8) & 0xff; 115 if (devfn & 0x07) { 116 sprintf(tmp_buf, "%s@%x,%x", 117 dp->name, 118 devfn >> 3, 119 devfn & 0x07); 120 } else { 121 sprintf(tmp_buf, "%s@%x", 122 dp->name, 123 devfn >> 3); 124 } 125 } 126 127 /* "name@addrhi,addrlo" */ 128 static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) 129 { 130 struct linux_prom_registers *regs; 131 struct property *prop; 132 133 prop = of_find_property(dp, "reg", NULL); 134 if (!prop) 135 return; 136 137 regs = prop->value; 138 139 sprintf(tmp_buf, "%s@%x,%x", 140 dp->name, 141 regs->which_io, regs->phys_addr); 142 } 143 144 static void __init __build_path_component(struct device_node *dp, char *tmp_buf) 145 { 146 struct device_node *parent = dp->parent; 147 148 if (parent != NULL) { 149 if (!strcmp(parent->type, "pci") || 150 !strcmp(parent->type, "pciex")) 151 return pci_path_component(dp, tmp_buf); 152 if (!strcmp(parent->type, "sbus")) 153 return sbus_path_component(dp, tmp_buf); 154 if (!strcmp(parent->type, "ebus")) 155 return ebus_path_component(dp, tmp_buf); 156 157 /* "isa" is handled with platform naming */ 158 } 159 160 /* Use platform naming convention. */ 161 return sparc32_path_component(dp, tmp_buf); 162 } 163 164 static char * __init build_path_component(struct device_node *dp) 165 { 166 char tmp_buf[64], *n; 167 168 tmp_buf[0] = '\0'; 169 __build_path_component(dp, tmp_buf); 170 if (tmp_buf[0] == '\0') 171 strcpy(tmp_buf, dp->name); 172 173 n = prom_early_alloc(strlen(tmp_buf) + 1); 174 strcpy(n, tmp_buf); 175 176 return n; 177 } 178 179 static char * __init build_full_name(struct device_node *dp) 180 { 181 int len, ourlen, plen; 182 char *n; 183 184 plen = strlen(dp->parent->full_name); 185 ourlen = strlen(dp->path_component_name); 186 len = ourlen + plen + 2; 187 188 n = prom_early_alloc(len); 189 strcpy(n, dp->parent->full_name); 190 if (!is_root_node(dp->parent)) { 191 strcpy(n + plen, "/"); 192 plen++; 193 } 194 strcpy(n + plen, dp->path_component_name); 195 196 return n; 197 } 198 199 static unsigned int unique_id; 200 201 static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) 202 { 203 static struct property *tmp = NULL; 204 struct property *p; 205 int len; 206 const char *name; 207 208 if (tmp) { 209 p = tmp; 210 memset(p, 0, sizeof(*p) + 32); 211 tmp = NULL; 212 } else { 213 p = prom_early_alloc(sizeof(struct property) + 32); 214 p->unique_id = unique_id++; 215 } 216 217 p->name = (char *) (p + 1); 218 if (special_name) { 219 strcpy(p->name, special_name); 220 p->length = special_len; 221 p->value = prom_early_alloc(special_len); 222 memcpy(p->value, special_val, special_len); 223 } else { 224 if (prev == NULL) { 225 name = prom_firstprop(node, NULL); 226 } else { 227 name = prom_nextprop(node, prev, NULL); 228 } 229 if (strlen(name) == 0) { 230 tmp = p; 231 return NULL; 232 } 233 strcpy(p->name, name); 234 p->length = prom_getproplen(node, p->name); 235 if (p->length <= 0) { 236 p->length = 0; 237 } else { 238 p->value = prom_early_alloc(p->length + 1); 239 len = prom_getproperty(node, p->name, p->value, 240 p->length); 241 if (len <= 0) 242 p->length = 0; 243 ((unsigned char *)p->value)[p->length] = '\0'; 244 } 245 } 246 return p; 247 } 248 249 static struct property * __init build_prop_list(phandle node) 250 { 251 struct property *head, *tail; 252 253 head = tail = build_one_prop(node, NULL, 254 ".node", &node, sizeof(node)); 255 256 tail->next = build_one_prop(node, NULL, NULL, NULL, 0); 257 tail = tail->next; 258 while(tail) { 259 tail->next = build_one_prop(node, tail->name, 260 NULL, NULL, 0); 261 tail = tail->next; 262 } 263 264 return head; 265 } 266 267 static char * __init get_one_property(phandle node, char *name) 268 { 269 char *buf = "<NULL>"; 270 int len; 271 272 len = prom_getproplen(node, name); 273 if (len > 0) { 274 buf = prom_early_alloc(len); 275 len = prom_getproperty(node, name, buf, len); 276 } 277 278 return buf; 279 } 280 281 static struct device_node * __init create_node(phandle node) 282 { 283 struct device_node *dp; 284 285 if (!node) 286 return NULL; 287 288 dp = prom_early_alloc(sizeof(*dp)); 289 dp->unique_id = unique_id++; 290 291 kref_init(&dp->kref); 292 293 dp->name = get_one_property(node, "name"); 294 dp->type = get_one_property(node, "device_type"); 295 dp->node = node; 296 297 /* Build interrupts later... */ 298 299 dp->properties = build_prop_list(node); 300 301 return dp; 302 } 303 304 static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) 305 { 306 struct device_node *dp; 307 308 dp = create_node(node); 309 if (dp) { 310 *(*nextp) = dp; 311 *nextp = &dp->allnext; 312 313 dp->parent = parent; 314 dp->path_component_name = build_path_component(dp); 315 dp->full_name = build_full_name(dp); 316 317 dp->child = build_tree(dp, prom_getchild(node), nextp); 318 319 dp->sibling = build_tree(parent, prom_getsibling(node), nextp); 320 } 321 322 return dp; 323 } 324 325 struct device_node *of_console_device; 326 EXPORT_SYMBOL(of_console_device); 327 328 char *of_console_path; 329 EXPORT_SYMBOL(of_console_path); 330 331 char *of_console_options; 332 EXPORT_SYMBOL(of_console_options); 333 334 extern void restore_current(void); 335 336 static void __init of_console_init(void) 337 { 338 char *msg = "OF stdout device is: %s\n"; 339 struct device_node *dp; 340 unsigned long flags; 341 const char *type; 342 phandle node; 343 int skip, tmp, fd; 344 345 of_console_path = prom_early_alloc(256); 346 347 switch (prom_vers) { 348 case PROM_V0: 349 skip = 0; 350 switch (*romvec->pv_stdout) { 351 case PROMDEV_SCREEN: 352 type = "display"; 353 break; 354 355 case PROMDEV_TTYB: 356 skip = 1; 357 /* FALLTHRU */ 358 359 case PROMDEV_TTYA: 360 type = "serial"; 361 break; 362 363 default: 364 prom_printf("Invalid PROM_V0 stdout value %u\n", 365 *romvec->pv_stdout); 366 prom_halt(); 367 } 368 369 tmp = skip; 370 for_each_node_by_type(dp, type) { 371 if (!tmp--) 372 break; 373 } 374 if (!dp) { 375 prom_printf("Cannot find PROM_V0 console node.\n"); 376 prom_halt(); 377 } 378 of_console_device = dp; 379 380 strcpy(of_console_path, dp->full_name); 381 if (!strcmp(type, "serial")) { 382 strcat(of_console_path, 383 (skip ? ":b" : ":a")); 384 } 385 break; 386 387 default: 388 case PROM_V2: 389 case PROM_V3: 390 fd = *romvec->pv_v2bootargs.fd_stdout; 391 392 spin_lock_irqsave(&prom_lock, flags); 393 node = (*romvec->pv_v2devops.v2_inst2pkg)(fd); 394 restore_current(); 395 spin_unlock_irqrestore(&prom_lock, flags); 396 397 if (!node) { 398 prom_printf("Cannot resolve stdout node from " 399 "instance %08x.\n", fd); 400 prom_halt(); 401 } 402 dp = of_find_node_by_phandle(node); 403 type = of_get_property(dp, "device_type", NULL); 404 405 if (!type) { 406 prom_printf("Console stdout lacks " 407 "device_type property.\n"); 408 prom_halt(); 409 } 410 411 if (strcmp(type, "display") && strcmp(type, "serial")) { 412 prom_printf("Console device_type is neither display " 413 "nor serial.\n"); 414 prom_halt(); 415 } 416 417 of_console_device = dp; 418 419 if (prom_vers == PROM_V2) { 420 strcpy(of_console_path, dp->full_name); 421 switch (*romvec->pv_stdout) { 422 case PROMDEV_TTYA: 423 strcat(of_console_path, ":a"); 424 break; 425 case PROMDEV_TTYB: 426 strcat(of_console_path, ":b"); 427 break; 428 } 429 } else { 430 const char *path; 431 432 dp = of_find_node_by_path("/"); 433 path = of_get_property(dp, "stdout-path", NULL); 434 if (!path) { 435 prom_printf("No stdout-path in root node.\n"); 436 prom_halt(); 437 } 438 strcpy(of_console_path, path); 439 } 440 break; 441 } 442 443 of_console_options = strrchr(of_console_path, ':'); 444 if (of_console_options) { 445 of_console_options++; 446 if (*of_console_options == '\0') 447 of_console_options = NULL; 448 } 449 450 prom_printf(msg, of_console_path); 451 printk(msg, of_console_path); 452 } 453 454 void __init prom_build_devicetree(void) 455 { 456 struct device_node **nextp; 457 458 allnodes = create_node(prom_root_node); 459 allnodes->path_component_name = ""; 460 allnodes->full_name = "/"; 461 462 nextp = &allnodes->allnext; 463 allnodes->child = build_tree(allnodes, 464 prom_getchild(allnodes->node), 465 &nextp); 466 of_console_init(); 467 468 printk("PROM: Built device tree with %u bytes of memory.\n", 469 prom_early_allocated); 470 } 471