NFS: Ensure that nfs_link() instantiates the dentry correctly
[linux-2.6/mini2440.git] / arch / ppc / syslib / prom_init.c
blob7f15136830f4fbf38fe38e3a5418e85e51e47b96
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 */
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>
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>
36 #ifdef CONFIG_LOGO_LINUX_CLUT224
37 #include <linux/linux_logo.h>
38 extern const struct linux_logo logo_linux_clut224;
39 #endif
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.
48 #define MAX_PROPERTY_LENGTH 4096
50 #ifndef FB_MAX /* avoid pulling in all of the fb stuff */
51 #define FB_MAX 8
52 #endif
54 #define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
56 typedef u32 prom_arg_t;
58 struct prom_args {
59 const char *service;
60 int nargs;
61 int nret;
62 prom_arg_t args[10];
65 struct pci_address {
66 unsigned a_hi;
67 unsigned a_mid;
68 unsigned a_lo;
71 struct pci_reg_property {
72 struct pci_address addr;
73 unsigned size_hi;
74 unsigned size_lo;
77 struct pci_range {
78 struct pci_address addr;
79 unsigned phys;
80 unsigned size_hi;
81 unsigned size_lo;
84 struct isa_reg_property {
85 unsigned space;
86 unsigned address;
87 unsigned size;
90 struct pci_intr_map {
91 struct pci_address addr;
92 unsigned dunno;
93 phandle int_ctrler;
94 unsigned intr;
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);
116 prom_entry prom __initdata;
117 ihandle prom_chosen __initdata;
118 ihandle prom_stdout __initdata;
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;
126 unsigned int rtas_data; /* physical pointer */
127 unsigned int rtas_entry; /* physical pointer */
128 unsigned int rtas_size;
129 unsigned int old_rtas;
131 boot_infos_t *boot_infos;
132 char *bootpath;
133 char *bootdevice;
134 struct device_node *allnodes;
136 extern char *klimit;
138 static void __init
139 prom_exit(void)
141 struct prom_args args;
143 args.service = "exit";
144 args.nargs = 0;
145 args.nret = 0;
146 prom(&args);
147 for (;;) /* should never get here */
151 static int __init
152 call_prom(const char *service, int nargs, int nret, ...)
154 va_list list;
155 int i;
156 struct prom_args prom_args;
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];
171 static int __init
172 call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...)
174 va_list list;
175 int i;
176 struct prom_args prom_args;
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];
193 void __init
194 prom_print(const char *msg)
196 const char *p, *q;
198 if (prom_stdout == 0)
199 return;
201 for (p = msg; *p != 0; p = q) {
202 for (q = p; *q != 0 && *q != '\n'; ++q)
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);
213 static void __init
214 prom_print_hex(unsigned int v)
216 char buf[16];
217 int i, c;
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;
224 buf[i] = ' ';
225 buf[i+1] = 0;
226 prom_print(buf);
229 static int __init
230 prom_set_color(ihandle ih, int i, int r, int g, int b)
232 return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r);
235 static int __init
236 prom_next_node(phandle *nodep)
238 phandle node;
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;
253 #ifdef CONFIG_POWER4
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.
260 static inline void make_pte(unsigned long htab, unsigned int hsize,
261 unsigned int va, unsigned int pa, int mode)
263 unsigned int *pteg;
264 unsigned int hash, i, vsid;
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;
278 extern unsigned long _SDR1;
279 extern PTE *Hash;
280 extern unsigned long Hash_size;
282 static void __init
283 prom_alloc_htab(void)
285 unsigned int hsize;
286 unsigned long htab;
287 unsigned int addr;
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.
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;
307 * Put in PTEs for the first 64MB of RAM
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
318 #endif /* CONFIG_POWER4 */
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.
329 static unsigned long __init
330 check_display(unsigned long mem)
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
354 const unsigned char *clut;
356 prom_disp_node = 0;
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;
371 * If this display is the device that OF is using for stdout,
372 * move it to the front of the list.
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];
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;
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];
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);
416 * Setup a usable color table when the appropriate
417 * method is available.
418 * Should update this to use set-colors.
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;
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 */
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);
450 return ALIGNUL(mem);
453 /* This function will enable the early boot text when doing OF booting. This
454 * way, xmon output should work too
456 static void __init
457 setup_disp_fake_bi(ihandle dp)
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";
467 prom_print("Initializing fake screen: ");
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;
499 if (address == 0) {
500 prom_print("Failed to get address\n");
501 return;
504 /* kludge for valkyrie */
505 if (strcmp(name, "valkyrie") == 0)
506 address += 0x1000;
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
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;
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;
526 btext_setup_display(width, height, depth, pitch, 0x90000000 | offset);
527 disp_bi.dispDeviceBase = (u8 *)address;
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 */
537 * Make a copy of the device tree from the PROM.
539 static unsigned long __init
540 copy_device_tree(unsigned long mem_start, unsigned long mem_end)
542 phandle root;
543 unsigned long new_start;
544 struct device_node **allnextp;
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();
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;
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)
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;
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;
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;
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);
623 *prev_propp = NULL;
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;
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
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--;
641 mem_start = ALIGNUL(mem_start + l + 1);
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);
652 return mem_start;
655 unsigned long smp_chrp_cpu_nr __initdata = 0;
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.
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.
672 * We also use physical address 0x4 here to tell when a cpu
673 * is in its holding pattern code.
675 * -- Cort
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
682 static void __init
683 prom_hold_cpus(unsigned long mem)
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;
693 * XXX: hack to make sure we're chrp, assume that if we're
694 * chrp we have a device_type property -- Cort
696 node = call_prom("finddevice", 1, 1, "/");
697 if (call_prom("getprop", 4, 1, node,
698 "device_type", type, sizeof(type)) <= 0)
699 return;
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);
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++ )
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");
747 static void __init
748 prom_instantiate_rtas(void)
750 ihandle prom_rtas;
751 prom_arg_t result;
753 prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
754 if (prom_rtas == -1)
755 return;
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 {
765 * Ask OF for some space for RTAS.
766 * Actually OF has bugs so we just arbitrarily
767 * use memory at the 6MB point.
769 rtas_data = 6 << 20;
770 prom_print(" at ");
771 prom_print_hex(rtas_data);
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");
787 * We enter here early on, when the Open Firmware prom is still
788 * handling exceptions and the MMU hash table for us.
790 unsigned long __init
791 prom_init(int r3, int r4, prom_entry pp)
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;
804 /* Default */
805 phys = (unsigned long) &_stext;
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();
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;
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);
838 prom_instantiate_rtas();
840 #ifdef CONFIG_POWER4
842 * Find out how much memory we have and allocate a
843 * suitably-sized hash table.
845 prom_alloc_htab();
846 #endif
847 mem = check_display(mem);
849 prom_print("copying OF device tree...");
850 mem = copy_device_tree(mem, mem + (1<<20));
851 prom_print("done\n");
853 prom_hold_cpus(mem);
855 klimit = (char *) (mem - offset);
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.
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.
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];
884 if (prom_disp_node != 0)
885 setup_disp_fake_bi(prom_disp_node);
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);
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]);
896 #ifdef CONFIG_SERIAL_CORE_CONSOLE
897 /* Relocate the of stdout for console autodetection */
898 of_stdout_device = PTRUNRELOC(of_stdout_device);
899 #endif
901 prom_print("returning 0x");
902 prom_print_hex(phys);
903 prom_print("from prom_init\n");
904 prom_stdout = 0;
906 return phys;
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.
913 static void * __init
914 early_get_property(unsigned long base, unsigned long node, char *prop)
916 struct device_node *np = (struct device_node *)(base + node);
917 struct property *pp;
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);
926 return NULL;
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)
934 void __init
935 bootx_init(unsigned long r4, unsigned long phys)
937 boot_infos_t *bi = (boot_infos_t *) r4;
938 unsigned long space;
939 unsigned long ptr, x;
940 char *model;
942 boot_infos = PTRUNRELOC(bi);
943 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
944 bi->logicalDisplayBase = NULL;
946 #ifdef CONFIG_BOOTX_TEXT
947 btext_init(bi);
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...
955 * I'll try to keep enough of boot-info compatible in the
956 * future to always allow display of this message;
958 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
959 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
960 btext_flushscreen();
962 #endif /* CONFIG_BOOTX_TEXT */
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.
967 if (bi->version < 4) {
969 * XXX If this is an iMac, turn off the USB controller.
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 */
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);
989 /* New BootX will have flushed all TLBs and enters kernel with
990 MMU switched OFF, so this should not be useful anymore.
992 if (bi->version < 4) {
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.
998 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
999 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
1000 x = *(volatile unsigned long *)ptr;
1003 #ifdef CONFIG_BOOTX_TEXT
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.
1010 btext_prepare_BAT();
1011 #endif