blob: 2d80653aa2af54e866eee220d8193dde6d663c49 [file] [log] [blame]
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001/*
2 * Procedures for interfacing to Open Firmware.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#undef DEBUG_PROM
17
18#include <stdarg.h>
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/init.h>
23#include <linux/threads.h>
24#include <linux/spinlock.h>
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/proc_fs.h>
28#include <linux/stringify.h>
29#include <linux/delay.h>
30#include <linux/initrd.h>
31#include <linux/bitops.h>
32#include <asm/prom.h>
33#include <asm/rtas.h>
34#include <asm/page.h>
35#include <asm/processor.h>
36#include <asm/irq.h>
37#include <asm/io.h>
38#include <asm/smp.h>
39#include <asm/system.h>
40#include <asm/mmu.h>
41#include <asm/pgtable.h>
42#include <asm/pci.h>
43#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100044#include <asm/btext.h>
45#include <asm/sections.h>
46#include <asm/machdep.h>
47
48#ifdef CONFIG_LOGO_LINUX_CLUT224
49#include <linux/linux_logo.h>
50extern const struct linux_logo logo_linux_clut224;
51#endif
52
53/*
54 * Properties whose value is longer than this get excluded from our
55 * copy of the device tree. This value does need to be big enough to
56 * ensure that we don't lose things like the interrupt-map property
57 * on a PCI-PCI bridge.
58 */
59#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
60
61/*
62 * Eventually bump that one up
63 */
64#define DEVTREE_CHUNK_SIZE 0x100000
65
66/*
67 * This is the size of the local memory reserve map that gets copied
68 * into the boot params passed to the kernel. That size is totally
69 * flexible as the kernel just reads the list until it encounters an
70 * entry with size 0, so it can be changed without breaking binary
71 * compatibility
72 */
73#define MEM_RESERVE_MAP_SIZE 8
74
75/*
76 * prom_init() is called very early on, before the kernel text
77 * and data have been mapped to KERNELBASE. At this point the code
78 * is running at whatever address it has been loaded at.
79 * On ppc32 we compile with -mrelocatable, which means that references
80 * to extern and static variables get relocated automatically.
81 * On ppc64 we have to relocate the references explicitly with
82 * RELOC. (Note that strings count as static variables.)
83 *
84 * Because OF may have mapped I/O devices into the area starting at
85 * KERNELBASE, particularly on CHRP machines, we can't safely call
86 * OF once the kernel has been mapped to KERNELBASE. Therefore all
87 * OF calls must be done within prom_init().
88 *
89 * ADDR is used in calls to call_prom. The 4th and following
90 * arguments to call_prom should be 32-bit values.
91 * On ppc64, 64 bit values are truncated to 32 bits (and
92 * fortunately don't get interpreted as two arguments).
93 */
94#ifdef CONFIG_PPC64
95#define RELOC(x) (*PTRRELOC(&(x)))
96#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
Paul Mackerrasa23414b2005-11-10 12:00:55 +110097#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100098#else
99#define RELOC(x) (x)
100#define ADDR(x) (u32) (x)
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100101#define OF_WORKAROUNDS of_workarounds
102int of_workarounds;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000103#endif
104
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100105#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
106#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
107
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000108#define PROM_BUG() do { \
109 prom_printf("kernel BUG at %s line 0x%x!\n", \
110 RELOC(__FILE__), __LINE__); \
111 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
112} while (0)
113
114#ifdef DEBUG_PROM
115#define prom_debug(x...) prom_printf(x)
116#else
117#define prom_debug(x...)
118#endif
119
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000120
121typedef u32 prom_arg_t;
122
123struct prom_args {
124 u32 service;
125 u32 nargs;
126 u32 nret;
127 prom_arg_t args[10];
128};
129
130struct prom_t {
131 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100132 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000133 int cpu;
134 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000135 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100136 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000137};
138
139struct mem_map_entry {
Kumar Galacbbcf342006-01-11 17:57:13 -0600140 u64 base;
141 u64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000142};
143
144typedef u32 cell_t;
145
146extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
147
148#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000149extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000150#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000151static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000152{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000153 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000154}
155#endif
156
157extern void copy_and_flush(unsigned long dest, unsigned long src,
158 unsigned long size, unsigned long offset);
159
160/* prom structure */
161static struct prom_t __initdata prom;
162
163static unsigned long prom_entry __initdata;
164
165#define PROM_SCRATCH_SIZE 256
166
167static char __initdata of_stdout_device[256];
168static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
169
170static unsigned long __initdata dt_header_start;
171static unsigned long __initdata dt_struct_start, dt_struct_end;
172static unsigned long __initdata dt_string_start, dt_string_end;
173
174static unsigned long __initdata prom_initrd_start, prom_initrd_end;
175
176#ifdef CONFIG_PPC64
177static int __initdata iommu_force_on;
178static int __initdata ppc64_iommu_off;
179static unsigned long __initdata prom_tce_alloc_start;
180static unsigned long __initdata prom_tce_alloc_end;
181#endif
182
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100183/* Platforms codes are now obsolete in the kernel. Now only used within this
184 * file and ultimately gone too. Feel free to change them if you need, they
185 * are not shared with anything outside of this file anymore
186 */
187#define PLATFORM_PSERIES 0x0100
188#define PLATFORM_PSERIES_LPAR 0x0101
189#define PLATFORM_LPAR 0x0001
190#define PLATFORM_POWERMAC 0x0400
191#define PLATFORM_GENERIC 0x0500
192
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000193static int __initdata of_platform;
194
195static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
196
197static unsigned long __initdata prom_memory_limit;
198
199static unsigned long __initdata alloc_top;
200static unsigned long __initdata alloc_top_high;
201static unsigned long __initdata alloc_bottom;
202static unsigned long __initdata rmo_top;
203static unsigned long __initdata ram_top;
204
Michael Ellermandcee3032005-12-04 18:39:48 +1100205#ifdef CONFIG_KEXEC
206static unsigned long __initdata prom_crashk_base;
207static unsigned long __initdata prom_crashk_size;
208#endif
209
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000210static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
211static int __initdata mem_reserve_cnt;
212
213static cell_t __initdata regbuf[1024];
214
215
216#define MAX_CPU_THREADS 2
217
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000218/*
219 * Error results ... some OF calls will return "-1" on error, some
220 * will return 0, some will return either. To simplify, here are
221 * macros to use with any ihandle or phandle return value to check if
222 * it is valid
223 */
224
225#define PROM_ERROR (-1u)
226#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
227#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
228
229
230/* This is the one and *ONLY* place where we actually call open
231 * firmware.
232 */
233
234static int __init call_prom(const char *service, int nargs, int nret, ...)
235{
236 int i;
237 struct prom_args args;
238 va_list list;
239
240 args.service = ADDR(service);
241 args.nargs = nargs;
242 args.nret = nret;
243
244 va_start(list, nret);
245 for (i = 0; i < nargs; i++)
246 args.args[i] = va_arg(list, prom_arg_t);
247 va_end(list);
248
249 for (i = 0; i < nret; i++)
250 args.args[nargs+i] = 0;
251
Paul Mackerrasc49888202005-10-26 21:52:53 +1000252 if (enter_prom(&args, RELOC(prom_entry)) < 0)
253 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000254
255 return (nret > 0) ? args.args[nargs] : 0;
256}
257
258static int __init call_prom_ret(const char *service, int nargs, int nret,
259 prom_arg_t *rets, ...)
260{
261 int i;
262 struct prom_args args;
263 va_list list;
264
265 args.service = ADDR(service);
266 args.nargs = nargs;
267 args.nret = nret;
268
269 va_start(list, rets);
270 for (i = 0; i < nargs; i++)
271 args.args[i] = va_arg(list, prom_arg_t);
272 va_end(list);
273
274 for (i = 0; i < nret; i++)
Olaf Heringed1189b2005-11-29 14:04:05 +0100275 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000276
Paul Mackerrasc49888202005-10-26 21:52:53 +1000277 if (enter_prom(&args, RELOC(prom_entry)) < 0)
278 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000279
280 if (rets != NULL)
281 for (i = 1; i < nret; ++i)
Paul Mackerrasc5200c92005-10-10 22:57:03 +1000282 rets[i-1] = args.args[nargs+i];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000283
284 return (nret > 0) ? args.args[nargs] : 0;
285}
286
287
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000288static void __init prom_print(const char *msg)
289{
290 const char *p, *q;
291 struct prom_t *_prom = &RELOC(prom);
292
293 if (_prom->stdout == 0)
294 return;
295
296 for (p = msg; *p != 0; p = q) {
297 for (q = p; *q != 0 && *q != '\n'; ++q)
298 ;
299 if (q > p)
300 call_prom("write", 3, 1, _prom->stdout, p, q - p);
301 if (*q == 0)
302 break;
303 ++q;
304 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
305 }
306}
307
308
309static void __init prom_print_hex(unsigned long val)
310{
311 int i, nibbles = sizeof(val)*2;
312 char buf[sizeof(val)*2+1];
313 struct prom_t *_prom = &RELOC(prom);
314
315 for (i = nibbles-1; i >= 0; i--) {
316 buf[i] = (val & 0xf) + '0';
317 if (buf[i] > '9')
318 buf[i] += ('a'-'0'-10);
319 val >>= 4;
320 }
321 buf[nibbles] = '\0';
322 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
323}
324
325
326static void __init prom_printf(const char *format, ...)
327{
328 const char *p, *q, *s;
329 va_list args;
330 unsigned long v;
331 struct prom_t *_prom = &RELOC(prom);
332
333 va_start(args, format);
334#ifdef CONFIG_PPC64
335 format = PTRRELOC(format);
336#endif
337 for (p = format; *p != 0; p = q) {
338 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
339 ;
340 if (q > p)
341 call_prom("write", 3, 1, _prom->stdout, p, q - p);
342 if (*q == 0)
343 break;
344 if (*q == '\n') {
345 ++q;
346 call_prom("write", 3, 1, _prom->stdout,
347 ADDR("\r\n"), 2);
348 continue;
349 }
350 ++q;
351 if (*q == 0)
352 break;
353 switch (*q) {
354 case 's':
355 ++q;
356 s = va_arg(args, const char *);
357 prom_print(s);
358 break;
359 case 'x':
360 ++q;
361 v = va_arg(args, unsigned long);
362 prom_print_hex(v);
363 break;
364 }
365 }
366}
367
368
Paul Mackerrasa575b802005-10-23 17:23:21 +1000369static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
370 unsigned long align)
371{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000372 struct prom_t *_prom = &RELOC(prom);
373
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100374 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
375 /*
376 * Old OF requires we claim physical and virtual separately
377 * and then map explicitly (assuming virtual mode)
378 */
379 int ret;
380 prom_arg_t result;
381
382 ret = call_prom_ret("call-method", 5, 2, &result,
383 ADDR("claim"), _prom->memory,
384 align, size, virt);
385 if (ret != 0 || result == -1)
386 return -1;
387 ret = call_prom_ret("call-method", 5, 2, &result,
388 ADDR("claim"), _prom->mmumap,
389 align, size, virt);
390 if (ret != 0) {
391 call_prom("call-method", 4, 1, ADDR("release"),
392 _prom->memory, size, virt);
393 return -1;
394 }
395 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000396 call_prom("call-method", 6, 1,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100397 ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
398 return virt;
399 }
400 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
401 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000402}
403
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000404static void __init __attribute__((noreturn)) prom_panic(const char *reason)
405{
406#ifdef CONFIG_PPC64
407 reason = PTRRELOC(reason);
408#endif
409 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100410 /* Do not call exit because it clears the screen on pmac
411 * it also causes some sort of double-fault on early pmacs */
412 if (RELOC(of_platform) == PLATFORM_POWERMAC)
413 asm("trap\n");
414
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000415 /* ToDo: should put up an SRC here on p/iSeries */
416 call_prom("exit", 0, 0);
417
418 for (;;) /* should never get here */
419 ;
420}
421
422
423static int __init prom_next_node(phandle *nodep)
424{
425 phandle node;
426
427 if ((node = *nodep) != 0
428 && (*nodep = call_prom("child", 1, 1, node)) != 0)
429 return 1;
430 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
431 return 1;
432 for (;;) {
433 if ((node = call_prom("parent", 1, 1, node)) == 0)
434 return 0;
435 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
436 return 1;
437 }
438}
439
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100440static int inline prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000441 void *value, size_t valuelen)
442{
443 return call_prom("getprop", 4, 1, node, ADDR(pname),
444 (u32)(unsigned long) value, (u32) valuelen);
445}
446
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100447static int inline prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000448{
449 return call_prom("getproplen", 2, 1, node, ADDR(pname));
450}
451
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100452static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000453{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100454 char *p = *str;
455
456 while (*q)
457 *p++ = *q++;
458 *p++ = ' ';
459 *str = p;
460}
461
462static char *tohex(unsigned int x)
463{
464 static char digits[] = "0123456789abcdef";
465 static char result[9];
466 int i;
467
468 result[8] = 0;
469 i = 8;
470 do {
471 --i;
472 result[i] = digits[x & 0xf];
473 x >>= 4;
474 } while (x != 0 && i > 0);
475 return &result[i];
476}
477
478static int __init prom_setprop(phandle node, const char *nodename,
479 const char *pname, void *value, size_t valuelen)
480{
481 char cmd[256], *p;
482
483 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
484 return call_prom("setprop", 4, 1, node, ADDR(pname),
485 (u32)(unsigned long) value, (u32) valuelen);
486
487 /* gah... setprop doesn't work on longtrail, have to use interpret */
488 p = cmd;
489 add_string(&p, "dev");
490 add_string(&p, nodename);
491 add_string(&p, tohex((u32)(unsigned long) value));
492 add_string(&p, tohex(valuelen));
493 add_string(&p, tohex(ADDR(pname)));
494 add_string(&p, tohex(strlen(RELOC(pname))));
495 add_string(&p, "property");
496 *p = 0;
497 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000498}
499
500/* We can't use the standard versions because of RELOC headaches. */
501#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
502 || ('a' <= (c) && (c) <= 'f') \
503 || ('A' <= (c) && (c) <= 'F'))
504
505#define isdigit(c) ('0' <= (c) && (c) <= '9')
506#define islower(c) ('a' <= (c) && (c) <= 'z')
507#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
508
509unsigned long prom_strtoul(const char *cp, const char **endp)
510{
511 unsigned long result = 0, base = 10, value;
512
513 if (*cp == '0') {
514 base = 8;
515 cp++;
516 if (toupper(*cp) == 'X') {
517 cp++;
518 base = 16;
519 }
520 }
521
522 while (isxdigit(*cp) &&
523 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
524 result = result * base + value;
525 cp++;
526 }
527
528 if (endp)
529 *endp = cp;
530
531 return result;
532}
533
534unsigned long prom_memparse(const char *ptr, const char **retptr)
535{
536 unsigned long ret = prom_strtoul(ptr, retptr);
537 int shift = 0;
538
539 /*
540 * We can't use a switch here because GCC *may* generate a
541 * jump table which won't work, because we're not running at
542 * the address we're linked at.
543 */
544 if ('G' == **retptr || 'g' == **retptr)
545 shift = 30;
546
547 if ('M' == **retptr || 'm' == **retptr)
548 shift = 20;
549
550 if ('K' == **retptr || 'k' == **retptr)
551 shift = 10;
552
553 if (shift) {
554 ret <<= shift;
555 (*retptr)++;
556 }
557
558 return ret;
559}
560
561/*
562 * Early parsing of the command line passed to the kernel, used for
563 * "mem=x" and the options that affect the iommu
564 */
565static void __init early_cmdline_parse(void)
566{
567 struct prom_t *_prom = &RELOC(prom);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100568 const char *opt;
569 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000570 int l = 0;
571
572 RELOC(prom_cmd_line[0]) = 0;
573 p = RELOC(prom_cmd_line);
574 if ((long)_prom->chosen > 0)
575 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
576#ifdef CONFIG_CMDLINE
577 if (l == 0) /* dbl check */
578 strlcpy(RELOC(prom_cmd_line),
579 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
580#endif /* CONFIG_CMDLINE */
581 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
582
583#ifdef CONFIG_PPC64
584 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
585 if (opt) {
586 prom_printf("iommu opt is: %s\n", opt);
587 opt += 6;
588 while (*opt && *opt == ' ')
589 opt++;
590 if (!strncmp(opt, RELOC("off"), 3))
591 RELOC(ppc64_iommu_off) = 1;
592 else if (!strncmp(opt, RELOC("force"), 5))
593 RELOC(iommu_force_on) = 1;
594 }
595#endif
596
597 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
598 if (opt) {
599 opt += 4;
600 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
601#ifdef CONFIG_PPC64
602 /* Align to 16 MB == size of ppc64 large page */
603 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
604#endif
605 }
Michael Ellermandcee3032005-12-04 18:39:48 +1100606
607#ifdef CONFIG_KEXEC
608 /*
609 * crashkernel=size@addr specifies the location to reserve for
610 * crash kernel.
611 */
612 opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
613 if (opt) {
614 opt += 12;
Haren Myneni8385a6a2006-01-13 19:15:36 -0800615 RELOC(prom_crashk_size) =
616 prom_memparse(opt, (const char **)&opt);
Michael Ellermandcee3032005-12-04 18:39:48 +1100617
618 if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
619 RELOC(prom_crashk_size)) {
620 prom_printf("Warning: crashkernel size is not "
621 "aligned to 16MB\n");
622 }
623
624 /*
625 * At present, the crash kernel always run at 32MB.
626 * Just ignore whatever user passed.
627 */
628 RELOC(prom_crashk_base) = 0x2000000;
629 if (*opt == '@') {
630 prom_printf("Warning: PPC64 kdump kernel always runs "
631 "at 32 MB\n");
632 }
633 }
634#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000635}
636
637#ifdef CONFIG_PPC_PSERIES
638/*
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000639 * There are two methods for telling firmware what our capabilities are.
640 * Newer machines have an "ibm,client-architecture-support" method on the
641 * root node. For older machines, we have to call the "process-elf-header"
642 * method in the /packages/elf-loader node, passing it a fake 32-bit
643 * ELF header containing a couple of PT_NOTE sections that contain
644 * structures that contain various information.
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000645 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000646
647/*
648 * New method - extensible architecture description vector.
649 *
650 * Because the description vector contains a mix of byte and word
651 * values, we declare it as an unsigned char array, and use this
652 * macro to put word values in.
653 */
654#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
655 ((x) >> 8) & 0xff, (x) & 0xff
656
657/* Option vector bits - generic bits in byte 1 */
658#define OV_IGNORE 0x80 /* ignore this vector */
659#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
660
661/* Option vector 1: processor architectures supported */
662#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
663#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
664#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
665#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
666#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
667#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
668
669/* Option vector 2: Open Firmware options supported */
670#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
671
672/* Option vector 3: processor options supported */
673#define OV3_FP 0x80 /* floating point */
674#define OV3_VMX 0x40 /* VMX/Altivec */
675
676/* Option vector 5: PAPR/OF options supported */
677#define OV5_LPAR 0x80 /* logical partitioning supported */
678#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
679/* ibm,dynamic-reconfiguration-memory property supported */
680#define OV5_DRCONF_MEMORY 0x20
681#define OV5_LARGE_PAGES 0x10 /* large pages supported */
682
683/*
684 * The architecture vector has an array of PVR mask/value pairs,
685 * followed by # option vectors - 1, followed by the option vectors.
686 */
687static unsigned char ibm_architecture_vec[] = {
688 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
Anton Blanchard03054d52006-04-29 09:51:06 +1000689 W(0xffff0000), W(0x003e0000), /* POWER6 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000690 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
691 5 - 1, /* 5 option vectors */
692
693 /* option vector 1: processor architectures supported */
694 3 - 1, /* length */
695 0, /* don't ignore, don't halt */
696 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
697 OV1_PPC_2_04 | OV1_PPC_2_05,
698
699 /* option vector 2: Open Firmware options supported */
700 34 - 1, /* length */
701 OV2_REAL_MODE,
702 0, 0,
703 W(0xffffffff), /* real_base */
704 W(0xffffffff), /* real_size */
705 W(0xffffffff), /* virt_base */
706 W(0xffffffff), /* virt_size */
707 W(0xffffffff), /* load_base */
708 W(64), /* 128MB min RMA */
709 W(0xffffffff), /* full client load */
710 0, /* min RMA percentage of total RAM */
711 48, /* max log_2(hash table size) */
712
713 /* option vector 3: processor options supported */
714 3 - 1, /* length */
715 0, /* don't ignore, don't halt */
716 OV3_FP | OV3_VMX,
717
718 /* option vector 4: IBM PAPR implementation */
719 2 - 1, /* length */
720 0, /* don't halt */
721
722 /* option vector 5: PAPR/OF options */
723 3 - 1, /* length */
724 0, /* don't ignore, don't halt */
725 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
726};
727
728/* Old method - ELF header with PT_NOTE sections */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000729static struct fake_elf {
730 Elf32_Ehdr elfhdr;
731 Elf32_Phdr phdr[2];
732 struct chrpnote {
733 u32 namesz;
734 u32 descsz;
735 u32 type;
736 char name[8]; /* "PowerPC" */
737 struct chrpdesc {
738 u32 real_mode;
739 u32 real_base;
740 u32 real_size;
741 u32 virt_base;
742 u32 virt_size;
743 u32 load_base;
744 } chrpdesc;
745 } chrpnote;
746 struct rpanote {
747 u32 namesz;
748 u32 descsz;
749 u32 type;
750 char name[24]; /* "IBM,RPA-Client-Config" */
751 struct rpadesc {
752 u32 lpar_affinity;
753 u32 min_rmo_size;
754 u32 min_rmo_percent;
755 u32 max_pft_size;
756 u32 splpar;
757 u32 min_load;
758 u32 new_mem_def;
759 u32 ignore_me;
760 } rpadesc;
761 } rpanote;
762} fake_elf = {
763 .elfhdr = {
764 .e_ident = { 0x7f, 'E', 'L', 'F',
765 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
766 .e_type = ET_EXEC, /* yeah right */
767 .e_machine = EM_PPC,
768 .e_version = EV_CURRENT,
769 .e_phoff = offsetof(struct fake_elf, phdr),
770 .e_phentsize = sizeof(Elf32_Phdr),
771 .e_phnum = 2
772 },
773 .phdr = {
774 [0] = {
775 .p_type = PT_NOTE,
776 .p_offset = offsetof(struct fake_elf, chrpnote),
777 .p_filesz = sizeof(struct chrpnote)
778 }, [1] = {
779 .p_type = PT_NOTE,
780 .p_offset = offsetof(struct fake_elf, rpanote),
781 .p_filesz = sizeof(struct rpanote)
782 }
783 },
784 .chrpnote = {
785 .namesz = sizeof("PowerPC"),
786 .descsz = sizeof(struct chrpdesc),
787 .type = 0x1275,
788 .name = "PowerPC",
789 .chrpdesc = {
790 .real_mode = ~0U, /* ~0 means "don't care" */
791 .real_base = ~0U,
792 .real_size = ~0U,
793 .virt_base = ~0U,
794 .virt_size = ~0U,
795 .load_base = ~0U
796 },
797 },
798 .rpanote = {
799 .namesz = sizeof("IBM,RPA-Client-Config"),
800 .descsz = sizeof(struct rpadesc),
801 .type = 0x12759999,
802 .name = "IBM,RPA-Client-Config",
803 .rpadesc = {
804 .lpar_affinity = 0,
805 .min_rmo_size = 64, /* in megabytes */
806 .min_rmo_percent = 0,
807 .max_pft_size = 48, /* 2^48 bytes max PFT size */
808 .splpar = 1,
809 .min_load = ~0U,
810 .new_mem_def = 0
811 }
812 }
813};
814
815static void __init prom_send_capabilities(void)
816{
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000817 ihandle elfloader, root;
818 prom_arg_t ret;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000819
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000820 root = call_prom("open", 1, 1, ADDR("/"));
821 if (root != 0) {
822 /* try calling the ibm,client-architecture-support method */
823 if (call_prom_ret("call-method", 3, 2, &ret,
824 ADDR("ibm,client-architecture-support"),
825 ADDR(ibm_architecture_vec)) == 0) {
826 /* the call exists... */
827 if (ret)
828 prom_printf("WARNING: ibm,client-architecture"
829 "-support call FAILED!\n");
830 call_prom("close", 1, 0, root);
831 return;
832 }
833 call_prom("close", 1, 0, root);
834 }
835
836 /* no ibm,client-architecture-support call, try the old way */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000837 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
838 if (elfloader == 0) {
839 prom_printf("couldn't open /packages/elf-loader\n");
840 return;
841 }
842 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
843 elfloader, ADDR(&fake_elf));
844 call_prom("close", 1, 0, elfloader);
845}
846#endif
847
848/*
849 * Memory allocation strategy... our layout is normally:
850 *
851 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
852 * rare cases, initrd might end up being before the kernel though.
853 * We assume this won't override the final kernel at 0, we have no
854 * provision to handle that in this version, but it should hopefully
855 * never happen.
856 *
857 * alloc_top is set to the top of RMO, eventually shrink down if the
858 * TCEs overlap
859 *
860 * alloc_bottom is set to the top of kernel/initrd
861 *
862 * from there, allocations are done this way : rtas is allocated
863 * topmost, and the device-tree is allocated from the bottom. We try
864 * to grow the device-tree allocation as we progress. If we can't,
865 * then we fail, we don't currently have a facility to restart
866 * elsewhere, but that shouldn't be necessary.
867 *
868 * Note that calls to reserve_mem have to be done explicitly, memory
869 * allocated with either alloc_up or alloc_down isn't automatically
870 * reserved.
871 */
872
873
874/*
875 * Allocates memory in the RMO upward from the kernel/initrd
876 *
877 * When align is 0, this is a special case, it means to allocate in place
878 * at the current location of alloc_bottom or fail (that is basically
879 * extending the previous allocation). Used for the device-tree flattening
880 */
881static unsigned long __init alloc_up(unsigned long size, unsigned long align)
882{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000883 unsigned long base = RELOC(alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000884 unsigned long addr = 0;
885
Paul Mackerrasc49888202005-10-26 21:52:53 +1000886 if (align)
887 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000888 prom_debug("alloc_up(%x, %x)\n", size, align);
889 if (RELOC(ram_top) == 0)
890 prom_panic("alloc_up() called with mem not initialized\n");
891
892 if (align)
893 base = _ALIGN_UP(RELOC(alloc_bottom), align);
894 else
895 base = RELOC(alloc_bottom);
896
897 for(; (base + size) <= RELOC(alloc_top);
898 base = _ALIGN_UP(base + 0x100000, align)) {
899 prom_debug(" trying: 0x%x\n\r", base);
900 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000901 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000902 break;
903 addr = 0;
904 if (align == 0)
905 break;
906 }
907 if (addr == 0)
908 return 0;
909 RELOC(alloc_bottom) = addr;
910
911 prom_debug(" -> %x\n", addr);
912 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
913 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
914 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
915 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
916 prom_debug(" ram_top : %x\n", RELOC(ram_top));
917
918 return addr;
919}
920
921/*
922 * Allocates memory downward, either from top of RMO, or if highmem
923 * is set, from the top of RAM. Note that this one doesn't handle
924 * failures. It does claim memory if highmem is not set.
925 */
926static unsigned long __init alloc_down(unsigned long size, unsigned long align,
927 int highmem)
928{
929 unsigned long base, addr = 0;
930
931 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
932 highmem ? RELOC("(high)") : RELOC("(low)"));
933 if (RELOC(ram_top) == 0)
934 prom_panic("alloc_down() called with mem not initialized\n");
935
936 if (highmem) {
937 /* Carve out storage for the TCE table. */
938 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
939 if (addr <= RELOC(alloc_bottom))
940 return 0;
941 /* Will we bump into the RMO ? If yes, check out that we
942 * didn't overlap existing allocations there, if we did,
943 * we are dead, we must be the first in town !
944 */
945 if (addr < RELOC(rmo_top)) {
946 /* Good, we are first */
947 if (RELOC(alloc_top) == RELOC(rmo_top))
948 RELOC(alloc_top) = RELOC(rmo_top) = addr;
949 else
950 return 0;
951 }
952 RELOC(alloc_top_high) = addr;
953 goto bail;
954 }
955
956 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
957 for (; base > RELOC(alloc_bottom);
958 base = _ALIGN_DOWN(base - 0x100000, align)) {
959 prom_debug(" trying: 0x%x\n\r", base);
960 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000961 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000962 break;
963 addr = 0;
964 }
965 if (addr == 0)
966 return 0;
967 RELOC(alloc_top) = addr;
968
969 bail:
970 prom_debug(" -> %x\n", addr);
971 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
972 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
973 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
974 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
975 prom_debug(" ram_top : %x\n", RELOC(ram_top));
976
977 return addr;
978}
979
980/*
981 * Parse a "reg" cell
982 */
983static unsigned long __init prom_next_cell(int s, cell_t **cellp)
984{
985 cell_t *p = *cellp;
986 unsigned long r = 0;
987
988 /* Ignore more than 2 cells */
989 while (s > sizeof(unsigned long) / 4) {
990 p++;
991 s--;
992 }
993 r = *p++;
994#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +1000995 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000996 r <<= 32;
997 r |= *(p++);
998 }
999#endif
1000 *cellp = p;
1001 return r;
1002}
1003
1004/*
1005 * Very dumb function for adding to the memory reserve list, but
1006 * we don't need anything smarter at this point
1007 *
1008 * XXX Eventually check for collisions. They should NEVER happen.
1009 * If problems seem to show up, it would be a good start to track
1010 * them down.
1011 */
Kumar Galacbbcf342006-01-11 17:57:13 -06001012static void reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001013{
Kumar Galacbbcf342006-01-11 17:57:13 -06001014 u64 top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001015 unsigned long cnt = RELOC(mem_reserve_cnt);
1016
1017 if (size == 0)
1018 return;
1019
1020 /* We need to always keep one empty entry so that we
1021 * have our terminator with "size" set to 0 since we are
1022 * dumb and just copy this entire array to the boot params
1023 */
1024 base = _ALIGN_DOWN(base, PAGE_SIZE);
1025 top = _ALIGN_UP(top, PAGE_SIZE);
1026 size = top - base;
1027
1028 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1029 prom_panic("Memory reserve map exhausted !\n");
1030 RELOC(mem_reserve_map)[cnt].base = base;
1031 RELOC(mem_reserve_map)[cnt].size = size;
1032 RELOC(mem_reserve_cnt) = cnt + 1;
1033}
1034
1035/*
1036 * Initialize memory allocation mecanism, parse "memory" nodes and
1037 * obtain that way the top of memory and RMO to setup out local allocator
1038 */
1039static void __init prom_init_mem(void)
1040{
1041 phandle node;
1042 char *path, type[64];
1043 unsigned int plen;
1044 cell_t *p, *endp;
1045 struct prom_t *_prom = &RELOC(prom);
1046 u32 rac, rsc;
1047
1048 /*
1049 * We iterate the memory nodes to find
1050 * 1) top of RMO (first node)
1051 * 2) top of memory
1052 */
1053 rac = 2;
1054 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1055 rsc = 1;
1056 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1057 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1058 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1059
1060 prom_debug("scanning memory:\n");
1061 path = RELOC(prom_scratch);
1062
1063 for (node = 0; prom_next_node(&node); ) {
1064 type[0] = 0;
1065 prom_getprop(node, "device_type", type, sizeof(type));
1066
Paul Mackerrasc49888202005-10-26 21:52:53 +10001067 if (type[0] == 0) {
1068 /*
1069 * CHRP Longtrail machines have no device_type
1070 * on the memory node, so check the name instead...
1071 */
1072 prom_getprop(node, "name", type, sizeof(type));
1073 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001074 if (strcmp(type, RELOC("memory")))
1075 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001076
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001077 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1078 if (plen > sizeof(regbuf)) {
1079 prom_printf("memory node too large for buffer !\n");
1080 plen = sizeof(regbuf);
1081 }
1082 p = RELOC(regbuf);
1083 endp = p + (plen / sizeof(cell_t));
1084
1085#ifdef DEBUG_PROM
1086 memset(path, 0, PROM_SCRATCH_SIZE);
1087 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1088 prom_debug(" node %s :\n", path);
1089#endif /* DEBUG_PROM */
1090
1091 while ((endp - p) >= (rac + rsc)) {
1092 unsigned long base, size;
1093
1094 base = prom_next_cell(rac, &p);
1095 size = prom_next_cell(rsc, &p);
1096
1097 if (size == 0)
1098 continue;
1099 prom_debug(" %x %x\n", base, size);
Benjamin Herrenschmidtab1b55e2006-03-03 10:35:40 +11001100 if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001101 RELOC(rmo_top) = size;
1102 if ((base + size) > RELOC(ram_top))
1103 RELOC(ram_top) = base + size;
1104 }
1105 }
1106
1107 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1108
1109 /* Check if we have an initrd after the kernel, if we do move our bottom
1110 * point to after it
1111 */
1112 if (RELOC(prom_initrd_start)) {
1113 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1114 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1115 }
1116
1117 /*
1118 * If prom_memory_limit is set we reduce the upper limits *except* for
1119 * alloc_top_high. This must be the real top of RAM so we can put
1120 * TCE's up there.
1121 */
1122
1123 RELOC(alloc_top_high) = RELOC(ram_top);
1124
1125 if (RELOC(prom_memory_limit)) {
1126 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
1127 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
1128 RELOC(prom_memory_limit));
1129 RELOC(prom_memory_limit) = 0;
1130 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
1131 prom_printf("Ignoring mem=%x >= ram_top.\n",
1132 RELOC(prom_memory_limit));
1133 RELOC(prom_memory_limit) = 0;
1134 } else {
1135 RELOC(ram_top) = RELOC(prom_memory_limit);
1136 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
1137 }
1138 }
1139
1140 /*
1141 * Setup our top alloc point, that is top of RMO or top of
1142 * segment 0 when running non-LPAR.
1143 * Some RS64 machines have buggy firmware where claims up at
1144 * 1GB fail. Cap at 768MB as a workaround.
1145 * Since 768MB is plenty of room, and we need to cap to something
1146 * reasonable on 32-bit, cap at 768MB on all machines.
1147 */
1148 if (!RELOC(rmo_top))
1149 RELOC(rmo_top) = RELOC(ram_top);
1150 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1151 RELOC(alloc_top) = RELOC(rmo_top);
1152
1153 prom_printf("memory layout at init:\n");
1154 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
1155 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1156 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
1157 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1158 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1159 prom_printf(" ram_top : %x\n", RELOC(ram_top));
Michael Ellermandcee3032005-12-04 18:39:48 +11001160#ifdef CONFIG_KEXEC
1161 if (RELOC(prom_crashk_base)) {
1162 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1163 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1164 }
1165#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001166}
1167
1168
1169/*
1170 * Allocate room for and instantiate RTAS
1171 */
1172static void __init prom_instantiate_rtas(void)
1173{
1174 phandle rtas_node;
1175 ihandle rtas_inst;
1176 u32 base, entry = 0;
1177 u32 size = 0;
1178
1179 prom_debug("prom_instantiate_rtas: start...\n");
1180
1181 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1182 prom_debug("rtas_node: %x\n", rtas_node);
1183 if (!PHANDLE_VALID(rtas_node))
1184 return;
1185
1186 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1187 if (size == 0)
1188 return;
1189
1190 base = alloc_down(size, PAGE_SIZE, 0);
1191 if (base == 0) {
1192 prom_printf("RTAS allocation failed !\n");
1193 return;
1194 }
1195
1196 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1197 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001198 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001199 return;
1200 }
1201
1202 prom_printf("instantiating rtas at 0x%x ...", base);
1203
1204 if (call_prom_ret("call-method", 3, 2, &entry,
1205 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001206 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001207 || entry == 0) {
1208 prom_printf(" failed\n");
1209 return;
1210 }
1211 prom_printf(" done\n");
1212
1213 reserve_mem(base, size);
1214
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001215 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1216 &base, sizeof(base));
1217 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1218 &entry, sizeof(entry));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001219
1220 prom_debug("rtas base = 0x%x\n", base);
1221 prom_debug("rtas entry = 0x%x\n", entry);
1222 prom_debug("rtas size = 0x%x\n", (long)size);
1223
1224 prom_debug("prom_instantiate_rtas: end...\n");
1225}
1226
1227#ifdef CONFIG_PPC64
1228/*
1229 * Allocate room for and initialize TCE tables
1230 */
1231static void __init prom_initialize_tce_table(void)
1232{
1233 phandle node;
1234 ihandle phb_node;
1235 char compatible[64], type[64], model[64];
1236 char *path = RELOC(prom_scratch);
1237 u64 base, align;
1238 u32 minalign, minsize;
1239 u64 tce_entry, *tce_entryp;
1240 u64 local_alloc_top, local_alloc_bottom;
1241 u64 i;
1242
1243 if (RELOC(ppc64_iommu_off))
1244 return;
1245
1246 prom_debug("starting prom_initialize_tce_table\n");
1247
1248 /* Cache current top of allocs so we reserve a single block */
1249 local_alloc_top = RELOC(alloc_top_high);
1250 local_alloc_bottom = local_alloc_top;
1251
1252 /* Search all nodes looking for PHBs. */
1253 for (node = 0; prom_next_node(&node); ) {
1254 compatible[0] = 0;
1255 type[0] = 0;
1256 model[0] = 0;
1257 prom_getprop(node, "compatible",
1258 compatible, sizeof(compatible));
1259 prom_getprop(node, "device_type", type, sizeof(type));
1260 prom_getprop(node, "model", model, sizeof(model));
1261
1262 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1263 continue;
1264
1265 /* Keep the old logic in tack to avoid regression. */
1266 if (compatible[0] != 0) {
1267 if ((strstr(compatible, RELOC("python")) == NULL) &&
1268 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1269 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1270 continue;
1271 } else if (model[0] != 0) {
1272 if ((strstr(model, RELOC("ython")) == NULL) &&
1273 (strstr(model, RELOC("peedwagon")) == NULL) &&
1274 (strstr(model, RELOC("innipeg")) == NULL))
1275 continue;
1276 }
1277
1278 if (prom_getprop(node, "tce-table-minalign", &minalign,
1279 sizeof(minalign)) == PROM_ERROR)
1280 minalign = 0;
1281 if (prom_getprop(node, "tce-table-minsize", &minsize,
1282 sizeof(minsize)) == PROM_ERROR)
1283 minsize = 4UL << 20;
1284
1285 /*
1286 * Even though we read what OF wants, we just set the table
1287 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1288 * By doing this, we avoid the pitfalls of trying to DMA to
1289 * MMIO space and the DMA alias hole.
1290 *
1291 * On POWER4, firmware sets the TCE region by assuming
1292 * each TCE table is 8MB. Using this memory for anything
1293 * else will impact performance, so we always allocate 8MB.
1294 * Anton
1295 */
1296 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1297 minsize = 8UL << 20;
1298 else
1299 minsize = 4UL << 20;
1300
1301 /* Align to the greater of the align or size */
1302 align = max(minalign, minsize);
1303 base = alloc_down(minsize, align, 1);
1304 if (base == 0)
1305 prom_panic("ERROR, cannot find space for TCE table.\n");
1306 if (base < local_alloc_bottom)
1307 local_alloc_bottom = base;
1308
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001309 /* It seems OF doesn't null-terminate the path :-( */
1310 memset(path, 0, sizeof(path));
1311 /* Call OF to setup the TCE hardware */
1312 if (call_prom("package-to-path", 3, 1, node,
1313 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1314 prom_printf("package-to-path failed\n");
1315 }
1316
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001317 /* Save away the TCE table attributes for later use. */
1318 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1319 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1320
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001321 prom_debug("TCE table: %s\n", path);
1322 prom_debug("\tnode = 0x%x\n", node);
1323 prom_debug("\tbase = 0x%x\n", base);
1324 prom_debug("\tsize = 0x%x\n", minsize);
1325
1326 /* Initialize the table to have a one-to-one mapping
1327 * over the allocated size.
1328 */
1329 tce_entryp = (unsigned long *)base;
1330 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1331 tce_entry = (i << PAGE_SHIFT);
1332 tce_entry |= 0x3;
1333 *tce_entryp = tce_entry;
1334 }
1335
1336 prom_printf("opening PHB %s", path);
1337 phb_node = call_prom("open", 1, 1, path);
1338 if (phb_node == 0)
1339 prom_printf("... failed\n");
1340 else
1341 prom_printf("... done\n");
1342
1343 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1344 phb_node, -1, minsize,
1345 (u32) base, (u32) (base >> 32));
1346 call_prom("close", 1, 0, phb_node);
1347 }
1348
1349 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1350
1351 if (RELOC(prom_memory_limit)) {
1352 /*
1353 * We align the start to a 16MB boundary so we can map
1354 * the TCE area using large pages if possible.
1355 * The end should be the top of RAM so no need to align it.
1356 */
1357 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
1358 0x1000000);
1359 RELOC(prom_tce_alloc_end) = local_alloc_top;
1360 }
1361
1362 /* Flag the first invalid entry */
1363 prom_debug("ending prom_initialize_tce_table\n");
1364}
1365#endif
1366
1367/*
1368 * With CHRP SMP we need to use the OF to start the other processors.
1369 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1370 * so we have to put the processors into a holding pattern controlled
1371 * by the kernel (not OF) before we destroy the OF.
1372 *
1373 * This uses a chunk of low memory, puts some holding pattern
1374 * code there and sends the other processors off to there until
1375 * smp_boot_cpus tells them to do something. The holding pattern
1376 * checks that address until its cpu # is there, when it is that
1377 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1378 * of setting those values.
1379 *
1380 * We also use physical address 0x4 here to tell when a cpu
1381 * is in its holding pattern code.
1382 *
1383 * -- Cort
1384 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001385extern void __secondary_hold(void);
1386extern unsigned long __secondary_hold_spinloop;
1387extern unsigned long __secondary_hold_acknowledge;
1388
1389/*
1390 * We want to reference the copy of __secondary_hold_* in the
1391 * 0 - 0x100 address range
1392 */
1393#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1394
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001395static void __init prom_hold_cpus(void)
1396{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001397 unsigned long i;
1398 unsigned int reg;
1399 phandle node;
1400 char type[64];
1401 int cpuid = 0;
1402 unsigned int interrupt_server[MAX_CPU_THREADS];
1403 unsigned int cpu_threads, hw_cpu_num;
1404 int propsize;
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001405 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001406 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001407 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001408 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001409 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001410#ifdef CONFIG_PPC64
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001411 /* __secondary_hold is actually a descriptor, not the text address */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001412 unsigned long secondary_hold
1413 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1414#else
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001415 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001416#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001417
1418 prom_debug("prom_hold_cpus: start...\n");
1419 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1420 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1421 prom_debug(" 1) acknowledge = 0x%x\n",
1422 (unsigned long)acknowledge);
1423 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1424 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1425
1426 /* Set the common spinloop variable, so all of the secondary cpus
1427 * will block when they are awakened from their OF spinloop.
1428 * This must occur for both SMP and non SMP kernels, since OF will
1429 * be trashed when we move the kernel.
1430 */
1431 *spinloop = 0;
1432
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001433 /* look for cpus */
1434 for (node = 0; prom_next_node(&node); ) {
1435 type[0] = 0;
1436 prom_getprop(node, "device_type", type, sizeof(type));
1437 if (strcmp(type, RELOC("cpu")) != 0)
1438 continue;
1439
1440 /* Skip non-configured cpus. */
1441 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1442 if (strcmp(type, RELOC("okay")) != 0)
1443 continue;
1444
1445 reg = -1;
1446 prom_getprop(node, "reg", &reg, sizeof(reg));
1447
1448 prom_debug("\ncpuid = 0x%x\n", cpuid);
1449 prom_debug("cpu hw idx = 0x%x\n", reg);
1450
1451 /* Init the acknowledge var which will be reset by
1452 * the secondary cpu when it awakens from its OF
1453 * spinloop.
1454 */
1455 *acknowledge = (unsigned long)-1;
1456
1457 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1458 &interrupt_server,
1459 sizeof(interrupt_server));
1460 if (propsize < 0) {
1461 /* no property. old hardware has no SMT */
1462 cpu_threads = 1;
1463 interrupt_server[0] = reg; /* fake it with phys id */
1464 } else {
1465 /* We have a threaded processor */
1466 cpu_threads = propsize / sizeof(u32);
1467 if (cpu_threads > MAX_CPU_THREADS) {
1468 prom_printf("SMT: too many threads!\n"
1469 "SMT: found %x, max is %x\n",
1470 cpu_threads, MAX_CPU_THREADS);
1471 cpu_threads = 1; /* ToDo: panic? */
1472 }
1473 }
1474
1475 hw_cpu_num = interrupt_server[0];
1476 if (hw_cpu_num != _prom->cpu) {
1477 /* Primary Thread of non-boot cpu */
1478 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1479 call_prom("start-cpu", 3, 0, node,
1480 secondary_hold, reg);
1481
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001482 for (i = 0; (i < 100000000) &&
1483 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001484 mb();
1485
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001486 if (*acknowledge == reg)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001487 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001488 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001489 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001490 }
1491#ifdef CONFIG_SMP
1492 else
1493 prom_printf("%x : boot cpu %x\n", cpuid, reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001494#endif /* CONFIG_SMP */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001495
1496 /* Reserve cpu #s for secondary threads. They start later. */
1497 cpuid += cpu_threads;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001498 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001499
1500 if (cpuid > NR_CPUS)
1501 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1502 ") exceeded: ignoring extras\n");
1503
1504 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001505}
1506
1507
1508static void __init prom_init_client_services(unsigned long pp)
1509{
1510 struct prom_t *_prom = &RELOC(prom);
1511
1512 /* Get a handle to the prom entry point before anything else */
1513 RELOC(prom_entry) = pp;
1514
1515 /* get a handle for the stdout device */
1516 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1517 if (!PHANDLE_VALID(_prom->chosen))
1518 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1519
1520 /* get device tree root */
1521 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1522 if (!PHANDLE_VALID(_prom->root))
1523 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001524
1525 _prom->mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001526}
1527
Paul Mackerrasa575b802005-10-23 17:23:21 +10001528#ifdef CONFIG_PPC32
1529/*
1530 * For really old powermacs, we need to map things we claim.
1531 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001532 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001533 */
1534static void __init prom_find_mmu(void)
1535{
1536 struct prom_t *_prom = &RELOC(prom);
1537 phandle oprom;
1538 char version[64];
1539
1540 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1541 if (!PHANDLE_VALID(oprom))
1542 return;
1543 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1544 return;
1545 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001546 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001547 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1548 of_workarounds = OF_WA_CLAIM;
1549 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1550 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1551 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1552 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001553 return;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001554 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
Paul Mackerrasa575b802005-10-23 17:23:21 +10001555 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1556 sizeof(_prom->mmumap));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001557 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1558 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001559}
1560#else
1561#define prom_find_mmu()
1562#endif
1563
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001564static void __init prom_init_stdout(void)
1565{
1566 struct prom_t *_prom = &RELOC(prom);
1567 char *path = RELOC(of_stdout_device);
1568 char type[16];
1569 u32 val;
1570
1571 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1572 prom_panic("cannot find stdout");
1573
1574 _prom->stdout = val;
1575
1576 /* Get the full OF pathname of the stdout device */
1577 memset(path, 0, 256);
1578 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1579 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001580 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1581 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001582 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001583 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1584 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001585
1586 /* If it's a display, note it */
1587 memset(type, 0, sizeof(type));
1588 prom_getprop(val, "device_type", type, sizeof(type));
1589 if (strcmp(type, RELOC("display")) == 0)
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001590 prom_setprop(val, path, "linux,boot-display", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001591}
1592
1593static void __init prom_close_stdin(void)
1594{
1595 struct prom_t *_prom = &RELOC(prom);
1596 ihandle val;
1597
1598 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1599 call_prom("close", 1, 0, val);
1600}
1601
1602static int __init prom_find_machine_type(void)
1603{
1604 struct prom_t *_prom = &RELOC(prom);
1605 char compat[256];
1606 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001607#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001608 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001609 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001610#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001611
1612 /* Look for a PowerMac */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001613 len = prom_getprop(_prom->root, "compatible",
1614 compat, sizeof(compat)-1);
1615 if (len > 0) {
1616 compat[len] = 0;
1617 while (i < len) {
1618 char *p = &compat[i];
1619 int sl = strlen(p);
1620 if (sl == 0)
1621 break;
1622 if (strstr(p, RELOC("Power Macintosh")) ||
Paul Mackerrasa575b802005-10-23 17:23:21 +10001623 strstr(p, RELOC("MacRISC")))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001624 return PLATFORM_POWERMAC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001625 i += sl + 1;
1626 }
1627 }
1628#ifdef CONFIG_PPC64
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001629 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1630 * PAPR compliant platform. We assume it is if :
1631 * - /device_type is "chrp" (please, do NOT use that for future
1632 * non-IBM designs !
1633 * - it has /rtas
1634 */
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001635 len = prom_getprop(_prom->root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001636 compat, sizeof(compat)-1);
1637 if (len <= 0)
1638 return PLATFORM_GENERIC;
Benjamin Herrenschmidtcb6b2eb2006-05-15 15:46:03 +10001639 if (strcmp(compat, RELOC("chrp")))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001640 return PLATFORM_GENERIC;
1641
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001642 /* Default to pSeries. We need to know if we are running LPAR */
1643 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001644 if (!PHANDLE_VALID(rtas))
1645 return PLATFORM_GENERIC;
1646 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1647 if (x != PROM_ERROR) {
1648 prom_printf("Hypertas detected, assuming LPAR !\n");
1649 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001650 }
1651 return PLATFORM_PSERIES;
1652#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001653 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001654#endif
1655}
1656
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001657static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1658{
1659 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1660}
1661
1662/*
1663 * If we have a display that we don't know how to drive,
1664 * we will want to try to execute OF's open method for it
1665 * later. However, OF will probably fall over if we do that
1666 * we've taken over the MMU.
1667 * So we check whether we will need to open the display,
1668 * and if so, open it now.
1669 */
1670static void __init prom_check_displays(void)
1671{
1672 char type[16], *path;
1673 phandle node;
1674 ihandle ih;
1675 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001676
1677 static unsigned char default_colors[] = {
1678 0x00, 0x00, 0x00,
1679 0x00, 0x00, 0xaa,
1680 0x00, 0xaa, 0x00,
1681 0x00, 0xaa, 0xaa,
1682 0xaa, 0x00, 0x00,
1683 0xaa, 0x00, 0xaa,
1684 0xaa, 0xaa, 0x00,
1685 0xaa, 0xaa, 0xaa,
1686 0x55, 0x55, 0x55,
1687 0x55, 0x55, 0xff,
1688 0x55, 0xff, 0x55,
1689 0x55, 0xff, 0xff,
1690 0xff, 0x55, 0x55,
1691 0xff, 0x55, 0xff,
1692 0xff, 0xff, 0x55,
1693 0xff, 0xff, 0xff
1694 };
1695 const unsigned char *clut;
1696
1697 prom_printf("Looking for displays\n");
1698 for (node = 0; prom_next_node(&node); ) {
1699 memset(type, 0, sizeof(type));
1700 prom_getprop(node, "device_type", type, sizeof(type));
1701 if (strcmp(type, RELOC("display")) != 0)
1702 continue;
1703
1704 /* It seems OF doesn't null-terminate the path :-( */
1705 path = RELOC(prom_scratch);
1706 memset(path, 0, PROM_SCRATCH_SIZE);
1707
1708 /*
1709 * leave some room at the end of the path for appending extra
1710 * arguments
1711 */
1712 if (call_prom("package-to-path", 3, 1, node, path,
1713 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1714 continue;
1715 prom_printf("found display : %s, opening ... ", path);
1716
1717 ih = call_prom("open", 1, 1, path);
1718 if (ih == 0) {
1719 prom_printf("failed\n");
1720 continue;
1721 }
1722
1723 /* Success */
1724 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001725 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001726
1727 /* Setup a usable color table when the appropriate
1728 * method is available. Should update this to set-colors */
1729 clut = RELOC(default_colors);
1730 for (i = 0; i < 32; i++, clut += 3)
1731 if (prom_set_color(ih, i, clut[0], clut[1],
1732 clut[2]) != 0)
1733 break;
1734
1735#ifdef CONFIG_LOGO_LINUX_CLUT224
1736 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1737 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1738 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1739 clut[2]) != 0)
1740 break;
1741#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001742 }
1743}
1744
1745
1746/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1747static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1748 unsigned long needed, unsigned long align)
1749{
1750 void *ret;
1751
1752 *mem_start = _ALIGN(*mem_start, align);
1753 while ((*mem_start + needed) > *mem_end) {
1754 unsigned long room, chunk;
1755
1756 prom_debug("Chunk exhausted, claiming more at %x...\n",
1757 RELOC(alloc_bottom));
1758 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1759 if (room > DEVTREE_CHUNK_SIZE)
1760 room = DEVTREE_CHUNK_SIZE;
1761 if (room < PAGE_SIZE)
1762 prom_panic("No memory for flatten_device_tree (no room)");
1763 chunk = alloc_up(room, 0);
1764 if (chunk == 0)
1765 prom_panic("No memory for flatten_device_tree (claim failed)");
1766 *mem_end = RELOC(alloc_top);
1767 }
1768
1769 ret = (void *)*mem_start;
1770 *mem_start += needed;
1771
1772 return ret;
1773}
1774
1775#define dt_push_token(token, mem_start, mem_end) \
1776 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1777
1778static unsigned long __init dt_find_string(char *str)
1779{
1780 char *s, *os;
1781
1782 s = os = (char *)RELOC(dt_string_start);
1783 s += 4;
1784 while (s < (char *)RELOC(dt_string_end)) {
1785 if (strcmp(s, str) == 0)
1786 return s - os;
1787 s += strlen(s) + 1;
1788 }
1789 return 0;
1790}
1791
1792/*
1793 * The Open Firmware 1275 specification states properties must be 31 bytes or
1794 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1795 */
1796#define MAX_PROPERTY_NAME 64
1797
1798static void __init scan_dt_build_strings(phandle node,
1799 unsigned long *mem_start,
1800 unsigned long *mem_end)
1801{
1802 char *prev_name, *namep, *sstart;
1803 unsigned long soff;
1804 phandle child;
1805
1806 sstart = (char *)RELOC(dt_string_start);
1807
1808 /* get and store all property names */
1809 prev_name = RELOC("");
1810 for (;;) {
1811 /* 64 is max len of name including nul. */
1812 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1813 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1814 /* No more nodes: unwind alloc */
1815 *mem_start = (unsigned long)namep;
1816 break;
1817 }
1818
1819 /* skip "name" */
1820 if (strcmp(namep, RELOC("name")) == 0) {
1821 *mem_start = (unsigned long)namep;
1822 prev_name = RELOC("name");
1823 continue;
1824 }
1825 /* get/create string entry */
1826 soff = dt_find_string(namep);
1827 if (soff != 0) {
1828 *mem_start = (unsigned long)namep;
1829 namep = sstart + soff;
1830 } else {
1831 /* Trim off some if we can */
1832 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1833 RELOC(dt_string_end) = *mem_start;
1834 }
1835 prev_name = namep;
1836 }
1837
1838 /* do all our children */
1839 child = call_prom("child", 1, 1, node);
1840 while (child != 0) {
1841 scan_dt_build_strings(child, mem_start, mem_end);
1842 child = call_prom("peer", 1, 1, child);
1843 }
1844}
1845
1846static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1847 unsigned long *mem_end)
1848{
1849 phandle child;
1850 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1851 unsigned long soff;
1852 unsigned char *valp;
1853 static char pname[MAX_PROPERTY_NAME];
Paul Mackerrasc49888202005-10-26 21:52:53 +10001854 int l, room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001855
1856 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1857
1858 /* get the node's full name */
1859 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001860 room = *mem_end - *mem_start;
1861 if (room > 255)
1862 room = 255;
1863 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001864 if (l >= 0) {
1865 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10001866 if (l >= room) {
1867 if (l >= *mem_end - *mem_start)
1868 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001869 call_prom("package-to-path", 3, 1, node, namep, l);
1870 }
1871 namep[l] = '\0';
1872
1873 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10001874 * middle of the path in some properties, and extract
1875 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001876 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001877 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001878 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10001879 lp = namep;
1880 else if (*p != 0)
1881 *lp++ = *p;
1882 }
1883 *lp = 0;
1884 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001885 }
1886
1887 /* get it again for debugging */
1888 path = RELOC(prom_scratch);
1889 memset(path, 0, PROM_SCRATCH_SIZE);
1890 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1891
1892 /* get and store all properties */
1893 prev_name = RELOC("");
1894 sstart = (char *)RELOC(dt_string_start);
1895 for (;;) {
1896 if (call_prom("nextprop", 3, 1, node, prev_name,
1897 RELOC(pname)) != 1)
1898 break;
1899
1900 /* skip "name" */
1901 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1902 prev_name = RELOC("name");
1903 continue;
1904 }
1905
1906 /* find string offset */
1907 soff = dt_find_string(RELOC(pname));
1908 if (soff == 0) {
1909 prom_printf("WARNING: Can't find string index for"
1910 " <%s>, node %s\n", RELOC(pname), path);
1911 break;
1912 }
1913 prev_name = sstart + soff;
1914
1915 /* get length */
1916 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1917
1918 /* sanity checks */
1919 if (l == PROM_ERROR)
1920 continue;
1921 if (l > MAX_PROPERTY_LENGTH) {
1922 prom_printf("WARNING: ignoring large property ");
1923 /* It seems OF doesn't null-terminate the path :-( */
1924 prom_printf("[%s] ", path);
1925 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1926 continue;
1927 }
1928
1929 /* push property head */
1930 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1931 dt_push_token(l, mem_start, mem_end);
1932 dt_push_token(soff, mem_start, mem_end);
1933
1934 /* push property content */
1935 valp = make_room(mem_start, mem_end, l, 4);
1936 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1937 *mem_start = _ALIGN(*mem_start, 4);
1938 }
1939
1940 /* Add a "linux,phandle" property. */
1941 soff = dt_find_string(RELOC("linux,phandle"));
1942 if (soff == 0)
1943 prom_printf("WARNING: Can't find string index for"
1944 " <linux-phandle> node %s\n", path);
1945 else {
1946 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1947 dt_push_token(4, mem_start, mem_end);
1948 dt_push_token(soff, mem_start, mem_end);
1949 valp = make_room(mem_start, mem_end, 4, 4);
1950 *(u32 *)valp = node;
1951 }
1952
1953 /* do all our children */
1954 child = call_prom("child", 1, 1, node);
1955 while (child != 0) {
1956 scan_dt_build_struct(child, mem_start, mem_end);
1957 child = call_prom("peer", 1, 1, child);
1958 }
1959
1960 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1961}
1962
1963static void __init flatten_device_tree(void)
1964{
1965 phandle root;
1966 unsigned long mem_start, mem_end, room;
1967 struct boot_param_header *hdr;
1968 struct prom_t *_prom = &RELOC(prom);
1969 char *namep;
1970 u64 *rsvmap;
1971
1972 /*
1973 * Check how much room we have between alloc top & bottom (+/- a
1974 * few pages), crop to 4Mb, as this is our "chuck" size
1975 */
1976 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1977 if (room > DEVTREE_CHUNK_SIZE)
1978 room = DEVTREE_CHUNK_SIZE;
1979 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1980
1981 /* Now try to claim that */
1982 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1983 if (mem_start == 0)
1984 prom_panic("Can't allocate initial device-tree chunk\n");
1985 mem_end = RELOC(alloc_top);
1986
1987 /* Get root of tree */
1988 root = call_prom("peer", 1, 1, (phandle)0);
1989 if (root == (phandle)0)
1990 prom_panic ("couldn't get device tree root\n");
1991
1992 /* Build header and make room for mem rsv map */
1993 mem_start = _ALIGN(mem_start, 4);
1994 hdr = make_room(&mem_start, &mem_end,
1995 sizeof(struct boot_param_header), 4);
1996 RELOC(dt_header_start) = (unsigned long)hdr;
1997 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1998
1999 /* Start of strings */
2000 mem_start = PAGE_ALIGN(mem_start);
2001 RELOC(dt_string_start) = mem_start;
2002 mem_start += 4; /* hole */
2003
2004 /* Add "linux,phandle" in there, we'll need it */
2005 namep = make_room(&mem_start, &mem_end, 16, 1);
2006 strcpy(namep, RELOC("linux,phandle"));
2007 mem_start = (unsigned long)namep + strlen(namep) + 1;
2008
2009 /* Build string array */
2010 prom_printf("Building dt strings...\n");
2011 scan_dt_build_strings(root, &mem_start, &mem_end);
2012 RELOC(dt_string_end) = mem_start;
2013
2014 /* Build structure */
2015 mem_start = PAGE_ALIGN(mem_start);
2016 RELOC(dt_struct_start) = mem_start;
2017 prom_printf("Building dt structure...\n");
2018 scan_dt_build_struct(root, &mem_start, &mem_end);
2019 dt_push_token(OF_DT_END, &mem_start, &mem_end);
2020 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
2021
2022 /* Finish header */
2023 hdr->boot_cpuid_phys = _prom->cpu;
2024 hdr->magic = OF_DT_HEADER;
2025 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
2026 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
2027 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
2028 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
2029 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
2030 hdr->version = OF_DT_VERSION;
2031 /* Version 16 is not backward compatible */
2032 hdr->last_comp_version = 0x10;
2033
2034 /* Reserve the whole thing and copy the reserve map in, we
2035 * also bump mem_reserve_cnt to cause further reservations to
2036 * fail since it's too late.
2037 */
2038 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
2039 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
2040
2041#ifdef DEBUG_PROM
2042 {
2043 int i;
2044 prom_printf("reserved memory map:\n");
2045 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
2046 prom_printf(" %x - %x\n",
2047 RELOC(mem_reserve_map)[i].base,
2048 RELOC(mem_reserve_map)[i].size);
2049 }
2050#endif
2051 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2052
2053 prom_printf("Device tree strings 0x%x -> 0x%x\n",
2054 RELOC(dt_string_start), RELOC(dt_string_end));
2055 prom_printf("Device tree struct 0x%x -> 0x%x\n",
2056 RELOC(dt_struct_start), RELOC(dt_struct_end));
2057
2058}
2059
2060
2061static void __init fixup_device_tree(void)
2062{
2063#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2064 phandle u3, i2c, mpic;
2065 u32 u3_rev;
2066 u32 interrupts[2];
2067 u32 parent;
2068
2069 /* Some G5s have a missing interrupt definition, fix it up here */
2070 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2071 if (!PHANDLE_VALID(u3))
2072 return;
2073 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2074 if (!PHANDLE_VALID(i2c))
2075 return;
2076 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2077 if (!PHANDLE_VALID(mpic))
2078 return;
2079
2080 /* check if proper rev of u3 */
2081 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2082 == PROM_ERROR)
2083 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002084 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002085 return;
2086 /* does it need fixup ? */
2087 if (prom_getproplen(i2c, "interrupts") > 0)
2088 return;
2089
2090 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2091
2092 /* interrupt on this revision of u3 is number 0 and level */
2093 interrupts[0] = 0;
2094 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002095 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2096 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002097 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002098 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2099 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002100#endif
2101}
2102
2103
2104static void __init prom_find_boot_cpu(void)
2105{
2106 struct prom_t *_prom = &RELOC(prom);
2107 u32 getprop_rval;
2108 ihandle prom_cpu;
2109 phandle cpu_pkg;
2110
Paul Mackerrasa575b802005-10-23 17:23:21 +10002111 _prom->cpu = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002112 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002113 return;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002114
2115 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2116
2117 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2118 _prom->cpu = getprop_rval;
2119
2120 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2121}
2122
2123static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2124{
2125#ifdef CONFIG_BLK_DEV_INITRD
2126 struct prom_t *_prom = &RELOC(prom);
2127
2128 if (r3 && r4 && r4 != 0xdeadbeef) {
2129 unsigned long val;
2130
Michael Ellerman51fae6de2005-12-04 18:39:15 +11002131 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002132 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2133
2134 val = RELOC(prom_initrd_start);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002135 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2136 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002137 val = RELOC(prom_initrd_end);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002138 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2139 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002140
2141 reserve_mem(RELOC(prom_initrd_start),
2142 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2143
2144 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2145 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2146 }
2147#endif /* CONFIG_BLK_DEV_INITRD */
2148}
2149
2150/*
2151 * We enter here early on, when the Open Firmware prom is still
2152 * handling exceptions and the MMU hash table for us.
2153 */
2154
2155unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2156 unsigned long pp,
2157 unsigned long r6, unsigned long r7)
2158{
2159 struct prom_t *_prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002160 unsigned long hdr;
Paul Mackerrasb42b6612005-10-10 22:37:16 +10002161 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002162
2163#ifdef CONFIG_PPC32
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002164 reloc_got2(offset);
2165#endif
2166
2167 _prom = &RELOC(prom);
2168
2169 /*
2170 * First zero the BSS
2171 */
2172 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2173
2174 /*
2175 * Init interface to Open Firmware, get some node references,
2176 * like /chosen
2177 */
2178 prom_init_client_services(pp);
2179
2180 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002181 * See if this OF is old enough that we need to do explicit maps
2182 * and other workarounds
2183 */
2184 prom_find_mmu();
2185
2186 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002187 * Init prom stdout device
2188 */
2189 prom_init_stdout();
2190
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002191 /*
2192 * Get default machine type. At this point, we do not differentiate
2193 * between pSeries SMP and pSeries LPAR
2194 */
2195 RELOC(of_platform) = prom_find_machine_type();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002196
Olaf Heringadd60ef2006-03-23 22:03:57 +01002197 /* Bail if this is a kdump kernel. */
2198 if (PHYSICAL_START > 0)
2199 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
2200
2201 /*
2202 * Check for an initrd
2203 */
2204 prom_check_initrd(r3, r4);
2205
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002206#ifdef CONFIG_PPC_PSERIES
2207 /*
2208 * On pSeries, inform the firmware about our capabilities
2209 */
Paul Mackerras799d6042005-11-10 13:37:51 +11002210 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2211 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002212 prom_send_capabilities();
2213#endif
2214
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002215 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002216 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002217 */
David Gibson55d36332005-10-13 15:46:22 +10002218 if (RELOC(of_platform) != PLATFORM_POWERMAC)
Paul Mackerras5a408322005-10-10 22:41:25 +10002219 copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002220
2221 /*
2222 * Do early parsing of command line
2223 */
2224 early_cmdline_parse();
2225
2226 /*
2227 * Initialize memory management within prom_init
2228 */
2229 prom_init_mem();
2230
Michael Ellermandcee3032005-12-04 18:39:48 +11002231#ifdef CONFIG_KEXEC
2232 if (RELOC(prom_crashk_base))
2233 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2234#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002235 /*
2236 * Determine which cpu is actually running right _now_
2237 */
2238 prom_find_boot_cpu();
2239
2240 /*
2241 * Initialize display devices
2242 */
2243 prom_check_displays();
2244
2245#ifdef CONFIG_PPC64
2246 /*
2247 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2248 * that uses the allocator, we need to make sure we get the top of memory
2249 * available for us here...
2250 */
2251 if (RELOC(of_platform) == PLATFORM_PSERIES)
2252 prom_initialize_tce_table();
2253#endif
2254
2255 /*
2256 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2257 * in spin-loops. PowerMacs don't have a working RTAS and use
2258 * a different way to spin CPUs
2259 */
2260 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2261 prom_instantiate_rtas();
2262 prom_hold_cpus();
2263 }
2264
2265 /*
2266 * Fill in some infos for use by the kernel later on
2267 */
2268 if (RELOC(prom_memory_limit))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002269 prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002270 &RELOC(prom_memory_limit),
2271 sizeof(prom_memory_limit));
2272#ifdef CONFIG_PPC64
2273 if (RELOC(ppc64_iommu_off))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002274 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2275 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002276
2277 if (RELOC(iommu_force_on))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002278 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2279 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002280
2281 if (RELOC(prom_tce_alloc_start)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002282 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002283 &RELOC(prom_tce_alloc_start),
2284 sizeof(prom_tce_alloc_start));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002285 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002286 &RELOC(prom_tce_alloc_end),
2287 sizeof(prom_tce_alloc_end));
2288 }
2289#endif
2290
Michael Ellermandcee3032005-12-04 18:39:48 +11002291#ifdef CONFIG_KEXEC
2292 if (RELOC(prom_crashk_base)) {
2293 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2294 PTRRELOC(&prom_crashk_base),
2295 sizeof(RELOC(prom_crashk_base)));
2296 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2297 PTRRELOC(&prom_crashk_size),
2298 sizeof(RELOC(prom_crashk_size)));
2299 }
2300#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002301 /*
2302 * Fixup any known bugs in the device-tree
2303 */
2304 fixup_device_tree();
2305
2306 /*
2307 * Now finally create the flattened device-tree
2308 */
2309 prom_printf("copying OF device tree ...\n");
2310 flatten_device_tree();
2311
Paul Mackerras3825ac02005-11-08 22:48:08 +11002312 /*
2313 * in case stdin is USB and still active on IBM machines...
2314 * Unfortunately quiesce crashes on some powermacs if we have
2315 * closed stdin already (in particular the powerbook 101).
2316 */
2317 if (RELOC(of_platform) != PLATFORM_POWERMAC)
2318 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002319
2320 /*
2321 * Call OF "quiesce" method to shut down pending DMA's from
2322 * devices etc...
2323 */
2324 prom_printf("Calling quiesce ...\n");
2325 call_prom("quiesce", 0, 0);
2326
2327 /*
2328 * And finally, call the kernel passing it the flattened device
2329 * tree and NULL as r5, thus triggering the new entry point which
2330 * is common to us and kexec
2331 */
2332 hdr = RELOC(dt_header_start);
2333 prom_printf("returning from prom_init\n");
2334 prom_debug("->dt_header_start=0x%x\n", hdr);
2335
2336#ifdef CONFIG_PPC32
2337 reloc_got2(-offset);
2338#endif
2339
Paul Mackerras35499c02005-10-22 16:02:39 +10002340 __start(hdr, KERNELBASE + offset, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002341
2342 return 0;
2343}