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 void * __init prom_early_alloc(unsigned long size) 31 { 32 void *ret; 33 34 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); 35 if (ret != NULL) 36 memset(ret, 0, size); 37 38 prom_early_allocated += size; 39 40 return ret; 41 } 42 43 /* The following routines deal with the black magic of fully naming a 44 * node. 45 * 46 * Certain well known named nodes are just the simple name string. 47 * 48 * Actual devices have an address specifier appended to the base name 49 * string, like this "foo@addr". The "addr" can be in any number of 50 * formats, and the platform plus the type of the node determine the 51 * format and how it is constructed. 52 * 53 * For children of the ROOT node, the naming convention is fixed and 54 * determined by whether this is a sun4u or sun4v system. 55 * 56 * For children of other nodes, it is bus type specific. So 57 * we walk up the tree until we discover a "device_type" property 58 * we recognize and we go from there. 59 */ 60 static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf) 61 { 62 struct linux_prom_registers *regs; 63 struct property *rprop; 64 65 rprop = of_find_property(dp, "reg", NULL); 66 if (!rprop) 67 return; 68 69 regs = rprop->value; 70 sprintf(tmp_buf, "%s@%x,%x", 71 dp->name, 72 regs->which_io, regs->phys_addr); 73 } 74 75 /* "name@slot,offset" */ 76 static void __init sbus_path_component(struct device_node *dp, char *tmp_buf) 77 { 78 struct linux_prom_registers *regs; 79 struct property *prop; 80 81 prop = of_find_property(dp, "reg", NULL); 82 if (!prop) 83 return; 84 85 regs = prop->value; 86 sprintf(tmp_buf, "%s@%x,%x", 87 dp->name, 88 regs->which_io, 89 regs->phys_addr); 90 } 91 92 /* "name@devnum[,func]" */ 93 static void __init pci_path_component(struct device_node *dp, char *tmp_buf) 94 { 95 struct linux_prom_pci_registers *regs; 96 struct property *prop; 97 unsigned int devfn; 98 99 prop = of_find_property(dp, "reg", NULL); 100 if (!prop) 101 return; 102 103 regs = prop->value; 104 devfn = (regs->phys_hi >> 8) & 0xff; 105 if (devfn & 0x07) { 106 sprintf(tmp_buf, "%s@%x,%x", 107 dp->name, 108 devfn >> 3, 109 devfn & 0x07); 110 } else { 111 sprintf(tmp_buf, "%s@%x", 112 dp->name, 113 devfn >> 3); 114 } 115 } 116 117 /* "name@addrhi,addrlo" */ 118 static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) 119 { 120 struct linux_prom_registers *regs; 121 struct property *prop; 122 123 prop = of_find_property(dp, "reg", NULL); 124 if (!prop) 125 return; 126 127 regs = prop->value; 128 129 sprintf(tmp_buf, "%s@%x,%x", 130 dp->name, 131 regs->which_io, regs->phys_addr); 132 } 133 134 static void __init __build_path_component(struct device_node *dp, char *tmp_buf) 135 { 136 struct device_node *parent = dp->parent; 137 138 if (parent != NULL) { 139 if (!strcmp(parent->type, "pci") || 140 !strcmp(parent->type, "pciex")) 141 return pci_path_component(dp, tmp_buf); 142 if (!strcmp(parent->type, "sbus")) 143 return sbus_path_component(dp, tmp_buf); 144 if (!strcmp(parent->type, "ebus")) 145 return ebus_path_component(dp, tmp_buf); 146 147 /* "isa" is handled with platform naming */ 148 } 149 150 /* Use platform naming convention. */ 151 return sparc32_path_component(dp, tmp_buf); 152 } 153 154 char * __init build_path_component(struct device_node *dp) 155 { 156 char tmp_buf[64], *n; 157 158 tmp_buf[0] = '\0'; 159 __build_path_component(dp, tmp_buf); 160 if (tmp_buf[0] == '\0') 161 strcpy(tmp_buf, dp->name); 162 163 n = prom_early_alloc(strlen(tmp_buf) + 1); 164 strcpy(n, tmp_buf); 165 166 return n; 167 } 168 169 extern void restore_current(void); 170 171 void __init of_console_init(void) 172 { 173 char *msg = "OF stdout device is: %s\n"; 174 struct device_node *dp; 175 unsigned long flags; 176 const char *type; 177 phandle node; 178 int skip, tmp, fd; 179 180 of_console_path = prom_early_alloc(256); 181 182 switch (prom_vers) { 183 case PROM_V0: 184 skip = 0; 185 switch (*romvec->pv_stdout) { 186 case PROMDEV_SCREEN: 187 type = "display"; 188 break; 189 190 case PROMDEV_TTYB: 191 skip = 1; 192 /* FALLTHRU */ 193 194 case PROMDEV_TTYA: 195 type = "serial"; 196 break; 197 198 default: 199 prom_printf("Invalid PROM_V0 stdout value %u\n", 200 *romvec->pv_stdout); 201 prom_halt(); 202 } 203 204 tmp = skip; 205 for_each_node_by_type(dp, type) { 206 if (!tmp--) 207 break; 208 } 209 if (!dp) { 210 prom_printf("Cannot find PROM_V0 console node.\n"); 211 prom_halt(); 212 } 213 of_console_device = dp; 214 215 strcpy(of_console_path, dp->full_name); 216 if (!strcmp(type, "serial")) { 217 strcat(of_console_path, 218 (skip ? ":b" : ":a")); 219 } 220 break; 221 222 default: 223 case PROM_V2: 224 case PROM_V3: 225 fd = *romvec->pv_v2bootargs.fd_stdout; 226 227 spin_lock_irqsave(&prom_lock, flags); 228 node = (*romvec->pv_v2devops.v2_inst2pkg)(fd); 229 restore_current(); 230 spin_unlock_irqrestore(&prom_lock, flags); 231 232 if (!node) { 233 prom_printf("Cannot resolve stdout node from " 234 "instance %08x.\n", fd); 235 prom_halt(); 236 } 237 dp = of_find_node_by_phandle(node); 238 type = of_get_property(dp, "device_type", NULL); 239 240 if (!type) { 241 prom_printf("Console stdout lacks " 242 "device_type property.\n"); 243 prom_halt(); 244 } 245 246 if (strcmp(type, "display") && strcmp(type, "serial")) { 247 prom_printf("Console device_type is neither display " 248 "nor serial.\n"); 249 prom_halt(); 250 } 251 252 of_console_device = dp; 253 254 if (prom_vers == PROM_V2) { 255 strcpy(of_console_path, dp->full_name); 256 switch (*romvec->pv_stdout) { 257 case PROMDEV_TTYA: 258 strcat(of_console_path, ":a"); 259 break; 260 case PROMDEV_TTYB: 261 strcat(of_console_path, ":b"); 262 break; 263 } 264 } else { 265 const char *path; 266 267 dp = of_find_node_by_path("/"); 268 path = of_get_property(dp, "stdout-path", NULL); 269 if (!path) { 270 prom_printf("No stdout-path in root node.\n"); 271 prom_halt(); 272 } 273 strcpy(of_console_path, path); 274 } 275 break; 276 } 277 278 of_console_options = strrchr(of_console_path, ':'); 279 if (of_console_options) { 280 of_console_options++; 281 if (*of_console_options == '\0') 282 of_console_options = NULL; 283 } 284 285 prom_printf(msg, of_console_path); 286 printk(msg, of_console_path); 287 } 288 289 void __init of_fill_in_cpu_data(void) 290 { 291 } 292 293 void __init irq_trans_init(struct device_node *dp) 294 { 295 } 296