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.
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>
26 #include <asm/bootx.h>
27 #include <asm/system.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
;
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 */
54 #define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
56 typedef u32 prom_arg_t
;
71 struct pci_reg_property
{
72 struct pci_address addr
;
78 struct pci_address addr
;
84 struct isa_reg_property
{
91 struct pci_address addr
;
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
,
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
;
134 struct device_node
*allnodes
;
141 struct prom_args args
;
143 args
.service
= "exit";
147 for (;;) /* should never get here */
152 call_prom(const char *service
, int nargs
, int nret
, ...)
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
);
165 for (i
= 0; i
< nret
; ++i
)
166 prom_args
.args
[i
+ nargs
] = 0;
168 return prom_args
.args
[nargs
];
172 call_prom_ret(const char *service
, int nargs
, int nret
, prom_arg_t
*rets
, ...)
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);
185 for (i
= 0; i
< nret
; ++i
)
186 prom_args
.args
[i
+ nargs
] = 0;
188 for (i
= 1; i
< nret
; ++i
)
189 rets
[i
-1] = prom_args
.args
[nargs
+ i
];
190 return prom_args
.args
[nargs
];
194 prom_print(const char *msg
)
198 if (prom_stdout
== 0)
201 for (p
= msg
; *p
!= 0; p
= q
) {
202 for (q
= p
; *q
!= 0 && *q
!= '\n'; ++q
)
205 call_prom("write", 3, 1, prom_stdout
, p
, q
- p
);
208 call_prom("write", 3, 1, prom_stdout
, "\r\n", 2);
214 prom_print_hex(unsigned int v
)
219 for (i
= 0; i
< 8; ++i
) {
220 c
= (v
>> ((7-i
)*4)) & 0xf;
221 c
+= (c
>= 10)? ('a' - 10): '0';
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
);
236 prom_next_node(phandle
*nodep
)
240 if ((node
= *nodep
) != 0
241 && (*nodep
= call_prom("child", 1, 1, node
)) != 0)
243 if ((*nodep
= call_prom("peer", 1, 1, node
)) != 0)
246 if ((node
= call_prom("parent", 1, 1, node
)) == 0)
248 if ((*nodep
= call_prom("peer", 1, 1, node
)) != 0)
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
)
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;
278 extern unsigned long _SDR1
;
280 extern unsigned long Hash_size
;
283 prom_alloc_htab(void)
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
299 hsize
= 4 << 20; /* POWER4 has no BATs */
301 call_prom("claim", 3, 1, htab
, hsize
, 0);
302 Hash
= (void *)(htab
+ KERNELBASE
);
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
);
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
)
335 char type
[16], *path
;
336 static unsigned char default_colors
[] = {
354 const unsigned char *clut
;
358 for (node
= 0; prom_next_node(&node
); ) {
360 call_prom("getprop", 4, 1, node
, "device_type",
362 if (strcmp(type
, "display") != 0)
364 /* It seems OF doesn't null-terminate the path :-( */
366 memset(path
, 0, 256);
367 if (call_prom("package-to-path", 3, 1, node
, path
, 255) < 0)
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) {
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
;
388 prom_disp_node
= node
;
389 if (prom_num_displays
>= FB_MAX
)
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 ");
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
];
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],
426 #ifdef CONFIG_LOGO_LINUX_CLUT224
427 clut
= PTRRELOC(logo_linux_clut224
.clut
);
428 for (i
= 0; i
< logo_linux_clut224
.clutsize
;
430 if (prom_set_color(ih
, i
+ 32, clut
[0],
431 clut
[1], clut
[2]) != 0)
433 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
439 p
= call_prom("instance-to-package", 1, 1, prom_stdout
);
442 call_prom("getprop", 4, 1, p
, "device_type",
444 if (strcmp(type
, "display") == 0)
445 call_prom("setprop", 4, 1, p
, "linux,boot-display",
453 /* This function will enable the early boot text when doing OF booting. This
454 * way, xmon output should work too
457 setup_disp_fake_bi(ihandle dp
)
459 #ifdef CONFIG_BOOTX_TEXT
460 int width
= 640, height
= 480, depth
= 8, pitch
;
462 struct pci_reg_property addrs
[8];
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;
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
));
481 pitch
= 0x1000; /* for strange IBM display */
483 call_prom(getprop
, 4, 1, dp
, "address",
484 &address
, sizeof(address
));
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);
500 prom_print("Failed to get address\n");
504 /* kludge for valkyrie */
505 if (strcmp(name
, "valkyrie") == 0)
509 #if CONFIG_TASK_SIZE > 0x80000000
510 #error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5
513 extern boot_infos_t disp_bi
;
514 unsigned long va
, pa
, i
, offset
;
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
);
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
);
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
)
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");
551 allnextp
= &allnodes
;
552 mem_start
= ALIGNUL(mem_start
);
553 new_start
= inspect_node(root
, NULL
, mem_start
, mem_end
, &allnextp
);
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
)
565 struct device_node
*np
;
566 struct property
*pp
, **prev_propp
;
567 char *prev_name
, *namep
;
570 np
= (struct device_node
*) mem_start
;
571 mem_start
+= sizeof(struct device_node
);
572 memset(np
, 0, sizeof(*np
));
574 **allnextpp
= PTRUNRELOC(np
);
575 *allnextpp
= &np
->allnext
;
577 np
->parent
= PTRUNRELOC(dad
);
578 /* we temporarily use the `next' field as `last_child'. */
580 dad
->child
= PTRUNRELOC(np
);
582 dad
->next
->sibling
= PTRUNRELOC(np
);
586 /* get and store all properties */
587 prev_propp
= &np
->properties
;
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)
595 mem_start
= ALIGNUL((unsigned long)namep
+ strlen(namep
) + 1);
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
);
603 #ifdef MAX_PROPERTY_LENGTH
604 if (pp
->length
> MAX_PROPERTY_LENGTH
)
605 continue; /* ignore this property */
607 mem_start
= ALIGNUL(mem_start
+ pp
->length
);
608 *prev_propp
= PTRUNRELOC(pp
);
609 prev_propp
= &pp
->next
;
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
);
625 /* get the node's full name */
626 l
= call_prom("package-to-path", 3, 1, node
,
627 mem_start
, mem_end
- mem_start
);
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
);
637 mem_start
= inspect_node(child
, np
, mem_start
, mem_end
,
639 child
= call_prom("peer", 1, 1, child
);
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
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
662 * We also use physical address 0x4 here to tell when a cpu
663 * is in its holding pattern code.
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
673 prom_hold_cpus(unsigned long mem
)
675 extern void __secondary_hold(void);
679 char type
[16], *path
;
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)
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);
698 *(unsigned long *)(0x0) = 0;
699 asm volatile("dcbf 0,%0": : "r" (0) : "memory");
700 for (node
= 0; prom_next_node(&node
); ) {
702 call_prom("getprop", 4, 1, node
, "device_type",
704 if (strcmp(type
, "cpu") != 0)
707 memset(path
, 0, 256);
708 if (call_prom("package-to-path", 3, 1, node
, path
, 255) < 0)
711 call_prom("getprop", 4, 1, node
, "reg", ®
, sizeof(reg
));
712 cpu
= smp_chrp_cpu_nr
++;
714 smp_hw_index
[cpu
] = reg
;
715 #endif /* CONFIG_SMP */
716 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
719 prom_print("starting cpu ");
722 call_prom("start-cpu", 3, 0, node
,
723 (char *)__secondary_hold
- _stext
, cpu
);
725 for ( i
= 0 ; (i
< 10000) && (*(ulong
*)(0x4) == 0); i
++ )
727 if (*(ulong
*)(0x4) == cpu
)
730 prom_print("failed: ");
731 prom_print_hex(*(ulong
*)0x4);
738 prom_instantiate_rtas(void)
743 prom_rtas
= call_prom("finddevice", 1, 1, "/rtas");
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) {
755 * Ask OF for some space for RTAS.
756 * Actually OF has bugs so we just arbitrarily
757 * use memory at the 6MB point.
761 prom_print_hex(rtas_data
);
764 prom_rtas
= call_prom("open", 1, 1, "/rtas");
767 if (call_prom_ret("call-method", 3, 2, &result
,
768 "instantiate-rtas", prom_rtas
, rtas_data
) == 0)
770 if ((rtas_entry
== -1) || (rtas_entry
== 0))
771 prom_print(" failed\n");
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.
781 prom_init(int r3
, int r4
, prom_entry pp
)
785 unsigned long offset
= reloc_offset();
789 prom_arg_t result
[3];
795 phys
= (unsigned long) &_stext
;
797 /* First get a handle for the stdout device */
799 prom_chosen
= call_prom("finddevice", 1, 1, "/chosen");
800 if (prom_chosen
== -1)
802 if (call_prom("getprop", 4, 1, prom_chosen
, "stdout",
803 &prom_stdout
, sizeof(prom_stdout
)) <= 0)
806 /* Get the full OF pathname of the stdout device */
807 mem
= (unsigned long) klimit
+ offset
;
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. */
816 l
= call_prom("getprop", 4, 1, prom_chosen
, "bootpath", p
, 1<<20);
818 p
[l
] = 0; /* should already be null-terminated */
819 bootpath
= PTRUNRELOC(p
);
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();
832 * Find out how much memory we have and allocate a
833 * suitably-sized hash table.
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");
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
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");
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");
870 /* We assume the phys. address size is 3 cells */
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
);
891 prom_print("returning 0x");
892 prom_print_hex(phys
);
893 prom_print("from prom_init\n");
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.
904 early_get_property(unsigned long base
, unsigned long node
, char *prop
)
906 struct device_node
*np
= (struct device_node
*)(base
+ node
);
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
),
913 return (void *)((unsigned long)pp
->value
+ base
);
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)
925 bootx_init(unsigned long r4
, unsigned long phys
)
927 boot_infos_t
*bi
= (boot_infos_t
*) r4
;
929 unsigned long ptr
, x
;
932 boot_infos
= PTRUNRELOC(bi
);
933 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi
))
934 bi
->logicalDisplayBase
= NULL
;
936 #ifdef CONFIG_BOOTX_TEXT
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");
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");
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
;
974 space
= bi
->ramDisk
+ bi
->ramDiskSize
;
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();