Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / ppc / syslib / prom_init.c
blob2cee87137f2efa9b6efff2d25aff5c1915061464
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 np->full_name = PTRUNRELOC((char *) mem_start);
630 *(char *)(mem_start + l) = 0;
631 mem_start = ALIGNUL(mem_start + l + 1);
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);
642 return mem_start;
645 unsigned long smp_chrp_cpu_nr __initdata = 0;
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.
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.
662 * We also use physical address 0x4 here to tell when a cpu
663 * is in its holding pattern code.
665 * -- Cort
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
672 static void __init
673 prom_hold_cpus(unsigned long mem)
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;
683 * XXX: hack to make sure we're chrp, assume that if we're
684 * chrp we have a device_type property -- Cort
686 node = call_prom("finddevice", 1, 1, "/");
687 if (call_prom("getprop", 4, 1, node,
688 "device_type", type, sizeof(type)) <= 0)
689 return;
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);
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++ )
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");
737 static void __init
738 prom_instantiate_rtas(void)
740 ihandle prom_rtas;
741 prom_arg_t result;
743 prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
744 if (prom_rtas == -1)
745 return;
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 {
755 * Ask OF for some space for RTAS.
756 * Actually OF has bugs so we just arbitrarily
757 * use memory at the 6MB point.
759 rtas_data = 6 << 20;
760 prom_print(" at ");
761 prom_print_hex(rtas_data);
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");
777 * We enter here early on, when the Open Firmware prom is still
778 * handling exceptions and the MMU hash table for us.
780 unsigned long __init
781 prom_init(int r3, int r4, prom_entry pp)
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;
794 /* Default */
795 phys = (unsigned long) &_stext;
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();
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;
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);
828 prom_instantiate_rtas();
830 #ifdef CONFIG_POWER4
832 * Find out how much memory we have and allocate a
833 * suitably-sized hash table.
835 prom_alloc_htab();
836 #endif
837 mem = check_display(mem);
839 prom_print("copying OF device tree...");
840 mem = copy_device_tree(mem, mem + (1<<20));
841 prom_print("done\n");
843 prom_hold_cpus(mem);
845 klimit = (char *) (mem - offset);
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.
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.
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];
874 if (prom_disp_node != 0)
875 setup_disp_fake_bi(prom_disp_node);
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);
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]);
886 #ifdef CONFIG_SERIAL_CORE_CONSOLE
887 /* Relocate the of stdout for console autodetection */
888 of_stdout_device = PTRUNRELOC(of_stdout_device);
889 #endif
891 prom_print("returning 0x");
892 prom_print_hex(phys);
893 prom_print("from prom_init\n");
894 prom_stdout = 0;
896 return phys;
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.
903 static void * __init
904 early_get_property(unsigned long base, unsigned long node, char *prop)
906 struct device_node *np = (struct device_node *)(base + node);
907 struct property *pp;
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);
916 return NULL;
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)
924 void __init
925 bootx_init(unsigned long r4, unsigned long phys)
927 boot_infos_t *bi = (boot_infos_t *) r4;
928 unsigned long space;
929 unsigned long ptr, x;
930 char *model;
932 boot_infos = PTRUNRELOC(bi);
933 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
934 bi->logicalDisplayBase = NULL;
936 #ifdef CONFIG_BOOTX_TEXT
937 btext_init(bi);
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...
945 * I'll try to keep enough of boot-info compatible in the
946 * future to always allow display of this message;
948 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
949 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
950 btext_flushscreen();
952 #endif /* CONFIG_BOOTX_TEXT */
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.
957 if (bi->version < 4) {
959 * XXX If this is an iMac, turn off the USB controller.
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 */
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);
979 /* New BootX will have flushed all TLBs and enters kernel with
980 MMU switched OFF, so this should not be useful anymore.
982 if (bi->version < 4) {
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.
988 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
989 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
990 x = *(volatile unsigned long *)ptr;
993 #ifdef CONFIG_BOOTX_TEXT
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.
1000 btext_prepare_BAT();
1001 #endif