blob: 2cee87137f2efa9b6efff2d25aff5c1915061464 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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>
38extern 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
56typedef u32 prom_arg_t;
57
58struct prom_args {
59 const char *service;
60 int nargs;
61 int nret;
62 prom_arg_t args[10];
63};
64
65struct pci_address {
66 unsigned a_hi;
67 unsigned a_mid;
68 unsigned a_lo;
69};
70
71struct pci_reg_property {
72 struct pci_address addr;
73 unsigned size_hi;
74 unsigned size_lo;
75};
76
77struct pci_range {
78 struct pci_address addr;
79 unsigned phys;
80 unsigned size_hi;
81 unsigned size_lo;
82};
83
84struct isa_reg_property {
85 unsigned space;
86 unsigned address;
87 unsigned size;
88};
89
90struct pci_intr_map {
91 struct pci_address addr;
92 unsigned dunno;
93 phandle int_ctrler;
94 unsigned intr;
95};
96
97static void prom_exit(void);
98static int call_prom(const char *service, int nargs, int nret, ...);
99static int call_prom_ret(const char *service, int nargs, int nret,
100 prom_arg_t *rets, ...);
101static void prom_print_hex(unsigned int v);
102static int prom_set_color(ihandle ih, int i, int r, int g, int b);
103static int prom_next_node(phandle *nodep);
104static unsigned long check_display(unsigned long mem);
105static void setup_disp_fake_bi(ihandle dp);
106static unsigned long copy_device_tree(unsigned long mem_start,
107 unsigned long mem_end);
108static unsigned long inspect_node(phandle node, struct device_node *dad,
109 unsigned long mem_start, unsigned long mem_end,
110 struct device_node ***allnextpp);
111static void prom_hold_cpus(unsigned long mem);
112static void prom_instantiate_rtas(void);
113static void * early_get_property(unsigned long base, unsigned long node,
114 char *prop);
115
116prom_entry prom __initdata;
117ihandle prom_chosen __initdata;
118ihandle prom_stdout __initdata;
119
120static char *prom_display_paths[FB_MAX] __initdata;
121static phandle prom_display_nodes[FB_MAX] __initdata;
122static unsigned int prom_num_displays __initdata;
123static ihandle prom_disp_node __initdata;
124char *of_stdout_device __initdata;
125
126unsigned int rtas_data; /* physical pointer */
127unsigned int rtas_entry; /* physical pointer */
128unsigned int rtas_size;
129unsigned int old_rtas;
130
131boot_infos_t *boot_infos;
132char *bootpath;
133char *bootdevice;
134struct device_node *allnodes;
135
136extern char *klimit;
137
138static void __init
139prom_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
151static int __init
152call_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
171static int __init
172call_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
193void __init
194prom_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
213static void __init
214prom_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
229static int __init
230prom_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
235static int __init
236prom_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
260static 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
278extern unsigned long _SDR1;
279extern PTE *Hash;
280extern unsigned long Hash_size;
281
282static void __init
283prom_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 */
329static unsigned long __init
330check_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 */
456static void __init
457setup_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 */
539static unsigned long __init
540copy_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
558static unsigned long __init
559inspect_node(phandle node, struct device_node *dad,
560 unsigned long mem_start, unsigned long mem_end,
561 struct device_node ***allnextpp)
562{
563 int l;
564 phandle child;
565 struct device_node *np;
566 struct property *pp, **prev_propp;
567 char *prev_name, *namep;
568 unsigned char *valp;
569
570 np = (struct device_node *) mem_start;
571 mem_start += sizeof(struct device_node);
572 memset(np, 0, sizeof(*np));
573 np->node = node;
574 **allnextpp = PTRUNRELOC(np);
575 *allnextpp = &np->allnext;
576 if (dad != 0) {
577 np->parent = PTRUNRELOC(dad);
578 /* we temporarily use the `next' field as `last_child'. */
579 if (dad->next == 0)
580 dad->child = PTRUNRELOC(np);
581 else
582 dad->next->sibling = PTRUNRELOC(np);
583 dad->next = np;
584 }
585
586 /* get and store all properties */
587 prev_propp = &np->properties;
588 prev_name = "";
589 for (;;) {
590 pp = (struct property *) mem_start;
591 namep = (char *) (pp + 1);
592 pp->name = PTRUNRELOC(namep);
593 if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0)
594 break;
595 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
596 prev_name = namep;
597 valp = (unsigned char *) mem_start;
598 pp->value = PTRUNRELOC(valp);
599 pp->length = call_prom("getprop", 4, 1, node, namep,
600 valp, mem_end - mem_start);
601 if (pp->length < 0)
602 continue;
603#ifdef MAX_PROPERTY_LENGTH
604 if (pp->length > MAX_PROPERTY_LENGTH)
605 continue; /* ignore this property */
606#endif
607 mem_start = ALIGNUL(mem_start + pp->length);
608 *prev_propp = PTRUNRELOC(pp);
609 prev_propp = &pp->next;
610 }
611 if (np->node != 0) {
612 /* Add a "linux,phandle" property" */
613 pp = (struct property *) mem_start;
614 *prev_propp = PTRUNRELOC(pp);
615 prev_propp = &pp->next;
616 namep = (char *) (pp + 1);
617 pp->name = PTRUNRELOC(namep);
618 strcpy(namep, "linux,phandle");
619 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
620 pp->value = (unsigned char *) PTRUNRELOC(&np->node);
621 pp->length = sizeof(np->node);
622 }
623 *prev_propp = NULL;
624
625 /* get the node's full name */
626 l = call_prom("package-to-path", 3, 1, node,
627 mem_start, mem_end - mem_start);
628 if (l >= 0) {
629 np->full_name = PTRUNRELOC((char *) mem_start);
630 *(char *)(mem_start + l) = 0;
631 mem_start = ALIGNUL(mem_start + l + 1);
632 }
633
634 /* do all our children */
635 child = call_prom("child", 1, 1, node);
636 while (child != 0) {
637 mem_start = inspect_node(child, np, mem_start, mem_end,
638 allnextpp);
639 child = call_prom("peer", 1, 1, child);
640 }
641
642 return mem_start;
643}
644
645unsigned long smp_chrp_cpu_nr __initdata = 0;
646
647/*
648 * With CHRP SMP we need to use the OF to start the other
649 * processors so we can't wait until smp_boot_cpus (the OF is
650 * trashed by then) so we have to put the processors into
651 * a holding pattern controlled by the kernel (not OF) before
652 * we destroy the OF.
653 *
654 * This uses a chunk of high memory, puts some holding pattern
655 * code there and sends the other processors off to there until
656 * smp_boot_cpus tells them to do something. We do that by using
657 * physical address 0x0. The holding pattern checks that address
658 * until its cpu # is there, when it is that cpu jumps to
659 * __secondary_start(). smp_boot_cpus() takes care of setting those
660 * values.
661 *
662 * We also use physical address 0x4 here to tell when a cpu
663 * is in its holding pattern code.
664 *
665 * -- Cort
666 *
667 * Note that we have to do this if we have more than one CPU,
668 * even if this is a UP kernel. Otherwise when we trash OF
669 * the other CPUs will start executing some random instructions
670 * and crash the system. -- paulus
671 */
672static void __init
673prom_hold_cpus(unsigned long mem)
674{
675 extern void __secondary_hold(void);
676 unsigned long i;
677 int cpu;
678 phandle node;
679 char type[16], *path;
680 unsigned int reg;
681
682 /*
683 * XXX: hack to make sure we're chrp, assume that if we're
684 * chrp we have a device_type property -- Cort
685 */
686 node = call_prom("finddevice", 1, 1, "/");
687 if (call_prom("getprop", 4, 1, node,
688 "device_type", type, sizeof(type)) <= 0)
689 return;
690
691 /* copy the holding pattern code to someplace safe (0) */
692 /* the holding pattern is now within the first 0x100
693 bytes of the kernel image -- paulus */
694 memcpy((void *)0, _stext, 0x100);
695 flush_icache_range(0, 0x100);
696
697 /* look for cpus */
698 *(unsigned long *)(0x0) = 0;
699 asm volatile("dcbf 0,%0": : "r" (0) : "memory");
700 for (node = 0; prom_next_node(&node); ) {
701 type[0] = 0;
702 call_prom("getprop", 4, 1, node, "device_type",
703 type, sizeof(type));
704 if (strcmp(type, "cpu") != 0)
705 continue;
706 path = (char *) mem;
707 memset(path, 0, 256);
708 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
709 continue;
710 reg = -1;
711 call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
712 cpu = smp_chrp_cpu_nr++;
713#ifdef CONFIG_SMP
714 smp_hw_index[cpu] = reg;
715#endif /* CONFIG_SMP */
716 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
717 if (cpu == 0)
718 continue;
719 prom_print("starting cpu ");
720 prom_print(path);
721 *(ulong *)(0x4) = 0;
722 call_prom("start-cpu", 3, 0, node,
723 (char *)__secondary_hold - _stext, cpu);
724 prom_print("...");
725 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
726 ;
727 if (*(ulong *)(0x4) == cpu)
728 prom_print("ok\n");
729 else {
730 prom_print("failed: ");
731 prom_print_hex(*(ulong *)0x4);
732 prom_print("\n");
733 }
734 }
735}
736
737static void __init
738prom_instantiate_rtas(void)
739{
740 ihandle prom_rtas;
741 prom_arg_t result;
742
743 prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
744 if (prom_rtas == -1)
745 return;
746
747 rtas_size = 0;
748 call_prom("getprop", 4, 1, prom_rtas,
749 "rtas-size", &rtas_size, sizeof(rtas_size));
750 prom_print("instantiating rtas");
751 if (rtas_size == 0) {
752 rtas_data = 0;
753 } else {
754 /*
755 * Ask OF for some space for RTAS.
756 * Actually OF has bugs so we just arbitrarily
757 * use memory at the 6MB point.
758 */
759 rtas_data = 6 << 20;
760 prom_print(" at ");
761 prom_print_hex(rtas_data);
762 }
763
764 prom_rtas = call_prom("open", 1, 1, "/rtas");
765 prom_print("...");
766 rtas_entry = 0;
767 if (call_prom_ret("call-method", 3, 2, &result,
768 "instantiate-rtas", prom_rtas, rtas_data) == 0)
769 rtas_entry = result;
770 if ((rtas_entry == -1) || (rtas_entry == 0))
771 prom_print(" failed\n");
772 else
773 prom_print(" done\n");
774}
775
776/*
777 * We enter here early on, when the Open Firmware prom is still
778 * handling exceptions and the MMU hash table for us.
779 */
780unsigned long __init
781prom_init(int r3, int r4, prom_entry pp)
782{
783 unsigned long mem;
784 ihandle prom_mmu;
785 unsigned long offset = reloc_offset();
786 int i, l;
787 char *p, *d;
788 unsigned long phys;
789 prom_arg_t result[3];
790 char model[32];
791 phandle node;
792 int rc;
793
794 /* Default */
795 phys = (unsigned long) &_stext;
796
797 /* First get a handle for the stdout device */
798 prom = pp;
799 prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
800 if (prom_chosen == -1)
801 prom_exit();
802 if (call_prom("getprop", 4, 1, prom_chosen, "stdout",
803 &prom_stdout, sizeof(prom_stdout)) <= 0)
804 prom_exit();
805
806 /* Get the full OF pathname of the stdout device */
807 mem = (unsigned long) klimit + offset;
808 p = (char *) mem;
809 memset(p, 0, 256);
810 call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
811 of_stdout_device = p;
812 mem += strlen(p) + 1;
813
814 /* Get the boot device and translate it to a full OF pathname. */
815 p = (char *) mem;
816 l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20);
817 if (l > 0) {
818 p[l] = 0; /* should already be null-terminated */
819 bootpath = PTRUNRELOC(p);
820 mem += l + 1;
821 d = (char *) mem;
822 *d = 0;
823 call_prom("canon", 3, 1, p, d, 1<<20);
824 bootdevice = PTRUNRELOC(d);
825 mem = ALIGNUL(mem + strlen(d) + 1);
826 }
827
828 prom_instantiate_rtas();
829
830#ifdef CONFIG_POWER4
831 /*
832 * Find out how much memory we have and allocate a
833 * suitably-sized hash table.
834 */
835 prom_alloc_htab();
836#endif
837 mem = check_display(mem);
838
839 prom_print("copying OF device tree...");
840 mem = copy_device_tree(mem, mem + (1<<20));
841 prom_print("done\n");
842
843 prom_hold_cpus(mem);
844
845 klimit = (char *) (mem - offset);
846
847 node = call_prom("finddevice", 1, 1, "/");
848 rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
849 if (rc > 0 && !strncmp (model, "Pegasos", 7)
850 && strncmp (model, "Pegasos2", 8)) {
851 /* Pegasos 1 has a broken translate method in the OF,
852 * and furthermore the BATs are mapped 1:1 so the phys
853 * address calculated above is correct, so let's use
854 * it directly.
855 */
856 } else if (offset == 0) {
857 /* If we are already running at 0xc0000000, we assume we were
858 * loaded by an OF bootloader which did set a BAT for us.
859 * This breaks OF translate so we force phys to be 0.
860 */
861 prom_print("(already at 0xc0000000) phys=0\n");
862 phys = 0;
863 } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu",
864 &prom_mmu, sizeof(prom_mmu)) <= 0) {
865 prom_print(" no MMU found\n");
866 } else if (call_prom_ret("call-method", 4, 4, result, "translate",
867 prom_mmu, &_stext, 1) != 0) {
868 prom_print(" (translate failed)\n");
869 } else {
870 /* We assume the phys. address size is 3 cells */
871 phys = result[2];
872 }
873
874 if (prom_disp_node != 0)
875 setup_disp_fake_bi(prom_disp_node);
876
877 /* Use quiesce call to get OF to shut down any devices it's using */
878 prom_print("Calling quiesce ...\n");
879 call_prom("quiesce", 0, 0);
880
881 /* Relocate various pointers which will be used once the
882 kernel is running at the address it was linked at. */
883 for (i = 0; i < prom_num_displays; ++i)
884 prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
885
886#ifdef CONFIG_SERIAL_CORE_CONSOLE
887 /* Relocate the of stdout for console autodetection */
888 of_stdout_device = PTRUNRELOC(of_stdout_device);
889#endif
890
891 prom_print("returning 0x");
892 prom_print_hex(phys);
893 prom_print("from prom_init\n");
894 prom_stdout = 0;
895
896 return phys;
897}
898
899/*
900 * early_get_property is used to access the device tree image prepared
901 * by BootX very early on, before the pointers in it have been relocated.
902 */
903static void * __init
904early_get_property(unsigned long base, unsigned long node, char *prop)
905{
906 struct device_node *np = (struct device_node *)(base + node);
907 struct property *pp;
908
909 for (pp = np->properties; pp != 0; pp = pp->next) {
910 pp = (struct property *) (base + (unsigned long)pp);
911 if (strcmp((char *)((unsigned long)pp->name + base),
912 prop) == 0) {
913 return (void *)((unsigned long)pp->value + base);
914 }
915 }
916 return NULL;
917}
918
919/* Is boot-info compatible ? */
920#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION)
921#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
922#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
923
924void __init
925bootx_init(unsigned long r4, unsigned long phys)
926{
927 boot_infos_t *bi = (boot_infos_t *) r4;
928 unsigned long space;
929 unsigned long ptr, x;
930 char *model;
931
932 boot_infos = PTRUNRELOC(bi);
933 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
934 bi->logicalDisplayBase = NULL;
935
936#ifdef CONFIG_BOOTX_TEXT
937 btext_init(bi);
938
939 /*
940 * Test if boot-info is compatible. Done only in config
941 * CONFIG_BOOTX_TEXT since there is nothing much we can do
942 * with an incompatible version, except display a message
943 * and eventually hang the processor...
944 *
945 * I'll try to keep enough of boot-info compatible in the
946 * future to always allow display of this message;
947 */
948 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
949 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
950 btext_flushscreen();
951 }
952#endif /* CONFIG_BOOTX_TEXT */
953
954 /* New BootX enters kernel with MMU off, i/os are not allowed
955 here. This hack will have been done by the boostrap anyway.
956 */
957 if (bi->version < 4) {
958 /*
959 * XXX If this is an iMac, turn off the USB controller.
960 */
961 model = (char *) early_get_property
962 (r4 + bi->deviceTreeOffset, 4, "model");
963 if (model
964 && (strcmp(model, "iMac,1") == 0
965 || strcmp(model, "PowerMac1,1") == 0)) {
966 out_le32((unsigned *)0x80880008, 1); /* XXX */
967 }
968 }
969
970 /* Move klimit to enclose device tree, args, ramdisk, etc... */
971 if (bi->version < 5) {
972 space = bi->deviceTreeOffset + bi->deviceTreeSize;
973 if (bi->ramDisk)
974 space = bi->ramDisk + bi->ramDiskSize;
975 } else
976 space = bi->totalParamsSize;
977 klimit = PTRUNRELOC((char *) bi + space);
978
979 /* New BootX will have flushed all TLBs and enters kernel with
980 MMU switched OFF, so this should not be useful anymore.
981 */
982 if (bi->version < 4) {
983 /*
984 * Touch each page to make sure the PTEs for them
985 * are in the hash table - the aim is to try to avoid
986 * getting DSI exceptions while copying the kernel image.
987 */
988 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
989 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
990 x = *(volatile unsigned long *)ptr;
991 }
992
993#ifdef CONFIG_BOOTX_TEXT
994 /*
995 * Note that after we call btext_prepare_BAT, we can't do
996 * prom_draw*, flushscreen or clearscreen until we turn the MMU
997 * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
998 * to a virtual address.
999 */
1000 btext_prepare_BAT();
1001#endif
1002}