]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - arch/ppc/syslib/prom_init.c
Linux-2.6.12-rc2
[sojka/nv-tegra/linux-3.10.git] / arch / ppc / syslib / prom_init.c
1 /*
2  * Note that prom_init() and anything called from prom_init()
3  * may be running at an address that is different from the address
4  * that it was linked at.  References to static data items are
5  * handled by compiling this file with -mrelocatable-lib.
6  */
7
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/init.h>
12 #include <linux/version.h>
13 #include <linux/threads.h>
14 #include <linux/spinlock.h>
15 #include <linux/ioport.h>
16 #include <linux/pci.h>
17 #include <linux/slab.h>
18 #include <linux/bitops.h>
19
20 #include <asm/sections.h>
21 #include <asm/prom.h>
22 #include <asm/page.h>
23 #include <asm/irq.h>
24 #include <asm/io.h>
25 #include <asm/smp.h>
26 #include <asm/bootx.h>
27 #include <asm/system.h>
28 #include <asm/mmu.h>
29 #include <asm/pgtable.h>
30 #include <asm/bootinfo.h>
31 #include <asm/btext.h>
32 #include <asm/pci-bridge.h>
33 #include <asm/open_pic.h>
34 #include <asm/cacheflush.h>
35
36 #ifdef CONFIG_LOGO_LINUX_CLUT224
37 #include <linux/linux_logo.h>
38 extern const struct linux_logo logo_linux_clut224;
39 #endif
40
41 /*
42  * Properties whose value is longer than this get excluded from our
43  * copy of the device tree.  This way we don't waste space storing
44  * things like "driver,AAPL,MacOS,PowerPC" properties.  But this value
45  * does need to be big enough to ensure that we don't lose things
46  * like the interrupt-map property on a PCI-PCI bridge.
47  */
48 #define MAX_PROPERTY_LENGTH     4096
49
50 #ifndef FB_MAX                  /* avoid pulling in all of the fb stuff */
51 #define FB_MAX  8
52 #endif
53
54 #define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
55
56 typedef u32 prom_arg_t;
57
58 struct prom_args {
59         const char *service;
60         int nargs;
61         int nret;
62         prom_arg_t args[10];
63 };
64
65 struct pci_address {
66         unsigned a_hi;
67         unsigned a_mid;
68         unsigned a_lo;
69 };
70
71 struct pci_reg_property {
72         struct pci_address addr;
73         unsigned size_hi;
74         unsigned size_lo;
75 };
76
77 struct pci_range {
78         struct pci_address addr;
79         unsigned phys;
80         unsigned size_hi;
81         unsigned size_lo;
82 };
83
84 struct isa_reg_property {
85         unsigned space;
86         unsigned address;
87         unsigned size;
88 };
89
90 struct pci_intr_map {
91         struct pci_address addr;
92         unsigned dunno;
93         phandle int_ctrler;
94         unsigned intr;
95 };
96
97 static void prom_exit(void);
98 static int  call_prom(const char *service, int nargs, int nret, ...);
99 static int  call_prom_ret(const char *service, int nargs, int nret,
100                           prom_arg_t *rets, ...);
101 static void prom_print_hex(unsigned int v);
102 static int  prom_set_color(ihandle ih, int i, int r, int g, int b);
103 static int  prom_next_node(phandle *nodep);
104 static unsigned long check_display(unsigned long mem);
105 static void setup_disp_fake_bi(ihandle dp);
106 static unsigned long copy_device_tree(unsigned long mem_start,
107                                 unsigned long mem_end);
108 static unsigned long inspect_node(phandle node, struct device_node *dad,
109                                 unsigned long mem_start, unsigned long mem_end,
110                                 struct device_node ***allnextpp);
111 static void prom_hold_cpus(unsigned long mem);
112 static void prom_instantiate_rtas(void);
113 static void * early_get_property(unsigned long base, unsigned long node,
114                                 char *prop);
115
116 prom_entry prom __initdata;
117 ihandle prom_chosen __initdata;
118 ihandle prom_stdout __initdata;
119
120 static char *prom_display_paths[FB_MAX] __initdata;
121 static phandle prom_display_nodes[FB_MAX] __initdata;
122 static unsigned int prom_num_displays __initdata;
123 static ihandle prom_disp_node __initdata;
124 char *of_stdout_device __initdata;
125
126 unsigned int rtas_data;   /* physical pointer */
127 unsigned int rtas_entry;  /* physical pointer */
128 unsigned int rtas_size;
129 unsigned int old_rtas;
130
131 boot_infos_t *boot_infos;
132 char *bootpath;
133 char *bootdevice;
134 struct device_node *allnodes;
135
136 extern char *klimit;
137
138 static void __init
139 prom_exit(void)
140 {
141         struct prom_args args;
142
143         args.service = "exit";
144         args.nargs = 0;
145         args.nret = 0;
146         prom(&args);
147         for (;;)                        /* should never get here */
148                 ;
149 }
150
151 static int __init
152 call_prom(const char *service, int nargs, int nret, ...)
153 {
154         va_list list;
155         int i;
156         struct prom_args prom_args;
157
158         prom_args.service = service;
159         prom_args.nargs = nargs;
160         prom_args.nret = nret;
161         va_start(list, nret);
162         for (i = 0; i < nargs; ++i)
163                 prom_args.args[i] = va_arg(list, prom_arg_t);
164         va_end(list);
165         for (i = 0; i < nret; ++i)
166                 prom_args.args[i + nargs] = 0;
167         prom(&prom_args);
168         return prom_args.args[nargs];
169 }
170
171 static int __init
172 call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...)
173 {
174         va_list list;
175         int i;
176         struct prom_args prom_args;
177
178         prom_args.service = service;
179         prom_args.nargs = nargs;
180         prom_args.nret = nret;
181         va_start(list, rets);
182         for (i = 0; i < nargs; ++i)
183                 prom_args.args[i] = va_arg(list, int);
184         va_end(list);
185         for (i = 0; i < nret; ++i)
186                 prom_args.args[i + nargs] = 0;
187         prom(&prom_args);
188         for (i = 1; i < nret; ++i)
189                 rets[i-1] = prom_args.args[nargs + i];
190         return prom_args.args[nargs];
191 }
192
193 void __init
194 prom_print(const char *msg)
195 {
196         const char *p, *q;
197
198         if (prom_stdout == 0)
199                 return;
200
201         for (p = msg; *p != 0; p = q) {
202                 for (q = p; *q != 0 && *q != '\n'; ++q)
203                         ;
204                 if (q > p)
205                         call_prom("write", 3, 1, prom_stdout, p, q - p);
206                 if (*q != 0) {
207                         ++q;
208                         call_prom("write", 3, 1, prom_stdout, "\r\n", 2);
209                 }
210         }
211 }
212
213 static void __init
214 prom_print_hex(unsigned int v)
215 {
216         char buf[16];
217         int i, c;
218
219         for (i = 0; i < 8; ++i) {
220                 c = (v >> ((7-i)*4)) & 0xf;
221                 c += (c >= 10)? ('a' - 10): '0';
222                 buf[i] = c;
223         }
224         buf[i] = ' ';
225         buf[i+1] = 0;
226         prom_print(buf);
227 }
228
229 static int __init
230 prom_set_color(ihandle ih, int i, int r, int g, int b)
231 {
232         return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r);
233 }
234
235 static int __init
236 prom_next_node(phandle *nodep)
237 {
238         phandle node;
239
240         if ((node = *nodep) != 0
241             && (*nodep = call_prom("child", 1, 1, node)) != 0)
242                 return 1;
243         if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
244                 return 1;
245         for (;;) {
246                 if ((node = call_prom("parent", 1, 1, node)) == 0)
247                         return 0;
248                 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
249                         return 1;
250         }
251 }
252
253 #ifdef CONFIG_POWER4
254 /*
255  * Set up a hash table with a set of entries in it to map the
256  * first 64MB of RAM.  This is used on 64-bit machines since
257  * some of them don't have BATs.
258  */
259
260 static inline void make_pte(unsigned long htab, unsigned int hsize,
261                             unsigned int va, unsigned int pa, int mode)
262 {
263         unsigned int *pteg;
264         unsigned int hash, i, vsid;
265
266         vsid = ((va >> 28) * 0x111) << 12;
267         hash = ((va ^ vsid) >> 5) & 0x7fff80;
268         pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
269         for (i = 0; i < 8; ++i, pteg += 4) {
270                 if ((pteg[1] & 1) == 0) {
271                         pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
272                         pteg[3] = pa | mode;
273                         break;
274                 }
275         }
276 }
277
278 extern unsigned long _SDR1;
279 extern PTE *Hash;
280 extern unsigned long Hash_size;
281
282 static void __init
283 prom_alloc_htab(void)
284 {
285         unsigned int hsize;
286         unsigned long htab;
287         unsigned int addr;
288
289         /*
290          * Because of OF bugs we can't use the "claim" client
291          * interface to allocate memory for the hash table.
292          * This code is only used on 64-bit PPCs, and the only
293          * 64-bit PPCs at the moment are RS/6000s, and their
294          * OF is based at 0xc00000 (the 12M point), so we just
295          * arbitrarily use the 0x800000 - 0xc00000 region for the
296          * hash table.
297          *  -- paulus.
298          */
299         hsize = 4 << 20;        /* POWER4 has no BATs */
300         htab = (8 << 20);
301         call_prom("claim", 3, 1, htab, hsize, 0);
302         Hash = (void *)(htab + KERNELBASE);
303         Hash_size = hsize;
304         _SDR1 = htab + __ilog2(hsize) - 18;
305
306         /*
307          * Put in PTEs for the first 64MB of RAM
308          */
309         memset((void *)htab, 0, hsize);
310         for (addr = 0; addr < 0x4000000; addr += 0x1000)
311                 make_pte(htab, hsize, addr + KERNELBASE, addr,
312                          _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
313 #if 0 /* DEBUG stuff mapping the SCC */
314         make_pte(htab, hsize, 0x80013000, 0x80013000,
315                  _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
316 #endif
317 }
318 #endif /* CONFIG_POWER4 */
319
320
321 /*
322  * If we have a display that we don't know how to drive,
323  * we will want to try to execute OF's open method for it
324  * later.  However, OF will probably fall over if we do that
325  * we've taken over the MMU.
326  * So we check whether we will need to open the display,
327  * and if so, open it now.
328  */
329 static unsigned long __init
330 check_display(unsigned long mem)
331 {
332         phandle node;
333         ihandle ih;
334         int i, j;
335         char type[16], *path;
336         static unsigned char default_colors[] = {
337                 0x00, 0x00, 0x00,
338                 0x00, 0x00, 0xaa,
339                 0x00, 0xaa, 0x00,
340                 0x00, 0xaa, 0xaa,
341                 0xaa, 0x00, 0x00,
342                 0xaa, 0x00, 0xaa,
343                 0xaa, 0xaa, 0x00,
344                 0xaa, 0xaa, 0xaa,
345                 0x55, 0x55, 0x55,
346                 0x55, 0x55, 0xff,
347                 0x55, 0xff, 0x55,
348                 0x55, 0xff, 0xff,
349                 0xff, 0x55, 0x55,
350                 0xff, 0x55, 0xff,
351                 0xff, 0xff, 0x55,
352                 0xff, 0xff, 0xff
353         };
354         const unsigned char *clut;
355
356         prom_disp_node = 0;
357
358         for (node = 0; prom_next_node(&node); ) {
359                 type[0] = 0;
360                 call_prom("getprop", 4, 1, node, "device_type",
361                           type, sizeof(type));
362                 if (strcmp(type, "display") != 0)
363                         continue;
364                 /* It seems OF doesn't null-terminate the path :-( */
365                 path = (char *) mem;
366                 memset(path, 0, 256);
367                 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
368                         continue;
369
370                 /*
371                  * If this display is the device that OF is using for stdout,
372                  * move it to the front of the list.
373                  */
374                 mem += strlen(path) + 1;
375                 i = prom_num_displays++;
376                 if (of_stdout_device != 0 && i > 0
377                     && strcmp(of_stdout_device, path) == 0) {
378                         for (; i > 0; --i) {
379                                 prom_display_paths[i]
380                                         = prom_display_paths[i-1];
381                                 prom_display_nodes[i]
382                                         = prom_display_nodes[i-1];
383                         }
384                 }
385                 prom_display_paths[i] = path;
386                 prom_display_nodes[i] = node;
387                 if (i == 0)
388                         prom_disp_node = node;
389                 if (prom_num_displays >= FB_MAX)
390                         break;
391         }
392
393         for (j=0; j<prom_num_displays; j++) {
394                 path = prom_display_paths[j];
395                 node = prom_display_nodes[j];
396                 prom_print("opening display ");
397                 prom_print(path);
398                 ih = call_prom("open", 1, 1, path);
399                 if (ih == 0 || ih == (ihandle) -1) {
400                         prom_print("... failed\n");
401                         for (i=j+1; i<prom_num_displays; i++) {
402                                 prom_display_paths[i-1] = prom_display_paths[i];
403                                 prom_display_nodes[i-1] = prom_display_nodes[i];
404                         }
405                         if (--prom_num_displays > 0) {
406                                 prom_disp_node = prom_display_nodes[j];
407                                 j--;
408                         } else
409                                 prom_disp_node = 0;
410                         continue;
411                 } else {
412                         prom_print("... ok\n");
413                         call_prom("setprop", 4, 1, node, "linux,opened", 0, 0);
414
415                         /*
416                          * Setup a usable color table when the appropriate
417                          * method is available.
418                          * Should update this to use set-colors.
419                          */
420                         clut = default_colors;
421                         for (i = 0; i < 32; i++, clut += 3)
422                                 if (prom_set_color(ih, i, clut[0], clut[1],
423                                                    clut[2]) != 0)
424                                         break;
425
426 #ifdef CONFIG_LOGO_LINUX_CLUT224
427                         clut = PTRRELOC(logo_linux_clut224.clut);
428                         for (i = 0; i < logo_linux_clut224.clutsize;
429                              i++, clut += 3)
430                                 if (prom_set_color(ih, i + 32, clut[0],
431                                                    clut[1], clut[2]) != 0)
432                                         break;
433 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
434                 }
435         }
436         
437         if (prom_stdout) {
438                 phandle p;
439                 p = call_prom("instance-to-package", 1, 1, prom_stdout);
440                 if (p && p != -1) {
441                         type[0] = 0;
442                         call_prom("getprop", 4, 1, p, "device_type",
443                                   type, sizeof(type));
444                         if (strcmp(type, "display") == 0)
445                                 call_prom("setprop", 4, 1, p, "linux,boot-display",
446                                           0, 0);
447                 }
448         }
449
450         return ALIGNUL(mem);
451 }
452
453 /* This function will enable the early boot text when doing OF booting. This
454  * way, xmon output should work too
455  */
456 static void __init
457 setup_disp_fake_bi(ihandle dp)
458 {
459 #ifdef CONFIG_BOOTX_TEXT
460         int width = 640, height = 480, depth = 8, pitch;
461         unsigned address;
462         struct pci_reg_property addrs[8];
463         int i, naddrs;
464         char name[32];
465         char *getprop = "getprop";
466
467         prom_print("Initializing fake screen: ");
468
469         memset(name, 0, sizeof(name));
470         call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
471         name[sizeof(name)-1] = 0;
472         prom_print(name);
473         prom_print("\n");
474         call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
475         call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
476         call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
477         pitch = width * ((depth + 7) / 8);
478         call_prom(getprop, 4, 1, dp, "linebytes",
479                   &pitch, sizeof(pitch));
480         if (pitch == 1)
481                 pitch = 0x1000;         /* for strange IBM display */
482         address = 0;
483         call_prom(getprop, 4, 1, dp, "address",
484                   &address, sizeof(address));
485         if (address == 0) {
486                 /* look for an assigned address with a size of >= 1MB */
487                 naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses",
488                                    addrs, sizeof(addrs));
489                 naddrs /= sizeof(struct pci_reg_property);
490                 for (i = 0; i < naddrs; ++i) {
491                         if (addrs[i].size_lo >= (1 << 20)) {
492                                 address = addrs[i].addr.a_lo;
493                                 /* use the BE aperture if possible */
494                                 if (addrs[i].size_lo >= (16 << 20))
495                                         address += (8 << 20);
496                                 break;
497                         }
498                 }
499                 if (address == 0) {
500                         prom_print("Failed to get address\n");
501                         return;
502                 }
503         }
504         /* kludge for valkyrie */
505         if (strcmp(name, "valkyrie") == 0)
506                 address += 0x1000;
507
508 #ifdef CONFIG_POWER4
509 #if CONFIG_TASK_SIZE > 0x80000000
510 #error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5
511 #endif
512         {
513                 extern boot_infos_t disp_bi;
514                 unsigned long va, pa, i, offset;
515                 va = 0x90000000;
516                 pa = address & 0xfffff000ul;
517                 offset = address & 0x00000fff;
518
519                 for (i=0; i<0x4000; i++) {  
520                         make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa, 
521                                  _PAGE_ACCESSED | _PAGE_NO_CACHE |
522                                  _PAGE_GUARDED | PP_RWXX);
523                         va += 0x1000;
524                         pa += 0x1000;
525                 }
526                 btext_setup_display(width, height, depth, pitch, 0x90000000 | offset);
527                 disp_bi.dispDeviceBase = (u8 *)address;
528         }
529 #else /* CONFIG_POWER4 */
530         btext_setup_display(width, height, depth, pitch, address);
531         btext_prepare_BAT();
532 #endif /* CONFIG_POWER4 */
533 #endif /* CONFIG_BOOTX_TEXT */
534 }
535
536 /*
537  * Make a copy of the device tree from the PROM.
538  */
539 static unsigned long __init
540 copy_device_tree(unsigned long mem_start, unsigned long mem_end)
541 {
542         phandle root;
543         unsigned long new_start;
544         struct device_node **allnextp;
545
546         root = call_prom("peer", 1, 1, (phandle)0);
547         if (root == (phandle)0) {
548                 prom_print("couldn't get device tree root\n");
549                 prom_exit();
550         }
551         allnextp = &allnodes;
552         mem_start = ALIGNUL(mem_start);
553         new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp);
554         *allnextp = NULL;
555         return new_start;
556 }
557
558 static unsigned long __init
559 inspect_node(phandle node, struct device_node *dad,
560              unsigned long mem_start, unsigned long mem_end,
561              struct device_node ***allnextpp)
562 {
563         int l;
564         phandle child;
565         struct device_node *np;
566         struct property *pp, **prev_propp;
567         char *prev_name, *namep;
568         unsigned char *valp;
569
570         np = (struct device_node *) mem_start;
571         mem_start += sizeof(struct device_node);
572         memset(np, 0, sizeof(*np));
573         np->node = node;
574         **allnextpp = PTRUNRELOC(np);
575         *allnextpp = &np->allnext;
576         if (dad != 0) {
577                 np->parent = PTRUNRELOC(dad);
578                 /* we temporarily use the `next' field as `last_child'. */
579                 if (dad->next == 0)
580                         dad->child = PTRUNRELOC(np);
581                 else
582                         dad->next->sibling = PTRUNRELOC(np);
583                 dad->next = np;
584         }
585
586         /* get and store all properties */
587         prev_propp = &np->properties;
588         prev_name = "";
589         for (;;) {
590                 pp = (struct property *) mem_start;
591                 namep = (char *) (pp + 1);
592                 pp->name = PTRUNRELOC(namep);
593                 if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0)
594                         break;
595                 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
596                 prev_name = namep;
597                 valp = (unsigned char *) mem_start;
598                 pp->value = PTRUNRELOC(valp);
599                 pp->length = call_prom("getprop", 4, 1, node, namep,
600                                        valp, mem_end - mem_start);
601                 if (pp->length < 0)
602                         continue;
603 #ifdef MAX_PROPERTY_LENGTH
604                 if (pp->length > MAX_PROPERTY_LENGTH)
605                         continue; /* ignore this property */
606 #endif
607                 mem_start = ALIGNUL(mem_start + pp->length);
608                 *prev_propp = PTRUNRELOC(pp);
609                 prev_propp = &pp->next;
610         }
611         if (np->node != 0) {
612                 /* Add a "linux,phandle" property" */
613                 pp = (struct property *) mem_start;
614                 *prev_propp = PTRUNRELOC(pp);
615                 prev_propp = &pp->next;
616                 namep = (char *) (pp + 1);
617                 pp->name = PTRUNRELOC(namep);
618                 strcpy(namep, "linux,phandle");
619                 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
620                 pp->value = (unsigned char *) PTRUNRELOC(&np->node);
621                 pp->length = sizeof(np->node);
622         }
623         *prev_propp = NULL;
624
625         /* get the node's full name */
626         l = call_prom("package-to-path", 3, 1, node,
627                       mem_start, mem_end - mem_start);
628         if (l >= 0) {
629                 np->full_name = PTRUNRELOC((char *) mem_start);
630                 *(char *)(mem_start + l) = 0;
631                 mem_start = ALIGNUL(mem_start + l + 1);
632         }
633
634         /* do all our children */
635         child = call_prom("child", 1, 1, node);
636         while (child != 0) {
637                 mem_start = inspect_node(child, np, mem_start, mem_end,
638                                          allnextpp);
639                 child = call_prom("peer", 1, 1, child);
640         }
641
642         return mem_start;
643 }
644
645 unsigned long smp_chrp_cpu_nr __initdata = 0;
646
647 /*
648  * With CHRP SMP we need to use the OF to start the other
649  * processors so we can't wait until smp_boot_cpus (the OF is
650  * trashed by then) so we have to put the processors into
651  * a holding pattern controlled by the kernel (not OF) before
652  * we destroy the OF.
653  *
654  * This uses a chunk of high memory, puts some holding pattern
655  * code there and sends the other processors off to there until
656  * smp_boot_cpus tells them to do something.  We do that by using
657  * physical address 0x0.  The holding pattern checks that address
658  * until its cpu # is there, when it is that cpu jumps to
659  * __secondary_start().  smp_boot_cpus() takes care of setting those
660  * values.
661  *
662  * We also use physical address 0x4 here to tell when a cpu
663  * is in its holding pattern code.
664  *
665  * -- Cort
666  *
667  * Note that we have to do this if we have more than one CPU,
668  * even if this is a UP kernel.  Otherwise when we trash OF
669  * the other CPUs will start executing some random instructions
670  * and crash the system.  -- paulus
671  */
672 static void __init
673 prom_hold_cpus(unsigned long mem)
674 {
675         extern void __secondary_hold(void);
676         unsigned long i;
677         int cpu;
678         phandle node;
679         char type[16], *path;
680         unsigned int reg;
681
682         /*
683          * XXX: hack to make sure we're chrp, assume that if we're
684          *      chrp we have a device_type property -- Cort
685          */
686         node = call_prom("finddevice", 1, 1, "/");
687         if (call_prom("getprop", 4, 1, node,
688                       "device_type", type, sizeof(type)) <= 0)
689                 return;
690
691         /* copy the holding pattern code to someplace safe (0) */
692         /* the holding pattern is now within the first 0x100
693            bytes of the kernel image -- paulus */
694         memcpy((void *)0, _stext, 0x100);
695         flush_icache_range(0, 0x100);
696
697         /* look for cpus */
698         *(unsigned long *)(0x0) = 0;
699         asm volatile("dcbf 0,%0": : "r" (0) : "memory");
700         for (node = 0; prom_next_node(&node); ) {
701                 type[0] = 0;
702                 call_prom("getprop", 4, 1, node, "device_type",
703                           type, sizeof(type));
704                 if (strcmp(type, "cpu") != 0)
705                         continue;
706                 path = (char *) mem;
707                 memset(path, 0, 256);
708                 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
709                         continue;
710                 reg = -1;
711                 call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
712                 cpu = smp_chrp_cpu_nr++;
713 #ifdef CONFIG_SMP
714                 smp_hw_index[cpu] = reg;
715 #endif /* CONFIG_SMP */
716                 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
717                 if (cpu == 0)
718                         continue;
719                 prom_print("starting cpu ");
720                 prom_print(path);
721                 *(ulong *)(0x4) = 0;
722                 call_prom("start-cpu", 3, 0, node,
723                           (char *)__secondary_hold - _stext, cpu);
724                 prom_print("...");
725                 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
726                         ;
727                 if (*(ulong *)(0x4) == cpu)
728                         prom_print("ok\n");
729                 else {
730                         prom_print("failed: ");
731                         prom_print_hex(*(ulong *)0x4);
732                         prom_print("\n");
733                 }
734         }
735 }
736
737 static void __init
738 prom_instantiate_rtas(void)
739 {
740         ihandle prom_rtas;
741         prom_arg_t result;
742
743         prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
744         if (prom_rtas == -1)
745                 return;
746
747         rtas_size = 0;
748         call_prom("getprop", 4, 1, prom_rtas,
749                   "rtas-size", &rtas_size, sizeof(rtas_size));
750         prom_print("instantiating rtas");
751         if (rtas_size == 0) {
752                 rtas_data = 0;
753         } else {
754                 /*
755                  * Ask OF for some space for RTAS.
756                  * Actually OF has bugs so we just arbitrarily
757                  * use memory at the 6MB point.
758                  */
759                 rtas_data = 6 << 20;
760                 prom_print(" at ");
761                 prom_print_hex(rtas_data);
762         }
763
764         prom_rtas = call_prom("open", 1, 1, "/rtas");
765         prom_print("...");
766         rtas_entry = 0;
767         if (call_prom_ret("call-method", 3, 2, &result,
768                           "instantiate-rtas", prom_rtas, rtas_data) == 0)
769                 rtas_entry = result;
770         if ((rtas_entry == -1) || (rtas_entry == 0))
771                 prom_print(" failed\n");
772         else
773                 prom_print(" done\n");
774 }
775
776 /*
777  * We enter here early on, when the Open Firmware prom is still
778  * handling exceptions and the MMU hash table for us.
779  */
780 unsigned long __init
781 prom_init(int r3, int r4, prom_entry pp)
782 {
783         unsigned long mem;
784         ihandle prom_mmu;
785         unsigned long offset = reloc_offset();
786         int i, l;
787         char *p, *d;
788         unsigned long phys;
789         prom_arg_t result[3];
790         char model[32];
791         phandle node;
792         int rc;
793
794         /* Default */
795         phys = (unsigned long) &_stext;
796
797         /* First get a handle for the stdout device */
798         prom = pp;
799         prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
800         if (prom_chosen == -1)
801                 prom_exit();
802         if (call_prom("getprop", 4, 1, prom_chosen, "stdout",
803                       &prom_stdout, sizeof(prom_stdout)) <= 0)
804                 prom_exit();
805
806         /* Get the full OF pathname of the stdout device */
807         mem = (unsigned long) klimit + offset;
808         p = (char *) mem;
809         memset(p, 0, 256);
810         call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
811         of_stdout_device = p;
812         mem += strlen(p) + 1;
813
814         /* Get the boot device and translate it to a full OF pathname. */
815         p = (char *) mem;
816         l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20);
817         if (l > 0) {
818                 p[l] = 0;       /* should already be null-terminated */
819                 bootpath = PTRUNRELOC(p);
820                 mem += l + 1;
821                 d = (char *) mem;
822                 *d = 0;
823                 call_prom("canon", 3, 1, p, d, 1<<20);
824                 bootdevice = PTRUNRELOC(d);
825                 mem = ALIGNUL(mem + strlen(d) + 1);
826         }
827
828         prom_instantiate_rtas();
829
830 #ifdef CONFIG_POWER4
831         /*
832          * Find out how much memory we have and allocate a
833          * suitably-sized hash table.
834          */
835         prom_alloc_htab();
836 #endif
837         mem = check_display(mem);
838
839         prom_print("copying OF device tree...");
840         mem = copy_device_tree(mem, mem + (1<<20));
841         prom_print("done\n");
842
843         prom_hold_cpus(mem);
844
845         klimit = (char *) (mem - offset);
846
847         node = call_prom("finddevice", 1, 1, "/");
848         rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
849         if (rc > 0 && !strncmp (model, "Pegasos", 7)
850                 && strncmp (model, "Pegasos2", 8)) {
851                 /* Pegasos 1 has a broken translate method in the OF,
852                  * and furthermore the BATs are mapped 1:1 so the phys
853                  * address calculated above is correct, so let's use
854                  * it directly.
855                  */
856         } else if (offset == 0) {
857                 /* If we are already running at 0xc0000000, we assume we were
858                  * loaded by an OF bootloader which did set a BAT for us.
859                  * This breaks OF translate so we force phys to be 0.
860                  */
861                 prom_print("(already at 0xc0000000) phys=0\n");
862                 phys = 0;
863         } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu",
864                              &prom_mmu, sizeof(prom_mmu)) <= 0) {
865                 prom_print(" no MMU found\n");
866         } else if (call_prom_ret("call-method", 4, 4, result, "translate",
867                                  prom_mmu, &_stext, 1) != 0) {
868                 prom_print(" (translate failed)\n");
869         } else {
870                 /* We assume the phys. address size is 3 cells */
871                 phys = result[2];
872         }
873
874         if (prom_disp_node != 0)
875                 setup_disp_fake_bi(prom_disp_node);
876
877         /* Use quiesce call to get OF to shut down any devices it's using */
878         prom_print("Calling quiesce ...\n");
879         call_prom("quiesce", 0, 0);
880
881         /* Relocate various pointers which will be used once the
882            kernel is running at the address it was linked at. */
883         for (i = 0; i < prom_num_displays; ++i)
884                 prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
885
886 #ifdef CONFIG_SERIAL_CORE_CONSOLE
887         /* Relocate the of stdout for console autodetection */
888         of_stdout_device = PTRUNRELOC(of_stdout_device);
889 #endif
890
891         prom_print("returning 0x");
892         prom_print_hex(phys);
893         prom_print("from prom_init\n");
894         prom_stdout = 0;
895
896         return phys;
897 }
898
899 /*
900  * early_get_property is used to access the device tree image prepared
901  * by BootX very early on, before the pointers in it have been relocated.
902  */
903 static void * __init
904 early_get_property(unsigned long base, unsigned long node, char *prop)
905 {
906         struct device_node *np = (struct device_node *)(base + node);
907         struct property *pp;
908
909         for (pp = np->properties; pp != 0; pp = pp->next) {
910                 pp = (struct property *) (base + (unsigned long)pp);
911                 if (strcmp((char *)((unsigned long)pp->name + base),
912                            prop) == 0) {
913                         return (void *)((unsigned long)pp->value + base);
914                 }
915         }
916         return NULL;
917 }
918
919 /* Is boot-info compatible ? */
920 #define BOOT_INFO_IS_COMPATIBLE(bi)             ((bi)->compatible_version <= BOOT_INFO_VERSION)
921 #define BOOT_INFO_IS_V2_COMPATIBLE(bi)  ((bi)->version >= 2)
922 #define BOOT_INFO_IS_V4_COMPATIBLE(bi)  ((bi)->version >= 4)
923
924 void __init
925 bootx_init(unsigned long r4, unsigned long phys)
926 {
927         boot_infos_t *bi = (boot_infos_t *) r4;
928         unsigned long space;
929         unsigned long ptr, x;
930         char *model;
931
932         boot_infos = PTRUNRELOC(bi);
933         if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
934                 bi->logicalDisplayBase = NULL;
935
936 #ifdef CONFIG_BOOTX_TEXT
937         btext_init(bi);
938
939         /*
940          * Test if boot-info is compatible.  Done only in config
941          * CONFIG_BOOTX_TEXT since there is nothing much we can do
942          * with an incompatible version, except display a message
943          * and eventually hang the processor...
944          *
945          * I'll try to keep enough of boot-info compatible in the
946          * future to always allow display of this message;
947          */
948         if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
949                 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
950                 btext_flushscreen();
951         }
952 #endif  /* CONFIG_BOOTX_TEXT */
953
954         /* New BootX enters kernel with MMU off, i/os are not allowed
955            here. This hack will have been done by the boostrap anyway.
956         */
957         if (bi->version < 4) {
958                 /*
959                  * XXX If this is an iMac, turn off the USB controller.
960                  */
961                 model = (char *) early_get_property
962                         (r4 + bi->deviceTreeOffset, 4, "model");
963                 if (model
964                     && (strcmp(model, "iMac,1") == 0
965                         || strcmp(model, "PowerMac1,1") == 0)) {
966                         out_le32((unsigned *)0x80880008, 1);    /* XXX */
967                 }
968         }
969
970         /* Move klimit to enclose device tree, args, ramdisk, etc... */
971         if (bi->version < 5) {
972                 space = bi->deviceTreeOffset + bi->deviceTreeSize;
973                 if (bi->ramDisk)
974                         space = bi->ramDisk + bi->ramDiskSize;
975         } else
976                 space = bi->totalParamsSize;
977         klimit = PTRUNRELOC((char *) bi + space);
978
979         /* New BootX will have flushed all TLBs and enters kernel with
980            MMU switched OFF, so this should not be useful anymore.
981         */
982         if (bi->version < 4) {
983                 /*
984                  * Touch each page to make sure the PTEs for them
985                  * are in the hash table - the aim is to try to avoid
986                  * getting DSI exceptions while copying the kernel image.
987                  */
988                 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
989                      ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
990                         x = *(volatile unsigned long *)ptr;
991         }
992
993 #ifdef CONFIG_BOOTX_TEXT
994         /*
995          * Note that after we call btext_prepare_BAT, we can't do
996          * prom_draw*, flushscreen or clearscreen until we turn the MMU
997          * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
998          * to a virtual address.
999          */
1000         btext_prepare_BAT();
1001 #endif
1002 }