1 /*
2 * Procedures for interfacing to the Open Firmware PROM on
3 * Power Macintosh computers.
4 *
5 * In particular, we are interested in the device tree
6 * and in using some of its services (exit, write to stdout).
7 *
8 * Paul Mackerras August 1996.
9 * Copyright (C) 1996 Paul Mackerras.
10 */
11 /*
12 * Note that prom_init() and anything called from prom_init()
13 * may be running at an address that is different from the address
14 * that it was linked at. References to static data items are
15 * handled by compiling this file with -mrelocatable-lib.
16 */
17
18 #include <linux/config.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21
22 #include <asm/prom.h>
23 #include <asm/io.h>
24 #include <asm/bootx.h>
25 #include <asm/btext.h>
26 #include <asm/mmu.h>
27 #include <asm/pgtable.h>
28
29 #ifdef CONFIG_FB
30 #include <asm/linux_logo.h>
31 #endif
32
33 /*
34 * Properties whose value is longer than this get excluded from our
35 * copy of the device tree. This way we don't waste space storing
36 * things like "driver,AAPL,MacOS,PowerPC" properties. But this value
37 * does need to be big enough to ensure that we don't lose things
38 * like the interrupt-map property on a PCI-PCI bridge.
39 */
40 #define MAX_PROPERTY_LENGTH 4096
41
42 #ifndef FB_MAX /* avoid pulling in all of the fb stuff */
43 #define FB_MAX 8
44 #endif
45
46 #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
47
48 struct prom_args {
49 const char *service;
50 int nargs;
51 int nret;
52 void *args[10];
53 };
54
55 struct pci_address {
56 unsigned a_hi;
57 unsigned a_mid;
58 unsigned a_lo;
59 };
60
61 struct pci_reg_property {
62 struct pci_address addr;
63 unsigned size_hi;
64 unsigned size_lo;
65 };
66
67 struct pci_range {
68 struct pci_address addr;
69 unsigned phys;
70 unsigned size_hi;
71 unsigned size_lo;
72 };
73
74 struct isa_reg_property {
75 unsigned space;
76 unsigned address;
77 unsigned size;
78 };
79
80 struct pci_intr_map {
81 struct pci_address addr;
82 unsigned dunno;
83 phandle int_ctrler;
84 unsigned intr;
85 };
86
87 static void prom_exit(void);
88 static void *call_prom(const char *service, int nargs, int nret, ...);
89 static void *call_prom_ret(const char *service, int nargs, int nret,
90 void **rets, ...);
91 static void prom_print_hex(unsigned int v);
92 static int prom_set_color(ihandle ih, int i, int r, int g, int b);
93 static int prom_next_node(phandle *nodep);
94 static unsigned long check_display(unsigned long mem);
95 static void setup_disp_fake_bi(ihandle dp);
96 static unsigned long copy_device_tree(unsigned long mem_start,
97 unsigned long mem_end);
98 static unsigned long inspect_node(phandle node, struct device_node *dad,
99 unsigned long mem_start, unsigned long mem_end,
100 struct device_node ***allnextpp);
101 static void prom_hold_cpus(unsigned long mem);
102 static void prom_instantiate_rtas(void);
103 static void * early_get_property(unsigned long base, unsigned long node,
104 char *prop);
105
106 prom_entry prom __initdata = 0;
107 ihandle prom_chosen __initdata = 0;
108 ihandle prom_stdout __initdata = 0;
109
110 char *prom_display_paths[FB_MAX] __initdata = { 0, };
111 phandle prom_display_nodes[FB_MAX] __initdata;
112 unsigned int prom_num_displays __initdata = 0;
113 static char *of_stdout_device __initdata = 0;
114 static ihandle prom_disp_node __initdata = 0;
115
116 unsigned int rtas_data; /* physical pointer */
117 unsigned int rtas_entry; /* physical pointer */
118 unsigned int rtas_size;
119 unsigned int old_rtas;
120
121 boot_infos_t *boot_infos;
122 char *bootpath;
123 char *bootdevice;
124 struct device_node *allnodes;
125
126 extern char *klimit;
127 extern char _stext;
128
129 static void __init
prom_exit(void)130 prom_exit(void)
131 {
132 struct prom_args args;
133
134 args.service = "exit";
135 args.nargs = 0;
136 args.nret = 0;
137 prom(&args);
138 for (;;) /* should never get here */
139 ;
140 }
141
142 static void * __init
call_prom(const char * service,int nargs,int nret,...)143 call_prom(const char *service, int nargs, int nret, ...)
144 {
145 va_list list;
146 int i;
147 struct prom_args prom_args;
148
149 prom_args.service = service;
150 prom_args.nargs = nargs;
151 prom_args.nret = nret;
152 va_start(list, nret);
153 for (i = 0; i < nargs; ++i)
154 prom_args.args[i] = va_arg(list, void *);
155 va_end(list);
156 for (i = 0; i < nret; ++i)
157 prom_args.args[i + nargs] = 0;
158 prom(&prom_args);
159 return prom_args.args[nargs];
160 }
161
162 static void * __init
call_prom_ret(const char * service,int nargs,int nret,void ** rets,...)163 call_prom_ret(const char *service, int nargs, int nret, void **rets, ...)
164 {
165 va_list list;
166 int i;
167 struct prom_args prom_args;
168
169 prom_args.service = service;
170 prom_args.nargs = nargs;
171 prom_args.nret = nret;
172 va_start(list, rets);
173 for (i = 0; i < nargs; ++i)
174 prom_args.args[i] = va_arg(list, void *);
175 va_end(list);
176 for (i = 0; i < nret; ++i)
177 prom_args.args[i + nargs] = 0;
178 prom(&prom_args);
179 for (i = 1; i < nret; ++i)
180 rets[i-1] = prom_args.args[nargs + i];
181 return prom_args.args[nargs];
182 }
183
184 void __init
prom_print(const char * msg)185 prom_print(const char *msg)
186 {
187 const char *p, *q;
188
189 if (prom_stdout == 0)
190 return;
191
192 for (p = msg; *p != 0; p = q) {
193 for (q = p; *q != 0 && *q != '\n'; ++q)
194 ;
195 if (q > p)
196 call_prom("write", 3, 1, prom_stdout, p, q - p);
197 if (*q != 0) {
198 ++q;
199 call_prom("write", 3, 1, prom_stdout, "\r\n", 2);
200 }
201 }
202 }
203
204 static void __init
prom_print_hex(unsigned int v)205 prom_print_hex(unsigned int v)
206 {
207 char buf[16];
208 int i, c;
209
210 for (i = 0; i < 8; ++i) {
211 c = (v >> ((7-i)*4)) & 0xf;
212 c += (c >= 10)? ('a' - 10): '0';
213 buf[i] = c;
214 }
215 buf[i] = ' ';
216 buf[i+1] = 0;
217 prom_print(buf);
218 }
219
220 static int __init
prom_set_color(ihandle ih,int i,int r,int g,int b)221 prom_set_color(ihandle ih, int i, int r, int g, int b)
222 {
223 struct prom_args prom_args;
224
225 prom_args.service = "call-method";
226 prom_args.nargs = 6;
227 prom_args.nret = 1;
228 prom_args.args[0] = "color!";
229 prom_args.args[1] = ih;
230 prom_args.args[2] = (void *) i;
231 prom_args.args[3] = (void *) b;
232 prom_args.args[4] = (void *) g;
233 prom_args.args[5] = (void *) r;
234 prom(&prom_args);
235 return (int) prom_args.args[6];
236 }
237
238 static int __init
prom_next_node(phandle * nodep)239 prom_next_node(phandle *nodep)
240 {
241 phandle node;
242
243 if ((node = *nodep) != 0
244 && (*nodep = call_prom("child", 1, 1, node)) != 0)
245 return 1;
246 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
247 return 1;
248 for (;;) {
249 if ((node = call_prom("parent", 1, 1, node)) == 0)
250 return 0;
251 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
252 return 1;
253 }
254 }
255
256 /*
257 * If we have a display that we don't know how to drive,
258 * we will want to try to execute OF's open method for it
259 * later. However, OF will probably fall over if we do that
260 * we've taken over the MMU.
261 * So we check whether we will need to open the display,
262 * and if so, open it now.
263 */
264 static unsigned long __init
check_display(unsigned long mem)265 check_display(unsigned long mem)
266 {
267 phandle node;
268 ihandle ih;
269 int i, j;
270 char type[16], *path;
271 static unsigned char default_colors[] = {
272 0x00, 0x00, 0x00,
273 0x00, 0x00, 0xaa,
274 0x00, 0xaa, 0x00,
275 0x00, 0xaa, 0xaa,
276 0xaa, 0x00, 0x00,
277 0xaa, 0x00, 0xaa,
278 0xaa, 0xaa, 0x00,
279 0xaa, 0xaa, 0xaa,
280 0x55, 0x55, 0x55,
281 0x55, 0x55, 0xff,
282 0x55, 0xff, 0x55,
283 0x55, 0xff, 0xff,
284 0xff, 0x55, 0x55,
285 0xff, 0x55, 0xff,
286 0xff, 0xff, 0x55,
287 0xff, 0xff, 0xff
288 };
289
290 prom_disp_node = 0;
291
292 for (node = 0; prom_next_node(&node); ) {
293 type[0] = 0;
294 call_prom("getprop", 4, 1, node, "device_type",
295 type, sizeof(type));
296 if (strcmp(type, "display") != 0)
297 continue;
298 /* It seems OF doesn't null-terminate the path :-( */
299 path = (char *) mem;
300 memset(path, 0, 256);
301 if ((int) call_prom("package-to-path", 3, 1,
302 node, path, 255) < 0)
303 continue;
304
305 /*
306 * If this display is the device that OF is using for stdout,
307 * move it to the front of the list.
308 */
309 mem += strlen(path) + 1;
310 i = prom_num_displays++;
311 if (of_stdout_device != 0 && i > 0
312 && strcmp(of_stdout_device, path) == 0) {
313 for (; i > 0; --i) {
314 prom_display_paths[i]
315 = prom_display_paths[i-1];
316 prom_display_nodes[i]
317 = prom_display_nodes[i-1];
318 }
319 }
320 prom_display_paths[i] = path;
321 prom_display_nodes[i] = node;
322 if (i == 0)
323 prom_disp_node = node;
324 if (prom_num_displays >= FB_MAX)
325 break;
326 }
327
328 /*
329 * Open the first display and set its colormap.
330 */
331 for (j=0; j<prom_num_displays; j++) {
332 path = prom_display_paths[j];
333 prom_print("opening display ");
334 prom_print(path);
335 ih = call_prom("open", 1, 1, path);
336 if (ih == 0 || ih == (ihandle) -1) {
337 prom_print("... failed\n");
338 for (i=j+1; i<prom_num_displays; i++) {
339 prom_display_paths[i-1] = prom_display_paths[i];
340 prom_display_nodes[i-1] = prom_display_nodes[i];
341 }
342 if (--prom_num_displays > 0) {
343 prom_disp_node = prom_display_nodes[j];
344 j--;
345 } else
346 prom_disp_node = NULL;
347 continue;
348 } else {
349 prom_print("... ok\n");
350 /*
351 * Setup a usable color table when the appropriate
352 * method is available.
353 * Should update this to use set-colors.
354 */
355 for (i = 0; i < 32; i++)
356 if (prom_set_color(ih, i, default_colors[i*3],
357 default_colors[i*3+1],
358 default_colors[i*3+2]) != 0)
359 break;
360
361 #ifdef CONFIG_FB
362 for (i = 0; i < LINUX_LOGO_COLORS; i++)
363 if (prom_set_color(ih, i + 32,
364 linux_logo_red[i],
365 linux_logo_green[i],
366 linux_logo_blue[i]) != 0)
367 break;
368 #endif /* CONFIG_FB */
369 }
370 }
371
372 return ALIGN(mem);
373 }
374
375 /* This function will enable the early boot text when doing OF booting. This
376 * way, xmon output should work too
377 */
378 static void __init
setup_disp_fake_bi(ihandle dp)379 setup_disp_fake_bi(ihandle dp)
380 {
381 #ifdef CONFIG_BOOTX_TEXT
382 int width = 640, height = 480, depth = 8, pitch;
383 unsigned address;
384 struct pci_reg_property addrs[8];
385 int i, naddrs;
386 char name[32];
387 char *getprop = "getprop";
388
389 prom_print("Initializing fake screen: ");
390
391 memset(name, 0, sizeof(name));
392 call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
393 name[sizeof(name)-1] = 0;
394 prom_print(name);
395 prom_print("\n");
396 call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
397 call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
398 call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
399 pitch = width * ((depth + 7) / 8);
400 call_prom(getprop, 4, 1, dp, "linebytes",
401 &pitch, sizeof(pitch));
402 if (pitch == 1)
403 pitch = 0x1000; /* for strange IBM display */
404 address = 0;
405 call_prom(getprop, 4, 1, dp, "address",
406 &address, sizeof(address));
407 if (address == 0) {
408 /* look for an assigned address with a size of >= 1MB */
409 naddrs = (int) call_prom(getprop, 4, 1, dp,
410 "assigned-addresses",
411 addrs, sizeof(addrs));
412 naddrs /= sizeof(struct pci_reg_property);
413 for (i = 0; i < naddrs; ++i) {
414 if (addrs[i].size_lo >= (1 << 20)) {
415 address = addrs[i].addr.a_lo;
416 /* use the BE aperture if possible */
417 if (addrs[i].size_lo >= (16 << 20))
418 address += (8 << 20);
419 break;
420 }
421 }
422 if (address == 0) {
423 prom_print("Failed to get address\n");
424 return;
425 }
426 }
427 /* kludge for valkyrie */
428 if (strcmp(name, "valkyrie") == 0)
429 address += 0x1000;
430
431 btext_setup_display(width, height, depth, pitch, address);
432
433 btext_prepare_BAT();
434 #endif /* CONFIG_BOOTX_TEXT */
435 }
436
437 /*
438 * Make a copy of the device tree from the PROM.
439 */
440 static unsigned long __init
copy_device_tree(unsigned long mem_start,unsigned long mem_end)441 copy_device_tree(unsigned long mem_start, unsigned long mem_end)
442 {
443 phandle root;
444 unsigned long new_start;
445 struct device_node **allnextp;
446
447 root = call_prom("peer", 1, 1, (phandle)0);
448 if (root == (phandle)0) {
449 prom_print("couldn't get device tree root\n");
450 prom_exit();
451 }
452 allnextp = &allnodes;
453 mem_start = ALIGN(mem_start);
454 new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
455 *allnextp = 0;
456 return new_start;
457 }
458
459 static unsigned long __init
inspect_node(phandle node,struct device_node * dad,unsigned long mem_start,unsigned long mem_end,struct device_node *** allnextpp)460 inspect_node(phandle node, struct device_node *dad,
461 unsigned long mem_start, unsigned long mem_end,
462 struct device_node ***allnextpp)
463 {
464 int l;
465 phandle child;
466 struct device_node *np;
467 struct property *pp, **prev_propp;
468 char *prev_name, *namep;
469 unsigned char *valp;
470
471 np = (struct device_node *) mem_start;
472 mem_start += sizeof(struct device_node);
473 memset(np, 0, sizeof(*np));
474 np->node = node;
475 **allnextpp = PTRUNRELOC(np);
476 *allnextpp = &np->allnext;
477 if (dad != 0) {
478 np->parent = PTRUNRELOC(dad);
479 /* we temporarily use the `next' field as `last_child'. */
480 if (dad->next == 0)
481 dad->child = PTRUNRELOC(np);
482 else
483 dad->next->sibling = PTRUNRELOC(np);
484 dad->next = np;
485 }
486
487 /* get and store all properties */
488 prev_propp = &np->properties;
489 prev_name = "";
490 for (;;) {
491 pp = (struct property *) mem_start;
492 namep = (char *) (pp + 1);
493 pp->name = PTRUNRELOC(namep);
494 if ((int) call_prom("nextprop", 3, 1, node, prev_name,
495 namep) <= 0)
496 break;
497 mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
498 prev_name = namep;
499 valp = (unsigned char *) mem_start;
500 pp->value = PTRUNRELOC(valp);
501 pp->length = (int)
502 call_prom("getprop", 4, 1, node, namep,
503 valp, mem_end - mem_start);
504 if (pp->length < 0)
505 continue;
506 #ifdef MAX_PROPERTY_LENGTH
507 if (pp->length > MAX_PROPERTY_LENGTH)
508 continue; /* ignore this property */
509 #endif
510 mem_start = ALIGN(mem_start + pp->length);
511 *prev_propp = PTRUNRELOC(pp);
512 prev_propp = &pp->next;
513 }
514 if (np->node != NULL) {
515 /* Add a "linux,phandle" property" */
516 pp = (struct property *) mem_start;
517 *prev_propp = PTRUNRELOC(pp);
518 prev_propp = &pp->next;
519 namep = (char *) (pp + 1);
520 pp->name = PTRUNRELOC(namep);
521 strcpy(namep, "linux,phandle");
522 mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
523 pp->value = (unsigned char *) PTRUNRELOC(&np->node);
524 pp->length = sizeof(np->node);
525 }
526 *prev_propp = NULL;
527
528 /* get the node's full name */
529 l = (int) call_prom("package-to-path", 3, 1, node,
530 (char *) mem_start, mem_end - mem_start);
531 if (l >= 0) {
532 np->full_name = PTRUNRELOC((char *) mem_start);
533 *(char *)(mem_start + l) = 0;
534 mem_start = ALIGN(mem_start + l + 1);
535 }
536
537 /* do all our children */
538 child = call_prom("child", 1, 1, node);
539 while (child != (void *)0) {
540 mem_start = inspect_node(child, np, mem_start, mem_end,
541 allnextpp);
542 child = call_prom("peer", 1, 1, child);
543 }
544
545 return mem_start;
546 }
547
548 unsigned long smp_chrp_cpu_nr __initdata = 0;
549
550 /*
551 * With CHRP SMP we need to use the OF to start the other
552 * processors so we can't wait until smp_boot_cpus (the OF is
553 * trashed by then) so we have to put the processors into
554 * a holding pattern controlled by the kernel (not OF) before
555 * we destroy the OF.
556 *
557 * This uses a chunk of high memory, puts some holding pattern
558 * code there and sends the other processors off to there until
559 * smp_boot_cpus tells them to do something. We do that by using
560 * physical address 0x0. The holding pattern checks that address
561 * until its cpu # is there, when it is that cpu jumps to
562 * __secondary_start(). smp_boot_cpus() takes care of setting those
563 * values.
564 *
565 * We also use physical address 0x4 here to tell when a cpu
566 * is in its holding pattern code.
567 *
568 * -- Cort
569 *
570 * Note that we have to do this if we have more than one CPU,
571 * even if this is a UP kernel. Otherwise when we trash OF
572 * the other CPUs will start executing some random instructions
573 * and crash the system. -- paulus
574 */
575 static void __init
prom_hold_cpus(unsigned long mem)576 prom_hold_cpus(unsigned long mem)
577 {
578 extern void __secondary_hold(void);
579 unsigned long i;
580 int cpu;
581 phandle node;
582 char type[16], *path;
583 unsigned int reg;
584
585 /*
586 * XXX: hack to make sure we're chrp, assume that if we're
587 * chrp we have a device_type property -- Cort
588 */
589 node = call_prom("finddevice", 1, 1, "/");
590 if ((int)call_prom("getprop", 4, 1, node,
591 "device_type",type, sizeof(type)) <= 0)
592 return;
593
594 /* copy the holding pattern code to someplace safe (0) */
595 /* the holding pattern is now within the first 0x100
596 bytes of the kernel image -- paulus */
597 memcpy((void *)0, &_stext, 0x100);
598 flush_icache_range(0, 0x100);
599
600 /* look for cpus */
601 *(unsigned long *)(0x0) = 0;
602 asm volatile("dcbf 0,%0": : "r" (0) : "memory");
603 for (node = 0; prom_next_node(&node); ) {
604 type[0] = 0;
605 call_prom("getprop", 4, 1, node, "device_type",
606 type, sizeof(type));
607 if (strcmp(type, "cpu") != 0)
608 continue;
609 path = (char *) mem;
610 memset(path, 0, 256);
611 if ((int) call_prom("package-to-path", 3, 1,
612 node, path, 255) < 0)
613 continue;
614 reg = -1;
615 call_prom("getprop", 4, 1, node, "reg", ®, sizeof(reg));
616 cpu = smp_chrp_cpu_nr++;
617 #ifdef CONFIG_SMP
618 smp_hw_index[cpu] = reg;
619 #endif /* CONFIG_SMP */
620 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
621 if (cpu == 0)
622 continue;
623 prom_print("starting cpu ");
624 prom_print(path);
625 *(ulong *)(0x4) = 0;
626 call_prom("start-cpu", 3, 0, node,
627 (char *)__secondary_hold - &_stext, cpu);
628 prom_print("...");
629 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
630 ;
631 if (*(ulong *)(0x4) == cpu)
632 prom_print("ok\n");
633 else {
634 prom_print("failed: ");
635 prom_print_hex(*(ulong *)0x4);
636 prom_print("\n");
637 }
638 }
639 }
640
641 #ifdef CONFIG_POWER4
642 /*
643 * Set up a hash table with a set of entries in it to map the
644 * first 64MB of RAM. This is used on 64-bit machines since
645 * some of them don't have BATs.
646 * We assume the PTE will fit in the primary PTEG.
647 */
648
make_pte(unsigned long htab,unsigned int hsize,unsigned int va,unsigned int pa,int mode)649 static inline void make_pte(unsigned long htab, unsigned int hsize,
650 unsigned int va, unsigned int pa, int mode)
651 {
652 unsigned int *pteg;
653 unsigned int hash, i, vsid;
654
655 vsid = ((va >> 28) * 0x111) << 12;
656 hash = ((va ^ vsid) >> 5) & 0x7fff80;
657 pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
658 for (i = 0; i < 8; ++i, pteg += 4) {
659 if ((pteg[1] & 1) == 0) {
660 pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
661 pteg[3] = pa | mode;
662 break;
663 }
664 }
665 }
666
667 extern unsigned long _SDR1;
668 extern PTE *Hash;
669 extern unsigned long Hash_size;
670
671 static void __init
prom_alloc_htab(void)672 prom_alloc_htab(void)
673 {
674 unsigned int hsize;
675 unsigned long htab;
676 unsigned int addr;
677
678 /*
679 * Because of OF bugs we can't use the "claim" client
680 * interface to allocate memory for the hash table.
681 * This code is only used on 64-bit PPCs, and the only
682 * 64-bit PPCs at the moment are RS/6000s, and their
683 * OF is based at 0xc00000 (the 12M point), so we just
684 * arbitrarily use the 0x800000 - 0xc00000 region for the
685 * hash table.
686 * -- paulus.
687 */
688 hsize = 4 << 20; /* POWER4 has no BATs */
689 htab = (8 << 20);
690 call_prom("claim", 3, 1, htab, hsize, 0);
691 Hash = (void *)(htab + KERNELBASE);
692 Hash_size = hsize;
693 _SDR1 = htab + __ilog2(hsize) - 18;
694
695 /*
696 * Put in PTEs for the first 64MB of RAM
697 */
698 cacheable_memzero((void *)htab, hsize);
699 for (addr = 0; addr < 0x4000000; addr += 0x1000)
700 make_pte(htab, hsize, addr + KERNELBASE, addr,
701 _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
702 make_pte(htab, hsize, 0x80013000, 0x80013000,
703 _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
704 }
705 #endif /* CONFIG_POWER4 */
706
707 static void __init
prom_instantiate_rtas(void)708 prom_instantiate_rtas(void)
709 {
710 ihandle prom_rtas;
711 unsigned int i;
712 struct prom_args prom_args;
713
714 prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
715 if (prom_rtas == (void *) -1)
716 return;
717
718 rtas_size = 0;
719 call_prom("getprop", 4, 1, prom_rtas,
720 "rtas-size", &rtas_size, sizeof(rtas_size));
721 prom_print("instantiating rtas");
722 if (rtas_size == 0) {
723 rtas_data = 0;
724 } else {
725 /*
726 * Ask OF for some space for RTAS.
727 * Actually OF has bugs so we just arbitrarily
728 * use memory at the 6MB point.
729 */
730 rtas_data = 6 << 20;
731 prom_print(" at ");
732 prom_print_hex(rtas_data);
733 }
734
735 prom_rtas = call_prom("open", 1, 1, "/rtas");
736 prom_print("...");
737 prom_args.service = "call-method";
738 prom_args.nargs = 3;
739 prom_args.nret = 2;
740 prom_args.args[0] = "instantiate-rtas";
741 prom_args.args[1] = prom_rtas;
742 prom_args.args[2] = (void *) rtas_data;
743 prom(&prom_args);
744 i = 0;
745 if (prom_args.args[3] == 0)
746 i = (unsigned int)prom_args.args[4];
747 rtas_entry = i;
748 if ((rtas_entry == -1) || (rtas_entry == 0))
749 prom_print(" failed\n");
750 else
751 prom_print(" done\n");
752 }
753
754 /*
755 * We enter here early on, when the Open Firmware prom is still
756 * handling exceptions and the MMU hash table for us.
757 */
758 unsigned long __init
prom_init(int r3,int r4,prom_entry pp)759 prom_init(int r3, int r4, prom_entry pp)
760 {
761 unsigned long mem;
762 ihandle prom_mmu;
763 unsigned long offset = reloc_offset();
764 int i, l;
765 char *p, *d;
766 unsigned long phys;
767 void *result[3];
768
769 /* Default */
770 phys = (unsigned long) &_stext;
771
772 /* First get a handle for the stdout device */
773 prom = pp;
774 prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
775 if (prom_chosen == (void *)-1)
776 prom_exit();
777 if ((int) call_prom("getprop", 4, 1, prom_chosen,
778 "stdout", &prom_stdout,
779 sizeof(prom_stdout)) <= 0)
780 prom_exit();
781
782 /* Get the full OF pathname of the stdout device */
783 mem = (unsigned long) klimit + offset;
784 p = (char *) mem;
785 memset(p, 0, 256);
786 call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
787 of_stdout_device = p;
788 mem += strlen(p) + 1;
789
790 /* Get the boot device and translate it to a full OF pathname. */
791 p = (char *) mem;
792 l = (int) call_prom("getprop", 4, 1, prom_chosen,
793 "bootpath", p, 1<<20);
794 if (l > 0) {
795 p[l] = 0; /* should already be null-terminated */
796 bootpath = PTRUNRELOC(p);
797 mem += l + 1;
798 d = (char *) mem;
799 *d = 0;
800 call_prom("canon", 3, 1, p, d, 1<<20);
801 bootdevice = PTRUNRELOC(d);
802 mem = ALIGN(mem + strlen(d) + 1);
803 }
804
805 prom_instantiate_rtas();
806
807 #ifdef CONFIG_POWER4
808 /*
809 * Find out how much memory we have and allocate a
810 * suitably-sized hash table.
811 */
812 prom_alloc_htab();
813 #endif
814
815 mem = check_display(mem);
816
817 prom_print("copying OF device tree...");
818 mem = copy_device_tree(mem, mem + (1<<20));
819 prom_print("done\n");
820
821 prom_hold_cpus(mem);
822
823 klimit = (char *) (mem - offset);
824
825 /* If we are already running at 0xc0000000, we assume we were
826 * loaded by an OF bootloader which did set a BAT for us.
827 * This breaks OF translate so we force phys to be 0.
828 */
829 if (offset == 0)
830 phys = 0;
831 else if ((int) call_prom("getprop", 4, 1, prom_chosen, "mmu",
832 &prom_mmu, sizeof(prom_mmu)) <= 0) {
833 prom_print(" no MMU found\n");
834 } else if ((int)call_prom_ret("call-method", 4, 4, result, "translate",
835 prom_mmu, &_stext, 1) != 0) {
836 prom_print(" (translate failed)\n");
837 } else {
838 /* We assume the phys. address size is 3 cells */
839 phys = (unsigned long)result[2];
840 }
841
842 if (prom_disp_node != 0)
843 setup_disp_fake_bi(prom_disp_node);
844
845 /* Use quiesce call to get OF to shut down any devices it's using */
846 prom_print("Calling quiesce ...\n");
847 call_prom("quiesce", 0, 0);
848
849 /* Relocate various pointers which will be used once the
850 kernel is running at the address it was linked at. */
851 for (i = 0; i < prom_num_displays; ++i)
852 prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
853
854 prom_print("returning 0x");
855 prom_print_hex(phys);
856 prom_print("from prom_init\n");
857 prom_stdout = 0;
858
859 return phys;
860 }
861
862 /*
863 * early_get_property is used to access the device tree image prepared
864 * by BootX very early on, before the pointers in it have been relocated.
865 */
866 static void * __init
early_get_property(unsigned long base,unsigned long node,char * prop)867 early_get_property(unsigned long base, unsigned long node, char *prop)
868 {
869 struct device_node *np = (struct device_node *)(base + node);
870 struct property *pp;
871
872 for (pp = np->properties; pp != 0; pp = pp->next) {
873 pp = (struct property *) (base + (unsigned long)pp);
874 if (strcmp((char *)((unsigned long)pp->name + base),
875 prop) == 0) {
876 return (void *)((unsigned long)pp->value + base);
877 }
878 }
879 return 0;
880 }
881
882 /* Is boot-info compatible ? */
883 #define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION)
884 #define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
885 #define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
886
887 void __init
bootx_init(unsigned long r4,unsigned long phys)888 bootx_init(unsigned long r4, unsigned long phys)
889 {
890 boot_infos_t *bi = (boot_infos_t *) r4;
891 unsigned long space;
892 unsigned long ptr, x;
893 char *model;
894
895 boot_infos = PTRUNRELOC(bi);
896 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
897 bi->logicalDisplayBase = 0;
898
899 #ifdef CONFIG_BOOTX_TEXT
900 btext_init(bi);
901
902 /*
903 * Test if boot-info is compatible. Done only in config
904 * CONFIG_BOOTX_TEXT since there is nothing much we can do
905 * with an incompatible version, except display a message
906 * and eventually hang the processor...
907 *
908 * I'll try to keep enough of boot-info compatible in the
909 * future to always allow display of this message;
910 */
911 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
912 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
913 btext_flushscreen();
914 }
915 #endif /* CONFIG_BOOTX_TEXT */
916
917 /* New BootX enters kernel with MMU off, i/os are not allowed
918 here. This hack will have been done by the boostrap anyway.
919 */
920 if (bi->version < 4) {
921 /*
922 * XXX If this is an iMac, turn off the USB controller.
923 */
924 model = (char *) early_get_property
925 (r4 + bi->deviceTreeOffset, 4, "model");
926 if (model
927 && (strcmp(model, "iMac,1") == 0
928 || strcmp(model, "PowerMac1,1") == 0)) {
929 out_le32((unsigned *)0x80880008, 1); /* XXX */
930 }
931 }
932
933 /* Move klimit to enclose device tree, args, ramdisk, etc... */
934 if (bi->version < 5) {
935 space = bi->deviceTreeOffset + bi->deviceTreeSize;
936 if (bi->ramDisk)
937 space = bi->ramDisk + bi->ramDiskSize;
938 } else
939 space = bi->totalParamsSize;
940 klimit = PTRUNRELOC((char *) bi + space);
941
942 /* New BootX will have flushed all TLBs and enters kernel with
943 MMU switched OFF, so this should not be useful anymore.
944 */
945 if (bi->version < 4) {
946 /*
947 * Touch each page to make sure the PTEs for them
948 * are in the hash table - the aim is to try to avoid
949 * getting DSI exceptions while copying the kernel image.
950 */
951 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
952 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
953 x = *(volatile unsigned long *)ptr;
954 }
955
956 #ifdef CONFIG_BOOTX_TEXT
957 /*
958 * Note that after we call btext_prepare_BAT, we can't do
959 * prom_draw*, flushscreen or clearscreen until we turn the MMU
960 * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
961 * to a virtual address.
962 */
963 btext_prepare_BAT();
964 #endif
965 }
966