0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/types.h>
0016 #include <linux/string.h>
0017 #include <linux/mm.h>
0018 #include <linux/memblock.h>
0019
0020 #include <asm/prom.h>
0021 #include <asm/oplib.h>
0022 #include <asm/leon.h>
0023 #include <asm/leon_amba.h>
0024
0025 #include "prom.h"
0026
0027 void * __init prom_early_alloc(unsigned long size)
0028 {
0029 void *ret;
0030
0031 ret = memblock_alloc(size, SMP_CACHE_BYTES);
0032 if (!ret)
0033 panic("%s: Failed to allocate %lu bytes\n", __func__, size);
0034
0035 prom_early_allocated += size;
0036
0037 return ret;
0038 }
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf)
0058 {
0059 const char *name = of_get_property(dp, "name", NULL);
0060 struct linux_prom_registers *regs;
0061 struct property *rprop;
0062
0063 rprop = of_find_property(dp, "reg", NULL);
0064 if (!rprop)
0065 return;
0066
0067 regs = rprop->value;
0068 sprintf(tmp_buf, "%s@%x,%x",
0069 name,
0070 regs->which_io, regs->phys_addr);
0071 }
0072
0073
0074 static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
0075 {
0076 const char *name = of_get_property(dp, "name", NULL);
0077 struct linux_prom_registers *regs;
0078 struct property *prop;
0079
0080 prop = of_find_property(dp, "reg", NULL);
0081 if (!prop)
0082 return;
0083
0084 regs = prop->value;
0085 sprintf(tmp_buf, "%s@%x,%x",
0086 name,
0087 regs->which_io,
0088 regs->phys_addr);
0089 }
0090
0091
0092 static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
0093 {
0094 const char *name = of_get_property(dp, "name", NULL);
0095 struct linux_prom_pci_registers *regs;
0096 struct property *prop;
0097 unsigned int devfn;
0098
0099 prop = of_find_property(dp, "reg", NULL);
0100 if (!prop)
0101 return;
0102
0103 regs = prop->value;
0104 devfn = (regs->phys_hi >> 8) & 0xff;
0105 if (devfn & 0x07) {
0106 sprintf(tmp_buf, "%s@%x,%x",
0107 name,
0108 devfn >> 3,
0109 devfn & 0x07);
0110 } else {
0111 sprintf(tmp_buf, "%s@%x",
0112 name,
0113 devfn >> 3);
0114 }
0115 }
0116
0117
0118 static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
0119 {
0120 const char *name = of_get_property(dp, "name", NULL);
0121 struct linux_prom_registers *regs;
0122 struct property *prop;
0123
0124 prop = of_find_property(dp, "reg", NULL);
0125 if (!prop)
0126 return;
0127
0128 regs = prop->value;
0129
0130 sprintf(tmp_buf, "%s@%x,%x",
0131 name,
0132 regs->which_io, regs->phys_addr);
0133 }
0134
0135
0136 static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
0137 {
0138 const char *name = of_get_property(dp, "name", NULL);
0139 struct amba_prom_registers *regs;
0140 unsigned int *intr;
0141 unsigned int reg0;
0142 struct property *prop;
0143 int interrupt = 0;
0144
0145
0146
0147
0148 prop = of_find_property(dp, "reg", NULL);
0149 if (!prop) {
0150 reg0 = (unsigned int)dp->phandle;
0151 } else {
0152 regs = prop->value;
0153 reg0 = regs->phys_addr;
0154 }
0155
0156
0157 prop = of_find_property(dp, "interrupts", NULL);
0158 if (!prop)
0159 intr = &interrupt;
0160 else
0161 intr = prop->value;
0162
0163 sprintf(tmp_buf, "%s@%x,%x", name, *intr, reg0);
0164 }
0165
0166 static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
0167 {
0168 struct device_node *parent = dp->parent;
0169
0170 if (parent != NULL) {
0171 if (of_node_is_type(parent, "pci") ||
0172 of_node_is_type(parent, "pciex"))
0173 return pci_path_component(dp, tmp_buf);
0174 if (of_node_is_type(parent, "sbus"))
0175 return sbus_path_component(dp, tmp_buf);
0176 if (of_node_is_type(parent, "ebus"))
0177 return ebus_path_component(dp, tmp_buf);
0178 if (of_node_is_type(parent, "ambapp"))
0179 return ambapp_path_component(dp, tmp_buf);
0180
0181
0182 }
0183
0184
0185 return sparc32_path_component(dp, tmp_buf);
0186 }
0187
0188 char * __init build_path_component(struct device_node *dp)
0189 {
0190 const char *name = of_get_property(dp, "name", NULL);
0191 char tmp_buf[64], *n;
0192
0193 tmp_buf[0] = '\0';
0194 __build_path_component(dp, tmp_buf);
0195 if (tmp_buf[0] == '\0')
0196 strcpy(tmp_buf, name);
0197
0198 n = prom_early_alloc(strlen(tmp_buf) + 1);
0199 strcpy(n, tmp_buf);
0200
0201 return n;
0202 }
0203
0204 extern void restore_current(void);
0205
0206 void __init of_console_init(void)
0207 {
0208 char *msg = "OF stdout device is: %s\n";
0209 struct device_node *dp;
0210 unsigned long flags;
0211 const char *type;
0212 phandle node;
0213 int skip, tmp, fd;
0214
0215 of_console_path = prom_early_alloc(256);
0216
0217 switch (prom_vers) {
0218 case PROM_V0:
0219 skip = 0;
0220 switch (*romvec->pv_stdout) {
0221 case PROMDEV_SCREEN:
0222 type = "display";
0223 break;
0224
0225 case PROMDEV_TTYB:
0226 skip = 1;
0227 fallthrough;
0228
0229 case PROMDEV_TTYA:
0230 type = "serial";
0231 break;
0232
0233 default:
0234 prom_printf("Invalid PROM_V0 stdout value %u\n",
0235 *romvec->pv_stdout);
0236 prom_halt();
0237 }
0238
0239 tmp = skip;
0240 for_each_node_by_type(dp, type) {
0241 if (!tmp--)
0242 break;
0243 }
0244 if (!dp) {
0245 prom_printf("Cannot find PROM_V0 console node.\n");
0246 prom_halt();
0247 }
0248 of_console_device = dp;
0249
0250 sprintf(of_console_path, "%pOF", dp);
0251 if (!strcmp(type, "serial")) {
0252 strcat(of_console_path,
0253 (skip ? ":b" : ":a"));
0254 }
0255 break;
0256
0257 default:
0258 case PROM_V2:
0259 case PROM_V3:
0260 fd = *romvec->pv_v2bootargs.fd_stdout;
0261
0262 spin_lock_irqsave(&prom_lock, flags);
0263 node = (*romvec->pv_v2devops.v2_inst2pkg)(fd);
0264 restore_current();
0265 spin_unlock_irqrestore(&prom_lock, flags);
0266
0267 if (!node) {
0268 prom_printf("Cannot resolve stdout node from "
0269 "instance %08x.\n", fd);
0270 prom_halt();
0271 }
0272 dp = of_find_node_by_phandle(node);
0273
0274 if (!of_node_is_type(dp, "display") &&
0275 !of_node_is_type(dp, "serial")) {
0276 prom_printf("Console device_type is neither display "
0277 "nor serial.\n");
0278 prom_halt();
0279 }
0280
0281 of_console_device = dp;
0282
0283 if (prom_vers == PROM_V2) {
0284 sprintf(of_console_path, "%pOF", dp);
0285 switch (*romvec->pv_stdout) {
0286 case PROMDEV_TTYA:
0287 strcat(of_console_path, ":a");
0288 break;
0289 case PROMDEV_TTYB:
0290 strcat(of_console_path, ":b");
0291 break;
0292 }
0293 } else {
0294 const char *path;
0295
0296 dp = of_find_node_by_path("/");
0297 path = of_get_property(dp, "stdout-path", NULL);
0298 if (!path) {
0299 prom_printf("No stdout-path in root node.\n");
0300 prom_halt();
0301 }
0302 strcpy(of_console_path, path);
0303 }
0304 break;
0305 }
0306
0307 of_console_options = strrchr(of_console_path, ':');
0308 if (of_console_options) {
0309 of_console_options++;
0310 if (*of_console_options == '\0')
0311 of_console_options = NULL;
0312 }
0313
0314 printk(msg, of_console_path);
0315 }
0316
0317 void __init of_fill_in_cpu_data(void)
0318 {
0319 }
0320
0321 void __init irq_trans_init(struct device_node *dp)
0322 {
0323 }