blob: 59d5bd1c064d4aabef1b2368a6e02a4c40abe8c5 [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>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100019#include <linux/kernel.h>
20#include <linux/string.h>
21#include <linux/init.h>
22#include <linux/threads.h>
23#include <linux/spinlock.h>
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/proc_fs.h>
27#include <linux/stringify.h>
28#include <linux/delay.h>
29#include <linux/initrd.h>
30#include <linux/bitops.h>
31#include <asm/prom.h>
32#include <asm/rtas.h>
33#include <asm/page.h>
34#include <asm/processor.h>
35#include <asm/irq.h>
36#include <asm/io.h>
37#include <asm/smp.h>
38#include <asm/system.h>
39#include <asm/mmu.h>
40#include <asm/pgtable.h>
41#include <asm/pci.h>
42#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100043#include <asm/btext.h>
44#include <asm/sections.h>
45#include <asm/machdep.h>
46
Paul Mackerras9b6b5632005-10-06 12:06:20 +100047#include <linux/linux_logo.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100048
49/*
50 * Properties whose value is longer than this get excluded from our
51 * copy of the device tree. This value does need to be big enough to
52 * ensure that we don't lose things like the interrupt-map property
53 * on a PCI-PCI bridge.
54 */
55#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
56
57/*
58 * Eventually bump that one up
59 */
60#define DEVTREE_CHUNK_SIZE 0x100000
61
62/*
63 * This is the size of the local memory reserve map that gets copied
64 * into the boot params passed to the kernel. That size is totally
65 * flexible as the kernel just reads the list until it encounters an
66 * entry with size 0, so it can be changed without breaking binary
67 * compatibility
68 */
69#define MEM_RESERVE_MAP_SIZE 8
70
71/*
72 * prom_init() is called very early on, before the kernel text
73 * and data have been mapped to KERNELBASE. At this point the code
74 * is running at whatever address it has been loaded at.
75 * On ppc32 we compile with -mrelocatable, which means that references
76 * to extern and static variables get relocated automatically.
77 * On ppc64 we have to relocate the references explicitly with
78 * RELOC. (Note that strings count as static variables.)
79 *
80 * Because OF may have mapped I/O devices into the area starting at
81 * KERNELBASE, particularly on CHRP machines, we can't safely call
82 * OF once the kernel has been mapped to KERNELBASE. Therefore all
83 * OF calls must be done within prom_init().
84 *
85 * ADDR is used in calls to call_prom. The 4th and following
86 * arguments to call_prom should be 32-bit values.
87 * On ppc64, 64 bit values are truncated to 32 bits (and
88 * fortunately don't get interpreted as two arguments).
89 */
90#ifdef CONFIG_PPC64
91#define RELOC(x) (*PTRRELOC(&(x)))
92#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
Paul Mackerrasa23414b2005-11-10 12:00:55 +110093#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100094#else
95#define RELOC(x) (x)
96#define ADDR(x) (u32) (x)
Paul Mackerrasa23414b2005-11-10 12:00:55 +110097#define OF_WORKAROUNDS of_workarounds
98int of_workarounds;
Paul Mackerras9b6b5632005-10-06 12:06:20 +100099#endif
100
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100101#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
102#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
103
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000104#define PROM_BUG() do { \
105 prom_printf("kernel BUG at %s line 0x%x!\n", \
106 RELOC(__FILE__), __LINE__); \
107 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
108} while (0)
109
110#ifdef DEBUG_PROM
111#define prom_debug(x...) prom_printf(x)
112#else
113#define prom_debug(x...)
114#endif
115
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000116
117typedef u32 prom_arg_t;
118
119struct prom_args {
120 u32 service;
121 u32 nargs;
122 u32 nret;
123 prom_arg_t args[10];
124};
125
126struct prom_t {
127 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100128 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000129 int cpu;
130 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000131 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100132 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000133};
134
135struct mem_map_entry {
Kumar Galacbbcf342006-01-11 17:57:13 -0600136 u64 base;
137 u64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000138};
139
140typedef u32 cell_t;
141
142extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
143
144#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000145extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000146#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000147static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000148{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000149 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000150}
151#endif
152
153extern void copy_and_flush(unsigned long dest, unsigned long src,
154 unsigned long size, unsigned long offset);
155
156/* prom structure */
157static struct prom_t __initdata prom;
158
159static unsigned long prom_entry __initdata;
160
161#define PROM_SCRATCH_SIZE 256
162
163static char __initdata of_stdout_device[256];
164static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
165
166static unsigned long __initdata dt_header_start;
167static unsigned long __initdata dt_struct_start, dt_struct_end;
168static unsigned long __initdata dt_string_start, dt_string_end;
169
170static unsigned long __initdata prom_initrd_start, prom_initrd_end;
171
172#ifdef CONFIG_PPC64
Jeremy Kerr165785e2006-11-11 17:25:18 +1100173static int __initdata prom_iommu_force_on;
174static int __initdata prom_iommu_off;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000175static unsigned long __initdata prom_tce_alloc_start;
176static unsigned long __initdata prom_tce_alloc_end;
177#endif
178
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100179/* Platforms codes are now obsolete in the kernel. Now only used within this
180 * file and ultimately gone too. Feel free to change them if you need, they
181 * are not shared with anything outside of this file anymore
182 */
183#define PLATFORM_PSERIES 0x0100
184#define PLATFORM_PSERIES_LPAR 0x0101
185#define PLATFORM_LPAR 0x0001
186#define PLATFORM_POWERMAC 0x0400
187#define PLATFORM_GENERIC 0x0500
188
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000189static int __initdata of_platform;
190
191static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
192
Benjamin Krillcf687872009-07-27 22:02:39 +0000193static unsigned long __initdata prom_memory_limit;
194
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000195static unsigned long __initdata alloc_top;
196static unsigned long __initdata alloc_top_high;
197static unsigned long __initdata alloc_bottom;
198static unsigned long __initdata rmo_top;
199static unsigned long __initdata ram_top;
200
201static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
202static int __initdata mem_reserve_cnt;
203
204static cell_t __initdata regbuf[1024];
205
206
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000207/*
208 * Error results ... some OF calls will return "-1" on error, some
209 * will return 0, some will return either. To simplify, here are
210 * macros to use with any ihandle or phandle return value to check if
211 * it is valid
212 */
213
214#define PROM_ERROR (-1u)
215#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
216#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
217
218
219/* This is the one and *ONLY* place where we actually call open
220 * firmware.
221 */
222
223static int __init call_prom(const char *service, int nargs, int nret, ...)
224{
225 int i;
226 struct prom_args args;
227 va_list list;
228
229 args.service = ADDR(service);
230 args.nargs = nargs;
231 args.nret = nret;
232
233 va_start(list, nret);
234 for (i = 0; i < nargs; i++)
235 args.args[i] = va_arg(list, prom_arg_t);
236 va_end(list);
237
238 for (i = 0; i < nret; i++)
239 args.args[nargs+i] = 0;
240
Paul Mackerrasc49888202005-10-26 21:52:53 +1000241 if (enter_prom(&args, RELOC(prom_entry)) < 0)
242 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000243
244 return (nret > 0) ? args.args[nargs] : 0;
245}
246
247static int __init call_prom_ret(const char *service, int nargs, int nret,
248 prom_arg_t *rets, ...)
249{
250 int i;
251 struct prom_args args;
252 va_list list;
253
254 args.service = ADDR(service);
255 args.nargs = nargs;
256 args.nret = nret;
257
258 va_start(list, rets);
259 for (i = 0; i < nargs; i++)
260 args.args[i] = va_arg(list, prom_arg_t);
261 va_end(list);
262
263 for (i = 0; i < nret; i++)
Olaf Heringed1189b2005-11-29 14:04:05 +0100264 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000265
Paul Mackerrasc49888202005-10-26 21:52:53 +1000266 if (enter_prom(&args, RELOC(prom_entry)) < 0)
267 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000268
269 if (rets != NULL)
270 for (i = 1; i < nret; ++i)
Paul Mackerrasc5200c92005-10-10 22:57:03 +1000271 rets[i-1] = args.args[nargs+i];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000272
273 return (nret > 0) ? args.args[nargs] : 0;
274}
275
276
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000277static void __init prom_print(const char *msg)
278{
279 const char *p, *q;
280 struct prom_t *_prom = &RELOC(prom);
281
282 if (_prom->stdout == 0)
283 return;
284
285 for (p = msg; *p != 0; p = q) {
286 for (q = p; *q != 0 && *q != '\n'; ++q)
287 ;
288 if (q > p)
289 call_prom("write", 3, 1, _prom->stdout, p, q - p);
290 if (*q == 0)
291 break;
292 ++q;
293 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
294 }
295}
296
297
298static void __init prom_print_hex(unsigned long val)
299{
300 int i, nibbles = sizeof(val)*2;
301 char buf[sizeof(val)*2+1];
302 struct prom_t *_prom = &RELOC(prom);
303
304 for (i = nibbles-1; i >= 0; i--) {
305 buf[i] = (val & 0xf) + '0';
306 if (buf[i] > '9')
307 buf[i] += ('a'-'0'-10);
308 val >>= 4;
309 }
310 buf[nibbles] = '\0';
311 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
312}
313
314
315static void __init prom_printf(const char *format, ...)
316{
317 const char *p, *q, *s;
318 va_list args;
319 unsigned long v;
320 struct prom_t *_prom = &RELOC(prom);
321
322 va_start(args, format);
323#ifdef CONFIG_PPC64
324 format = PTRRELOC(format);
325#endif
326 for (p = format; *p != 0; p = q) {
327 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
328 ;
329 if (q > p)
330 call_prom("write", 3, 1, _prom->stdout, p, q - p);
331 if (*q == 0)
332 break;
333 if (*q == '\n') {
334 ++q;
335 call_prom("write", 3, 1, _prom->stdout,
336 ADDR("\r\n"), 2);
337 continue;
338 }
339 ++q;
340 if (*q == 0)
341 break;
342 switch (*q) {
343 case 's':
344 ++q;
345 s = va_arg(args, const char *);
346 prom_print(s);
347 break;
348 case 'x':
349 ++q;
350 v = va_arg(args, unsigned long);
351 prom_print_hex(v);
352 break;
353 }
354 }
355}
356
357
Paul Mackerrasa575b802005-10-23 17:23:21 +1000358static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
359 unsigned long align)
360{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000361 struct prom_t *_prom = &RELOC(prom);
362
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100363 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
364 /*
365 * Old OF requires we claim physical and virtual separately
366 * and then map explicitly (assuming virtual mode)
367 */
368 int ret;
369 prom_arg_t result;
370
371 ret = call_prom_ret("call-method", 5, 2, &result,
372 ADDR("claim"), _prom->memory,
373 align, size, virt);
374 if (ret != 0 || result == -1)
375 return -1;
376 ret = call_prom_ret("call-method", 5, 2, &result,
377 ADDR("claim"), _prom->mmumap,
378 align, size, virt);
379 if (ret != 0) {
380 call_prom("call-method", 4, 1, ADDR("release"),
381 _prom->memory, size, virt);
382 return -1;
383 }
384 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000385 call_prom("call-method", 6, 1,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100386 ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
387 return virt;
388 }
389 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
390 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000391}
392
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000393static void __init __attribute__((noreturn)) prom_panic(const char *reason)
394{
395#ifdef CONFIG_PPC64
396 reason = PTRRELOC(reason);
397#endif
398 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100399 /* Do not call exit because it clears the screen on pmac
400 * it also causes some sort of double-fault on early pmacs */
401 if (RELOC(of_platform) == PLATFORM_POWERMAC)
402 asm("trap\n");
403
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000404 /* ToDo: should put up an SRC here on p/iSeries */
405 call_prom("exit", 0, 0);
406
407 for (;;) /* should never get here */
408 ;
409}
410
411
412static int __init prom_next_node(phandle *nodep)
413{
414 phandle node;
415
416 if ((node = *nodep) != 0
417 && (*nodep = call_prom("child", 1, 1, node)) != 0)
418 return 1;
419 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
420 return 1;
421 for (;;) {
422 if ((node = call_prom("parent", 1, 1, node)) == 0)
423 return 0;
424 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
425 return 1;
426 }
427}
428
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100429static int inline prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000430 void *value, size_t valuelen)
431{
432 return call_prom("getprop", 4, 1, node, ADDR(pname),
433 (u32)(unsigned long) value, (u32) valuelen);
434}
435
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100436static int inline prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000437{
438 return call_prom("getproplen", 2, 1, node, ADDR(pname));
439}
440
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100441static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000442{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100443 char *p = *str;
444
445 while (*q)
446 *p++ = *q++;
447 *p++ = ' ';
448 *str = p;
449}
450
451static char *tohex(unsigned int x)
452{
453 static char digits[] = "0123456789abcdef";
454 static char result[9];
455 int i;
456
457 result[8] = 0;
458 i = 8;
459 do {
460 --i;
461 result[i] = digits[x & 0xf];
462 x >>= 4;
463 } while (x != 0 && i > 0);
464 return &result[i];
465}
466
467static int __init prom_setprop(phandle node, const char *nodename,
468 const char *pname, void *value, size_t valuelen)
469{
470 char cmd[256], *p;
471
472 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
473 return call_prom("setprop", 4, 1, node, ADDR(pname),
474 (u32)(unsigned long) value, (u32) valuelen);
475
476 /* gah... setprop doesn't work on longtrail, have to use interpret */
477 p = cmd;
478 add_string(&p, "dev");
479 add_string(&p, nodename);
480 add_string(&p, tohex((u32)(unsigned long) value));
481 add_string(&p, tohex(valuelen));
482 add_string(&p, tohex(ADDR(pname)));
483 add_string(&p, tohex(strlen(RELOC(pname))));
484 add_string(&p, "property");
485 *p = 0;
486 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000487}
488
Benjamin Krillcf687872009-07-27 22:02:39 +0000489/* We can't use the standard versions because of RELOC headaches. */
490#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
491 || ('a' <= (c) && (c) <= 'f') \
492 || ('A' <= (c) && (c) <= 'F'))
493
494#define isdigit(c) ('0' <= (c) && (c) <= '9')
495#define islower(c) ('a' <= (c) && (c) <= 'z')
496#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
497
498unsigned long prom_strtoul(const char *cp, const char **endp)
499{
500 unsigned long result = 0, base = 10, value;
501
502 if (*cp == '0') {
503 base = 8;
504 cp++;
505 if (toupper(*cp) == 'X') {
506 cp++;
507 base = 16;
508 }
509 }
510
511 while (isxdigit(*cp) &&
512 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
513 result = result * base + value;
514 cp++;
515 }
516
517 if (endp)
518 *endp = cp;
519
520 return result;
521}
522
523unsigned long prom_memparse(const char *ptr, const char **retptr)
524{
525 unsigned long ret = prom_strtoul(ptr, retptr);
526 int shift = 0;
527
528 /*
529 * We can't use a switch here because GCC *may* generate a
530 * jump table which won't work, because we're not running at
531 * the address we're linked at.
532 */
533 if ('G' == **retptr || 'g' == **retptr)
534 shift = 30;
535
536 if ('M' == **retptr || 'm' == **retptr)
537 shift = 20;
538
539 if ('K' == **retptr || 'k' == **retptr)
540 shift = 10;
541
542 if (shift) {
543 ret <<= shift;
544 (*retptr)++;
545 }
546
547 return ret;
548}
549
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000550/*
551 * Early parsing of the command line passed to the kernel, used for
552 * "mem=x" and the options that affect the iommu
553 */
554static void __init early_cmdline_parse(void)
555{
556 struct prom_t *_prom = &RELOC(prom);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100557 const char *opt;
Benjamin Krillcf687872009-07-27 22:02:39 +0000558
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100559 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000560 int l = 0;
561
562 RELOC(prom_cmd_line[0]) = 0;
563 p = RELOC(prom_cmd_line);
564 if ((long)_prom->chosen > 0)
565 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
566#ifdef CONFIG_CMDLINE
Amos Waterland0e4aa9c2006-06-12 23:45:02 -0400567 if (l <= 0 || p[0] == '\0') /* dbl check */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000568 strlcpy(RELOC(prom_cmd_line),
569 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
570#endif /* CONFIG_CMDLINE */
571 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
572
573#ifdef CONFIG_PPC64
574 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
575 if (opt) {
576 prom_printf("iommu opt is: %s\n", opt);
577 opt += 6;
578 while (*opt && *opt == ' ')
579 opt++;
580 if (!strncmp(opt, RELOC("off"), 3))
Jeremy Kerr165785e2006-11-11 17:25:18 +1100581 RELOC(prom_iommu_off) = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000582 else if (!strncmp(opt, RELOC("force"), 5))
Jeremy Kerr165785e2006-11-11 17:25:18 +1100583 RELOC(prom_iommu_force_on) = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000584 }
585#endif
Benjamin Krillcf687872009-07-27 22:02:39 +0000586 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
587 if (opt) {
588 opt += 4;
589 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
590#ifdef CONFIG_PPC64
591 /* Align to 16 MB == size of ppc64 large page */
592 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
593#endif
594 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000595}
596
597#ifdef CONFIG_PPC_PSERIES
598/*
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000599 * There are two methods for telling firmware what our capabilities are.
600 * Newer machines have an "ibm,client-architecture-support" method on the
601 * root node. For older machines, we have to call the "process-elf-header"
602 * method in the /packages/elf-loader node, passing it a fake 32-bit
603 * ELF header containing a couple of PT_NOTE sections that contain
604 * structures that contain various information.
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000605 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000606
607/*
608 * New method - extensible architecture description vector.
609 *
610 * Because the description vector contains a mix of byte and word
611 * values, we declare it as an unsigned char array, and use this
612 * macro to put word values in.
613 */
614#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
615 ((x) >> 8) & 0xff, (x) & 0xff
616
617/* Option vector bits - generic bits in byte 1 */
618#define OV_IGNORE 0x80 /* ignore this vector */
619#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
620
621/* Option vector 1: processor architectures supported */
622#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
623#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
624#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
625#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
626#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
627#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
Joel Schopp0cb99012008-06-19 06:23:23 +1000628#define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000629
630/* Option vector 2: Open Firmware options supported */
631#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
632
633/* Option vector 3: processor options supported */
634#define OV3_FP 0x80 /* floating point */
635#define OV3_VMX 0x40 /* VMX/Altivec */
Paul Mackerras974a76f2006-11-10 20:38:53 +1100636#define OV3_DFP 0x20 /* decimal FP */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000637
638/* Option vector 5: PAPR/OF options supported */
639#define OV5_LPAR 0x80 /* logical partitioning supported */
640#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
641/* ibm,dynamic-reconfiguration-memory property supported */
642#define OV5_DRCONF_MEMORY 0x20
643#define OV5_LARGE_PAGES 0x10 /* large pages supported */
Jake Moilanend8c391a2007-06-08 07:27:11 +1000644#define OV5_DONATE_DEDICATE_CPU 0x02 /* donate dedicated CPU support */
Michael Ellerman014dad92007-05-08 12:58:35 +1000645/* PCIe/MSI support. Without MSI full PCIe is not supported */
646#ifdef CONFIG_PCI_MSI
647#define OV5_MSI 0x01 /* PCIe/MSI support */
648#else
649#define OV5_MSI 0x00
650#endif /* CONFIG_PCI_MSI */
Nathan Fontenot8391e422008-07-24 04:36:38 +1000651#ifdef CONFIG_PPC_SMLPAR
652#define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */
653#else
654#define OV5_CMO 0x00
655#endif
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000656
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000657/* Option Vector 6: IBM PAPR hints */
658#define OV6_LINUX 0x02 /* Linux is our OS */
659
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000660/*
661 * The architecture vector has an array of PVR mask/value pairs,
662 * followed by # option vectors - 1, followed by the option vectors.
663 */
664static unsigned char ibm_architecture_vec[] = {
665 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
Anton Blanchard03054d52006-04-29 09:51:06 +1000666 W(0xffff0000), W(0x003e0000), /* POWER6 */
Michael Neulinge952e6c2008-06-18 10:47:26 +1000667 W(0xffff0000), W(0x003f0000), /* POWER7 */
Joel Schopp0cb99012008-06-19 06:23:23 +1000668 W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
Paul Mackerras0efbc182006-11-29 22:31:47 +1100669 W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000670 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000671 6 - 1, /* 6 option vectors */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000672
673 /* option vector 1: processor architectures supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500674 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000675 0, /* don't ignore, don't halt */
676 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
Joel Schopp0cb99012008-06-19 06:23:23 +1000677 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000678
679 /* option vector 2: Open Firmware options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500680 34 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000681 OV2_REAL_MODE,
682 0, 0,
683 W(0xffffffff), /* real_base */
684 W(0xffffffff), /* real_size */
685 W(0xffffffff), /* virt_base */
686 W(0xffffffff), /* virt_size */
687 W(0xffffffff), /* load_base */
Anton Blanchard856cc2f2009-03-31 20:14:01 +0000688 W(64), /* 64MB min RMA */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000689 W(0xffffffff), /* full client load */
690 0, /* min RMA percentage of total RAM */
691 48, /* max log_2(hash table size) */
692
693 /* option vector 3: processor options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500694 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000695 0, /* don't ignore, don't halt */
Paul Mackerras974a76f2006-11-10 20:38:53 +1100696 OV3_FP | OV3_VMX | OV3_DFP,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000697
698 /* option vector 4: IBM PAPR implementation */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500699 2 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000700 0, /* don't halt */
701
702 /* option vector 5: PAPR/OF options */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000703 13 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000704 0, /* don't ignore, don't halt */
Jake Moilanend8c391a2007-06-08 07:27:11 +1000705 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
706 OV5_DONATE_DEDICATE_CPU | OV5_MSI,
Nathan Fontenot8391e422008-07-24 04:36:38 +1000707 0,
708 OV5_CMO,
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000709 0,
710 0,
711 0,
712 0,
713 W(NR_CPUS), /* number of cores supported*/
714
715 /* option vector 6: IBM PAPR hints */
716 4 - 2, /* length */
717 0,
718 0,
719 OV6_LINUX,
720
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000721};
722
723/* Old method - ELF header with PT_NOTE sections */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000724static struct fake_elf {
725 Elf32_Ehdr elfhdr;
726 Elf32_Phdr phdr[2];
727 struct chrpnote {
728 u32 namesz;
729 u32 descsz;
730 u32 type;
731 char name[8]; /* "PowerPC" */
732 struct chrpdesc {
733 u32 real_mode;
734 u32 real_base;
735 u32 real_size;
736 u32 virt_base;
737 u32 virt_size;
738 u32 load_base;
739 } chrpdesc;
740 } chrpnote;
741 struct rpanote {
742 u32 namesz;
743 u32 descsz;
744 u32 type;
745 char name[24]; /* "IBM,RPA-Client-Config" */
746 struct rpadesc {
747 u32 lpar_affinity;
748 u32 min_rmo_size;
749 u32 min_rmo_percent;
750 u32 max_pft_size;
751 u32 splpar;
752 u32 min_load;
753 u32 new_mem_def;
754 u32 ignore_me;
755 } rpadesc;
756 } rpanote;
Paul Mackerras5663a122008-10-31 22:27:17 +1100757} fake_elf = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000758 .elfhdr = {
759 .e_ident = { 0x7f, 'E', 'L', 'F',
760 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
761 .e_type = ET_EXEC, /* yeah right */
762 .e_machine = EM_PPC,
763 .e_version = EV_CURRENT,
764 .e_phoff = offsetof(struct fake_elf, phdr),
765 .e_phentsize = sizeof(Elf32_Phdr),
766 .e_phnum = 2
767 },
768 .phdr = {
769 [0] = {
770 .p_type = PT_NOTE,
771 .p_offset = offsetof(struct fake_elf, chrpnote),
772 .p_filesz = sizeof(struct chrpnote)
773 }, [1] = {
774 .p_type = PT_NOTE,
775 .p_offset = offsetof(struct fake_elf, rpanote),
776 .p_filesz = sizeof(struct rpanote)
777 }
778 },
779 .chrpnote = {
780 .namesz = sizeof("PowerPC"),
781 .descsz = sizeof(struct chrpdesc),
782 .type = 0x1275,
783 .name = "PowerPC",
784 .chrpdesc = {
785 .real_mode = ~0U, /* ~0 means "don't care" */
786 .real_base = ~0U,
787 .real_size = ~0U,
788 .virt_base = ~0U,
789 .virt_size = ~0U,
790 .load_base = ~0U
791 },
792 },
793 .rpanote = {
794 .namesz = sizeof("IBM,RPA-Client-Config"),
795 .descsz = sizeof(struct rpadesc),
796 .type = 0x12759999,
797 .name = "IBM,RPA-Client-Config",
798 .rpadesc = {
Paul Mackerras5663a122008-10-31 22:27:17 +1100799 .lpar_affinity = 0,
800 .min_rmo_size = 64, /* in megabytes */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000801 .min_rmo_percent = 0,
Paul Mackerras5663a122008-10-31 22:27:17 +1100802 .max_pft_size = 48, /* 2^48 bytes max PFT size */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000803 .splpar = 1,
804 .min_load = ~0U,
Paul Mackerras5663a122008-10-31 22:27:17 +1100805 .new_mem_def = 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000806 }
807 }
808};
809
810static void __init prom_send_capabilities(void)
811{
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000812 ihandle elfloader, root;
813 prom_arg_t ret;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000814
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000815 root = call_prom("open", 1, 1, ADDR("/"));
816 if (root != 0) {
817 /* try calling the ibm,client-architecture-support method */
Anton Blanchard049d0492009-09-21 20:47:39 +0000818 prom_printf("Calling ibm,client-architecture-support...");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000819 if (call_prom_ret("call-method", 3, 2, &ret,
820 ADDR("ibm,client-architecture-support"),
Benjamin Herrenschmidt33b74972006-06-07 12:01:32 +1000821 root,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000822 ADDR(ibm_architecture_vec)) == 0) {
823 /* the call exists... */
824 if (ret)
Anton Blanchard4da727a2009-03-31 20:06:14 +0000825 prom_printf("\nWARNING: ibm,client-architecture"
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000826 "-support call FAILED!\n");
827 call_prom("close", 1, 0, root);
Anton Blanchard4da727a2009-03-31 20:06:14 +0000828 prom_printf(" done\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000829 return;
830 }
831 call_prom("close", 1, 0, root);
Anton Blanchard049d0492009-09-21 20:47:39 +0000832 prom_printf(" not implemented\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000833 }
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 */
Michael Ellerman0108d3f2007-05-07 15:58:28 +10001011static void __init 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/*
Adrian Bunkb3c2ffd2006-06-30 18:20:44 +02001035 * Initialize memory allocation mechanism, parse "memory" nodes and
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001036 * 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 /*
Benjamin Krillcf687872009-07-27 22:02:39 +00001117 * 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 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001140 * 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);
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001151 RELOC(alloc_top_high) = RELOC(ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001152
1153 prom_printf("memory layout at init:\n");
Benjamin Krillcf687872009-07-27 22:02:39 +00001154 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001155 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));
1160}
1161
1162
1163/*
1164 * Allocate room for and instantiate RTAS
1165 */
1166static void __init prom_instantiate_rtas(void)
1167{
1168 phandle rtas_node;
1169 ihandle rtas_inst;
1170 u32 base, entry = 0;
1171 u32 size = 0;
1172
1173 prom_debug("prom_instantiate_rtas: start...\n");
1174
1175 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1176 prom_debug("rtas_node: %x\n", rtas_node);
1177 if (!PHANDLE_VALID(rtas_node))
1178 return;
1179
1180 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1181 if (size == 0)
1182 return;
1183
1184 base = alloc_down(size, PAGE_SIZE, 0);
1185 if (base == 0) {
1186 prom_printf("RTAS allocation failed !\n");
1187 return;
1188 }
1189
1190 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1191 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001192 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001193 return;
1194 }
1195
Anton Blanchard1f8737a2009-03-31 20:06:15 +00001196 prom_printf("instantiating rtas at 0x%x...", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001197
1198 if (call_prom_ret("call-method", 3, 2, &entry,
1199 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001200 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001201 || entry == 0) {
1202 prom_printf(" failed\n");
1203 return;
1204 }
1205 prom_printf(" done\n");
1206
1207 reserve_mem(base, size);
1208
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001209 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1210 &base, sizeof(base));
1211 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1212 &entry, sizeof(entry));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001213
1214 prom_debug("rtas base = 0x%x\n", base);
1215 prom_debug("rtas entry = 0x%x\n", entry);
1216 prom_debug("rtas size = 0x%x\n", (long)size);
1217
1218 prom_debug("prom_instantiate_rtas: end...\n");
1219}
1220
1221#ifdef CONFIG_PPC64
1222/*
1223 * Allocate room for and initialize TCE tables
1224 */
1225static void __init prom_initialize_tce_table(void)
1226{
1227 phandle node;
1228 ihandle phb_node;
1229 char compatible[64], type[64], model[64];
1230 char *path = RELOC(prom_scratch);
1231 u64 base, align;
1232 u32 minalign, minsize;
1233 u64 tce_entry, *tce_entryp;
1234 u64 local_alloc_top, local_alloc_bottom;
1235 u64 i;
1236
Jeremy Kerr165785e2006-11-11 17:25:18 +11001237 if (RELOC(prom_iommu_off))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001238 return;
1239
1240 prom_debug("starting prom_initialize_tce_table\n");
1241
1242 /* Cache current top of allocs so we reserve a single block */
1243 local_alloc_top = RELOC(alloc_top_high);
1244 local_alloc_bottom = local_alloc_top;
1245
1246 /* Search all nodes looking for PHBs. */
1247 for (node = 0; prom_next_node(&node); ) {
1248 compatible[0] = 0;
1249 type[0] = 0;
1250 model[0] = 0;
1251 prom_getprop(node, "compatible",
1252 compatible, sizeof(compatible));
1253 prom_getprop(node, "device_type", type, sizeof(type));
1254 prom_getprop(node, "model", model, sizeof(model));
1255
1256 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1257 continue;
1258
Linas Vepstase788ff12007-09-07 03:45:21 +10001259 /* Keep the old logic intact to avoid regression. */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001260 if (compatible[0] != 0) {
1261 if ((strstr(compatible, RELOC("python")) == NULL) &&
1262 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1263 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1264 continue;
1265 } else if (model[0] != 0) {
1266 if ((strstr(model, RELOC("ython")) == NULL) &&
1267 (strstr(model, RELOC("peedwagon")) == NULL) &&
1268 (strstr(model, RELOC("innipeg")) == NULL))
1269 continue;
1270 }
1271
1272 if (prom_getprop(node, "tce-table-minalign", &minalign,
1273 sizeof(minalign)) == PROM_ERROR)
1274 minalign = 0;
1275 if (prom_getprop(node, "tce-table-minsize", &minsize,
1276 sizeof(minsize)) == PROM_ERROR)
1277 minsize = 4UL << 20;
1278
1279 /*
1280 * Even though we read what OF wants, we just set the table
1281 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1282 * By doing this, we avoid the pitfalls of trying to DMA to
1283 * MMIO space and the DMA alias hole.
1284 *
1285 * On POWER4, firmware sets the TCE region by assuming
1286 * each TCE table is 8MB. Using this memory for anything
1287 * else will impact performance, so we always allocate 8MB.
1288 * Anton
1289 */
1290 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1291 minsize = 8UL << 20;
1292 else
1293 minsize = 4UL << 20;
1294
1295 /* Align to the greater of the align or size */
1296 align = max(minalign, minsize);
1297 base = alloc_down(minsize, align, 1);
1298 if (base == 0)
1299 prom_panic("ERROR, cannot find space for TCE table.\n");
1300 if (base < local_alloc_bottom)
1301 local_alloc_bottom = base;
1302
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001303 /* It seems OF doesn't null-terminate the path :-( */
Li Zefanaca71ef2007-11-05 13:21:56 +11001304 memset(path, 0, PROM_SCRATCH_SIZE);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001305 /* Call OF to setup the TCE hardware */
1306 if (call_prom("package-to-path", 3, 1, node,
1307 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1308 prom_printf("package-to-path failed\n");
1309 }
1310
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001311 /* Save away the TCE table attributes for later use. */
1312 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1313 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1314
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001315 prom_debug("TCE table: %s\n", path);
1316 prom_debug("\tnode = 0x%x\n", node);
1317 prom_debug("\tbase = 0x%x\n", base);
1318 prom_debug("\tsize = 0x%x\n", minsize);
1319
1320 /* Initialize the table to have a one-to-one mapping
1321 * over the allocated size.
1322 */
Ingo Molnar2b931fb2009-01-06 13:56:52 +00001323 tce_entryp = (u64 *)base;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001324 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1325 tce_entry = (i << PAGE_SHIFT);
1326 tce_entry |= 0x3;
1327 *tce_entryp = tce_entry;
1328 }
1329
1330 prom_printf("opening PHB %s", path);
1331 phb_node = call_prom("open", 1, 1, path);
1332 if (phb_node == 0)
1333 prom_printf("... failed\n");
1334 else
1335 prom_printf("... done\n");
1336
1337 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1338 phb_node, -1, minsize,
1339 (u32) base, (u32) (base >> 32));
1340 call_prom("close", 1, 0, phb_node);
1341 }
1342
1343 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1344
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001345 /* These are only really needed if there is a memory limit in
1346 * effect, but we don't know so export them always. */
1347 RELOC(prom_tce_alloc_start) = local_alloc_bottom;
1348 RELOC(prom_tce_alloc_end) = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001349
1350 /* Flag the first invalid entry */
1351 prom_debug("ending prom_initialize_tce_table\n");
1352}
1353#endif
1354
1355/*
1356 * With CHRP SMP we need to use the OF to start the other processors.
1357 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1358 * so we have to put the processors into a holding pattern controlled
1359 * by the kernel (not OF) before we destroy the OF.
1360 *
1361 * This uses a chunk of low memory, puts some holding pattern
1362 * code there and sends the other processors off to there until
1363 * smp_boot_cpus tells them to do something. The holding pattern
1364 * checks that address until its cpu # is there, when it is that
1365 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1366 * of setting those values.
1367 *
1368 * We also use physical address 0x4 here to tell when a cpu
1369 * is in its holding pattern code.
1370 *
1371 * -- Cort
1372 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001373/*
1374 * We want to reference the copy of __secondary_hold_* in the
1375 * 0 - 0x100 address range
1376 */
1377#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1378
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001379static void __init prom_hold_cpus(void)
1380{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001381 unsigned long i;
1382 unsigned int reg;
1383 phandle node;
1384 char type[64];
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001385 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001386 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001387 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001388 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001389 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001390 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001391
1392 prom_debug("prom_hold_cpus: start...\n");
1393 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1394 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1395 prom_debug(" 1) acknowledge = 0x%x\n",
1396 (unsigned long)acknowledge);
1397 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1398 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1399
1400 /* Set the common spinloop variable, so all of the secondary cpus
1401 * will block when they are awakened from their OF spinloop.
1402 * This must occur for both SMP and non SMP kernels, since OF will
1403 * be trashed when we move the kernel.
1404 */
1405 *spinloop = 0;
1406
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001407 /* look for cpus */
1408 for (node = 0; prom_next_node(&node); ) {
1409 type[0] = 0;
1410 prom_getprop(node, "device_type", type, sizeof(type));
1411 if (strcmp(type, RELOC("cpu")) != 0)
1412 continue;
1413
1414 /* Skip non-configured cpus. */
1415 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1416 if (strcmp(type, RELOC("okay")) != 0)
1417 continue;
1418
1419 reg = -1;
1420 prom_getprop(node, "reg", &reg, sizeof(reg));
1421
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001422 prom_debug("cpu hw idx = 0x%x\n", reg);
1423
1424 /* Init the acknowledge var which will be reset by
1425 * the secondary cpu when it awakens from its OF
1426 * spinloop.
1427 */
1428 *acknowledge = (unsigned long)-1;
1429
Nathan Lynch7d2f6072008-07-27 15:24:50 +10001430 if (reg != _prom->cpu) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001431 /* Primary Thread of non-boot cpu */
Nathan Lynch7d2f6072008-07-27 15:24:50 +10001432 prom_printf("starting cpu hw idx %x... ", reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001433 call_prom("start-cpu", 3, 0, node,
1434 secondary_hold, reg);
1435
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001436 for (i = 0; (i < 100000000) &&
1437 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001438 mb();
1439
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001440 if (*acknowledge == reg)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001441 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001442 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001443 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001444 }
1445#ifdef CONFIG_SMP
1446 else
Nathan Lynch7d2f6072008-07-27 15:24:50 +10001447 prom_printf("boot cpu hw idx %x\n", reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001448#endif /* CONFIG_SMP */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001449 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001450
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001451 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001452}
1453
1454
1455static void __init prom_init_client_services(unsigned long pp)
1456{
1457 struct prom_t *_prom = &RELOC(prom);
1458
1459 /* Get a handle to the prom entry point before anything else */
1460 RELOC(prom_entry) = pp;
1461
1462 /* get a handle for the stdout device */
1463 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1464 if (!PHANDLE_VALID(_prom->chosen))
1465 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1466
1467 /* get device tree root */
1468 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1469 if (!PHANDLE_VALID(_prom->root))
1470 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001471
1472 _prom->mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001473}
1474
Paul Mackerrasa575b802005-10-23 17:23:21 +10001475#ifdef CONFIG_PPC32
1476/*
1477 * For really old powermacs, we need to map things we claim.
1478 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001479 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001480 */
1481static void __init prom_find_mmu(void)
1482{
1483 struct prom_t *_prom = &RELOC(prom);
1484 phandle oprom;
1485 char version[64];
1486
1487 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1488 if (!PHANDLE_VALID(oprom))
1489 return;
1490 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1491 return;
1492 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001493 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001494 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1495 of_workarounds = OF_WA_CLAIM;
1496 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1497 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1498 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1499 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001500 return;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001501 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
Paul Mackerrasa575b802005-10-23 17:23:21 +10001502 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1503 sizeof(_prom->mmumap));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001504 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1505 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001506}
1507#else
1508#define prom_find_mmu()
1509#endif
1510
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001511static void __init prom_init_stdout(void)
1512{
1513 struct prom_t *_prom = &RELOC(prom);
1514 char *path = RELOC(of_stdout_device);
1515 char type[16];
1516 u32 val;
1517
1518 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1519 prom_panic("cannot find stdout");
1520
1521 _prom->stdout = val;
1522
1523 /* Get the full OF pathname of the stdout device */
1524 memset(path, 0, 256);
1525 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1526 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001527 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1528 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001529 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001530 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1531 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001532
1533 /* If it's a display, note it */
1534 memset(type, 0, sizeof(type));
1535 prom_getprop(val, "device_type", type, sizeof(type));
1536 if (strcmp(type, RELOC("display")) == 0)
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001537 prom_setprop(val, path, "linux,boot-display", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001538}
1539
1540static void __init prom_close_stdin(void)
1541{
1542 struct prom_t *_prom = &RELOC(prom);
1543 ihandle val;
1544
1545 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1546 call_prom("close", 1, 0, val);
1547}
1548
1549static int __init prom_find_machine_type(void)
1550{
1551 struct prom_t *_prom = &RELOC(prom);
1552 char compat[256];
1553 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001554#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001555 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001556 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001557#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001558
1559 /* Look for a PowerMac */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001560 len = prom_getprop(_prom->root, "compatible",
1561 compat, sizeof(compat)-1);
1562 if (len > 0) {
1563 compat[len] = 0;
1564 while (i < len) {
1565 char *p = &compat[i];
1566 int sl = strlen(p);
1567 if (sl == 0)
1568 break;
1569 if (strstr(p, RELOC("Power Macintosh")) ||
Paul Mackerrasa575b802005-10-23 17:23:21 +10001570 strstr(p, RELOC("MacRISC")))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001571 return PLATFORM_POWERMAC;
Arnd Bergmann133dda12006-06-07 12:04:18 +10001572#ifdef CONFIG_PPC64
1573 /* We must make sure we don't detect the IBM Cell
1574 * blades as pSeries due to some firmware issues,
1575 * so we do it here.
1576 */
1577 if (strstr(p, RELOC("IBM,CBEA")) ||
1578 strstr(p, RELOC("IBM,CPBW-1.0")))
1579 return PLATFORM_GENERIC;
1580#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001581 i += sl + 1;
1582 }
1583 }
1584#ifdef CONFIG_PPC64
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001585 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1586 * PAPR compliant platform. We assume it is if :
1587 * - /device_type is "chrp" (please, do NOT use that for future
1588 * non-IBM designs !
1589 * - it has /rtas
1590 */
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001591 len = prom_getprop(_prom->root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001592 compat, sizeof(compat)-1);
1593 if (len <= 0)
1594 return PLATFORM_GENERIC;
Benjamin Herrenschmidtcb6b2eb2006-05-15 15:46:03 +10001595 if (strcmp(compat, RELOC("chrp")))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001596 return PLATFORM_GENERIC;
1597
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001598 /* Default to pSeries. We need to know if we are running LPAR */
1599 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001600 if (!PHANDLE_VALID(rtas))
1601 return PLATFORM_GENERIC;
1602 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1603 if (x != PROM_ERROR) {
Anton Blanchard4da727a2009-03-31 20:06:14 +00001604 prom_debug("Hypertas detected, assuming LPAR !\n");
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001605 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001606 }
1607 return PLATFORM_PSERIES;
1608#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001609 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001610#endif
1611}
1612
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001613static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1614{
1615 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1616}
1617
1618/*
1619 * If we have a display that we don't know how to drive,
1620 * we will want to try to execute OF's open method for it
1621 * later. However, OF will probably fall over if we do that
1622 * we've taken over the MMU.
1623 * So we check whether we will need to open the display,
1624 * and if so, open it now.
1625 */
1626static void __init prom_check_displays(void)
1627{
1628 char type[16], *path;
1629 phandle node;
1630 ihandle ih;
1631 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001632
1633 static unsigned char default_colors[] = {
1634 0x00, 0x00, 0x00,
1635 0x00, 0x00, 0xaa,
1636 0x00, 0xaa, 0x00,
1637 0x00, 0xaa, 0xaa,
1638 0xaa, 0x00, 0x00,
1639 0xaa, 0x00, 0xaa,
1640 0xaa, 0xaa, 0x00,
1641 0xaa, 0xaa, 0xaa,
1642 0x55, 0x55, 0x55,
1643 0x55, 0x55, 0xff,
1644 0x55, 0xff, 0x55,
1645 0x55, 0xff, 0xff,
1646 0xff, 0x55, 0x55,
1647 0xff, 0x55, 0xff,
1648 0xff, 0xff, 0x55,
1649 0xff, 0xff, 0xff
1650 };
1651 const unsigned char *clut;
1652
Anton Blanchard4da727a2009-03-31 20:06:14 +00001653 prom_debug("Looking for displays\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001654 for (node = 0; prom_next_node(&node); ) {
1655 memset(type, 0, sizeof(type));
1656 prom_getprop(node, "device_type", type, sizeof(type));
1657 if (strcmp(type, RELOC("display")) != 0)
1658 continue;
1659
1660 /* It seems OF doesn't null-terminate the path :-( */
1661 path = RELOC(prom_scratch);
1662 memset(path, 0, PROM_SCRATCH_SIZE);
1663
1664 /*
1665 * leave some room at the end of the path for appending extra
1666 * arguments
1667 */
1668 if (call_prom("package-to-path", 3, 1, node, path,
1669 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1670 continue;
Anton Blanchard1f8737a2009-03-31 20:06:15 +00001671 prom_printf("found display : %s, opening... ", path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001672
1673 ih = call_prom("open", 1, 1, path);
1674 if (ih == 0) {
1675 prom_printf("failed\n");
1676 continue;
1677 }
1678
1679 /* Success */
1680 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001681 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001682
1683 /* Setup a usable color table when the appropriate
1684 * method is available. Should update this to set-colors */
1685 clut = RELOC(default_colors);
1686 for (i = 0; i < 32; i++, clut += 3)
1687 if (prom_set_color(ih, i, clut[0], clut[1],
1688 clut[2]) != 0)
1689 break;
1690
1691#ifdef CONFIG_LOGO_LINUX_CLUT224
1692 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1693 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1694 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1695 clut[2]) != 0)
1696 break;
1697#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001698 }
1699}
1700
1701
1702/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1703static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1704 unsigned long needed, unsigned long align)
1705{
1706 void *ret;
1707
1708 *mem_start = _ALIGN(*mem_start, align);
1709 while ((*mem_start + needed) > *mem_end) {
1710 unsigned long room, chunk;
1711
1712 prom_debug("Chunk exhausted, claiming more at %x...\n",
1713 RELOC(alloc_bottom));
1714 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1715 if (room > DEVTREE_CHUNK_SIZE)
1716 room = DEVTREE_CHUNK_SIZE;
1717 if (room < PAGE_SIZE)
1718 prom_panic("No memory for flatten_device_tree (no room)");
1719 chunk = alloc_up(room, 0);
1720 if (chunk == 0)
1721 prom_panic("No memory for flatten_device_tree (claim failed)");
1722 *mem_end = RELOC(alloc_top);
1723 }
1724
1725 ret = (void *)*mem_start;
1726 *mem_start += needed;
1727
1728 return ret;
1729}
1730
1731#define dt_push_token(token, mem_start, mem_end) \
1732 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1733
1734static unsigned long __init dt_find_string(char *str)
1735{
1736 char *s, *os;
1737
1738 s = os = (char *)RELOC(dt_string_start);
1739 s += 4;
1740 while (s < (char *)RELOC(dt_string_end)) {
1741 if (strcmp(s, str) == 0)
1742 return s - os;
1743 s += strlen(s) + 1;
1744 }
1745 return 0;
1746}
1747
1748/*
1749 * The Open Firmware 1275 specification states properties must be 31 bytes or
1750 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1751 */
1752#define MAX_PROPERTY_NAME 64
1753
1754static void __init scan_dt_build_strings(phandle node,
1755 unsigned long *mem_start,
1756 unsigned long *mem_end)
1757{
1758 char *prev_name, *namep, *sstart;
1759 unsigned long soff;
1760 phandle child;
1761
1762 sstart = (char *)RELOC(dt_string_start);
1763
1764 /* get and store all property names */
1765 prev_name = RELOC("");
1766 for (;;) {
1767 /* 64 is max len of name including nul. */
1768 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1769 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1770 /* No more nodes: unwind alloc */
1771 *mem_start = (unsigned long)namep;
1772 break;
1773 }
1774
1775 /* skip "name" */
1776 if (strcmp(namep, RELOC("name")) == 0) {
1777 *mem_start = (unsigned long)namep;
1778 prev_name = RELOC("name");
1779 continue;
1780 }
1781 /* get/create string entry */
1782 soff = dt_find_string(namep);
1783 if (soff != 0) {
1784 *mem_start = (unsigned long)namep;
1785 namep = sstart + soff;
1786 } else {
1787 /* Trim off some if we can */
1788 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1789 RELOC(dt_string_end) = *mem_start;
1790 }
1791 prev_name = namep;
1792 }
1793
1794 /* do all our children */
1795 child = call_prom("child", 1, 1, node);
1796 while (child != 0) {
1797 scan_dt_build_strings(child, mem_start, mem_end);
1798 child = call_prom("peer", 1, 1, child);
1799 }
1800}
1801
1802static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1803 unsigned long *mem_end)
1804{
1805 phandle child;
1806 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1807 unsigned long soff;
1808 unsigned char *valp;
1809 static char pname[MAX_PROPERTY_NAME];
Paul Mackerrasc49888202005-10-26 21:52:53 +10001810 int l, room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001811
1812 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1813
1814 /* get the node's full name */
1815 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001816 room = *mem_end - *mem_start;
1817 if (room > 255)
1818 room = 255;
1819 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001820 if (l >= 0) {
1821 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10001822 if (l >= room) {
1823 if (l >= *mem_end - *mem_start)
1824 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001825 call_prom("package-to-path", 3, 1, node, namep, l);
1826 }
1827 namep[l] = '\0';
1828
1829 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10001830 * middle of the path in some properties, and extract
1831 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001832 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001833 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001834 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10001835 lp = namep;
1836 else if (*p != 0)
1837 *lp++ = *p;
1838 }
1839 *lp = 0;
1840 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001841 }
1842
1843 /* get it again for debugging */
1844 path = RELOC(prom_scratch);
1845 memset(path, 0, PROM_SCRATCH_SIZE);
1846 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1847
1848 /* get and store all properties */
1849 prev_name = RELOC("");
1850 sstart = (char *)RELOC(dt_string_start);
1851 for (;;) {
1852 if (call_prom("nextprop", 3, 1, node, prev_name,
1853 RELOC(pname)) != 1)
1854 break;
1855
1856 /* skip "name" */
1857 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1858 prev_name = RELOC("name");
1859 continue;
1860 }
1861
1862 /* find string offset */
1863 soff = dt_find_string(RELOC(pname));
1864 if (soff == 0) {
1865 prom_printf("WARNING: Can't find string index for"
1866 " <%s>, node %s\n", RELOC(pname), path);
1867 break;
1868 }
1869 prev_name = sstart + soff;
1870
1871 /* get length */
1872 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1873
1874 /* sanity checks */
1875 if (l == PROM_ERROR)
1876 continue;
1877 if (l > MAX_PROPERTY_LENGTH) {
1878 prom_printf("WARNING: ignoring large property ");
1879 /* It seems OF doesn't null-terminate the path :-( */
1880 prom_printf("[%s] ", path);
1881 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1882 continue;
1883 }
1884
1885 /* push property head */
1886 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1887 dt_push_token(l, mem_start, mem_end);
1888 dt_push_token(soff, mem_start, mem_end);
1889
1890 /* push property content */
1891 valp = make_room(mem_start, mem_end, l, 4);
1892 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1893 *mem_start = _ALIGN(*mem_start, 4);
1894 }
1895
1896 /* Add a "linux,phandle" property. */
1897 soff = dt_find_string(RELOC("linux,phandle"));
1898 if (soff == 0)
1899 prom_printf("WARNING: Can't find string index for"
1900 " <linux-phandle> node %s\n", path);
1901 else {
1902 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1903 dt_push_token(4, mem_start, mem_end);
1904 dt_push_token(soff, mem_start, mem_end);
1905 valp = make_room(mem_start, mem_end, 4, 4);
1906 *(u32 *)valp = node;
1907 }
1908
1909 /* do all our children */
1910 child = call_prom("child", 1, 1, node);
1911 while (child != 0) {
1912 scan_dt_build_struct(child, mem_start, mem_end);
1913 child = call_prom("peer", 1, 1, child);
1914 }
1915
1916 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1917}
1918
1919static void __init flatten_device_tree(void)
1920{
1921 phandle root;
1922 unsigned long mem_start, mem_end, room;
1923 struct boot_param_header *hdr;
1924 struct prom_t *_prom = &RELOC(prom);
1925 char *namep;
1926 u64 *rsvmap;
1927
1928 /*
1929 * Check how much room we have between alloc top & bottom (+/- a
1930 * few pages), crop to 4Mb, as this is our "chuck" size
1931 */
1932 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1933 if (room > DEVTREE_CHUNK_SIZE)
1934 room = DEVTREE_CHUNK_SIZE;
1935 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1936
1937 /* Now try to claim that */
1938 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1939 if (mem_start == 0)
1940 prom_panic("Can't allocate initial device-tree chunk\n");
1941 mem_end = RELOC(alloc_top);
1942
1943 /* Get root of tree */
1944 root = call_prom("peer", 1, 1, (phandle)0);
1945 if (root == (phandle)0)
1946 prom_panic ("couldn't get device tree root\n");
1947
1948 /* Build header and make room for mem rsv map */
1949 mem_start = _ALIGN(mem_start, 4);
1950 hdr = make_room(&mem_start, &mem_end,
1951 sizeof(struct boot_param_header), 4);
1952 RELOC(dt_header_start) = (unsigned long)hdr;
1953 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1954
1955 /* Start of strings */
1956 mem_start = PAGE_ALIGN(mem_start);
1957 RELOC(dt_string_start) = mem_start;
1958 mem_start += 4; /* hole */
1959
1960 /* Add "linux,phandle" in there, we'll need it */
1961 namep = make_room(&mem_start, &mem_end, 16, 1);
1962 strcpy(namep, RELOC("linux,phandle"));
1963 mem_start = (unsigned long)namep + strlen(namep) + 1;
1964
1965 /* Build string array */
1966 prom_printf("Building dt strings...\n");
1967 scan_dt_build_strings(root, &mem_start, &mem_end);
1968 RELOC(dt_string_end) = mem_start;
1969
1970 /* Build structure */
1971 mem_start = PAGE_ALIGN(mem_start);
1972 RELOC(dt_struct_start) = mem_start;
1973 prom_printf("Building dt structure...\n");
1974 scan_dt_build_struct(root, &mem_start, &mem_end);
1975 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1976 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1977
1978 /* Finish header */
1979 hdr->boot_cpuid_phys = _prom->cpu;
1980 hdr->magic = OF_DT_HEADER;
1981 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1982 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1983 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1984 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1985 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1986 hdr->version = OF_DT_VERSION;
1987 /* Version 16 is not backward compatible */
1988 hdr->last_comp_version = 0x10;
1989
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05001990 /* Copy the reserve map in */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001991 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1992
1993#ifdef DEBUG_PROM
1994 {
1995 int i;
1996 prom_printf("reserved memory map:\n");
1997 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1998 prom_printf(" %x - %x\n",
1999 RELOC(mem_reserve_map)[i].base,
2000 RELOC(mem_reserve_map)[i].size);
2001 }
2002#endif
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002003 /* Bump mem_reserve_cnt to cause further reservations to fail
2004 * since it's too late.
2005 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002006 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2007
2008 prom_printf("Device tree strings 0x%x -> 0x%x\n",
2009 RELOC(dt_string_start), RELOC(dt_string_end));
2010 prom_printf("Device tree struct 0x%x -> 0x%x\n",
2011 RELOC(dt_struct_start), RELOC(dt_struct_end));
2012
2013}
2014
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002015#ifdef CONFIG_PPC_MAPLE
2016/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2017 * The values are bad, and it doesn't even have the right number of cells. */
2018static void __init fixup_device_tree_maple(void)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002019{
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002020 phandle isa;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002021 u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002022 u32 isa_ranges[6];
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002023 char *name;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002024
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002025 name = "/ht@0/isa@4";
2026 isa = call_prom("finddevice", 1, 1, ADDR(name));
2027 if (!PHANDLE_VALID(isa)) {
2028 name = "/ht@0/isa@6";
2029 isa = call_prom("finddevice", 1, 1, ADDR(name));
2030 rloc = 0x01003000; /* IO space; PCI device = 6 */
2031 }
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002032 if (!PHANDLE_VALID(isa))
2033 return;
2034
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002035 if (prom_getproplen(isa, "ranges") != 12)
2036 return;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002037 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2038 == PROM_ERROR)
2039 return;
2040
2041 if (isa_ranges[0] != 0x1 ||
2042 isa_ranges[1] != 0xf4000000 ||
2043 isa_ranges[2] != 0x00010000)
2044 return;
2045
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002046 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002047
2048 isa_ranges[0] = 0x1;
2049 isa_ranges[1] = 0x0;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002050 isa_ranges[2] = rloc;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002051 isa_ranges[3] = 0x0;
2052 isa_ranges[4] = 0x0;
2053 isa_ranges[5] = 0x00010000;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002054 prom_setprop(isa, name, "ranges",
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002055 isa_ranges, sizeof(isa_ranges));
2056}
Harry Ciao8f101a02009-06-17 16:28:00 -07002057
2058#define CPC925_MC_START 0xf8000000
2059#define CPC925_MC_LENGTH 0x1000000
2060/* The values for memory-controller don't have right number of cells */
2061static void __init fixup_device_tree_maple_memory_controller(void)
2062{
2063 phandle mc;
2064 u32 mc_reg[4];
2065 char *name = "/hostbridge@f8000000";
2066 struct prom_t *_prom = &RELOC(prom);
2067 u32 ac, sc;
2068
2069 mc = call_prom("finddevice", 1, 1, ADDR(name));
2070 if (!PHANDLE_VALID(mc))
2071 return;
2072
2073 if (prom_getproplen(mc, "reg") != 8)
2074 return;
2075
2076 prom_getprop(_prom->root, "#address-cells", &ac, sizeof(ac));
2077 prom_getprop(_prom->root, "#size-cells", &sc, sizeof(sc));
2078 if ((ac != 2) || (sc != 2))
2079 return;
2080
2081 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2082 return;
2083
2084 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2085 return;
2086
2087 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2088
2089 mc_reg[0] = 0x0;
2090 mc_reg[1] = CPC925_MC_START;
2091 mc_reg[2] = 0x0;
2092 mc_reg[3] = CPC925_MC_LENGTH;
2093 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2094}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002095#else
2096#define fixup_device_tree_maple()
Harry Ciao8f101a02009-06-17 16:28:00 -07002097#define fixup_device_tree_maple_memory_controller()
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002098#endif
2099
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002100#ifdef CONFIG_PPC_CHRP
Olaf Heringe4805922007-04-04 18:20:04 +02002101/*
2102 * Pegasos and BriQ lacks the "ranges" property in the isa node
2103 * Pegasos needs decimal IRQ 14/15, not hexadecimal
Olaf Hering556ecf92007-08-18 04:27:17 +10002104 * Pegasos has the IDE configured in legacy mode, but advertised as native
Olaf Heringe4805922007-04-04 18:20:04 +02002105 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002106static void __init fixup_device_tree_chrp(void)
2107{
Olaf Heringe4805922007-04-04 18:20:04 +02002108 phandle ph;
2109 u32 prop[6];
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002110 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002111 char *name;
2112 int rc;
2113
2114 name = "/pci@80000000/isa@c";
Olaf Heringe4805922007-04-04 18:20:04 +02002115 ph = call_prom("finddevice", 1, 1, ADDR(name));
2116 if (!PHANDLE_VALID(ph)) {
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002117 name = "/pci@ff500000/isa@6";
Olaf Heringe4805922007-04-04 18:20:04 +02002118 ph = call_prom("finddevice", 1, 1, ADDR(name));
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002119 rloc = 0x01003000; /* IO space; PCI device = 6 */
2120 }
Olaf Heringe4805922007-04-04 18:20:04 +02002121 if (PHANDLE_VALID(ph)) {
2122 rc = prom_getproplen(ph, "ranges");
2123 if (rc == 0 || rc == PROM_ERROR) {
2124 prom_printf("Fixing up missing ISA range on Pegasos...\n");
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002125
Olaf Heringe4805922007-04-04 18:20:04 +02002126 prop[0] = 0x1;
2127 prop[1] = 0x0;
2128 prop[2] = rloc;
2129 prop[3] = 0x0;
2130 prop[4] = 0x0;
2131 prop[5] = 0x00010000;
2132 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2133 }
2134 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002135
Olaf Heringe4805922007-04-04 18:20:04 +02002136 name = "/pci@80000000/ide@C,1";
2137 ph = call_prom("finddevice", 1, 1, ADDR(name));
2138 if (PHANDLE_VALID(ph)) {
2139 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2140 prop[0] = 14;
2141 prop[1] = 0x0;
Olaf Hering556ecf92007-08-18 04:27:17 +10002142 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2143 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2144 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2145 if (rc == sizeof(u32)) {
2146 prop[0] &= ~0x5;
2147 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2148 }
Olaf Heringe4805922007-04-04 18:20:04 +02002149 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002150}
2151#else
2152#define fixup_device_tree_chrp()
2153#endif
2154
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002155#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002156static void __init fixup_device_tree_pmac(void)
2157{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002158 phandle u3, i2c, mpic;
2159 u32 u3_rev;
2160 u32 interrupts[2];
2161 u32 parent;
2162
2163 /* Some G5s have a missing interrupt definition, fix it up here */
2164 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2165 if (!PHANDLE_VALID(u3))
2166 return;
2167 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2168 if (!PHANDLE_VALID(i2c))
2169 return;
2170 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2171 if (!PHANDLE_VALID(mpic))
2172 return;
2173
2174 /* check if proper rev of u3 */
2175 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2176 == PROM_ERROR)
2177 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002178 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002179 return;
2180 /* does it need fixup ? */
2181 if (prom_getproplen(i2c, "interrupts") > 0)
2182 return;
2183
2184 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2185
2186 /* interrupt on this revision of u3 is number 0 and level */
2187 interrupts[0] = 0;
2188 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002189 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2190 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002191 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002192 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2193 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002194}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002195#else
2196#define fixup_device_tree_pmac()
2197#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002198
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002199#ifdef CONFIG_PPC_EFIKA
Grant Likely94d2dde2008-01-24 22:25:32 -07002200/*
2201 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2202 * to talk to the phy. If the phy-handle property is missing, then this
2203 * function is called to add the appropriate nodes and link it to the
2204 * ethernet node.
2205 */
2206static void __init fixup_device_tree_efika_add_phy(void)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002207{
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002208 u32 node;
2209 char prop[64];
Grant Likely94d2dde2008-01-24 22:25:32 -07002210 int rv;
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002211
Grant Likely94d2dde2008-01-24 22:25:32 -07002212 /* Check if /builtin/ethernet exists - bail if it doesn't */
2213 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002214 if (!PHANDLE_VALID(node))
2215 return;
2216
Grant Likely94d2dde2008-01-24 22:25:32 -07002217 /* Check if the phy-handle property exists - bail if it does */
2218 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2219 if (!rv)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002220 return;
2221
Grant Likely94d2dde2008-01-24 22:25:32 -07002222 /*
2223 * At this point the ethernet device doesn't have a phy described.
2224 * Now we need to add the missing phy node and linkage
2225 */
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002226
Grant Likely94d2dde2008-01-24 22:25:32 -07002227 /* Check for an MDIO bus node - if missing then create one */
Olaf Hering6f4347c2008-01-10 01:06:08 +11002228 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2229 if (!PHANDLE_VALID(node)) {
2230 prom_printf("Adding Ethernet MDIO node\n");
2231 call_prom("interpret", 1, 1,
2232 " s\" /builtin\" find-device"
2233 " new-device"
2234 " 1 encode-int s\" #address-cells\" property"
2235 " 0 encode-int s\" #size-cells\" property"
Grant Likely94d2dde2008-01-24 22:25:32 -07002236 " s\" mdio\" device-name"
2237 " s\" fsl,mpc5200b-mdio\" encode-string"
Olaf Hering6f4347c2008-01-10 01:06:08 +11002238 " s\" compatible\" property"
2239 " 0xf0003000 0x400 reg"
2240 " 0x2 encode-int"
2241 " 0x5 encode-int encode+"
2242 " 0x3 encode-int encode+"
2243 " s\" interrupts\" property"
2244 " finish-device");
2245 };
2246
Grant Likely94d2dde2008-01-24 22:25:32 -07002247 /* Check for a PHY device node - if missing then create one and
2248 * give it's phandle to the ethernet node */
2249 node = call_prom("finddevice", 1, 1,
2250 ADDR("/builtin/mdio/ethernet-phy"));
Olaf Hering6f4347c2008-01-10 01:06:08 +11002251 if (!PHANDLE_VALID(node)) {
2252 prom_printf("Adding Ethernet PHY node\n");
2253 call_prom("interpret", 1, 1,
2254 " s\" /builtin/mdio\" find-device"
2255 " new-device"
2256 " s\" ethernet-phy\" device-name"
2257 " 0x10 encode-int s\" reg\" property"
2258 " my-self"
2259 " ihandle>phandle"
2260 " finish-device"
2261 " s\" /builtin/ethernet\" find-device"
2262 " encode-int"
2263 " s\" phy-handle\" property"
2264 " device-end");
2265 }
Grant Likely94d2dde2008-01-24 22:25:32 -07002266}
Olaf Hering6f4347c2008-01-10 01:06:08 +11002267
Grant Likely94d2dde2008-01-24 22:25:32 -07002268static void __init fixup_device_tree_efika(void)
2269{
2270 int sound_irq[3] = { 2, 2, 0 };
2271 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2272 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2273 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2274 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2275 u32 node;
2276 char prop[64];
2277 int rv, len;
2278
2279 /* Check if we're really running on a EFIKA */
2280 node = call_prom("finddevice", 1, 1, ADDR("/"));
2281 if (!PHANDLE_VALID(node))
2282 return;
2283
2284 rv = prom_getprop(node, "model", prop, sizeof(prop));
2285 if (rv == PROM_ERROR)
2286 return;
2287 if (strcmp(prop, "EFIKA5K2"))
2288 return;
2289
2290 prom_printf("Applying EFIKA device tree fixups\n");
2291
2292 /* Claiming to be 'chrp' is death */
2293 node = call_prom("finddevice", 1, 1, ADDR("/"));
2294 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2295 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2296 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2297
David Woodhouse7f4392c2008-04-14 02:52:38 +10002298 /* CODEGEN,description is exposed in /proc/cpuinfo so
2299 fix that too */
2300 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2301 if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2302 prom_setprop(node, "/", "CODEGEN,description",
2303 "Efika 5200B PowerPC System",
2304 sizeof("Efika 5200B PowerPC System"));
2305
Grant Likely94d2dde2008-01-24 22:25:32 -07002306 /* Fixup bestcomm interrupts property */
2307 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2308 if (PHANDLE_VALID(node)) {
2309 len = prom_getproplen(node, "interrupts");
2310 if (len == 12) {
2311 prom_printf("Fixing bestcomm interrupts property\n");
2312 prom_setprop(node, "/builtin/bestcom", "interrupts",
2313 bcomm_irq, sizeof(bcomm_irq));
2314 }
2315 }
2316
2317 /* Fixup sound interrupts property */
2318 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2319 if (PHANDLE_VALID(node)) {
2320 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2321 if (rv == PROM_ERROR) {
2322 prom_printf("Adding sound interrupts property\n");
2323 prom_setprop(node, "/builtin/sound", "interrupts",
2324 sound_irq, sizeof(sound_irq));
2325 }
2326 }
2327
2328 /* Make sure ethernet phy-handle property exists */
2329 fixup_device_tree_efika_add_phy();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002330}
2331#else
2332#define fixup_device_tree_efika()
2333#endif
2334
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002335static void __init fixup_device_tree(void)
2336{
2337 fixup_device_tree_maple();
Harry Ciao8f101a02009-06-17 16:28:00 -07002338 fixup_device_tree_maple_memory_controller();
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002339 fixup_device_tree_chrp();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002340 fixup_device_tree_pmac();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002341 fixup_device_tree_efika();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002342}
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002343
2344static void __init prom_find_boot_cpu(void)
2345{
Linas Vepstase788ff12007-09-07 03:45:21 +10002346 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002347 u32 getprop_rval;
2348 ihandle prom_cpu;
2349 phandle cpu_pkg;
2350
Paul Mackerrasa575b802005-10-23 17:23:21 +10002351 _prom->cpu = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002352 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002353 return;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002354
2355 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2356
2357 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2358 _prom->cpu = getprop_rval;
2359
2360 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2361}
2362
2363static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2364{
2365#ifdef CONFIG_BLK_DEV_INITRD
Linas Vepstase788ff12007-09-07 03:45:21 +10002366 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002367
2368 if (r3 && r4 && r4 != 0xdeadbeef) {
2369 unsigned long val;
2370
Michael Ellerman51fae6d2005-12-04 18:39:15 +11002371 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002372 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2373
2374 val = RELOC(prom_initrd_start);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002375 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2376 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002377 val = RELOC(prom_initrd_end);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002378 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2379 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002380
2381 reserve_mem(RELOC(prom_initrd_start),
2382 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2383
2384 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2385 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2386 }
2387#endif /* CONFIG_BLK_DEV_INITRD */
2388}
2389
2390/*
2391 * We enter here early on, when the Open Firmware prom is still
2392 * handling exceptions and the MMU hash table for us.
2393 */
2394
2395unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2396 unsigned long pp,
Paul Mackerras549e8152008-08-30 11:43:47 +10002397 unsigned long r6, unsigned long r7,
2398 unsigned long kbase)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002399{
Linas Vepstase788ff12007-09-07 03:45:21 +10002400 struct prom_t *_prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002401 unsigned long hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002402
2403#ifdef CONFIG_PPC32
Paul Mackerras549e8152008-08-30 11:43:47 +10002404 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002405 reloc_got2(offset);
2406#endif
2407
2408 _prom = &RELOC(prom);
2409
2410 /*
2411 * First zero the BSS
2412 */
2413 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2414
2415 /*
2416 * Init interface to Open Firmware, get some node references,
2417 * like /chosen
2418 */
2419 prom_init_client_services(pp);
2420
2421 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002422 * See if this OF is old enough that we need to do explicit maps
2423 * and other workarounds
2424 */
2425 prom_find_mmu();
2426
2427 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002428 * Init prom stdout device
2429 */
2430 prom_init_stdout();
2431
Benjamin Herrenschmidt151a9f42009-03-22 16:04:53 +00002432 prom_printf("Preparing to boot %s", RELOC(linux_banner));
Michael Ellermane7943fb2009-03-04 19:02:01 +00002433
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002434 /*
2435 * Get default machine type. At this point, we do not differentiate
2436 * between pSeries SMP and pSeries LPAR
2437 */
2438 RELOC(of_platform) = prom_find_machine_type();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002439
Paul Mackerras549e8152008-08-30 11:43:47 +10002440#ifndef CONFIG_RELOCATABLE
Olaf Heringadd60ef2006-03-23 22:03:57 +01002441 /* Bail if this is a kdump kernel. */
2442 if (PHYSICAL_START > 0)
2443 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
Paul Mackerras549e8152008-08-30 11:43:47 +10002444#endif
Olaf Heringadd60ef2006-03-23 22:03:57 +01002445
2446 /*
2447 * Check for an initrd
2448 */
2449 prom_check_initrd(r3, r4);
2450
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002451#ifdef CONFIG_PPC_PSERIES
2452 /*
2453 * On pSeries, inform the firmware about our capabilities
2454 */
Paul Mackerras799d6042005-11-10 13:37:51 +11002455 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2456 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002457 prom_send_capabilities();
2458#endif
2459
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002460 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002461 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002462 */
Linas Vepstase788ff12007-09-07 03:45:21 +10002463 if (RELOC(of_platform) != PLATFORM_POWERMAC)
Paul Mackerras549e8152008-08-30 11:43:47 +10002464 copy_and_flush(0, kbase, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002465
2466 /*
2467 * Do early parsing of command line
2468 */
2469 early_cmdline_parse();
2470
2471 /*
2472 * Initialize memory management within prom_init
2473 */
2474 prom_init_mem();
2475
2476 /*
2477 * Determine which cpu is actually running right _now_
2478 */
2479 prom_find_boot_cpu();
2480
2481 /*
2482 * Initialize display devices
2483 */
2484 prom_check_displays();
2485
2486#ifdef CONFIG_PPC64
2487 /*
2488 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2489 * that uses the allocator, we need to make sure we get the top of memory
2490 * available for us here...
2491 */
2492 if (RELOC(of_platform) == PLATFORM_PSERIES)
2493 prom_initialize_tce_table();
2494#endif
2495
2496 /*
2497 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2498 * in spin-loops. PowerMacs don't have a working RTAS and use
2499 * a different way to spin CPUs
2500 */
2501 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2502 prom_instantiate_rtas();
2503 prom_hold_cpus();
2504 }
2505
2506 /*
2507 * Fill in some infos for use by the kernel later on
2508 */
Benjamin Krillcf687872009-07-27 22:02:39 +00002509 if (RELOC(prom_memory_limit))
2510 prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
2511 &RELOC(prom_memory_limit),
2512 sizeof(prom_memory_limit));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002513#ifdef CONFIG_PPC64
Jeremy Kerr165785e2006-11-11 17:25:18 +11002514 if (RELOC(prom_iommu_off))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002515 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2516 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002517
Jeremy Kerr165785e2006-11-11 17:25:18 +11002518 if (RELOC(prom_iommu_force_on))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002519 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2520 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002521
2522 if (RELOC(prom_tce_alloc_start)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002523 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002524 &RELOC(prom_tce_alloc_start),
2525 sizeof(prom_tce_alloc_start));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002526 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002527 &RELOC(prom_tce_alloc_end),
2528 sizeof(prom_tce_alloc_end));
2529 }
2530#endif
2531
2532 /*
2533 * Fixup any known bugs in the device-tree
2534 */
2535 fixup_device_tree();
2536
2537 /*
2538 * Now finally create the flattened device-tree
2539 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002540 prom_printf("copying OF device tree...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002541 flatten_device_tree();
2542
Paul Mackerras3825ac02005-11-08 22:48:08 +11002543 /*
2544 * in case stdin is USB and still active on IBM machines...
2545 * Unfortunately quiesce crashes on some powermacs if we have
2546 * closed stdin already (in particular the powerbook 101).
2547 */
2548 if (RELOC(of_platform) != PLATFORM_POWERMAC)
2549 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002550
2551 /*
2552 * Call OF "quiesce" method to shut down pending DMA's from
2553 * devices etc...
2554 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002555 prom_printf("Calling quiesce...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002556 call_prom("quiesce", 0, 0);
2557
2558 /*
2559 * And finally, call the kernel passing it the flattened device
2560 * tree and NULL as r5, thus triggering the new entry point which
2561 * is common to us and kexec
2562 */
2563 hdr = RELOC(dt_header_start);
2564 prom_printf("returning from prom_init\n");
2565 prom_debug("->dt_header_start=0x%x\n", hdr);
2566
2567#ifdef CONFIG_PPC32
2568 reloc_got2(-offset);
2569#endif
2570
Paul Mackerras549e8152008-08-30 11:43:47 +10002571 __start(hdr, kbase, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002572
2573 return 0;
2574}