]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/sparc/kernel/prom_64.c
sparc: Move core of OF device tree building code into prom_common.c
[karo-tx-linux.git] / arch / sparc / kernel / prom_64.c
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 sparc64 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/module.h>
23 #include <linux/lmb.h>
24 #include <linux/of_device.h>
25
26 #include <asm/prom.h>
27 #include <asm/oplib.h>
28 #include <asm/irq.h>
29 #include <asm/asi.h>
30 #include <asm/upa.h>
31 #include <asm/smp.h>
32
33 #include "prom.h"
34
35 static unsigned int prom_early_allocated __initdata;
36
37 void * __init prom_early_alloc(unsigned long size)
38 {
39         unsigned long paddr = lmb_alloc(size, SMP_CACHE_BYTES);
40         void *ret;
41
42         if (!paddr) {
43                 prom_printf("prom_early_alloc(%lu) failed\n");
44                 prom_halt();
45         }
46
47         ret = __va(paddr);
48         memset(ret, 0, size);
49         prom_early_allocated += size;
50
51         return ret;
52 }
53
54 /* The following routines deal with the black magic of fully naming a
55  * node.
56  *
57  * Certain well known named nodes are just the simple name string.
58  *
59  * Actual devices have an address specifier appended to the base name
60  * string, like this "foo@addr".  The "addr" can be in any number of
61  * formats, and the platform plus the type of the node determine the
62  * format and how it is constructed.
63  *
64  * For children of the ROOT node, the naming convention is fixed and
65  * determined by whether this is a sun4u or sun4v system.
66  *
67  * For children of other nodes, it is bus type specific.  So
68  * we walk up the tree until we discover a "device_type" property
69  * we recognize and we go from there.
70  *
71  * As an example, the boot device on my workstation has a full path:
72  *
73  *      /pci@1e,600000/ide@d/disk@0,0:c
74  */
75 static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
76 {
77         struct linux_prom64_registers *regs;
78         struct property *rprop;
79         u32 high_bits, low_bits, type;
80
81         rprop = of_find_property(dp, "reg", NULL);
82         if (!rprop)
83                 return;
84
85         regs = rprop->value;
86         if (!is_root_node(dp->parent)) {
87                 sprintf(tmp_buf, "%s@%x,%x",
88                         dp->name,
89                         (unsigned int) (regs->phys_addr >> 32UL),
90                         (unsigned int) (regs->phys_addr & 0xffffffffUL));
91                 return;
92         }
93
94         type = regs->phys_addr >> 60UL;
95         high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
96         low_bits = (regs->phys_addr & 0xffffffffUL);
97
98         if (type == 0 || type == 8) {
99                 const char *prefix = (type == 0) ? "m" : "i";
100
101                 if (low_bits)
102                         sprintf(tmp_buf, "%s@%s%x,%x",
103                                 dp->name, prefix,
104                                 high_bits, low_bits);
105                 else
106                         sprintf(tmp_buf, "%s@%s%x",
107                                 dp->name,
108                                 prefix,
109                                 high_bits);
110         } else if (type == 12) {
111                 sprintf(tmp_buf, "%s@%x",
112                         dp->name, high_bits);
113         }
114 }
115
116 static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
117 {
118         struct linux_prom64_registers *regs;
119         struct property *prop;
120
121         prop = of_find_property(dp, "reg", NULL);
122         if (!prop)
123                 return;
124
125         regs = prop->value;
126         if (!is_root_node(dp->parent)) {
127                 sprintf(tmp_buf, "%s@%x,%x",
128                         dp->name,
129                         (unsigned int) (regs->phys_addr >> 32UL),
130                         (unsigned int) (regs->phys_addr & 0xffffffffUL));
131                 return;
132         }
133
134         prop = of_find_property(dp, "upa-portid", NULL);
135         if (!prop)
136                 prop = of_find_property(dp, "portid", NULL);
137         if (prop) {
138                 unsigned long mask = 0xffffffffUL;
139
140                 if (tlb_type >= cheetah)
141                         mask = 0x7fffff;
142
143                 sprintf(tmp_buf, "%s@%x,%x",
144                         dp->name,
145                         *(u32 *)prop->value,
146                         (unsigned int) (regs->phys_addr & mask));
147         }
148 }
149
150 /* "name@slot,offset"  */
151 static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
152 {
153         struct linux_prom_registers *regs;
154         struct property *prop;
155
156         prop = of_find_property(dp, "reg", NULL);
157         if (!prop)
158                 return;
159
160         regs = prop->value;
161         sprintf(tmp_buf, "%s@%x,%x",
162                 dp->name,
163                 regs->which_io,
164                 regs->phys_addr);
165 }
166
167 /* "name@devnum[,func]" */
168 static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
169 {
170         struct linux_prom_pci_registers *regs;
171         struct property *prop;
172         unsigned int devfn;
173
174         prop = of_find_property(dp, "reg", NULL);
175         if (!prop)
176                 return;
177
178         regs = prop->value;
179         devfn = (regs->phys_hi >> 8) & 0xff;
180         if (devfn & 0x07) {
181                 sprintf(tmp_buf, "%s@%x,%x",
182                         dp->name,
183                         devfn >> 3,
184                         devfn & 0x07);
185         } else {
186                 sprintf(tmp_buf, "%s@%x",
187                         dp->name,
188                         devfn >> 3);
189         }
190 }
191
192 /* "name@UPA_PORTID,offset" */
193 static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
194 {
195         struct linux_prom64_registers *regs;
196         struct property *prop;
197
198         prop = of_find_property(dp, "reg", NULL);
199         if (!prop)
200                 return;
201
202         regs = prop->value;
203
204         prop = of_find_property(dp, "upa-portid", NULL);
205         if (!prop)
206                 return;
207
208         sprintf(tmp_buf, "%s@%x,%x",
209                 dp->name,
210                 *(u32 *) prop->value,
211                 (unsigned int) (regs->phys_addr & 0xffffffffUL));
212 }
213
214 /* "name@reg" */
215 static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
216 {
217         struct property *prop;
218         u32 *regs;
219
220         prop = of_find_property(dp, "reg", NULL);
221         if (!prop)
222                 return;
223
224         regs = prop->value;
225
226         sprintf(tmp_buf, "%s@%x", dp->name, *regs);
227 }
228
229 /* "name@addrhi,addrlo" */
230 static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
231 {
232         struct linux_prom64_registers *regs;
233         struct property *prop;
234
235         prop = of_find_property(dp, "reg", NULL);
236         if (!prop)
237                 return;
238
239         regs = prop->value;
240
241         sprintf(tmp_buf, "%s@%x,%x",
242                 dp->name,
243                 (unsigned int) (regs->phys_addr >> 32UL),
244                 (unsigned int) (regs->phys_addr & 0xffffffffUL));
245 }
246
247 /* "name@bus,addr" */
248 static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
249 {
250         struct property *prop;
251         u32 *regs;
252
253         prop = of_find_property(dp, "reg", NULL);
254         if (!prop)
255                 return;
256
257         regs = prop->value;
258
259         /* This actually isn't right... should look at the #address-cells
260          * property of the i2c bus node etc. etc.
261          */
262         sprintf(tmp_buf, "%s@%x,%x",
263                 dp->name, regs[0], regs[1]);
264 }
265
266 /* "name@reg0[,reg1]" */
267 static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
268 {
269         struct property *prop;
270         u32 *regs;
271
272         prop = of_find_property(dp, "reg", NULL);
273         if (!prop)
274                 return;
275
276         regs = prop->value;
277
278         if (prop->length == sizeof(u32) || regs[1] == 1) {
279                 sprintf(tmp_buf, "%s@%x",
280                         dp->name, regs[0]);
281         } else {
282                 sprintf(tmp_buf, "%s@%x,%x",
283                         dp->name, regs[0], regs[1]);
284         }
285 }
286
287 /* "name@reg0reg1[,reg2reg3]" */
288 static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
289 {
290         struct property *prop;
291         u32 *regs;
292
293         prop = of_find_property(dp, "reg", NULL);
294         if (!prop)
295                 return;
296
297         regs = prop->value;
298
299         if (regs[2] || regs[3]) {
300                 sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
301                         dp->name, regs[0], regs[1], regs[2], regs[3]);
302         } else {
303                 sprintf(tmp_buf, "%s@%08x%08x",
304                         dp->name, regs[0], regs[1]);
305         }
306 }
307
308 static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
309 {
310         struct device_node *parent = dp->parent;
311
312         if (parent != NULL) {
313                 if (!strcmp(parent->type, "pci") ||
314                     !strcmp(parent->type, "pciex")) {
315                         pci_path_component(dp, tmp_buf);
316                         return;
317                 }
318                 if (!strcmp(parent->type, "sbus")) {
319                         sbus_path_component(dp, tmp_buf);
320                         return;
321                 }
322                 if (!strcmp(parent->type, "upa")) {
323                         upa_path_component(dp, tmp_buf);
324                         return;
325                 }
326                 if (!strcmp(parent->type, "ebus")) {
327                         ebus_path_component(dp, tmp_buf);
328                         return;
329                 }
330                 if (!strcmp(parent->name, "usb") ||
331                     !strcmp(parent->name, "hub")) {
332                         usb_path_component(dp, tmp_buf);
333                         return;
334                 }
335                 if (!strcmp(parent->type, "i2c")) {
336                         i2c_path_component(dp, tmp_buf);
337                         return;
338                 }
339                 if (!strcmp(parent->type, "firewire")) {
340                         ieee1394_path_component(dp, tmp_buf);
341                         return;
342                 }
343                 if (!strcmp(parent->type, "virtual-devices")) {
344                         vdev_path_component(dp, tmp_buf);
345                         return;
346                 }
347                 /* "isa" is handled with platform naming */
348         }
349
350         /* Use platform naming convention.  */
351         if (tlb_type == hypervisor) {
352                 sun4v_path_component(dp, tmp_buf);
353                 return;
354         } else {
355                 sun4u_path_component(dp, tmp_buf);
356         }
357 }
358
359 char * __init build_path_component(struct device_node *dp)
360 {
361         char tmp_buf[64], *n;
362
363         tmp_buf[0] = '\0';
364         __build_path_component(dp, tmp_buf);
365         if (tmp_buf[0] == '\0')
366                 strcpy(tmp_buf, dp->name);
367
368         n = prom_early_alloc(strlen(tmp_buf) + 1);
369         strcpy(n, tmp_buf);
370
371         return n;
372 }
373
374 static const char *get_mid_prop(void)
375 {
376         return (tlb_type == spitfire ? "upa-portid" : "portid");
377 }
378
379 struct device_node *of_find_node_by_cpuid(int cpuid)
380 {
381         struct device_node *dp;
382         const char *mid_prop = get_mid_prop();
383
384         for_each_node_by_type(dp, "cpu") {
385                 int id = of_getintprop_default(dp, mid_prop, -1);
386                 const char *this_mid_prop = mid_prop;
387
388                 if (id < 0) {
389                         this_mid_prop = "cpuid";
390                         id = of_getintprop_default(dp, this_mid_prop, -1);
391                 }
392
393                 if (id < 0) {
394                         prom_printf("OF: Serious problem, cpu lacks "
395                                     "%s property", this_mid_prop);
396                         prom_halt();
397                 }
398                 if (cpuid == id)
399                         return dp;
400         }
401         return NULL;
402 }
403
404 static void __init of_fill_in_cpu_data(void)
405 {
406         struct device_node *dp;
407         const char *mid_prop = get_mid_prop();
408
409         ncpus_probed = 0;
410         for_each_node_by_type(dp, "cpu") {
411                 int cpuid = of_getintprop_default(dp, mid_prop, -1);
412                 const char *this_mid_prop = mid_prop;
413                 struct device_node *portid_parent;
414                 int portid = -1;
415
416                 portid_parent = NULL;
417                 if (cpuid < 0) {
418                         this_mid_prop = "cpuid";
419                         cpuid = of_getintprop_default(dp, this_mid_prop, -1);
420                         if (cpuid >= 0) {
421                                 int limit = 2;
422
423                                 portid_parent = dp;
424                                 while (limit--) {
425                                         portid_parent = portid_parent->parent;
426                                         if (!portid_parent)
427                                                 break;
428                                         portid = of_getintprop_default(portid_parent,
429                                                                        "portid", -1);
430                                         if (portid >= 0)
431                                                 break;
432                                 }
433                         }
434                 }
435
436                 if (cpuid < 0) {
437                         prom_printf("OF: Serious problem, cpu lacks "
438                                     "%s property", this_mid_prop);
439                         prom_halt();
440                 }
441
442                 ncpus_probed++;
443
444 #ifdef CONFIG_SMP
445                 if (cpuid >= NR_CPUS) {
446                         printk(KERN_WARNING "Ignoring CPU %d which is "
447                                ">= NR_CPUS (%d)\n",
448                                cpuid, NR_CPUS);
449                         continue;
450                 }
451 #else
452                 /* On uniprocessor we only want the values for the
453                  * real physical cpu the kernel booted onto, however
454                  * cpu_data() only has one entry at index 0.
455                  */
456                 if (cpuid != real_hard_smp_processor_id())
457                         continue;
458                 cpuid = 0;
459 #endif
460
461                 cpu_data(cpuid).clock_tick =
462                         of_getintprop_default(dp, "clock-frequency", 0);
463
464                 if (portid_parent) {
465                         cpu_data(cpuid).dcache_size =
466                                 of_getintprop_default(dp, "l1-dcache-size",
467                                                       16 * 1024);
468                         cpu_data(cpuid).dcache_line_size =
469                                 of_getintprop_default(dp, "l1-dcache-line-size",
470                                                       32);
471                         cpu_data(cpuid).icache_size =
472                                 of_getintprop_default(dp, "l1-icache-size",
473                                                       8 * 1024);
474                         cpu_data(cpuid).icache_line_size =
475                                 of_getintprop_default(dp, "l1-icache-line-size",
476                                                       32);
477                         cpu_data(cpuid).ecache_size =
478                                 of_getintprop_default(dp, "l2-cache-size", 0);
479                         cpu_data(cpuid).ecache_line_size =
480                                 of_getintprop_default(dp, "l2-cache-line-size", 0);
481                         if (!cpu_data(cpuid).ecache_size ||
482                             !cpu_data(cpuid).ecache_line_size) {
483                                 cpu_data(cpuid).ecache_size =
484                                         of_getintprop_default(portid_parent,
485                                                               "l2-cache-size",
486                                                               (4 * 1024 * 1024));
487                                 cpu_data(cpuid).ecache_line_size =
488                                         of_getintprop_default(portid_parent,
489                                                               "l2-cache-line-size", 64);
490                         }
491
492                         cpu_data(cpuid).core_id = portid + 1;
493                         cpu_data(cpuid).proc_id = portid;
494 #ifdef CONFIG_SMP
495                         sparc64_multi_core = 1;
496 #endif
497                 } else {
498                         cpu_data(cpuid).dcache_size =
499                                 of_getintprop_default(dp, "dcache-size", 16 * 1024);
500                         cpu_data(cpuid).dcache_line_size =
501                                 of_getintprop_default(dp, "dcache-line-size", 32);
502
503                         cpu_data(cpuid).icache_size =
504                                 of_getintprop_default(dp, "icache-size", 16 * 1024);
505                         cpu_data(cpuid).icache_line_size =
506                                 of_getintprop_default(dp, "icache-line-size", 32);
507
508                         cpu_data(cpuid).ecache_size =
509                                 of_getintprop_default(dp, "ecache-size",
510                                                       (4 * 1024 * 1024));
511                         cpu_data(cpuid).ecache_line_size =
512                                 of_getintprop_default(dp, "ecache-line-size", 64);
513
514                         cpu_data(cpuid).core_id = 0;
515                         cpu_data(cpuid).proc_id = -1;
516                 }
517
518 #ifdef CONFIG_SMP
519                 cpu_set(cpuid, cpu_present_map);
520                 cpu_set(cpuid, cpu_possible_map);
521 #endif
522         }
523
524         smp_fill_in_sib_core_maps();
525 }
526
527 struct device_node *of_console_device;
528 EXPORT_SYMBOL(of_console_device);
529
530 char *of_console_path;
531 EXPORT_SYMBOL(of_console_path);
532
533 char *of_console_options;
534 EXPORT_SYMBOL(of_console_options);
535
536 static void __init of_console_init(void)
537 {
538         char *msg = "OF stdout device is: %s\n";
539         struct device_node *dp;
540         const char *type;
541         phandle node;
542
543         of_console_path = prom_early_alloc(256);
544         if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) {
545                 prom_printf("Cannot obtain path of stdout.\n");
546                 prom_halt();
547         }
548         of_console_options = strrchr(of_console_path, ':');
549         if (of_console_options) {
550                 of_console_options++;
551                 if (*of_console_options == '\0')
552                         of_console_options = NULL;
553         }
554
555         node = prom_inst2pkg(prom_stdout);
556         if (!node) {
557                 prom_printf("Cannot resolve stdout node from "
558                             "instance %08x.\n", prom_stdout);
559                 prom_halt();
560         }
561
562         dp = of_find_node_by_phandle(node);
563         type = of_get_property(dp, "device_type", NULL);
564         if (!type) {
565                 prom_printf("Console stdout lacks device_type property.\n");
566                 prom_halt();
567         }
568
569         if (strcmp(type, "display") && strcmp(type, "serial")) {
570                 prom_printf("Console device_type is neither display "
571                             "nor serial.\n");
572                 prom_halt();
573         }
574
575         of_console_device = dp;
576
577         printk(msg, of_console_path);
578 }
579
580 void __init prom_build_devicetree(void)
581 {
582         struct device_node **nextp;
583
584         allnodes = prom_create_node(prom_root_node, NULL);
585         allnodes->path_component_name = "";
586         allnodes->full_name = "/";
587
588         nextp = &allnodes->allnext;
589         allnodes->child = prom_build_tree(allnodes,
590                                           prom_getchild(allnodes->node),
591                                           &nextp);
592         of_console_init();
593
594         printk("PROM: Built device tree with %u bytes of memory.\n",
595                prom_early_allocated);
596
597         if (tlb_type != hypervisor)
598                 of_fill_in_cpu_data();
599 }