blob: 00ad7f981a0d7014efc4350adc0c965955055f8c [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+ */
689 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
690 5 - 1, /* 5 option vectors */
691
692 /* option vector 1: processor architectures supported */
693 3 - 1, /* length */
694 0, /* don't ignore, don't halt */
695 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
696 OV1_PPC_2_04 | OV1_PPC_2_05,
697
698 /* option vector 2: Open Firmware options supported */
699 34 - 1, /* length */
700 OV2_REAL_MODE,
701 0, 0,
702 W(0xffffffff), /* real_base */
703 W(0xffffffff), /* real_size */
704 W(0xffffffff), /* virt_base */
705 W(0xffffffff), /* virt_size */
706 W(0xffffffff), /* load_base */
707 W(64), /* 128MB min RMA */
708 W(0xffffffff), /* full client load */
709 0, /* min RMA percentage of total RAM */
710 48, /* max log_2(hash table size) */
711
712 /* option vector 3: processor options supported */
713 3 - 1, /* length */
714 0, /* don't ignore, don't halt */
715 OV3_FP | OV3_VMX,
716
717 /* option vector 4: IBM PAPR implementation */
718 2 - 1, /* length */
719 0, /* don't halt */
720
721 /* option vector 5: PAPR/OF options */
722 3 - 1, /* length */
723 0, /* don't ignore, don't halt */
724 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
725};
726
727/* Old method - ELF header with PT_NOTE sections */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000728static struct fake_elf {
729 Elf32_Ehdr elfhdr;
730 Elf32_Phdr phdr[2];
731 struct chrpnote {
732 u32 namesz;
733 u32 descsz;
734 u32 type;
735 char name[8]; /* "PowerPC" */
736 struct chrpdesc {
737 u32 real_mode;
738 u32 real_base;
739 u32 real_size;
740 u32 virt_base;
741 u32 virt_size;
742 u32 load_base;
743 } chrpdesc;
744 } chrpnote;
745 struct rpanote {
746 u32 namesz;
747 u32 descsz;
748 u32 type;
749 char name[24]; /* "IBM,RPA-Client-Config" */
750 struct rpadesc {
751 u32 lpar_affinity;
752 u32 min_rmo_size;
753 u32 min_rmo_percent;
754 u32 max_pft_size;
755 u32 splpar;
756 u32 min_load;
757 u32 new_mem_def;
758 u32 ignore_me;
759 } rpadesc;
760 } rpanote;
761} fake_elf = {
762 .elfhdr = {
763 .e_ident = { 0x7f, 'E', 'L', 'F',
764 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
765 .e_type = ET_EXEC, /* yeah right */
766 .e_machine = EM_PPC,
767 .e_version = EV_CURRENT,
768 .e_phoff = offsetof(struct fake_elf, phdr),
769 .e_phentsize = sizeof(Elf32_Phdr),
770 .e_phnum = 2
771 },
772 .phdr = {
773 [0] = {
774 .p_type = PT_NOTE,
775 .p_offset = offsetof(struct fake_elf, chrpnote),
776 .p_filesz = sizeof(struct chrpnote)
777 }, [1] = {
778 .p_type = PT_NOTE,
779 .p_offset = offsetof(struct fake_elf, rpanote),
780 .p_filesz = sizeof(struct rpanote)
781 }
782 },
783 .chrpnote = {
784 .namesz = sizeof("PowerPC"),
785 .descsz = sizeof(struct chrpdesc),
786 .type = 0x1275,
787 .name = "PowerPC",
788 .chrpdesc = {
789 .real_mode = ~0U, /* ~0 means "don't care" */
790 .real_base = ~0U,
791 .real_size = ~0U,
792 .virt_base = ~0U,
793 .virt_size = ~0U,
794 .load_base = ~0U
795 },
796 },
797 .rpanote = {
798 .namesz = sizeof("IBM,RPA-Client-Config"),
799 .descsz = sizeof(struct rpadesc),
800 .type = 0x12759999,
801 .name = "IBM,RPA-Client-Config",
802 .rpadesc = {
803 .lpar_affinity = 0,
804 .min_rmo_size = 64, /* in megabytes */
805 .min_rmo_percent = 0,
806 .max_pft_size = 48, /* 2^48 bytes max PFT size */
807 .splpar = 1,
808 .min_load = ~0U,
809 .new_mem_def = 0
810 }
811 }
812};
813
814static void __init prom_send_capabilities(void)
815{
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000816 ihandle elfloader, root;
817 prom_arg_t ret;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000818
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000819 root = call_prom("open", 1, 1, ADDR("/"));
820 if (root != 0) {
821 /* try calling the ibm,client-architecture-support method */
822 if (call_prom_ret("call-method", 3, 2, &ret,
823 ADDR("ibm,client-architecture-support"),
824 ADDR(ibm_architecture_vec)) == 0) {
825 /* the call exists... */
826 if (ret)
827 prom_printf("WARNING: ibm,client-architecture"
828 "-support call FAILED!\n");
829 call_prom("close", 1, 0, root);
830 return;
831 }
832 call_prom("close", 1, 0, root);
833 }
834
835 /* no ibm,client-architecture-support call, try the old way */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000836 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
837 if (elfloader == 0) {
838 prom_printf("couldn't open /packages/elf-loader\n");
839 return;
840 }
841 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
842 elfloader, ADDR(&fake_elf));
843 call_prom("close", 1, 0, elfloader);
844}
845#endif
846
847/*
848 * Memory allocation strategy... our layout is normally:
849 *
850 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
851 * rare cases, initrd might end up being before the kernel though.
852 * We assume this won't override the final kernel at 0, we have no
853 * provision to handle that in this version, but it should hopefully
854 * never happen.
855 *
856 * alloc_top is set to the top of RMO, eventually shrink down if the
857 * TCEs overlap
858 *
859 * alloc_bottom is set to the top of kernel/initrd
860 *
861 * from there, allocations are done this way : rtas is allocated
862 * topmost, and the device-tree is allocated from the bottom. We try
863 * to grow the device-tree allocation as we progress. If we can't,
864 * then we fail, we don't currently have a facility to restart
865 * elsewhere, but that shouldn't be necessary.
866 *
867 * Note that calls to reserve_mem have to be done explicitly, memory
868 * allocated with either alloc_up or alloc_down isn't automatically
869 * reserved.
870 */
871
872
873/*
874 * Allocates memory in the RMO upward from the kernel/initrd
875 *
876 * When align is 0, this is a special case, it means to allocate in place
877 * at the current location of alloc_bottom or fail (that is basically
878 * extending the previous allocation). Used for the device-tree flattening
879 */
880static unsigned long __init alloc_up(unsigned long size, unsigned long align)
881{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000882 unsigned long base = RELOC(alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000883 unsigned long addr = 0;
884
Paul Mackerrasc49888202005-10-26 21:52:53 +1000885 if (align)
886 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000887 prom_debug("alloc_up(%x, %x)\n", size, align);
888 if (RELOC(ram_top) == 0)
889 prom_panic("alloc_up() called with mem not initialized\n");
890
891 if (align)
892 base = _ALIGN_UP(RELOC(alloc_bottom), align);
893 else
894 base = RELOC(alloc_bottom);
895
896 for(; (base + size) <= RELOC(alloc_top);
897 base = _ALIGN_UP(base + 0x100000, align)) {
898 prom_debug(" trying: 0x%x\n\r", base);
899 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000900 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000901 break;
902 addr = 0;
903 if (align == 0)
904 break;
905 }
906 if (addr == 0)
907 return 0;
908 RELOC(alloc_bottom) = addr;
909
910 prom_debug(" -> %x\n", addr);
911 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
912 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
913 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
914 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
915 prom_debug(" ram_top : %x\n", RELOC(ram_top));
916
917 return addr;
918}
919
920/*
921 * Allocates memory downward, either from top of RMO, or if highmem
922 * is set, from the top of RAM. Note that this one doesn't handle
923 * failures. It does claim memory if highmem is not set.
924 */
925static unsigned long __init alloc_down(unsigned long size, unsigned long align,
926 int highmem)
927{
928 unsigned long base, addr = 0;
929
930 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
931 highmem ? RELOC("(high)") : RELOC("(low)"));
932 if (RELOC(ram_top) == 0)
933 prom_panic("alloc_down() called with mem not initialized\n");
934
935 if (highmem) {
936 /* Carve out storage for the TCE table. */
937 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
938 if (addr <= RELOC(alloc_bottom))
939 return 0;
940 /* Will we bump into the RMO ? If yes, check out that we
941 * didn't overlap existing allocations there, if we did,
942 * we are dead, we must be the first in town !
943 */
944 if (addr < RELOC(rmo_top)) {
945 /* Good, we are first */
946 if (RELOC(alloc_top) == RELOC(rmo_top))
947 RELOC(alloc_top) = RELOC(rmo_top) = addr;
948 else
949 return 0;
950 }
951 RELOC(alloc_top_high) = addr;
952 goto bail;
953 }
954
955 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
956 for (; base > RELOC(alloc_bottom);
957 base = _ALIGN_DOWN(base - 0x100000, align)) {
958 prom_debug(" trying: 0x%x\n\r", base);
959 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000960 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000961 break;
962 addr = 0;
963 }
964 if (addr == 0)
965 return 0;
966 RELOC(alloc_top) = addr;
967
968 bail:
969 prom_debug(" -> %x\n", addr);
970 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
971 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
972 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
973 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
974 prom_debug(" ram_top : %x\n", RELOC(ram_top));
975
976 return addr;
977}
978
979/*
980 * Parse a "reg" cell
981 */
982static unsigned long __init prom_next_cell(int s, cell_t **cellp)
983{
984 cell_t *p = *cellp;
985 unsigned long r = 0;
986
987 /* Ignore more than 2 cells */
988 while (s > sizeof(unsigned long) / 4) {
989 p++;
990 s--;
991 }
992 r = *p++;
993#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +1000994 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000995 r <<= 32;
996 r |= *(p++);
997 }
998#endif
999 *cellp = p;
1000 return r;
1001}
1002
1003/*
1004 * Very dumb function for adding to the memory reserve list, but
1005 * we don't need anything smarter at this point
1006 *
1007 * XXX Eventually check for collisions. They should NEVER happen.
1008 * If problems seem to show up, it would be a good start to track
1009 * them down.
1010 */
Kumar Galacbbcf342006-01-11 17:57:13 -06001011static void reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001012{
Kumar Galacbbcf342006-01-11 17:57:13 -06001013 u64 top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001014 unsigned long cnt = RELOC(mem_reserve_cnt);
1015
1016 if (size == 0)
1017 return;
1018
1019 /* We need to always keep one empty entry so that we
1020 * have our terminator with "size" set to 0 since we are
1021 * dumb and just copy this entire array to the boot params
1022 */
1023 base = _ALIGN_DOWN(base, PAGE_SIZE);
1024 top = _ALIGN_UP(top, PAGE_SIZE);
1025 size = top - base;
1026
1027 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1028 prom_panic("Memory reserve map exhausted !\n");
1029 RELOC(mem_reserve_map)[cnt].base = base;
1030 RELOC(mem_reserve_map)[cnt].size = size;
1031 RELOC(mem_reserve_cnt) = cnt + 1;
1032}
1033
1034/*
1035 * Initialize memory allocation mecanism, parse "memory" nodes and
1036 * obtain that way the top of memory and RMO to setup out local allocator
1037 */
1038static void __init prom_init_mem(void)
1039{
1040 phandle node;
1041 char *path, type[64];
1042 unsigned int plen;
1043 cell_t *p, *endp;
1044 struct prom_t *_prom = &RELOC(prom);
1045 u32 rac, rsc;
1046
1047 /*
1048 * We iterate the memory nodes to find
1049 * 1) top of RMO (first node)
1050 * 2) top of memory
1051 */
1052 rac = 2;
1053 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1054 rsc = 1;
1055 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1056 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1057 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1058
1059 prom_debug("scanning memory:\n");
1060 path = RELOC(prom_scratch);
1061
1062 for (node = 0; prom_next_node(&node); ) {
1063 type[0] = 0;
1064 prom_getprop(node, "device_type", type, sizeof(type));
1065
Paul Mackerrasc49888202005-10-26 21:52:53 +10001066 if (type[0] == 0) {
1067 /*
1068 * CHRP Longtrail machines have no device_type
1069 * on the memory node, so check the name instead...
1070 */
1071 prom_getprop(node, "name", type, sizeof(type));
1072 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001073 if (strcmp(type, RELOC("memory")))
1074 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001075
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001076 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1077 if (plen > sizeof(regbuf)) {
1078 prom_printf("memory node too large for buffer !\n");
1079 plen = sizeof(regbuf);
1080 }
1081 p = RELOC(regbuf);
1082 endp = p + (plen / sizeof(cell_t));
1083
1084#ifdef DEBUG_PROM
1085 memset(path, 0, PROM_SCRATCH_SIZE);
1086 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1087 prom_debug(" node %s :\n", path);
1088#endif /* DEBUG_PROM */
1089
1090 while ((endp - p) >= (rac + rsc)) {
1091 unsigned long base, size;
1092
1093 base = prom_next_cell(rac, &p);
1094 size = prom_next_cell(rsc, &p);
1095
1096 if (size == 0)
1097 continue;
1098 prom_debug(" %x %x\n", base, size);
Benjamin Herrenschmidtab1b55e2006-03-03 10:35:40 +11001099 if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001100 RELOC(rmo_top) = size;
1101 if ((base + size) > RELOC(ram_top))
1102 RELOC(ram_top) = base + size;
1103 }
1104 }
1105
1106 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1107
1108 /* Check if we have an initrd after the kernel, if we do move our bottom
1109 * point to after it
1110 */
1111 if (RELOC(prom_initrd_start)) {
1112 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1113 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1114 }
1115
1116 /*
1117 * If prom_memory_limit is set we reduce the upper limits *except* for
1118 * alloc_top_high. This must be the real top of RAM so we can put
1119 * TCE's up there.
1120 */
1121
1122 RELOC(alloc_top_high) = RELOC(ram_top);
1123
1124 if (RELOC(prom_memory_limit)) {
1125 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
1126 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
1127 RELOC(prom_memory_limit));
1128 RELOC(prom_memory_limit) = 0;
1129 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
1130 prom_printf("Ignoring mem=%x >= ram_top.\n",
1131 RELOC(prom_memory_limit));
1132 RELOC(prom_memory_limit) = 0;
1133 } else {
1134 RELOC(ram_top) = RELOC(prom_memory_limit);
1135 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
1136 }
1137 }
1138
1139 /*
1140 * Setup our top alloc point, that is top of RMO or top of
1141 * segment 0 when running non-LPAR.
1142 * Some RS64 machines have buggy firmware where claims up at
1143 * 1GB fail. Cap at 768MB as a workaround.
1144 * Since 768MB is plenty of room, and we need to cap to something
1145 * reasonable on 32-bit, cap at 768MB on all machines.
1146 */
1147 if (!RELOC(rmo_top))
1148 RELOC(rmo_top) = RELOC(ram_top);
1149 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1150 RELOC(alloc_top) = RELOC(rmo_top);
1151
1152 prom_printf("memory layout at init:\n");
1153 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
1154 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1155 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
1156 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1157 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1158 prom_printf(" ram_top : %x\n", RELOC(ram_top));
Michael Ellermandcee3032005-12-04 18:39:48 +11001159#ifdef CONFIG_KEXEC
1160 if (RELOC(prom_crashk_base)) {
1161 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1162 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1163 }
1164#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001165}
1166
1167
1168/*
1169 * Allocate room for and instantiate RTAS
1170 */
1171static void __init prom_instantiate_rtas(void)
1172{
1173 phandle rtas_node;
1174 ihandle rtas_inst;
1175 u32 base, entry = 0;
1176 u32 size = 0;
1177
1178 prom_debug("prom_instantiate_rtas: start...\n");
1179
1180 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1181 prom_debug("rtas_node: %x\n", rtas_node);
1182 if (!PHANDLE_VALID(rtas_node))
1183 return;
1184
1185 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1186 if (size == 0)
1187 return;
1188
1189 base = alloc_down(size, PAGE_SIZE, 0);
1190 if (base == 0) {
1191 prom_printf("RTAS allocation failed !\n");
1192 return;
1193 }
1194
1195 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1196 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001197 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001198 return;
1199 }
1200
1201 prom_printf("instantiating rtas at 0x%x ...", base);
1202
1203 if (call_prom_ret("call-method", 3, 2, &entry,
1204 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001205 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001206 || entry == 0) {
1207 prom_printf(" failed\n");
1208 return;
1209 }
1210 prom_printf(" done\n");
1211
1212 reserve_mem(base, size);
1213
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001214 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1215 &base, sizeof(base));
1216 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1217 &entry, sizeof(entry));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001218
1219 prom_debug("rtas base = 0x%x\n", base);
1220 prom_debug("rtas entry = 0x%x\n", entry);
1221 prom_debug("rtas size = 0x%x\n", (long)size);
1222
1223 prom_debug("prom_instantiate_rtas: end...\n");
1224}
1225
1226#ifdef CONFIG_PPC64
1227/*
1228 * Allocate room for and initialize TCE tables
1229 */
1230static void __init prom_initialize_tce_table(void)
1231{
1232 phandle node;
1233 ihandle phb_node;
1234 char compatible[64], type[64], model[64];
1235 char *path = RELOC(prom_scratch);
1236 u64 base, align;
1237 u32 minalign, minsize;
1238 u64 tce_entry, *tce_entryp;
1239 u64 local_alloc_top, local_alloc_bottom;
1240 u64 i;
1241
1242 if (RELOC(ppc64_iommu_off))
1243 return;
1244
1245 prom_debug("starting prom_initialize_tce_table\n");
1246
1247 /* Cache current top of allocs so we reserve a single block */
1248 local_alloc_top = RELOC(alloc_top_high);
1249 local_alloc_bottom = local_alloc_top;
1250
1251 /* Search all nodes looking for PHBs. */
1252 for (node = 0; prom_next_node(&node); ) {
1253 compatible[0] = 0;
1254 type[0] = 0;
1255 model[0] = 0;
1256 prom_getprop(node, "compatible",
1257 compatible, sizeof(compatible));
1258 prom_getprop(node, "device_type", type, sizeof(type));
1259 prom_getprop(node, "model", model, sizeof(model));
1260
1261 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1262 continue;
1263
1264 /* Keep the old logic in tack to avoid regression. */
1265 if (compatible[0] != 0) {
1266 if ((strstr(compatible, RELOC("python")) == NULL) &&
1267 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1268 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1269 continue;
1270 } else if (model[0] != 0) {
1271 if ((strstr(model, RELOC("ython")) == NULL) &&
1272 (strstr(model, RELOC("peedwagon")) == NULL) &&
1273 (strstr(model, RELOC("innipeg")) == NULL))
1274 continue;
1275 }
1276
1277 if (prom_getprop(node, "tce-table-minalign", &minalign,
1278 sizeof(minalign)) == PROM_ERROR)
1279 minalign = 0;
1280 if (prom_getprop(node, "tce-table-minsize", &minsize,
1281 sizeof(minsize)) == PROM_ERROR)
1282 minsize = 4UL << 20;
1283
1284 /*
1285 * Even though we read what OF wants, we just set the table
1286 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1287 * By doing this, we avoid the pitfalls of trying to DMA to
1288 * MMIO space and the DMA alias hole.
1289 *
1290 * On POWER4, firmware sets the TCE region by assuming
1291 * each TCE table is 8MB. Using this memory for anything
1292 * else will impact performance, so we always allocate 8MB.
1293 * Anton
1294 */
1295 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1296 minsize = 8UL << 20;
1297 else
1298 minsize = 4UL << 20;
1299
1300 /* Align to the greater of the align or size */
1301 align = max(minalign, minsize);
1302 base = alloc_down(minsize, align, 1);
1303 if (base == 0)
1304 prom_panic("ERROR, cannot find space for TCE table.\n");
1305 if (base < local_alloc_bottom)
1306 local_alloc_bottom = base;
1307
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001308 /* It seems OF doesn't null-terminate the path :-( */
1309 memset(path, 0, sizeof(path));
1310 /* Call OF to setup the TCE hardware */
1311 if (call_prom("package-to-path", 3, 1, node,
1312 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1313 prom_printf("package-to-path failed\n");
1314 }
1315
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001316 /* Save away the TCE table attributes for later use. */
1317 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1318 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1319
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001320 prom_debug("TCE table: %s\n", path);
1321 prom_debug("\tnode = 0x%x\n", node);
1322 prom_debug("\tbase = 0x%x\n", base);
1323 prom_debug("\tsize = 0x%x\n", minsize);
1324
1325 /* Initialize the table to have a one-to-one mapping
1326 * over the allocated size.
1327 */
1328 tce_entryp = (unsigned long *)base;
1329 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1330 tce_entry = (i << PAGE_SHIFT);
1331 tce_entry |= 0x3;
1332 *tce_entryp = tce_entry;
1333 }
1334
1335 prom_printf("opening PHB %s", path);
1336 phb_node = call_prom("open", 1, 1, path);
1337 if (phb_node == 0)
1338 prom_printf("... failed\n");
1339 else
1340 prom_printf("... done\n");
1341
1342 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1343 phb_node, -1, minsize,
1344 (u32) base, (u32) (base >> 32));
1345 call_prom("close", 1, 0, phb_node);
1346 }
1347
1348 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1349
1350 if (RELOC(prom_memory_limit)) {
1351 /*
1352 * We align the start to a 16MB boundary so we can map
1353 * the TCE area using large pages if possible.
1354 * The end should be the top of RAM so no need to align it.
1355 */
1356 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
1357 0x1000000);
1358 RELOC(prom_tce_alloc_end) = local_alloc_top;
1359 }
1360
1361 /* Flag the first invalid entry */
1362 prom_debug("ending prom_initialize_tce_table\n");
1363}
1364#endif
1365
1366/*
1367 * With CHRP SMP we need to use the OF to start the other processors.
1368 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1369 * so we have to put the processors into a holding pattern controlled
1370 * by the kernel (not OF) before we destroy the OF.
1371 *
1372 * This uses a chunk of low memory, puts some holding pattern
1373 * code there and sends the other processors off to there until
1374 * smp_boot_cpus tells them to do something. The holding pattern
1375 * checks that address until its cpu # is there, when it is that
1376 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1377 * of setting those values.
1378 *
1379 * We also use physical address 0x4 here to tell when a cpu
1380 * is in its holding pattern code.
1381 *
1382 * -- Cort
1383 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001384extern void __secondary_hold(void);
1385extern unsigned long __secondary_hold_spinloop;
1386extern unsigned long __secondary_hold_acknowledge;
1387
1388/*
1389 * We want to reference the copy of __secondary_hold_* in the
1390 * 0 - 0x100 address range
1391 */
1392#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1393
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001394static void __init prom_hold_cpus(void)
1395{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001396 unsigned long i;
1397 unsigned int reg;
1398 phandle node;
1399 char type[64];
1400 int cpuid = 0;
1401 unsigned int interrupt_server[MAX_CPU_THREADS];
1402 unsigned int cpu_threads, hw_cpu_num;
1403 int propsize;
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001404 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001405 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001406 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001407 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001408 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001409#ifdef CONFIG_PPC64
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001410 /* __secondary_hold is actually a descriptor, not the text address */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001411 unsigned long secondary_hold
1412 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1413#else
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001414 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001415#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001416
1417 prom_debug("prom_hold_cpus: start...\n");
1418 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1419 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1420 prom_debug(" 1) acknowledge = 0x%x\n",
1421 (unsigned long)acknowledge);
1422 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1423 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1424
1425 /* Set the common spinloop variable, so all of the secondary cpus
1426 * will block when they are awakened from their OF spinloop.
1427 * This must occur for both SMP and non SMP kernels, since OF will
1428 * be trashed when we move the kernel.
1429 */
1430 *spinloop = 0;
1431
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001432 /* look for cpus */
1433 for (node = 0; prom_next_node(&node); ) {
1434 type[0] = 0;
1435 prom_getprop(node, "device_type", type, sizeof(type));
1436 if (strcmp(type, RELOC("cpu")) != 0)
1437 continue;
1438
1439 /* Skip non-configured cpus. */
1440 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1441 if (strcmp(type, RELOC("okay")) != 0)
1442 continue;
1443
1444 reg = -1;
1445 prom_getprop(node, "reg", &reg, sizeof(reg));
1446
1447 prom_debug("\ncpuid = 0x%x\n", cpuid);
1448 prom_debug("cpu hw idx = 0x%x\n", reg);
1449
1450 /* Init the acknowledge var which will be reset by
1451 * the secondary cpu when it awakens from its OF
1452 * spinloop.
1453 */
1454 *acknowledge = (unsigned long)-1;
1455
1456 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1457 &interrupt_server,
1458 sizeof(interrupt_server));
1459 if (propsize < 0) {
1460 /* no property. old hardware has no SMT */
1461 cpu_threads = 1;
1462 interrupt_server[0] = reg; /* fake it with phys id */
1463 } else {
1464 /* We have a threaded processor */
1465 cpu_threads = propsize / sizeof(u32);
1466 if (cpu_threads > MAX_CPU_THREADS) {
1467 prom_printf("SMT: too many threads!\n"
1468 "SMT: found %x, max is %x\n",
1469 cpu_threads, MAX_CPU_THREADS);
1470 cpu_threads = 1; /* ToDo: panic? */
1471 }
1472 }
1473
1474 hw_cpu_num = interrupt_server[0];
1475 if (hw_cpu_num != _prom->cpu) {
1476 /* Primary Thread of non-boot cpu */
1477 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1478 call_prom("start-cpu", 3, 0, node,
1479 secondary_hold, reg);
1480
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001481 for (i = 0; (i < 100000000) &&
1482 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001483 mb();
1484
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001485 if (*acknowledge == reg)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001486 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001487 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001488 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001489 }
1490#ifdef CONFIG_SMP
1491 else
1492 prom_printf("%x : boot cpu %x\n", cpuid, reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001493#endif /* CONFIG_SMP */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001494
1495 /* Reserve cpu #s for secondary threads. They start later. */
1496 cpuid += cpu_threads;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001497 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001498
1499 if (cpuid > NR_CPUS)
1500 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1501 ") exceeded: ignoring extras\n");
1502
1503 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001504}
1505
1506
1507static void __init prom_init_client_services(unsigned long pp)
1508{
1509 struct prom_t *_prom = &RELOC(prom);
1510
1511 /* Get a handle to the prom entry point before anything else */
1512 RELOC(prom_entry) = pp;
1513
1514 /* get a handle for the stdout device */
1515 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1516 if (!PHANDLE_VALID(_prom->chosen))
1517 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1518
1519 /* get device tree root */
1520 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1521 if (!PHANDLE_VALID(_prom->root))
1522 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001523
1524 _prom->mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001525}
1526
Paul Mackerrasa575b802005-10-23 17:23:21 +10001527#ifdef CONFIG_PPC32
1528/*
1529 * For really old powermacs, we need to map things we claim.
1530 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001531 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001532 */
1533static void __init prom_find_mmu(void)
1534{
1535 struct prom_t *_prom = &RELOC(prom);
1536 phandle oprom;
1537 char version[64];
1538
1539 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1540 if (!PHANDLE_VALID(oprom))
1541 return;
1542 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1543 return;
1544 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001545 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001546 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1547 of_workarounds = OF_WA_CLAIM;
1548 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1549 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1550 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1551 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001552 return;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001553 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
Paul Mackerrasa575b802005-10-23 17:23:21 +10001554 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1555 sizeof(_prom->mmumap));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001556 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1557 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001558}
1559#else
1560#define prom_find_mmu()
1561#endif
1562
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001563static void __init prom_init_stdout(void)
1564{
1565 struct prom_t *_prom = &RELOC(prom);
1566 char *path = RELOC(of_stdout_device);
1567 char type[16];
1568 u32 val;
1569
1570 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1571 prom_panic("cannot find stdout");
1572
1573 _prom->stdout = val;
1574
1575 /* Get the full OF pathname of the stdout device */
1576 memset(path, 0, 256);
1577 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1578 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001579 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1580 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001581 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001582 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1583 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001584
1585 /* If it's a display, note it */
1586 memset(type, 0, sizeof(type));
1587 prom_getprop(val, "device_type", type, sizeof(type));
1588 if (strcmp(type, RELOC("display")) == 0)
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001589 prom_setprop(val, path, "linux,boot-display", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001590}
1591
1592static void __init prom_close_stdin(void)
1593{
1594 struct prom_t *_prom = &RELOC(prom);
1595 ihandle val;
1596
1597 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1598 call_prom("close", 1, 0, val);
1599}
1600
1601static int __init prom_find_machine_type(void)
1602{
1603 struct prom_t *_prom = &RELOC(prom);
1604 char compat[256];
1605 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001606#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001607 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001608 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001609#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001610
1611 /* Look for a PowerMac */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001612 len = prom_getprop(_prom->root, "compatible",
1613 compat, sizeof(compat)-1);
1614 if (len > 0) {
1615 compat[len] = 0;
1616 while (i < len) {
1617 char *p = &compat[i];
1618 int sl = strlen(p);
1619 if (sl == 0)
1620 break;
1621 if (strstr(p, RELOC("Power Macintosh")) ||
Paul Mackerrasa575b802005-10-23 17:23:21 +10001622 strstr(p, RELOC("MacRISC")))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001623 return PLATFORM_POWERMAC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001624 i += sl + 1;
1625 }
1626 }
1627#ifdef CONFIG_PPC64
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001628 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1629 * PAPR compliant platform. We assume it is if :
1630 * - /device_type is "chrp" (please, do NOT use that for future
1631 * non-IBM designs !
1632 * - it has /rtas
1633 */
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001634 len = prom_getprop(_prom->root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001635 compat, sizeof(compat)-1);
1636 if (len <= 0)
1637 return PLATFORM_GENERIC;
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001638 if (strncmp(compat, RELOC("chrp"), 4))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001639 return PLATFORM_GENERIC;
1640
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001641 /* Default to pSeries. We need to know if we are running LPAR */
1642 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001643 if (!PHANDLE_VALID(rtas))
1644 return PLATFORM_GENERIC;
1645 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1646 if (x != PROM_ERROR) {
1647 prom_printf("Hypertas detected, assuming LPAR !\n");
1648 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001649 }
1650 return PLATFORM_PSERIES;
1651#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001652 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001653#endif
1654}
1655
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001656static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1657{
1658 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1659}
1660
1661/*
1662 * If we have a display that we don't know how to drive,
1663 * we will want to try to execute OF's open method for it
1664 * later. However, OF will probably fall over if we do that
1665 * we've taken over the MMU.
1666 * So we check whether we will need to open the display,
1667 * and if so, open it now.
1668 */
1669static void __init prom_check_displays(void)
1670{
1671 char type[16], *path;
1672 phandle node;
1673 ihandle ih;
1674 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001675
1676 static unsigned char default_colors[] = {
1677 0x00, 0x00, 0x00,
1678 0x00, 0x00, 0xaa,
1679 0x00, 0xaa, 0x00,
1680 0x00, 0xaa, 0xaa,
1681 0xaa, 0x00, 0x00,
1682 0xaa, 0x00, 0xaa,
1683 0xaa, 0xaa, 0x00,
1684 0xaa, 0xaa, 0xaa,
1685 0x55, 0x55, 0x55,
1686 0x55, 0x55, 0xff,
1687 0x55, 0xff, 0x55,
1688 0x55, 0xff, 0xff,
1689 0xff, 0x55, 0x55,
1690 0xff, 0x55, 0xff,
1691 0xff, 0xff, 0x55,
1692 0xff, 0xff, 0xff
1693 };
1694 const unsigned char *clut;
1695
1696 prom_printf("Looking for displays\n");
1697 for (node = 0; prom_next_node(&node); ) {
1698 memset(type, 0, sizeof(type));
1699 prom_getprop(node, "device_type", type, sizeof(type));
1700 if (strcmp(type, RELOC("display")) != 0)
1701 continue;
1702
1703 /* It seems OF doesn't null-terminate the path :-( */
1704 path = RELOC(prom_scratch);
1705 memset(path, 0, PROM_SCRATCH_SIZE);
1706
1707 /*
1708 * leave some room at the end of the path for appending extra
1709 * arguments
1710 */
1711 if (call_prom("package-to-path", 3, 1, node, path,
1712 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1713 continue;
1714 prom_printf("found display : %s, opening ... ", path);
1715
1716 ih = call_prom("open", 1, 1, path);
1717 if (ih == 0) {
1718 prom_printf("failed\n");
1719 continue;
1720 }
1721
1722 /* Success */
1723 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001724 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001725
1726 /* Setup a usable color table when the appropriate
1727 * method is available. Should update this to set-colors */
1728 clut = RELOC(default_colors);
1729 for (i = 0; i < 32; i++, clut += 3)
1730 if (prom_set_color(ih, i, clut[0], clut[1],
1731 clut[2]) != 0)
1732 break;
1733
1734#ifdef CONFIG_LOGO_LINUX_CLUT224
1735 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1736 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1737 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1738 clut[2]) != 0)
1739 break;
1740#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001741 }
1742}
1743
1744
1745/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1746static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1747 unsigned long needed, unsigned long align)
1748{
1749 void *ret;
1750
1751 *mem_start = _ALIGN(*mem_start, align);
1752 while ((*mem_start + needed) > *mem_end) {
1753 unsigned long room, chunk;
1754
1755 prom_debug("Chunk exhausted, claiming more at %x...\n",
1756 RELOC(alloc_bottom));
1757 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1758 if (room > DEVTREE_CHUNK_SIZE)
1759 room = DEVTREE_CHUNK_SIZE;
1760 if (room < PAGE_SIZE)
1761 prom_panic("No memory for flatten_device_tree (no room)");
1762 chunk = alloc_up(room, 0);
1763 if (chunk == 0)
1764 prom_panic("No memory for flatten_device_tree (claim failed)");
1765 *mem_end = RELOC(alloc_top);
1766 }
1767
1768 ret = (void *)*mem_start;
1769 *mem_start += needed;
1770
1771 return ret;
1772}
1773
1774#define dt_push_token(token, mem_start, mem_end) \
1775 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1776
1777static unsigned long __init dt_find_string(char *str)
1778{
1779 char *s, *os;
1780
1781 s = os = (char *)RELOC(dt_string_start);
1782 s += 4;
1783 while (s < (char *)RELOC(dt_string_end)) {
1784 if (strcmp(s, str) == 0)
1785 return s - os;
1786 s += strlen(s) + 1;
1787 }
1788 return 0;
1789}
1790
1791/*
1792 * The Open Firmware 1275 specification states properties must be 31 bytes or
1793 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1794 */
1795#define MAX_PROPERTY_NAME 64
1796
1797static void __init scan_dt_build_strings(phandle node,
1798 unsigned long *mem_start,
1799 unsigned long *mem_end)
1800{
1801 char *prev_name, *namep, *sstart;
1802 unsigned long soff;
1803 phandle child;
1804
1805 sstart = (char *)RELOC(dt_string_start);
1806
1807 /* get and store all property names */
1808 prev_name = RELOC("");
1809 for (;;) {
1810 /* 64 is max len of name including nul. */
1811 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1812 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1813 /* No more nodes: unwind alloc */
1814 *mem_start = (unsigned long)namep;
1815 break;
1816 }
1817
1818 /* skip "name" */
1819 if (strcmp(namep, RELOC("name")) == 0) {
1820 *mem_start = (unsigned long)namep;
1821 prev_name = RELOC("name");
1822 continue;
1823 }
1824 /* get/create string entry */
1825 soff = dt_find_string(namep);
1826 if (soff != 0) {
1827 *mem_start = (unsigned long)namep;
1828 namep = sstart + soff;
1829 } else {
1830 /* Trim off some if we can */
1831 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1832 RELOC(dt_string_end) = *mem_start;
1833 }
1834 prev_name = namep;
1835 }
1836
1837 /* do all our children */
1838 child = call_prom("child", 1, 1, node);
1839 while (child != 0) {
1840 scan_dt_build_strings(child, mem_start, mem_end);
1841 child = call_prom("peer", 1, 1, child);
1842 }
1843}
1844
1845static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1846 unsigned long *mem_end)
1847{
1848 phandle child;
1849 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1850 unsigned long soff;
1851 unsigned char *valp;
1852 static char pname[MAX_PROPERTY_NAME];
Paul Mackerrasc49888202005-10-26 21:52:53 +10001853 int l, room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001854
1855 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1856
1857 /* get the node's full name */
1858 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001859 room = *mem_end - *mem_start;
1860 if (room > 255)
1861 room = 255;
1862 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001863 if (l >= 0) {
1864 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10001865 if (l >= room) {
1866 if (l >= *mem_end - *mem_start)
1867 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001868 call_prom("package-to-path", 3, 1, node, namep, l);
1869 }
1870 namep[l] = '\0';
1871
1872 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10001873 * middle of the path in some properties, and extract
1874 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001875 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001876 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001877 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10001878 lp = namep;
1879 else if (*p != 0)
1880 *lp++ = *p;
1881 }
1882 *lp = 0;
1883 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001884 }
1885
1886 /* get it again for debugging */
1887 path = RELOC(prom_scratch);
1888 memset(path, 0, PROM_SCRATCH_SIZE);
1889 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1890
1891 /* get and store all properties */
1892 prev_name = RELOC("");
1893 sstart = (char *)RELOC(dt_string_start);
1894 for (;;) {
1895 if (call_prom("nextprop", 3, 1, node, prev_name,
1896 RELOC(pname)) != 1)
1897 break;
1898
1899 /* skip "name" */
1900 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1901 prev_name = RELOC("name");
1902 continue;
1903 }
1904
1905 /* find string offset */
1906 soff = dt_find_string(RELOC(pname));
1907 if (soff == 0) {
1908 prom_printf("WARNING: Can't find string index for"
1909 " <%s>, node %s\n", RELOC(pname), path);
1910 break;
1911 }
1912 prev_name = sstart + soff;
1913
1914 /* get length */
1915 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1916
1917 /* sanity checks */
1918 if (l == PROM_ERROR)
1919 continue;
1920 if (l > MAX_PROPERTY_LENGTH) {
1921 prom_printf("WARNING: ignoring large property ");
1922 /* It seems OF doesn't null-terminate the path :-( */
1923 prom_printf("[%s] ", path);
1924 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1925 continue;
1926 }
1927
1928 /* push property head */
1929 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1930 dt_push_token(l, mem_start, mem_end);
1931 dt_push_token(soff, mem_start, mem_end);
1932
1933 /* push property content */
1934 valp = make_room(mem_start, mem_end, l, 4);
1935 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1936 *mem_start = _ALIGN(*mem_start, 4);
1937 }
1938
1939 /* Add a "linux,phandle" property. */
1940 soff = dt_find_string(RELOC("linux,phandle"));
1941 if (soff == 0)
1942 prom_printf("WARNING: Can't find string index for"
1943 " <linux-phandle> node %s\n", path);
1944 else {
1945 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1946 dt_push_token(4, mem_start, mem_end);
1947 dt_push_token(soff, mem_start, mem_end);
1948 valp = make_room(mem_start, mem_end, 4, 4);
1949 *(u32 *)valp = node;
1950 }
1951
1952 /* do all our children */
1953 child = call_prom("child", 1, 1, node);
1954 while (child != 0) {
1955 scan_dt_build_struct(child, mem_start, mem_end);
1956 child = call_prom("peer", 1, 1, child);
1957 }
1958
1959 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1960}
1961
1962static void __init flatten_device_tree(void)
1963{
1964 phandle root;
1965 unsigned long mem_start, mem_end, room;
1966 struct boot_param_header *hdr;
1967 struct prom_t *_prom = &RELOC(prom);
1968 char *namep;
1969 u64 *rsvmap;
1970
1971 /*
1972 * Check how much room we have between alloc top & bottom (+/- a
1973 * few pages), crop to 4Mb, as this is our "chuck" size
1974 */
1975 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1976 if (room > DEVTREE_CHUNK_SIZE)
1977 room = DEVTREE_CHUNK_SIZE;
1978 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1979
1980 /* Now try to claim that */
1981 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1982 if (mem_start == 0)
1983 prom_panic("Can't allocate initial device-tree chunk\n");
1984 mem_end = RELOC(alloc_top);
1985
1986 /* Get root of tree */
1987 root = call_prom("peer", 1, 1, (phandle)0);
1988 if (root == (phandle)0)
1989 prom_panic ("couldn't get device tree root\n");
1990
1991 /* Build header and make room for mem rsv map */
1992 mem_start = _ALIGN(mem_start, 4);
1993 hdr = make_room(&mem_start, &mem_end,
1994 sizeof(struct boot_param_header), 4);
1995 RELOC(dt_header_start) = (unsigned long)hdr;
1996 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1997
1998 /* Start of strings */
1999 mem_start = PAGE_ALIGN(mem_start);
2000 RELOC(dt_string_start) = mem_start;
2001 mem_start += 4; /* hole */
2002
2003 /* Add "linux,phandle" in there, we'll need it */
2004 namep = make_room(&mem_start, &mem_end, 16, 1);
2005 strcpy(namep, RELOC("linux,phandle"));
2006 mem_start = (unsigned long)namep + strlen(namep) + 1;
2007
2008 /* Build string array */
2009 prom_printf("Building dt strings...\n");
2010 scan_dt_build_strings(root, &mem_start, &mem_end);
2011 RELOC(dt_string_end) = mem_start;
2012
2013 /* Build structure */
2014 mem_start = PAGE_ALIGN(mem_start);
2015 RELOC(dt_struct_start) = mem_start;
2016 prom_printf("Building dt structure...\n");
2017 scan_dt_build_struct(root, &mem_start, &mem_end);
2018 dt_push_token(OF_DT_END, &mem_start, &mem_end);
2019 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
2020
2021 /* Finish header */
2022 hdr->boot_cpuid_phys = _prom->cpu;
2023 hdr->magic = OF_DT_HEADER;
2024 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
2025 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
2026 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
2027 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
2028 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
2029 hdr->version = OF_DT_VERSION;
2030 /* Version 16 is not backward compatible */
2031 hdr->last_comp_version = 0x10;
2032
2033 /* Reserve the whole thing and copy the reserve map in, we
2034 * also bump mem_reserve_cnt to cause further reservations to
2035 * fail since it's too late.
2036 */
2037 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
2038 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
2039
2040#ifdef DEBUG_PROM
2041 {
2042 int i;
2043 prom_printf("reserved memory map:\n");
2044 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
2045 prom_printf(" %x - %x\n",
2046 RELOC(mem_reserve_map)[i].base,
2047 RELOC(mem_reserve_map)[i].size);
2048 }
2049#endif
2050 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2051
2052 prom_printf("Device tree strings 0x%x -> 0x%x\n",
2053 RELOC(dt_string_start), RELOC(dt_string_end));
2054 prom_printf("Device tree struct 0x%x -> 0x%x\n",
2055 RELOC(dt_struct_start), RELOC(dt_struct_end));
2056
2057}
2058
2059
2060static void __init fixup_device_tree(void)
2061{
2062#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2063 phandle u3, i2c, mpic;
2064 u32 u3_rev;
2065 u32 interrupts[2];
2066 u32 parent;
2067
2068 /* Some G5s have a missing interrupt definition, fix it up here */
2069 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2070 if (!PHANDLE_VALID(u3))
2071 return;
2072 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2073 if (!PHANDLE_VALID(i2c))
2074 return;
2075 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2076 if (!PHANDLE_VALID(mpic))
2077 return;
2078
2079 /* check if proper rev of u3 */
2080 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2081 == PROM_ERROR)
2082 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002083 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002084 return;
2085 /* does it need fixup ? */
2086 if (prom_getproplen(i2c, "interrupts") > 0)
2087 return;
2088
2089 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2090
2091 /* interrupt on this revision of u3 is number 0 and level */
2092 interrupts[0] = 0;
2093 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002094 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2095 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002096 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002097 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2098 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002099#endif
2100}
2101
2102
2103static void __init prom_find_boot_cpu(void)
2104{
2105 struct prom_t *_prom = &RELOC(prom);
2106 u32 getprop_rval;
2107 ihandle prom_cpu;
2108 phandle cpu_pkg;
2109
Paul Mackerrasa575b802005-10-23 17:23:21 +10002110 _prom->cpu = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002111 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002112 return;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002113
2114 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2115
2116 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2117 _prom->cpu = getprop_rval;
2118
2119 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2120}
2121
2122static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2123{
2124#ifdef CONFIG_BLK_DEV_INITRD
2125 struct prom_t *_prom = &RELOC(prom);
2126
2127 if (r3 && r4 && r4 != 0xdeadbeef) {
2128 unsigned long val;
2129
Michael Ellerman51fae6de2005-12-04 18:39:15 +11002130 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002131 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2132
2133 val = RELOC(prom_initrd_start);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002134 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2135 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002136 val = RELOC(prom_initrd_end);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002137 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2138 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002139
2140 reserve_mem(RELOC(prom_initrd_start),
2141 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2142
2143 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2144 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2145 }
2146#endif /* CONFIG_BLK_DEV_INITRD */
2147}
2148
2149/*
2150 * We enter here early on, when the Open Firmware prom is still
2151 * handling exceptions and the MMU hash table for us.
2152 */
2153
2154unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2155 unsigned long pp,
2156 unsigned long r6, unsigned long r7)
2157{
2158 struct prom_t *_prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002159 unsigned long hdr;
Paul Mackerrasb42b6612005-10-10 22:37:16 +10002160 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002161
2162#ifdef CONFIG_PPC32
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002163 reloc_got2(offset);
2164#endif
2165
2166 _prom = &RELOC(prom);
2167
2168 /*
2169 * First zero the BSS
2170 */
2171 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2172
2173 /*
2174 * Init interface to Open Firmware, get some node references,
2175 * like /chosen
2176 */
2177 prom_init_client_services(pp);
2178
2179 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002180 * See if this OF is old enough that we need to do explicit maps
2181 * and other workarounds
2182 */
2183 prom_find_mmu();
2184
2185 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002186 * Init prom stdout device
2187 */
2188 prom_init_stdout();
2189
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002190 /*
2191 * Get default machine type. At this point, we do not differentiate
2192 * between pSeries SMP and pSeries LPAR
2193 */
2194 RELOC(of_platform) = prom_find_machine_type();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002195
Olaf Heringadd60ef2006-03-23 22:03:57 +01002196 /* Bail if this is a kdump kernel. */
2197 if (PHYSICAL_START > 0)
2198 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
2199
2200 /*
2201 * Check for an initrd
2202 */
2203 prom_check_initrd(r3, r4);
2204
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002205#ifdef CONFIG_PPC_PSERIES
2206 /*
2207 * On pSeries, inform the firmware about our capabilities
2208 */
Paul Mackerras799d6042005-11-10 13:37:51 +11002209 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2210 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002211 prom_send_capabilities();
2212#endif
2213
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002214 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002215 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002216 */
David Gibson55d36332005-10-13 15:46:22 +10002217 if (RELOC(of_platform) != PLATFORM_POWERMAC)
Paul Mackerras5a408322005-10-10 22:41:25 +10002218 copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002219
2220 /*
2221 * Do early parsing of command line
2222 */
2223 early_cmdline_parse();
2224
2225 /*
2226 * Initialize memory management within prom_init
2227 */
2228 prom_init_mem();
2229
Michael Ellermandcee3032005-12-04 18:39:48 +11002230#ifdef CONFIG_KEXEC
2231 if (RELOC(prom_crashk_base))
2232 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2233#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002234 /*
2235 * Determine which cpu is actually running right _now_
2236 */
2237 prom_find_boot_cpu();
2238
2239 /*
2240 * Initialize display devices
2241 */
2242 prom_check_displays();
2243
2244#ifdef CONFIG_PPC64
2245 /*
2246 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2247 * that uses the allocator, we need to make sure we get the top of memory
2248 * available for us here...
2249 */
2250 if (RELOC(of_platform) == PLATFORM_PSERIES)
2251 prom_initialize_tce_table();
2252#endif
2253
2254 /*
2255 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2256 * in spin-loops. PowerMacs don't have a working RTAS and use
2257 * a different way to spin CPUs
2258 */
2259 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2260 prom_instantiate_rtas();
2261 prom_hold_cpus();
2262 }
2263
2264 /*
2265 * Fill in some infos for use by the kernel later on
2266 */
2267 if (RELOC(prom_memory_limit))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002268 prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002269 &RELOC(prom_memory_limit),
2270 sizeof(prom_memory_limit));
2271#ifdef CONFIG_PPC64
2272 if (RELOC(ppc64_iommu_off))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002273 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2274 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002275
2276 if (RELOC(iommu_force_on))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002277 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2278 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002279
2280 if (RELOC(prom_tce_alloc_start)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002281 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002282 &RELOC(prom_tce_alloc_start),
2283 sizeof(prom_tce_alloc_start));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002284 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002285 &RELOC(prom_tce_alloc_end),
2286 sizeof(prom_tce_alloc_end));
2287 }
2288#endif
2289
Michael Ellermandcee3032005-12-04 18:39:48 +11002290#ifdef CONFIG_KEXEC
2291 if (RELOC(prom_crashk_base)) {
2292 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2293 PTRRELOC(&prom_crashk_base),
2294 sizeof(RELOC(prom_crashk_base)));
2295 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2296 PTRRELOC(&prom_crashk_size),
2297 sizeof(RELOC(prom_crashk_size)));
2298 }
2299#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002300 /*
2301 * Fixup any known bugs in the device-tree
2302 */
2303 fixup_device_tree();
2304
2305 /*
2306 * Now finally create the flattened device-tree
2307 */
2308 prom_printf("copying OF device tree ...\n");
2309 flatten_device_tree();
2310
Paul Mackerras3825ac02005-11-08 22:48:08 +11002311 /*
2312 * in case stdin is USB and still active on IBM machines...
2313 * Unfortunately quiesce crashes on some powermacs if we have
2314 * closed stdin already (in particular the powerbook 101).
2315 */
2316 if (RELOC(of_platform) != PLATFORM_POWERMAC)
2317 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002318
2319 /*
2320 * Call OF "quiesce" method to shut down pending DMA's from
2321 * devices etc...
2322 */
2323 prom_printf("Calling quiesce ...\n");
2324 call_prom("quiesce", 0, 0);
2325
2326 /*
2327 * And finally, call the kernel passing it the flattened device
2328 * tree and NULL as r5, thus triggering the new entry point which
2329 * is common to us and kexec
2330 */
2331 hdr = RELOC(dt_header_start);
2332 prom_printf("returning from prom_init\n");
2333 prom_debug("->dt_header_start=0x%x\n", hdr);
2334
2335#ifdef CONFIG_PPC32
2336 reloc_got2(-offset);
2337#endif
2338
Paul Mackerras35499c02005-10-22 16:02:39 +10002339 __start(hdr, KERNELBASE + offset, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002340
2341 return 0;
2342}