vserver 2.0 rc7
[linux-2.6.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                 char *p, *ep;
630
631                 np->full_name = PTRUNRELOC((char *) mem_start);
632                 *(char *)(mem_start + l) = 0;
633                 /* Fixup an Apple bug where they have bogus \0 chars in the
634                  * middle of the path in some properties
635                  */
636                 for (p = (char *)mem_start, ep = p + l; p < ep; p++)
637                         if ((*p) == '\0') {
638                                 memmove(p, p+1, ep - p);
639                                 ep--;
640                         }
641                 mem_start = ALIGNUL(mem_start + l + 1);
642         }
643
644         /* do all our children */
645         child = call_prom("child", 1, 1, node);
646         while (child != 0) {
647                 mem_start = inspect_node(child, np, mem_start, mem_end,
648                                          allnextpp);
649                 child = call_prom("peer", 1, 1, child);
650         }
651
652         return mem_start;
653 }
654
655 unsigned long smp_chrp_cpu_nr __initdata = 0;
656
657 /*
658  * With CHRP SMP we need to use the OF to start the other
659  * processors so we can't wait until smp_boot_cpus (the OF is
660  * trashed by then) so we have to put the processors into
661  * a holding pattern controlled by the kernel (not OF) before
662  * we destroy the OF.
663  *
664  * This uses a chunk of high memory, puts some holding pattern
665  * code there and sends the other processors off to there until
666  * smp_boot_cpus tells them to do something.  We do that by using
667  * physical address 0x0.  The holding pattern checks that address
668  * until its cpu # is there, when it is that cpu jumps to
669  * __secondary_start().  smp_boot_cpus() takes care of setting those
670  * values.
671  *
672  * We also use physical address 0x4 here to tell when a cpu
673  * is in its holding pattern code.
674  *
675  * -- Cort
676  *
677  * Note that we have to do this if we have more than one CPU,
678  * even if this is a UP kernel.  Otherwise when we trash OF
679  * the other CPUs will start executing some random instructions
680  * and crash the system.  -- paulus
681  */
682 static void __init
683 prom_hold_cpus(unsigned long mem)
684 {
685         extern void __secondary_hold(void);
686         unsigned long i;
687         int cpu;
688         phandle node;
689         char type[16], *path;
690         unsigned int reg;
691
692         /*
693          * XXX: hack to make sure we're chrp, assume that if we're
694          *      chrp we have a device_type property -- Cort
695          */
696         node = call_prom("finddevice", 1, 1, "/");
697         if (call_prom("getprop", 4, 1, node,
698                       "device_type", type, sizeof(type)) <= 0)
699                 return;
700
701         /* copy the holding pattern code to someplace safe (0) */
702         /* the holding pattern is now within the first 0x100
703            bytes of the kernel image -- paulus */
704         memcpy((void *)0, _stext, 0x100);
705         flush_icache_range(0, 0x100);
706
707         /* look for cpus */
708         *(unsigned long *)(0x0) = 0;
709         asm volatile("dcbf 0,%0": : "r" (0) : "memory");
710         for (node = 0; prom_next_node(&node); ) {
711                 type[0] = 0;
712                 call_prom("getprop", 4, 1, node, "device_type",
713                           type, sizeof(type));
714                 if (strcmp(type, "cpu") != 0)
715                         continue;
716                 path = (char *) mem;
717                 memset(path, 0, 256);
718                 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
719                         continue;
720                 reg = -1;
721                 call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
722                 cpu = smp_chrp_cpu_nr++;
723 #ifdef CONFIG_SMP
724                 smp_hw_index[cpu] = reg;
725 #endif /* CONFIG_SMP */
726                 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
727                 if (cpu == 0)
728                         continue;
729                 prom_print("starting cpu ");
730                 prom_print(path);
731                 *(ulong *)(0x4) = 0;
732                 call_prom("start-cpu", 3, 0, node,
733                           (char *)__secondary_hold - _stext, cpu);
734                 prom_print("...");
735                 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
736                         ;
737                 if (*(ulong *)(0x4) == cpu)
738                         prom_print("ok\n");
739                 else {
740                         prom_print("failed: ");
741                         prom_print_hex(*(ulong *)0x4);
742                         prom_print("\n");
743                 }
744         }
745 }
746
747 static void __init
748 prom_instantiate_rtas(void)
749 {
750         ihandle prom_rtas;
751         prom_arg_t result;
752
753         prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
754         if (prom_rtas == -1)
755                 return;
756
757         rtas_size = 0;
758         call_prom("getprop", 4, 1, prom_rtas,
759                   "rtas-size", &rtas_size, sizeof(rtas_size));
760         prom_print("instantiating rtas");
761         if (rtas_size == 0) {
762                 rtas_data = 0;
763         } else {
764                 /*
765                  * Ask OF for some space for RTAS.
766                  * Actually OF has bugs so we just arbitrarily
767                  * use memory at the 6MB point.
768                  */
769                 rtas_data = 6 << 20;
770                 prom_print(" at ");
771                 prom_print_hex(rtas_data);
772         }
773
774         prom_rtas = call_prom("open", 1, 1, "/rtas");
775         prom_print("...");
776         rtas_entry = 0;
777         if (call_prom_ret("call-method", 3, 2, &result,
778                           "instantiate-rtas", prom_rtas, rtas_data) == 0)
779                 rtas_entry = result;
780         if ((rtas_entry == -1) || (rtas_entry == 0))
781                 prom_print(" failed\n");
782         else
783                 prom_print(" done\n");
784 }
785
786 /*
787  * We enter here early on, when the Open Firmware prom is still
788  * handling exceptions and the MMU hash table for us.
789  */
790 unsigned long __init
791 prom_init(int r3, int r4, prom_entry pp)
792 {
793         unsigned long mem;
794         ihandle prom_mmu;
795         unsigned long offset = reloc_offset();
796         int i, l;
797         char *p, *d;
798         unsigned long phys;
799         prom_arg_t result[3];
800         char model[32];
801         phandle node;
802         int rc;
803
804         /* Default */
805         phys = (unsigned long) &_stext;
806
807         /* First get a handle for the stdout device */
808         prom = pp;
809         prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
810         if (prom_chosen == -1)
811                 prom_exit();
812         if (call_prom("getprop", 4, 1, prom_chosen, "stdout",
813                       &prom_stdout, sizeof(prom_stdout)) <= 0)
814                 prom_exit();
815
816         /* Get the full OF pathname of the stdout device */
817         mem = (unsigned long) klimit + offset;
818         p = (char *) mem;
819         memset(p, 0, 256);
820         call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
821         of_stdout_device = p;
822         mem += strlen(p) + 1;
823
824         /* Get the boot device and translate it to a full OF pathname. */
825         p = (char *) mem;
826         l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20);
827         if (l > 0) {
828                 p[l] = 0;       /* should already be null-terminated */
829                 bootpath = PTRUNRELOC(p);
830                 mem += l + 1;
831                 d = (char *) mem;
832                 *d = 0;
833                 call_prom("canon", 3, 1, p, d, 1<<20);
834                 bootdevice = PTRUNRELOC(d);
835                 mem = ALIGNUL(mem + strlen(d) + 1);
836         }
837
838         prom_instantiate_rtas();
839
840 #ifdef CONFIG_POWER4
841         /*
842          * Find out how much memory we have and allocate a
843          * suitably-sized hash table.
844          */
845         prom_alloc_htab();
846 #endif
847         mem = check_display(mem);
848
849         prom_print("copying OF device tree...");
850         mem = copy_device_tree(mem, mem + (1<<20));
851         prom_print("done\n");
852
853         prom_hold_cpus(mem);
854
855         klimit = (char *) (mem - offset);
856
857         node = call_prom("finddevice", 1, 1, "/");
858         rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
859         if (rc > 0 && !strncmp (model, "Pegasos", 7)
860                 && strncmp (model, "Pegasos2", 8)) {
861                 /* Pegasos 1 has a broken translate method in the OF,
862                  * and furthermore the BATs are mapped 1:1 so the phys
863                  * address calculated above is correct, so let's use
864                  * it directly.
865                  */
866         } else if (offset == 0) {
867                 /* If we are already running at 0xc0000000, we assume we were
868                  * loaded by an OF bootloader which did set a BAT for us.
869                  * This breaks OF translate so we force phys to be 0.
870                  */
871                 prom_print("(already at 0xc0000000) phys=0\n");
872                 phys = 0;
873         } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu",
874                              &prom_mmu, sizeof(prom_mmu)) <= 0) {
875                 prom_print(" no MMU found\n");
876         } else if (call_prom_ret("call-method", 4, 4, result, "translate",
877                                  prom_mmu, &_stext, 1) != 0) {
878                 prom_print(" (translate failed)\n");
879         } else {
880                 /* We assume the phys. address size is 3 cells */
881                 phys = result[2];
882         }
883
884         if (prom_disp_node != 0)
885                 setup_disp_fake_bi(prom_disp_node);
886
887         /* Use quiesce call to get OF to shut down any devices it's using */
888         prom_print("Calling quiesce ...\n");
889         call_prom("quiesce", 0, 0);
890
891         /* Relocate various pointers which will be used once the
892            kernel is running at the address it was linked at. */
893         for (i = 0; i < prom_num_displays; ++i)
894                 prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
895
896 #ifdef CONFIG_SERIAL_CORE_CONSOLE
897         /* Relocate the of stdout for console autodetection */
898         of_stdout_device = PTRUNRELOC(of_stdout_device);
899 #endif
900
901         prom_print("returning 0x");
902         prom_print_hex(phys);
903         prom_print("from prom_init\n");
904         prom_stdout = 0;
905
906         return phys;
907 }
908
909 /*
910  * early_get_property is used to access the device tree image prepared
911  * by BootX very early on, before the pointers in it have been relocated.
912  */
913 static void * __init
914 early_get_property(unsigned long base, unsigned long node, char *prop)
915 {
916         struct device_node *np = (struct device_node *)(base + node);
917         struct property *pp;
918
919         for (pp = np->properties; pp != 0; pp = pp->next) {
920                 pp = (struct property *) (base + (unsigned long)pp);
921                 if (strcmp((char *)((unsigned long)pp->name + base),
922                            prop) == 0) {
923                         return (void *)((unsigned long)pp->value + base);
924                 }
925         }
926         return NULL;
927 }
928
929 /* Is boot-info compatible ? */
930 #define BOOT_INFO_IS_COMPATIBLE(bi)             ((bi)->compatible_version <= BOOT_INFO_VERSION)
931 #define BOOT_INFO_IS_V2_COMPATIBLE(bi)  ((bi)->version >= 2)
932 #define BOOT_INFO_IS_V4_COMPATIBLE(bi)  ((bi)->version >= 4)
933
934 void __init
935 bootx_init(unsigned long r4, unsigned long phys)
936 {
937         boot_infos_t *bi = (boot_infos_t *) r4;
938         unsigned long space;
939         unsigned long ptr, x;
940         char *model;
941
942         boot_infos = PTRUNRELOC(bi);
943         if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
944                 bi->logicalDisplayBase = NULL;
945
946 #ifdef CONFIG_BOOTX_TEXT
947         btext_init(bi);
948
949         /*
950          * Test if boot-info is compatible.  Done only in config
951          * CONFIG_BOOTX_TEXT since there is nothing much we can do
952          * with an incompatible version, except display a message
953          * and eventually hang the processor...
954          *
955          * I'll try to keep enough of boot-info compatible in the
956          * future to always allow display of this message;
957          */
958         if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
959                 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
960                 btext_flushscreen();
961         }
962 #endif  /* CONFIG_BOOTX_TEXT */
963
964         /* New BootX enters kernel with MMU off, i/os are not allowed
965            here. This hack will have been done by the boostrap anyway.
966         */
967         if (bi->version < 4) {
968                 /*
969                  * XXX If this is an iMac, turn off the USB controller.
970                  */
971                 model = (char *) early_get_property
972                         (r4 + bi->deviceTreeOffset, 4, "model");
973                 if (model
974                     && (strcmp(model, "iMac,1") == 0
975                         || strcmp(model, "PowerMac1,1") == 0)) {
976                         out_le32((unsigned *)0x80880008, 1);    /* XXX */
977                 }
978         }
979
980         /* Move klimit to enclose device tree, args, ramdisk, etc... */
981         if (bi->version < 5) {
982                 space = bi->deviceTreeOffset + bi->deviceTreeSize;
983                 if (bi->ramDisk)
984                         space = bi->ramDisk + bi->ramDiskSize;
985         } else
986                 space = bi->totalParamsSize;
987         klimit = PTRUNRELOC((char *) bi + space);
988
989         /* New BootX will have flushed all TLBs and enters kernel with
990            MMU switched OFF, so this should not be useful anymore.
991         */
992         if (bi->version < 4) {
993                 /*
994                  * Touch each page to make sure the PTEs for them
995                  * are in the hash table - the aim is to try to avoid
996                  * getting DSI exceptions while copying the kernel image.
997                  */
998                 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
999                      ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
1000                         x = *(volatile unsigned long *)ptr;
1001         }
1002
1003 #ifdef CONFIG_BOOTX_TEXT
1004         /*
1005          * Note that after we call btext_prepare_BAT, we can't do
1006          * prom_draw*, flushscreen or clearscreen until we turn the MMU
1007          * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
1008          * to a virtual address.
1009          */
1010         btext_prepare_BAT();
1011 #endif
1012 }