blob: ea4e311e09d2609d6b0a7c4a0bf60629b7eb52fb [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>
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +000046#include <asm/opal.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100047
Paul Mackerras9b6b5632005-10-06 12:06:20 +100048#include <linux/linux_logo.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100049
50/*
Paul Mackerras9b6b5632005-10-06 12:06:20 +100051 * Eventually bump that one up
52 */
53#define DEVTREE_CHUNK_SIZE 0x100000
54
55/*
56 * This is the size of the local memory reserve map that gets copied
57 * into the boot params passed to the kernel. That size is totally
58 * flexible as the kernel just reads the list until it encounters an
59 * entry with size 0, so it can be changed without breaking binary
60 * compatibility
61 */
62#define MEM_RESERVE_MAP_SIZE 8
63
64/*
65 * prom_init() is called very early on, before the kernel text
66 * and data have been mapped to KERNELBASE. At this point the code
67 * is running at whatever address it has been loaded at.
68 * On ppc32 we compile with -mrelocatable, which means that references
69 * to extern and static variables get relocated automatically.
70 * On ppc64 we have to relocate the references explicitly with
71 * RELOC. (Note that strings count as static variables.)
72 *
73 * Because OF may have mapped I/O devices into the area starting at
74 * KERNELBASE, particularly on CHRP machines, we can't safely call
75 * OF once the kernel has been mapped to KERNELBASE. Therefore all
76 * OF calls must be done within prom_init().
77 *
78 * ADDR is used in calls to call_prom. The 4th and following
79 * arguments to call_prom should be 32-bit values.
80 * On ppc64, 64 bit values are truncated to 32 bits (and
81 * fortunately don't get interpreted as two arguments).
82 */
83#ifdef CONFIG_PPC64
84#define RELOC(x) (*PTRRELOC(&(x)))
85#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
Paul Mackerrasa23414b2005-11-10 12:00:55 +110086#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100087#else
88#define RELOC(x) (x)
89#define ADDR(x) (u32) (x)
Paul Mackerrasa23414b2005-11-10 12:00:55 +110090#define OF_WORKAROUNDS of_workarounds
91int of_workarounds;
Paul Mackerras9b6b5632005-10-06 12:06:20 +100092#endif
93
Paul Mackerrasa23414b2005-11-10 12:00:55 +110094#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
95#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
96
Paul Mackerras9b6b5632005-10-06 12:06:20 +100097#define PROM_BUG() do { \
98 prom_printf("kernel BUG at %s line 0x%x!\n", \
99 RELOC(__FILE__), __LINE__); \
100 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
101} while (0)
102
103#ifdef DEBUG_PROM
104#define prom_debug(x...) prom_printf(x)
105#else
106#define prom_debug(x...)
107#endif
108
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000109
110typedef u32 prom_arg_t;
111
112struct prom_args {
113 u32 service;
114 u32 nargs;
115 u32 nret;
116 prom_arg_t args[10];
117};
118
119struct prom_t {
120 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100121 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000122 int cpu;
123 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000124 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100125 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000126};
127
128struct mem_map_entry {
Kumar Galacbbcf342006-01-11 17:57:13 -0600129 u64 base;
130 u64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000131};
132
133typedef u32 cell_t;
134
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +0000135extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
136 unsigned long r6, unsigned long r7, unsigned long r8,
137 unsigned long r9);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000138
139#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000140extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000141#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000142static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000143{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000144 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000145}
146#endif
147
148extern void copy_and_flush(unsigned long dest, unsigned long src,
149 unsigned long size, unsigned long offset);
150
151/* prom structure */
152static struct prom_t __initdata prom;
153
154static unsigned long prom_entry __initdata;
155
156#define PROM_SCRATCH_SIZE 256
157
158static char __initdata of_stdout_device[256];
159static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
160
161static unsigned long __initdata dt_header_start;
162static unsigned long __initdata dt_struct_start, dt_struct_end;
163static unsigned long __initdata dt_string_start, dt_string_end;
164
165static unsigned long __initdata prom_initrd_start, prom_initrd_end;
166
167#ifdef CONFIG_PPC64
Jeremy Kerr165785e2006-11-11 17:25:18 +1100168static int __initdata prom_iommu_force_on;
169static int __initdata prom_iommu_off;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000170static unsigned long __initdata prom_tce_alloc_start;
171static unsigned long __initdata prom_tce_alloc_end;
172#endif
173
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100174/* Platforms codes are now obsolete in the kernel. Now only used within this
175 * file and ultimately gone too. Feel free to change them if you need, they
176 * are not shared with anything outside of this file anymore
177 */
178#define PLATFORM_PSERIES 0x0100
179#define PLATFORM_PSERIES_LPAR 0x0101
180#define PLATFORM_LPAR 0x0001
181#define PLATFORM_POWERMAC 0x0400
182#define PLATFORM_GENERIC 0x0500
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000183#define PLATFORM_OPAL 0x0600
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100184
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000185static int __initdata of_platform;
186
187static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
188
Benjamin Krillcf687872009-07-27 22:02:39 +0000189static unsigned long __initdata prom_memory_limit;
190
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000191static unsigned long __initdata alloc_top;
192static unsigned long __initdata alloc_top_high;
193static unsigned long __initdata alloc_bottom;
194static unsigned long __initdata rmo_top;
195static unsigned long __initdata ram_top;
196
197static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
198static int __initdata mem_reserve_cnt;
199
200static cell_t __initdata regbuf[1024];
201
202
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000203/*
204 * Error results ... some OF calls will return "-1" on error, some
205 * will return 0, some will return either. To simplify, here are
206 * macros to use with any ihandle or phandle return value to check if
207 * it is valid
208 */
209
210#define PROM_ERROR (-1u)
211#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
212#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
213
214
215/* This is the one and *ONLY* place where we actually call open
216 * firmware.
217 */
218
219static int __init call_prom(const char *service, int nargs, int nret, ...)
220{
221 int i;
222 struct prom_args args;
223 va_list list;
224
225 args.service = ADDR(service);
226 args.nargs = nargs;
227 args.nret = nret;
228
229 va_start(list, nret);
230 for (i = 0; i < nargs; i++)
231 args.args[i] = va_arg(list, prom_arg_t);
232 va_end(list);
233
234 for (i = 0; i < nret; i++)
235 args.args[nargs+i] = 0;
236
Paul Mackerrasc49888202005-10-26 21:52:53 +1000237 if (enter_prom(&args, RELOC(prom_entry)) < 0)
238 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000239
240 return (nret > 0) ? args.args[nargs] : 0;
241}
242
243static int __init call_prom_ret(const char *service, int nargs, int nret,
244 prom_arg_t *rets, ...)
245{
246 int i;
247 struct prom_args args;
248 va_list list;
249
250 args.service = ADDR(service);
251 args.nargs = nargs;
252 args.nret = nret;
253
254 va_start(list, rets);
255 for (i = 0; i < nargs; i++)
256 args.args[i] = va_arg(list, prom_arg_t);
257 va_end(list);
258
259 for (i = 0; i < nret; i++)
Olaf Heringed1189b2005-11-29 14:04:05 +0100260 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000261
Paul Mackerrasc49888202005-10-26 21:52:53 +1000262 if (enter_prom(&args, RELOC(prom_entry)) < 0)
263 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000264
265 if (rets != NULL)
266 for (i = 1; i < nret; ++i)
Paul Mackerrasc5200c92005-10-10 22:57:03 +1000267 rets[i-1] = args.args[nargs+i];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000268
269 return (nret > 0) ? args.args[nargs] : 0;
270}
271
272
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000273static void __init prom_print(const char *msg)
274{
275 const char *p, *q;
276 struct prom_t *_prom = &RELOC(prom);
277
278 if (_prom->stdout == 0)
279 return;
280
281 for (p = msg; *p != 0; p = q) {
282 for (q = p; *q != 0 && *q != '\n'; ++q)
283 ;
284 if (q > p)
285 call_prom("write", 3, 1, _prom->stdout, p, q - p);
286 if (*q == 0)
287 break;
288 ++q;
289 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
290 }
291}
292
293
294static void __init prom_print_hex(unsigned long val)
295{
296 int i, nibbles = sizeof(val)*2;
297 char buf[sizeof(val)*2+1];
298 struct prom_t *_prom = &RELOC(prom);
299
300 for (i = nibbles-1; i >= 0; i--) {
301 buf[i] = (val & 0xf) + '0';
302 if (buf[i] > '9')
303 buf[i] += ('a'-'0'-10);
304 val >>= 4;
305 }
306 buf[nibbles] = '\0';
307 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
308}
309
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000310/* max number of decimal digits in an unsigned long */
311#define UL_DIGITS 21
312static void __init prom_print_dec(unsigned long val)
313{
314 int i, size;
315 char buf[UL_DIGITS+1];
316 struct prom_t *_prom = &RELOC(prom);
317
318 for (i = UL_DIGITS-1; i >= 0; i--) {
319 buf[i] = (val % 10) + '0';
320 val = val/10;
321 if (val == 0)
322 break;
323 }
324 /* shift stuff down */
325 size = UL_DIGITS - i;
326 call_prom("write", 3, 1, _prom->stdout, buf+i, size);
327}
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000328
329static void __init prom_printf(const char *format, ...)
330{
331 const char *p, *q, *s;
332 va_list args;
333 unsigned long v;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000334 long vs;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000335 struct prom_t *_prom = &RELOC(prom);
336
337 va_start(args, format);
338#ifdef CONFIG_PPC64
339 format = PTRRELOC(format);
340#endif
341 for (p = format; *p != 0; p = q) {
342 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
343 ;
344 if (q > p)
345 call_prom("write", 3, 1, _prom->stdout, p, q - p);
346 if (*q == 0)
347 break;
348 if (*q == '\n') {
349 ++q;
350 call_prom("write", 3, 1, _prom->stdout,
351 ADDR("\r\n"), 2);
352 continue;
353 }
354 ++q;
355 if (*q == 0)
356 break;
357 switch (*q) {
358 case 's':
359 ++q;
360 s = va_arg(args, const char *);
361 prom_print(s);
362 break;
363 case 'x':
364 ++q;
365 v = va_arg(args, unsigned long);
366 prom_print_hex(v);
367 break;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000368 case 'd':
369 ++q;
370 vs = va_arg(args, int);
371 if (vs < 0) {
372 prom_print(RELOC("-"));
373 vs = -vs;
374 }
375 prom_print_dec(vs);
376 break;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000377 case 'l':
378 ++q;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000379 if (*q == 0)
380 break;
381 else if (*q == 'x') {
382 ++q;
383 v = va_arg(args, unsigned long);
384 prom_print_hex(v);
385 } else if (*q == 'u') { /* '%lu' */
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000386 ++q;
387 v = va_arg(args, unsigned long);
388 prom_print_dec(v);
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000389 } else if (*q == 'd') { /* %ld */
390 ++q;
391 vs = va_arg(args, long);
392 if (vs < 0) {
393 prom_print(RELOC("-"));
394 vs = -vs;
395 }
396 prom_print_dec(vs);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000397 }
398 break;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000399 }
400 }
401}
402
403
Paul Mackerrasa575b802005-10-23 17:23:21 +1000404static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
405 unsigned long align)
406{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000407 struct prom_t *_prom = &RELOC(prom);
408
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100409 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
410 /*
411 * Old OF requires we claim physical and virtual separately
412 * and then map explicitly (assuming virtual mode)
413 */
414 int ret;
415 prom_arg_t result;
416
417 ret = call_prom_ret("call-method", 5, 2, &result,
418 ADDR("claim"), _prom->memory,
419 align, size, virt);
420 if (ret != 0 || result == -1)
421 return -1;
422 ret = call_prom_ret("call-method", 5, 2, &result,
423 ADDR("claim"), _prom->mmumap,
424 align, size, virt);
425 if (ret != 0) {
426 call_prom("call-method", 4, 1, ADDR("release"),
427 _prom->memory, size, virt);
428 return -1;
429 }
430 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000431 call_prom("call-method", 6, 1,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100432 ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
433 return virt;
434 }
435 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
436 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000437}
438
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000439static void __init __attribute__((noreturn)) prom_panic(const char *reason)
440{
441#ifdef CONFIG_PPC64
442 reason = PTRRELOC(reason);
443#endif
444 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100445 /* Do not call exit because it clears the screen on pmac
446 * it also causes some sort of double-fault on early pmacs */
447 if (RELOC(of_platform) == PLATFORM_POWERMAC)
448 asm("trap\n");
449
Stephen Rothwell1d9a4732012-03-21 18:23:27 +0000450 /* ToDo: should put up an SRC here on pSeries */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000451 call_prom("exit", 0, 0);
452
453 for (;;) /* should never get here */
454 ;
455}
456
457
458static int __init prom_next_node(phandle *nodep)
459{
460 phandle node;
461
462 if ((node = *nodep) != 0
463 && (*nodep = call_prom("child", 1, 1, node)) != 0)
464 return 1;
465 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
466 return 1;
467 for (;;) {
468 if ((node = call_prom("parent", 1, 1, node)) == 0)
469 return 0;
470 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
471 return 1;
472 }
473}
474
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100475static int inline prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000476 void *value, size_t valuelen)
477{
478 return call_prom("getprop", 4, 1, node, ADDR(pname),
479 (u32)(unsigned long) value, (u32) valuelen);
480}
481
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100482static int inline prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000483{
484 return call_prom("getproplen", 2, 1, node, ADDR(pname));
485}
486
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100487static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000488{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100489 char *p = *str;
490
491 while (*q)
492 *p++ = *q++;
493 *p++ = ' ';
494 *str = p;
495}
496
497static char *tohex(unsigned int x)
498{
499 static char digits[] = "0123456789abcdef";
500 static char result[9];
501 int i;
502
503 result[8] = 0;
504 i = 8;
505 do {
506 --i;
507 result[i] = digits[x & 0xf];
508 x >>= 4;
509 } while (x != 0 && i > 0);
510 return &result[i];
511}
512
513static int __init prom_setprop(phandle node, const char *nodename,
514 const char *pname, void *value, size_t valuelen)
515{
516 char cmd[256], *p;
517
518 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
519 return call_prom("setprop", 4, 1, node, ADDR(pname),
520 (u32)(unsigned long) value, (u32) valuelen);
521
522 /* gah... setprop doesn't work on longtrail, have to use interpret */
523 p = cmd;
524 add_string(&p, "dev");
525 add_string(&p, nodename);
526 add_string(&p, tohex((u32)(unsigned long) value));
527 add_string(&p, tohex(valuelen));
528 add_string(&p, tohex(ADDR(pname)));
529 add_string(&p, tohex(strlen(RELOC(pname))));
530 add_string(&p, "property");
531 *p = 0;
532 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000533}
534
Benjamin Krillcf687872009-07-27 22:02:39 +0000535/* We can't use the standard versions because of RELOC headaches. */
536#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
537 || ('a' <= (c) && (c) <= 'f') \
538 || ('A' <= (c) && (c) <= 'F'))
539
540#define isdigit(c) ('0' <= (c) && (c) <= '9')
541#define islower(c) ('a' <= (c) && (c) <= 'z')
542#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
543
544unsigned long prom_strtoul(const char *cp, const char **endp)
545{
546 unsigned long result = 0, base = 10, value;
547
548 if (*cp == '0') {
549 base = 8;
550 cp++;
551 if (toupper(*cp) == 'X') {
552 cp++;
553 base = 16;
554 }
555 }
556
557 while (isxdigit(*cp) &&
558 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
559 result = result * base + value;
560 cp++;
561 }
562
563 if (endp)
564 *endp = cp;
565
566 return result;
567}
568
569unsigned long prom_memparse(const char *ptr, const char **retptr)
570{
571 unsigned long ret = prom_strtoul(ptr, retptr);
572 int shift = 0;
573
574 /*
575 * We can't use a switch here because GCC *may* generate a
576 * jump table which won't work, because we're not running at
577 * the address we're linked at.
578 */
579 if ('G' == **retptr || 'g' == **retptr)
580 shift = 30;
581
582 if ('M' == **retptr || 'm' == **retptr)
583 shift = 20;
584
585 if ('K' == **retptr || 'k' == **retptr)
586 shift = 10;
587
588 if (shift) {
589 ret <<= shift;
590 (*retptr)++;
591 }
592
593 return ret;
594}
595
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000596/*
597 * Early parsing of the command line passed to the kernel, used for
598 * "mem=x" and the options that affect the iommu
599 */
600static void __init early_cmdline_parse(void)
601{
602 struct prom_t *_prom = &RELOC(prom);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100603 const char *opt;
Benjamin Krillcf687872009-07-27 22:02:39 +0000604
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100605 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000606 int l = 0;
607
608 RELOC(prom_cmd_line[0]) = 0;
609 p = RELOC(prom_cmd_line);
610 if ((long)_prom->chosen > 0)
611 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
612#ifdef CONFIG_CMDLINE
Amos Waterland0e4aa9c2006-06-12 23:45:02 -0400613 if (l <= 0 || p[0] == '\0') /* dbl check */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000614 strlcpy(RELOC(prom_cmd_line),
615 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
616#endif /* CONFIG_CMDLINE */
617 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
618
619#ifdef CONFIG_PPC64
620 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
621 if (opt) {
622 prom_printf("iommu opt is: %s\n", opt);
623 opt += 6;
624 while (*opt && *opt == ' ')
625 opt++;
626 if (!strncmp(opt, RELOC("off"), 3))
Jeremy Kerr165785e2006-11-11 17:25:18 +1100627 RELOC(prom_iommu_off) = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000628 else if (!strncmp(opt, RELOC("force"), 5))
Jeremy Kerr165785e2006-11-11 17:25:18 +1100629 RELOC(prom_iommu_force_on) = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000630 }
631#endif
Benjamin Krillcf687872009-07-27 22:02:39 +0000632 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
633 if (opt) {
634 opt += 4;
635 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
636#ifdef CONFIG_PPC64
637 /* Align to 16 MB == size of ppc64 large page */
638 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
639#endif
640 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000641}
642
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000643#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000644/*
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000645 * There are two methods for telling firmware what our capabilities are.
646 * Newer machines have an "ibm,client-architecture-support" method on the
647 * root node. For older machines, we have to call the "process-elf-header"
648 * method in the /packages/elf-loader node, passing it a fake 32-bit
649 * ELF header containing a couple of PT_NOTE sections that contain
650 * structures that contain various information.
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000651 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000652
653/*
654 * New method - extensible architecture description vector.
655 *
656 * Because the description vector contains a mix of byte and word
657 * values, we declare it as an unsigned char array, and use this
658 * macro to put word values in.
659 */
660#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
661 ((x) >> 8) & 0xff, (x) & 0xff
662
663/* Option vector bits - generic bits in byte 1 */
664#define OV_IGNORE 0x80 /* ignore this vector */
665#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
666
667/* Option vector 1: processor architectures supported */
668#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
669#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
670#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
671#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
672#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
673#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
Joel Schopp0cb99012008-06-19 06:23:23 +1000674#define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000675
676/* Option vector 2: Open Firmware options supported */
677#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
678
679/* Option vector 3: processor options supported */
680#define OV3_FP 0x80 /* floating point */
681#define OV3_VMX 0x40 /* VMX/Altivec */
Paul Mackerras974a76f2006-11-10 20:38:53 +1100682#define OV3_DFP 0x20 /* decimal FP */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000683
684/* Option vector 5: PAPR/OF options supported */
685#define OV5_LPAR 0x80 /* logical partitioning supported */
686#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
687/* ibm,dynamic-reconfiguration-memory property supported */
688#define OV5_DRCONF_MEMORY 0x20
689#define OV5_LARGE_PAGES 0x10 /* large pages supported */
Jake Moilanend8c391a2007-06-08 07:27:11 +1000690#define OV5_DONATE_DEDICATE_CPU 0x02 /* donate dedicated CPU support */
Michael Ellerman014dad92007-05-08 12:58:35 +1000691/* PCIe/MSI support. Without MSI full PCIe is not supported */
692#ifdef CONFIG_PCI_MSI
693#define OV5_MSI 0x01 /* PCIe/MSI support */
694#else
695#define OV5_MSI 0x00
696#endif /* CONFIG_PCI_MSI */
Nathan Fontenot8391e422008-07-24 04:36:38 +1000697#ifdef CONFIG_PPC_SMLPAR
698#define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */
Brian King9ee820f2011-05-04 16:01:20 +1000699#define OV5_XCMO 0x40 /* Page Coalescing */
Nathan Fontenot8391e422008-07-24 04:36:38 +1000700#else
701#define OV5_CMO 0x00
Brian King9ee820f2011-05-04 16:01:20 +1000702#define OV5_XCMO 0x00
Nathan Fontenot8391e422008-07-24 04:36:38 +1000703#endif
Anton Blanchard4b83c332010-04-07 15:33:44 +0000704#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000705
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000706/* Option Vector 6: IBM PAPR hints */
707#define OV6_LINUX 0x02 /* Linux is our OS */
708
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000709/*
710 * The architecture vector has an array of PVR mask/value pairs,
711 * followed by # option vectors - 1, followed by the option vectors.
712 */
713static unsigned char ibm_architecture_vec[] = {
714 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
Anton Blanchard03054d52006-04-29 09:51:06 +1000715 W(0xffff0000), W(0x003e0000), /* POWER6 */
Michael Neulinge952e6c2008-06-18 10:47:26 +1000716 W(0xffff0000), W(0x003f0000), /* POWER7 */
Joel Schopp0cb99012008-06-19 06:23:23 +1000717 W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
Paul Mackerras0efbc182006-11-29 22:31:47 +1100718 W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000719 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000720 6 - 1, /* 6 option vectors */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000721
722 /* option vector 1: processor architectures supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500723 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000724 0, /* don't ignore, don't halt */
725 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
Joel Schopp0cb99012008-06-19 06:23:23 +1000726 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000727
728 /* option vector 2: Open Firmware options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500729 34 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000730 OV2_REAL_MODE,
731 0, 0,
732 W(0xffffffff), /* real_base */
733 W(0xffffffff), /* real_size */
734 W(0xffffffff), /* virt_base */
735 W(0xffffffff), /* virt_size */
736 W(0xffffffff), /* load_base */
Anton Blanchard33392642011-12-04 13:13:58 +0000737 W(256), /* 256MB min RMA */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000738 W(0xffffffff), /* full client load */
739 0, /* min RMA percentage of total RAM */
740 48, /* max log_2(hash table size) */
741
742 /* option vector 3: processor options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500743 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000744 0, /* don't ignore, don't halt */
Paul Mackerras974a76f2006-11-10 20:38:53 +1100745 OV3_FP | OV3_VMX | OV3_DFP,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000746
747 /* option vector 4: IBM PAPR implementation */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500748 2 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000749 0, /* don't halt */
750
751 /* option vector 5: PAPR/OF options */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000752 13 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000753 0, /* don't ignore, don't halt */
Jake Moilanend8c391a2007-06-08 07:27:11 +1000754 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
755 OV5_DONATE_DEDICATE_CPU | OV5_MSI,
Nathan Fontenot8391e422008-07-24 04:36:38 +1000756 0,
Brian King9ee820f2011-05-04 16:01:20 +1000757 OV5_CMO | OV5_XCMO,
Anton Blanchard4b83c332010-04-07 15:33:44 +0000758 OV5_TYPE1_AFFINITY,
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000759 0,
760 0,
761 0,
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100762 /* WARNING: The offset of the "number of cores" field below
763 * must match by the macro below. Update the definition if
764 * the structure layout changes.
765 */
766#define IBM_ARCH_VEC_NRCORES_OFFSET 100
767 W(NR_CPUS), /* number of cores supported */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000768
769 /* option vector 6: IBM PAPR hints */
770 4 - 2, /* length */
771 0,
772 0,
773 OV6_LINUX,
774
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000775};
776
777/* Old method - ELF header with PT_NOTE sections */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000778static struct fake_elf {
779 Elf32_Ehdr elfhdr;
780 Elf32_Phdr phdr[2];
781 struct chrpnote {
782 u32 namesz;
783 u32 descsz;
784 u32 type;
785 char name[8]; /* "PowerPC" */
786 struct chrpdesc {
787 u32 real_mode;
788 u32 real_base;
789 u32 real_size;
790 u32 virt_base;
791 u32 virt_size;
792 u32 load_base;
793 } chrpdesc;
794 } chrpnote;
795 struct rpanote {
796 u32 namesz;
797 u32 descsz;
798 u32 type;
799 char name[24]; /* "IBM,RPA-Client-Config" */
800 struct rpadesc {
801 u32 lpar_affinity;
802 u32 min_rmo_size;
803 u32 min_rmo_percent;
804 u32 max_pft_size;
805 u32 splpar;
806 u32 min_load;
807 u32 new_mem_def;
808 u32 ignore_me;
809 } rpadesc;
810 } rpanote;
Paul Mackerras5663a122008-10-31 22:27:17 +1100811} fake_elf = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000812 .elfhdr = {
813 .e_ident = { 0x7f, 'E', 'L', 'F',
814 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
815 .e_type = ET_EXEC, /* yeah right */
816 .e_machine = EM_PPC,
817 .e_version = EV_CURRENT,
818 .e_phoff = offsetof(struct fake_elf, phdr),
819 .e_phentsize = sizeof(Elf32_Phdr),
820 .e_phnum = 2
821 },
822 .phdr = {
823 [0] = {
824 .p_type = PT_NOTE,
825 .p_offset = offsetof(struct fake_elf, chrpnote),
826 .p_filesz = sizeof(struct chrpnote)
827 }, [1] = {
828 .p_type = PT_NOTE,
829 .p_offset = offsetof(struct fake_elf, rpanote),
830 .p_filesz = sizeof(struct rpanote)
831 }
832 },
833 .chrpnote = {
834 .namesz = sizeof("PowerPC"),
835 .descsz = sizeof(struct chrpdesc),
836 .type = 0x1275,
837 .name = "PowerPC",
838 .chrpdesc = {
839 .real_mode = ~0U, /* ~0 means "don't care" */
840 .real_base = ~0U,
841 .real_size = ~0U,
842 .virt_base = ~0U,
843 .virt_size = ~0U,
844 .load_base = ~0U
845 },
846 },
847 .rpanote = {
848 .namesz = sizeof("IBM,RPA-Client-Config"),
849 .descsz = sizeof(struct rpadesc),
850 .type = 0x12759999,
851 .name = "IBM,RPA-Client-Config",
852 .rpadesc = {
Paul Mackerras5663a122008-10-31 22:27:17 +1100853 .lpar_affinity = 0,
854 .min_rmo_size = 64, /* in megabytes */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000855 .min_rmo_percent = 0,
Paul Mackerras5663a122008-10-31 22:27:17 +1100856 .max_pft_size = 48, /* 2^48 bytes max PFT size */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000857 .splpar = 1,
858 .min_load = ~0U,
Paul Mackerras5663a122008-10-31 22:27:17 +1100859 .new_mem_def = 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000860 }
861 }
862};
863
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100864static int __init prom_count_smt_threads(void)
865{
866 phandle node;
867 char type[64];
868 unsigned int plen;
869
870 /* Pick up th first CPU node we can find */
871 for (node = 0; prom_next_node(&node); ) {
872 type[0] = 0;
873 prom_getprop(node, "device_type", type, sizeof(type));
874
875 if (strcmp(type, RELOC("cpu")))
876 continue;
877 /*
878 * There is an entry for each smt thread, each entry being
879 * 4 bytes long. All cpus should have the same number of
880 * smt threads, so return after finding the first.
881 */
882 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
883 if (plen == PROM_ERROR)
884 break;
885 plen >>= 2;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000886 prom_debug("Found %lu smt threads per core\n", (unsigned long)plen);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100887
888 /* Sanity check */
889 if (plen < 1 || plen > 64) {
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000890 prom_printf("Threads per core %lu out of bounds, assuming 1\n",
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100891 (unsigned long)plen);
892 return 1;
893 }
894 return plen;
895 }
896 prom_debug("No threads found, assuming 1 per core\n");
897
898 return 1;
899
900}
901
902
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000903static void __init prom_send_capabilities(void)
904{
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000905 ihandle elfloader, root;
906 prom_arg_t ret;
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100907 u32 *cores;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000908
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000909 root = call_prom("open", 1, 1, ADDR("/"));
910 if (root != 0) {
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100911 /* We need to tell the FW about the number of cores we support.
912 *
913 * To do that, we count the number of threads on the first core
914 * (we assume this is the same for all cores) and use it to
915 * divide NR_CPUS.
916 */
917 cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]);
918 if (*cores != NR_CPUS) {
919 prom_printf("WARNING ! "
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000920 "ibm_architecture_vec structure inconsistent: %lu!\n",
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100921 *cores);
922 } else {
Anton Blanchard33ad5e42010-06-17 14:33:06 +0000923 *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000924 prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
925 *cores, NR_CPUS);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100926 }
927
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000928 /* try calling the ibm,client-architecture-support method */
Anton Blanchard049d0492009-09-21 20:47:39 +0000929 prom_printf("Calling ibm,client-architecture-support...");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000930 if (call_prom_ret("call-method", 3, 2, &ret,
931 ADDR("ibm,client-architecture-support"),
Benjamin Herrenschmidt33b74972006-06-07 12:01:32 +1000932 root,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000933 ADDR(ibm_architecture_vec)) == 0) {
934 /* the call exists... */
935 if (ret)
Anton Blanchard4da727a2009-03-31 20:06:14 +0000936 prom_printf("\nWARNING: ibm,client-architecture"
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000937 "-support call FAILED!\n");
938 call_prom("close", 1, 0, root);
Anton Blanchard4da727a2009-03-31 20:06:14 +0000939 prom_printf(" done\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000940 return;
941 }
942 call_prom("close", 1, 0, root);
Anton Blanchard049d0492009-09-21 20:47:39 +0000943 prom_printf(" not implemented\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000944 }
945
946 /* no ibm,client-architecture-support call, try the old way */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000947 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
948 if (elfloader == 0) {
949 prom_printf("couldn't open /packages/elf-loader\n");
950 return;
951 }
952 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
953 elfloader, ADDR(&fake_elf));
954 call_prom("close", 1, 0, elfloader);
955}
956#endif
957
958/*
959 * Memory allocation strategy... our layout is normally:
960 *
961 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
962 * rare cases, initrd might end up being before the kernel though.
963 * We assume this won't override the final kernel at 0, we have no
964 * provision to handle that in this version, but it should hopefully
965 * never happen.
966 *
967 * alloc_top is set to the top of RMO, eventually shrink down if the
968 * TCEs overlap
969 *
970 * alloc_bottom is set to the top of kernel/initrd
971 *
972 * from there, allocations are done this way : rtas is allocated
973 * topmost, and the device-tree is allocated from the bottom. We try
974 * to grow the device-tree allocation as we progress. If we can't,
975 * then we fail, we don't currently have a facility to restart
976 * elsewhere, but that shouldn't be necessary.
977 *
978 * Note that calls to reserve_mem have to be done explicitly, memory
979 * allocated with either alloc_up or alloc_down isn't automatically
980 * reserved.
981 */
982
983
984/*
985 * Allocates memory in the RMO upward from the kernel/initrd
986 *
987 * When align is 0, this is a special case, it means to allocate in place
988 * at the current location of alloc_bottom or fail (that is basically
989 * extending the previous allocation). Used for the device-tree flattening
990 */
991static unsigned long __init alloc_up(unsigned long size, unsigned long align)
992{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000993 unsigned long base = RELOC(alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000994 unsigned long addr = 0;
995
Paul Mackerrasc49888202005-10-26 21:52:53 +1000996 if (align)
997 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000998 prom_debug("alloc_up(%x, %x)\n", size, align);
999 if (RELOC(ram_top) == 0)
1000 prom_panic("alloc_up() called with mem not initialized\n");
1001
1002 if (align)
1003 base = _ALIGN_UP(RELOC(alloc_bottom), align);
1004 else
1005 base = RELOC(alloc_bottom);
1006
1007 for(; (base + size) <= RELOC(alloc_top);
1008 base = _ALIGN_UP(base + 0x100000, align)) {
1009 prom_debug(" trying: 0x%x\n\r", base);
1010 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001011 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001012 break;
1013 addr = 0;
1014 if (align == 0)
1015 break;
1016 }
1017 if (addr == 0)
1018 return 0;
Anton Blanchard966728d2011-07-25 20:47:07 +00001019 RELOC(alloc_bottom) = addr + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001020
1021 prom_debug(" -> %x\n", addr);
1022 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1023 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
1024 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1025 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
1026 prom_debug(" ram_top : %x\n", RELOC(ram_top));
1027
1028 return addr;
1029}
1030
1031/*
1032 * Allocates memory downward, either from top of RMO, or if highmem
1033 * is set, from the top of RAM. Note that this one doesn't handle
1034 * failures. It does claim memory if highmem is not set.
1035 */
1036static unsigned long __init alloc_down(unsigned long size, unsigned long align,
1037 int highmem)
1038{
1039 unsigned long base, addr = 0;
1040
1041 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
1042 highmem ? RELOC("(high)") : RELOC("(low)"));
1043 if (RELOC(ram_top) == 0)
1044 prom_panic("alloc_down() called with mem not initialized\n");
1045
1046 if (highmem) {
1047 /* Carve out storage for the TCE table. */
1048 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
1049 if (addr <= RELOC(alloc_bottom))
1050 return 0;
1051 /* Will we bump into the RMO ? If yes, check out that we
1052 * didn't overlap existing allocations there, if we did,
1053 * we are dead, we must be the first in town !
1054 */
1055 if (addr < RELOC(rmo_top)) {
1056 /* Good, we are first */
1057 if (RELOC(alloc_top) == RELOC(rmo_top))
1058 RELOC(alloc_top) = RELOC(rmo_top) = addr;
1059 else
1060 return 0;
1061 }
1062 RELOC(alloc_top_high) = addr;
1063 goto bail;
1064 }
1065
1066 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
1067 for (; base > RELOC(alloc_bottom);
1068 base = _ALIGN_DOWN(base - 0x100000, align)) {
1069 prom_debug(" trying: 0x%x\n\r", base);
1070 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001071 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001072 break;
1073 addr = 0;
1074 }
1075 if (addr == 0)
1076 return 0;
1077 RELOC(alloc_top) = addr;
1078
1079 bail:
1080 prom_debug(" -> %x\n", addr);
1081 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1082 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
1083 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1084 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
1085 prom_debug(" ram_top : %x\n", RELOC(ram_top));
1086
1087 return addr;
1088}
1089
1090/*
1091 * Parse a "reg" cell
1092 */
1093static unsigned long __init prom_next_cell(int s, cell_t **cellp)
1094{
1095 cell_t *p = *cellp;
1096 unsigned long r = 0;
1097
1098 /* Ignore more than 2 cells */
1099 while (s > sizeof(unsigned long) / 4) {
1100 p++;
1101 s--;
1102 }
1103 r = *p++;
1104#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +10001105 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001106 r <<= 32;
1107 r |= *(p++);
1108 }
1109#endif
1110 *cellp = p;
1111 return r;
1112}
1113
1114/*
1115 * Very dumb function for adding to the memory reserve list, but
1116 * we don't need anything smarter at this point
1117 *
1118 * XXX Eventually check for collisions. They should NEVER happen.
1119 * If problems seem to show up, it would be a good start to track
1120 * them down.
1121 */
Michael Ellerman0108d3f2007-05-07 15:58:28 +10001122static void __init reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001123{
Kumar Galacbbcf342006-01-11 17:57:13 -06001124 u64 top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001125 unsigned long cnt = RELOC(mem_reserve_cnt);
1126
1127 if (size == 0)
1128 return;
1129
1130 /* We need to always keep one empty entry so that we
1131 * have our terminator with "size" set to 0 since we are
1132 * dumb and just copy this entire array to the boot params
1133 */
1134 base = _ALIGN_DOWN(base, PAGE_SIZE);
1135 top = _ALIGN_UP(top, PAGE_SIZE);
1136 size = top - base;
1137
1138 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1139 prom_panic("Memory reserve map exhausted !\n");
1140 RELOC(mem_reserve_map)[cnt].base = base;
1141 RELOC(mem_reserve_map)[cnt].size = size;
1142 RELOC(mem_reserve_cnt) = cnt + 1;
1143}
1144
1145/*
Adrian Bunkb3c2ffd2006-06-30 18:20:44 +02001146 * Initialize memory allocation mechanism, parse "memory" nodes and
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001147 * obtain that way the top of memory and RMO to setup out local allocator
1148 */
1149static void __init prom_init_mem(void)
1150{
1151 phandle node;
1152 char *path, type[64];
1153 unsigned int plen;
1154 cell_t *p, *endp;
1155 struct prom_t *_prom = &RELOC(prom);
1156 u32 rac, rsc;
1157
1158 /*
1159 * We iterate the memory nodes to find
1160 * 1) top of RMO (first node)
1161 * 2) top of memory
1162 */
1163 rac = 2;
1164 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1165 rsc = 1;
1166 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1167 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1168 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1169
1170 prom_debug("scanning memory:\n");
1171 path = RELOC(prom_scratch);
1172
1173 for (node = 0; prom_next_node(&node); ) {
1174 type[0] = 0;
1175 prom_getprop(node, "device_type", type, sizeof(type));
1176
Paul Mackerrasc49888202005-10-26 21:52:53 +10001177 if (type[0] == 0) {
1178 /*
1179 * CHRP Longtrail machines have no device_type
1180 * on the memory node, so check the name instead...
1181 */
1182 prom_getprop(node, "name", type, sizeof(type));
1183 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001184 if (strcmp(type, RELOC("memory")))
1185 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001186
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001187 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1188 if (plen > sizeof(regbuf)) {
1189 prom_printf("memory node too large for buffer !\n");
1190 plen = sizeof(regbuf);
1191 }
1192 p = RELOC(regbuf);
1193 endp = p + (plen / sizeof(cell_t));
1194
1195#ifdef DEBUG_PROM
1196 memset(path, 0, PROM_SCRATCH_SIZE);
1197 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1198 prom_debug(" node %s :\n", path);
1199#endif /* DEBUG_PROM */
1200
1201 while ((endp - p) >= (rac + rsc)) {
1202 unsigned long base, size;
1203
1204 base = prom_next_cell(rac, &p);
1205 size = prom_next_cell(rsc, &p);
1206
1207 if (size == 0)
1208 continue;
1209 prom_debug(" %x %x\n", base, size);
Benjamin Herrenschmidtab1b55e2006-03-03 10:35:40 +11001210 if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001211 RELOC(rmo_top) = size;
1212 if ((base + size) > RELOC(ram_top))
1213 RELOC(ram_top) = base + size;
1214 }
1215 }
1216
1217 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1218
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001219 /*
Benjamin Krillcf687872009-07-27 22:02:39 +00001220 * If prom_memory_limit is set we reduce the upper limits *except* for
1221 * alloc_top_high. This must be the real top of RAM so we can put
1222 * TCE's up there.
1223 */
1224
1225 RELOC(alloc_top_high) = RELOC(ram_top);
1226
1227 if (RELOC(prom_memory_limit)) {
1228 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
1229 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
1230 RELOC(prom_memory_limit));
1231 RELOC(prom_memory_limit) = 0;
1232 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
1233 prom_printf("Ignoring mem=%x >= ram_top.\n",
1234 RELOC(prom_memory_limit));
1235 RELOC(prom_memory_limit) = 0;
1236 } else {
1237 RELOC(ram_top) = RELOC(prom_memory_limit);
1238 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
1239 }
1240 }
1241
1242 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001243 * Setup our top alloc point, that is top of RMO or top of
1244 * segment 0 when running non-LPAR.
1245 * Some RS64 machines have buggy firmware where claims up at
1246 * 1GB fail. Cap at 768MB as a workaround.
1247 * Since 768MB is plenty of room, and we need to cap to something
1248 * reasonable on 32-bit, cap at 768MB on all machines.
1249 */
1250 if (!RELOC(rmo_top))
1251 RELOC(rmo_top) = RELOC(ram_top);
1252 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1253 RELOC(alloc_top) = RELOC(rmo_top);
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001254 RELOC(alloc_top_high) = RELOC(ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001255
Paul Mackerras64968f62011-12-13 17:54:13 +00001256 /*
1257 * Check if we have an initrd after the kernel but still inside
1258 * the RMO. If we do move our bottom point to after it.
1259 */
1260 if (RELOC(prom_initrd_start) &&
1261 RELOC(prom_initrd_start) < RELOC(rmo_top) &&
1262 RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1263 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1264
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001265 prom_printf("memory layout at init:\n");
Benjamin Krillcf687872009-07-27 22:02:39 +00001266 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001267 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1268 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
1269 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1270 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1271 prom_printf(" ram_top : %x\n", RELOC(ram_top));
1272}
1273
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001274static void __init prom_close_stdin(void)
1275{
1276 struct prom_t *_prom = &RELOC(prom);
1277 ihandle val;
1278
1279 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1280 call_prom("close", 1, 0, val);
1281}
1282
1283#ifdef CONFIG_PPC_POWERNV
1284
1285static u64 __initdata prom_opal_size;
1286static u64 __initdata prom_opal_align;
1287static int __initdata prom_rtas_start_cpu;
1288static u64 __initdata prom_rtas_data;
1289static u64 __initdata prom_rtas_entry;
1290
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001291#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1292static u64 __initdata prom_opal_base;
1293static u64 __initdata prom_opal_entry;
1294#endif
1295
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001296/* XXX Don't change this structure without updating opal-takeover.S */
1297static struct opal_secondary_data {
1298 s64 ack; /* 0 */
1299 u64 go; /* 8 */
1300 struct opal_takeover_args args; /* 16 */
1301} opal_secondary_data;
1302
1303extern char opal_secondary_entry;
1304
1305static void prom_query_opal(void)
1306{
1307 long rc;
1308
Benjamin Herrenschmidt76800572011-09-28 20:51:46 +00001309 /* We must not query for OPAL presence on a machine that
1310 * supports TNK takeover (970 blades), as this uses the same
1311 * h-call with different arguments and will crash
1312 */
1313 if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
1314 ADDR("/tnk-memory-map")))) {
1315 prom_printf("TNK takeover detected, skipping OPAL check\n");
1316 return;
1317 }
1318
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001319 prom_printf("Querying for OPAL presence... ");
1320 rc = opal_query_takeover(&RELOC(prom_opal_size),
1321 &RELOC(prom_opal_align));
1322 prom_debug("(rc = %ld) ", rc);
1323 if (rc != 0) {
1324 prom_printf("not there.\n");
1325 return;
1326 }
1327 RELOC(of_platform) = PLATFORM_OPAL;
1328 prom_printf(" there !\n");
1329 prom_debug(" opal_size = 0x%lx\n", RELOC(prom_opal_size));
1330 prom_debug(" opal_align = 0x%lx\n", RELOC(prom_opal_align));
1331 if (RELOC(prom_opal_align) < 0x10000)
1332 RELOC(prom_opal_align) = 0x10000;
1333}
1334
1335static int prom_rtas_call(int token, int nargs, int nret, int *outputs, ...)
1336{
1337 struct rtas_args rtas_args;
1338 va_list list;
1339 int i;
1340
1341 rtas_args.token = token;
1342 rtas_args.nargs = nargs;
1343 rtas_args.nret = nret;
1344 rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]);
1345 va_start(list, outputs);
1346 for (i = 0; i < nargs; ++i)
1347 rtas_args.args[i] = va_arg(list, rtas_arg_t);
1348 va_end(list);
1349
1350 for (i = 0; i < nret; ++i)
1351 rtas_args.rets[i] = 0;
1352
1353 opal_enter_rtas(&rtas_args, RELOC(prom_rtas_data),
1354 RELOC(prom_rtas_entry));
1355
1356 if (nret > 1 && outputs != NULL)
1357 for (i = 0; i < nret-1; ++i)
1358 outputs[i] = rtas_args.rets[i+1];
1359 return (nret > 0)? rtas_args.rets[0]: 0;
1360}
1361
1362static void __init prom_opal_hold_cpus(void)
1363{
1364 int i, cnt, cpu, rc;
1365 long j;
1366 phandle node;
1367 char type[64];
1368 u32 servers[8];
1369 struct prom_t *_prom = &RELOC(prom);
1370 void *entry = (unsigned long *)&RELOC(opal_secondary_entry);
1371 struct opal_secondary_data *data = &RELOC(opal_secondary_data);
1372
1373 prom_debug("prom_opal_hold_cpus: start...\n");
1374 prom_debug(" - entry = 0x%x\n", entry);
1375 prom_debug(" - data = 0x%x\n", data);
1376
1377 data->ack = -1;
1378 data->go = 0;
1379
1380 /* look for cpus */
1381 for (node = 0; prom_next_node(&node); ) {
1382 type[0] = 0;
1383 prom_getprop(node, "device_type", type, sizeof(type));
1384 if (strcmp(type, RELOC("cpu")) != 0)
1385 continue;
1386
1387 /* Skip non-configured cpus. */
1388 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1389 if (strcmp(type, RELOC("okay")) != 0)
1390 continue;
1391
1392 cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
1393 sizeof(servers));
1394 if (cnt == PROM_ERROR)
1395 break;
1396 cnt >>= 2;
1397 for (i = 0; i < cnt; i++) {
1398 cpu = servers[i];
1399 prom_debug("CPU %d ... ", cpu);
1400 if (cpu == _prom->cpu) {
1401 prom_debug("booted !\n");
1402 continue;
1403 }
1404 prom_debug("starting ... ");
1405
1406 /* Init the acknowledge var which will be reset by
1407 * the secondary cpu when it awakens from its OF
1408 * spinloop.
1409 */
1410 data->ack = -1;
1411 rc = prom_rtas_call(RELOC(prom_rtas_start_cpu), 3, 1,
1412 NULL, cpu, entry, data);
1413 prom_debug("rtas rc=%d ...", rc);
1414
1415 for (j = 0; j < 100000000 && data->ack == -1; j++) {
1416 HMT_low();
1417 mb();
1418 }
1419 HMT_medium();
1420 if (data->ack != -1)
1421 prom_debug("done, PIR=0x%x\n", data->ack);
1422 else
1423 prom_debug("timeout !\n");
1424 }
1425 }
1426 prom_debug("prom_opal_hold_cpus: end...\n");
1427}
1428
1429static void prom_opal_takeover(void)
1430{
1431 struct opal_secondary_data *data = &RELOC(opal_secondary_data);
1432 struct opal_takeover_args *args = &data->args;
1433 u64 align = RELOC(prom_opal_align);
1434 u64 top_addr, opal_addr;
1435
1436 args->k_image = (u64)RELOC(_stext);
1437 args->k_size = _end - _stext;
1438 args->k_entry = 0;
1439 args->k_entry2 = 0x60;
1440
1441 top_addr = _ALIGN_UP(args->k_size, align);
1442
1443 if (RELOC(prom_initrd_start) != 0) {
1444 args->rd_image = RELOC(prom_initrd_start);
1445 args->rd_size = RELOC(prom_initrd_end) - args->rd_image;
1446 args->rd_loc = top_addr;
1447 top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
1448 }
1449
1450 /* Pickup an address for the HAL. We want to go really high
1451 * up to avoid problem with future kexecs. On the other hand
1452 * we don't want to be all over the TCEs on P5IOC2 machines
1453 * which are going to be up there too. We assume the machine
1454 * has plenty of memory, and we ask for the HAL for now to
1455 * be just below the 1G point, or above the initrd
1456 */
1457 opal_addr = _ALIGN_DOWN(0x40000000 - RELOC(prom_opal_size), align);
1458 if (opal_addr < top_addr)
1459 opal_addr = top_addr;
1460 args->hal_addr = opal_addr;
1461
Benjamin Herrenschmidt817c21a2011-09-19 17:44:56 +00001462 /* Copy the command line to the kernel image */
1463 strlcpy(RELOC(boot_command_line), RELOC(prom_cmd_line),
1464 COMMAND_LINE_SIZE);
1465
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001466 prom_debug(" k_image = 0x%lx\n", args->k_image);
1467 prom_debug(" k_size = 0x%lx\n", args->k_size);
1468 prom_debug(" k_entry = 0x%lx\n", args->k_entry);
1469 prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2);
1470 prom_debug(" hal_addr = 0x%lx\n", args->hal_addr);
1471 prom_debug(" rd_image = 0x%lx\n", args->rd_image);
1472 prom_debug(" rd_size = 0x%lx\n", args->rd_size);
1473 prom_debug(" rd_loc = 0x%lx\n", args->rd_loc);
1474 prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
1475 prom_close_stdin();
1476 mb();
1477 data->go = 1;
1478 for (;;)
1479 opal_do_takeover(args);
1480}
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001481
1482/*
1483 * Allocate room for and instantiate OPAL
1484 */
1485static void __init prom_instantiate_opal(void)
1486{
1487 phandle opal_node;
1488 ihandle opal_inst;
1489 u64 base, entry;
1490 u64 size = 0, align = 0x10000;
1491 u32 rets[2];
1492
1493 prom_debug("prom_instantiate_opal: start...\n");
1494
1495 opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
1496 prom_debug("opal_node: %x\n", opal_node);
1497 if (!PHANDLE_VALID(opal_node))
1498 return;
1499
1500 prom_getprop(opal_node, "opal-runtime-size", &size, sizeof(size));
1501 if (size == 0)
1502 return;
1503 prom_getprop(opal_node, "opal-runtime-alignment", &align,
1504 sizeof(align));
1505
1506 base = alloc_down(size, align, 0);
1507 if (base == 0) {
1508 prom_printf("OPAL allocation failed !\n");
1509 return;
1510 }
1511
1512 opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
1513 if (!IHANDLE_VALID(opal_inst)) {
1514 prom_printf("opening opal package failed (%x)\n", opal_inst);
1515 return;
1516 }
1517
1518 prom_printf("instantiating opal at 0x%x...", base);
1519
1520 if (call_prom_ret("call-method", 4, 3, rets,
1521 ADDR("load-opal-runtime"),
1522 opal_inst,
1523 base >> 32, base & 0xffffffff) != 0
1524 || (rets[0] == 0 && rets[1] == 0)) {
1525 prom_printf(" failed\n");
1526 return;
1527 }
1528 entry = (((u64)rets[0]) << 32) | rets[1];
1529
1530 prom_printf(" done\n");
1531
1532 reserve_mem(base, size);
1533
1534 prom_debug("opal base = 0x%x\n", base);
1535 prom_debug("opal align = 0x%x\n", align);
1536 prom_debug("opal entry = 0x%x\n", entry);
1537 prom_debug("opal size = 0x%x\n", (long)size);
1538
1539 prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
1540 &base, sizeof(base));
1541 prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
1542 &entry, sizeof(entry));
1543
1544#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1545 RELOC(prom_opal_base) = base;
1546 RELOC(prom_opal_entry) = entry;
1547#endif
1548 prom_debug("prom_instantiate_opal: end...\n");
1549}
1550
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001551#endif /* CONFIG_PPC_POWERNV */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001552
1553/*
1554 * Allocate room for and instantiate RTAS
1555 */
1556static void __init prom_instantiate_rtas(void)
1557{
1558 phandle rtas_node;
1559 ihandle rtas_inst;
1560 u32 base, entry = 0;
1561 u32 size = 0;
1562
1563 prom_debug("prom_instantiate_rtas: start...\n");
1564
1565 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1566 prom_debug("rtas_node: %x\n", rtas_node);
1567 if (!PHANDLE_VALID(rtas_node))
1568 return;
1569
1570 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1571 if (size == 0)
1572 return;
1573
1574 base = alloc_down(size, PAGE_SIZE, 0);
Anton Blanchard6d1e2c62011-11-14 12:55:47 +00001575 if (base == 0)
1576 prom_panic("Could not allocate memory for RTAS\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001577
1578 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1579 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001580 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001581 return;
1582 }
1583
Anton Blanchard1f8737a2009-03-31 20:06:15 +00001584 prom_printf("instantiating rtas at 0x%x...", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001585
1586 if (call_prom_ret("call-method", 3, 2, &entry,
1587 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001588 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001589 || entry == 0) {
1590 prom_printf(" failed\n");
1591 return;
1592 }
1593 prom_printf(" done\n");
1594
1595 reserve_mem(base, size);
1596
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001597 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1598 &base, sizeof(base));
1599 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1600 &entry, sizeof(entry));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001601
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001602#ifdef CONFIG_PPC_POWERNV
1603 /* PowerVN takeover hack */
1604 RELOC(prom_rtas_data) = base;
1605 RELOC(prom_rtas_entry) = entry;
1606 prom_getprop(rtas_node, "start-cpu", &RELOC(prom_rtas_start_cpu), 4);
1607#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001608 prom_debug("rtas base = 0x%x\n", base);
1609 prom_debug("rtas entry = 0x%x\n", entry);
1610 prom_debug("rtas size = 0x%x\n", (long)size);
1611
1612 prom_debug("prom_instantiate_rtas: end...\n");
1613}
1614
1615#ifdef CONFIG_PPC64
1616/*
1617 * Allocate room for and initialize TCE tables
1618 */
1619static void __init prom_initialize_tce_table(void)
1620{
1621 phandle node;
1622 ihandle phb_node;
1623 char compatible[64], type[64], model[64];
1624 char *path = RELOC(prom_scratch);
1625 u64 base, align;
1626 u32 minalign, minsize;
1627 u64 tce_entry, *tce_entryp;
1628 u64 local_alloc_top, local_alloc_bottom;
1629 u64 i;
1630
Jeremy Kerr165785e2006-11-11 17:25:18 +11001631 if (RELOC(prom_iommu_off))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001632 return;
1633
1634 prom_debug("starting prom_initialize_tce_table\n");
1635
1636 /* Cache current top of allocs so we reserve a single block */
1637 local_alloc_top = RELOC(alloc_top_high);
1638 local_alloc_bottom = local_alloc_top;
1639
1640 /* Search all nodes looking for PHBs. */
1641 for (node = 0; prom_next_node(&node); ) {
1642 compatible[0] = 0;
1643 type[0] = 0;
1644 model[0] = 0;
1645 prom_getprop(node, "compatible",
1646 compatible, sizeof(compatible));
1647 prom_getprop(node, "device_type", type, sizeof(type));
1648 prom_getprop(node, "model", model, sizeof(model));
1649
1650 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1651 continue;
1652
Linas Vepstase788ff12007-09-07 03:45:21 +10001653 /* Keep the old logic intact to avoid regression. */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001654 if (compatible[0] != 0) {
1655 if ((strstr(compatible, RELOC("python")) == NULL) &&
1656 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1657 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1658 continue;
1659 } else if (model[0] != 0) {
1660 if ((strstr(model, RELOC("ython")) == NULL) &&
1661 (strstr(model, RELOC("peedwagon")) == NULL) &&
1662 (strstr(model, RELOC("innipeg")) == NULL))
1663 continue;
1664 }
1665
1666 if (prom_getprop(node, "tce-table-minalign", &minalign,
1667 sizeof(minalign)) == PROM_ERROR)
1668 minalign = 0;
1669 if (prom_getprop(node, "tce-table-minsize", &minsize,
1670 sizeof(minsize)) == PROM_ERROR)
1671 minsize = 4UL << 20;
1672
1673 /*
1674 * Even though we read what OF wants, we just set the table
1675 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1676 * By doing this, we avoid the pitfalls of trying to DMA to
1677 * MMIO space and the DMA alias hole.
1678 *
1679 * On POWER4, firmware sets the TCE region by assuming
1680 * each TCE table is 8MB. Using this memory for anything
1681 * else will impact performance, so we always allocate 8MB.
1682 * Anton
1683 */
1684 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1685 minsize = 8UL << 20;
1686 else
1687 minsize = 4UL << 20;
1688
1689 /* Align to the greater of the align or size */
1690 align = max(minalign, minsize);
1691 base = alloc_down(minsize, align, 1);
1692 if (base == 0)
1693 prom_panic("ERROR, cannot find space for TCE table.\n");
1694 if (base < local_alloc_bottom)
1695 local_alloc_bottom = base;
1696
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001697 /* It seems OF doesn't null-terminate the path :-( */
Li Zefanaca71ef2007-11-05 13:21:56 +11001698 memset(path, 0, PROM_SCRATCH_SIZE);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001699 /* Call OF to setup the TCE hardware */
1700 if (call_prom("package-to-path", 3, 1, node,
1701 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1702 prom_printf("package-to-path failed\n");
1703 }
1704
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001705 /* Save away the TCE table attributes for later use. */
1706 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1707 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1708
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001709 prom_debug("TCE table: %s\n", path);
1710 prom_debug("\tnode = 0x%x\n", node);
1711 prom_debug("\tbase = 0x%x\n", base);
1712 prom_debug("\tsize = 0x%x\n", minsize);
1713
1714 /* Initialize the table to have a one-to-one mapping
1715 * over the allocated size.
1716 */
Ingo Molnar2b931fb2009-01-06 13:56:52 +00001717 tce_entryp = (u64 *)base;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001718 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1719 tce_entry = (i << PAGE_SHIFT);
1720 tce_entry |= 0x3;
1721 *tce_entryp = tce_entry;
1722 }
1723
1724 prom_printf("opening PHB %s", path);
1725 phb_node = call_prom("open", 1, 1, path);
1726 if (phb_node == 0)
1727 prom_printf("... failed\n");
1728 else
1729 prom_printf("... done\n");
1730
1731 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1732 phb_node, -1, minsize,
1733 (u32) base, (u32) (base >> 32));
1734 call_prom("close", 1, 0, phb_node);
1735 }
1736
1737 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1738
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001739 /* These are only really needed if there is a memory limit in
1740 * effect, but we don't know so export them always. */
1741 RELOC(prom_tce_alloc_start) = local_alloc_bottom;
1742 RELOC(prom_tce_alloc_end) = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001743
1744 /* Flag the first invalid entry */
1745 prom_debug("ending prom_initialize_tce_table\n");
1746}
1747#endif
1748
1749/*
1750 * With CHRP SMP we need to use the OF to start the other processors.
1751 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1752 * so we have to put the processors into a holding pattern controlled
1753 * by the kernel (not OF) before we destroy the OF.
1754 *
1755 * This uses a chunk of low memory, puts some holding pattern
1756 * code there and sends the other processors off to there until
1757 * smp_boot_cpus tells them to do something. The holding pattern
1758 * checks that address until its cpu # is there, when it is that
1759 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1760 * of setting those values.
1761 *
1762 * We also use physical address 0x4 here to tell when a cpu
1763 * is in its holding pattern code.
1764 *
1765 * -- Cort
1766 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001767/*
1768 * We want to reference the copy of __secondary_hold_* in the
1769 * 0 - 0x100 address range
1770 */
1771#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1772
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001773static void __init prom_hold_cpus(void)
1774{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001775 unsigned long i;
1776 unsigned int reg;
1777 phandle node;
1778 char type[64];
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001779 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001780 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001781 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001782 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001783 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001784 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001785
1786 prom_debug("prom_hold_cpus: start...\n");
1787 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1788 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1789 prom_debug(" 1) acknowledge = 0x%x\n",
1790 (unsigned long)acknowledge);
1791 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1792 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1793
1794 /* Set the common spinloop variable, so all of the secondary cpus
1795 * will block when they are awakened from their OF spinloop.
1796 * This must occur for both SMP and non SMP kernels, since OF will
1797 * be trashed when we move the kernel.
1798 */
1799 *spinloop = 0;
1800
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001801 /* look for cpus */
1802 for (node = 0; prom_next_node(&node); ) {
1803 type[0] = 0;
1804 prom_getprop(node, "device_type", type, sizeof(type));
1805 if (strcmp(type, RELOC("cpu")) != 0)
1806 continue;
1807
1808 /* Skip non-configured cpus. */
1809 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1810 if (strcmp(type, RELOC("okay")) != 0)
1811 continue;
1812
1813 reg = -1;
1814 prom_getprop(node, "reg", &reg, sizeof(reg));
1815
Michael Neuling2c48a7d2010-07-27 18:26:21 +00001816 prom_debug("cpu hw idx = %lu\n", reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001817
1818 /* Init the acknowledge var which will be reset by
1819 * the secondary cpu when it awakens from its OF
1820 * spinloop.
1821 */
1822 *acknowledge = (unsigned long)-1;
1823
Nathan Lynch7d2f6072008-07-27 15:24:50 +10001824 if (reg != _prom->cpu) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001825 /* Primary Thread of non-boot cpu or any thread */
Michael Neuling2c48a7d2010-07-27 18:26:21 +00001826 prom_printf("starting cpu hw idx %lu... ", reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001827 call_prom("start-cpu", 3, 0, node,
1828 secondary_hold, reg);
1829
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001830 for (i = 0; (i < 100000000) &&
1831 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001832 mb();
1833
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001834 if (*acknowledge == reg)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001835 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001836 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001837 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001838 }
1839#ifdef CONFIG_SMP
1840 else
Michael Neuling2c48a7d2010-07-27 18:26:21 +00001841 prom_printf("boot cpu hw idx %lu\n", reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001842#endif /* CONFIG_SMP */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001843 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001844
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001845 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001846}
1847
1848
1849static void __init prom_init_client_services(unsigned long pp)
1850{
1851 struct prom_t *_prom = &RELOC(prom);
1852
1853 /* Get a handle to the prom entry point before anything else */
1854 RELOC(prom_entry) = pp;
1855
1856 /* get a handle for the stdout device */
1857 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1858 if (!PHANDLE_VALID(_prom->chosen))
1859 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1860
1861 /* get device tree root */
1862 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1863 if (!PHANDLE_VALID(_prom->root))
1864 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001865
1866 _prom->mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001867}
1868
Paul Mackerrasa575b802005-10-23 17:23:21 +10001869#ifdef CONFIG_PPC32
1870/*
1871 * For really old powermacs, we need to map things we claim.
1872 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001873 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001874 */
1875static void __init prom_find_mmu(void)
1876{
1877 struct prom_t *_prom = &RELOC(prom);
1878 phandle oprom;
1879 char version[64];
1880
1881 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1882 if (!PHANDLE_VALID(oprom))
1883 return;
1884 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1885 return;
1886 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001887 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001888 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1889 of_workarounds = OF_WA_CLAIM;
1890 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1891 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1892 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1893 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001894 return;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001895 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
Paul Mackerrasa575b802005-10-23 17:23:21 +10001896 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1897 sizeof(_prom->mmumap));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001898 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1899 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001900}
1901#else
1902#define prom_find_mmu()
1903#endif
1904
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001905static void __init prom_init_stdout(void)
1906{
1907 struct prom_t *_prom = &RELOC(prom);
1908 char *path = RELOC(of_stdout_device);
1909 char type[16];
1910 u32 val;
1911
1912 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1913 prom_panic("cannot find stdout");
1914
1915 _prom->stdout = val;
1916
1917 /* Get the full OF pathname of the stdout device */
1918 memset(path, 0, 256);
1919 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1920 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001921 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1922 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001923 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001924 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1925 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001926
1927 /* If it's a display, note it */
1928 memset(type, 0, sizeof(type));
1929 prom_getprop(val, "device_type", type, sizeof(type));
1930 if (strcmp(type, RELOC("display")) == 0)
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001931 prom_setprop(val, path, "linux,boot-display", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001932}
1933
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001934static int __init prom_find_machine_type(void)
1935{
1936 struct prom_t *_prom = &RELOC(prom);
1937 char compat[256];
1938 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001939#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001940 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001941 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001942#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001943
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001944 /* Look for a PowerMac or a Cell */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001945 len = prom_getprop(_prom->root, "compatible",
1946 compat, sizeof(compat)-1);
1947 if (len > 0) {
1948 compat[len] = 0;
1949 while (i < len) {
1950 char *p = &compat[i];
1951 int sl = strlen(p);
1952 if (sl == 0)
1953 break;
1954 if (strstr(p, RELOC("Power Macintosh")) ||
Paul Mackerrasa575b802005-10-23 17:23:21 +10001955 strstr(p, RELOC("MacRISC")))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001956 return PLATFORM_POWERMAC;
Arnd Bergmann133dda12006-06-07 12:04:18 +10001957#ifdef CONFIG_PPC64
1958 /* We must make sure we don't detect the IBM Cell
1959 * blades as pSeries due to some firmware issues,
1960 * so we do it here.
1961 */
1962 if (strstr(p, RELOC("IBM,CBEA")) ||
1963 strstr(p, RELOC("IBM,CPBW-1.0")))
1964 return PLATFORM_GENERIC;
1965#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001966 i += sl + 1;
1967 }
1968 }
1969#ifdef CONFIG_PPC64
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001970 /* Try to detect OPAL */
1971 if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
1972 return PLATFORM_OPAL;
1973
1974 /* Try to figure out if it's an IBM pSeries or any other
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001975 * PAPR compliant platform. We assume it is if :
1976 * - /device_type is "chrp" (please, do NOT use that for future
1977 * non-IBM designs !
1978 * - it has /rtas
1979 */
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001980 len = prom_getprop(_prom->root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001981 compat, sizeof(compat)-1);
1982 if (len <= 0)
1983 return PLATFORM_GENERIC;
Benjamin Herrenschmidtcb6b2eb2006-05-15 15:46:03 +10001984 if (strcmp(compat, RELOC("chrp")))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001985 return PLATFORM_GENERIC;
1986
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001987 /* Default to pSeries. We need to know if we are running LPAR */
1988 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001989 if (!PHANDLE_VALID(rtas))
1990 return PLATFORM_GENERIC;
1991 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1992 if (x != PROM_ERROR) {
Anton Blanchard4da727a2009-03-31 20:06:14 +00001993 prom_debug("Hypertas detected, assuming LPAR !\n");
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001994 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001995 }
1996 return PLATFORM_PSERIES;
1997#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001998 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001999#endif
2000}
2001
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002002static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
2003{
2004 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
2005}
2006
2007/*
2008 * If we have a display that we don't know how to drive,
2009 * we will want to try to execute OF's open method for it
2010 * later. However, OF will probably fall over if we do that
2011 * we've taken over the MMU.
2012 * So we check whether we will need to open the display,
2013 * and if so, open it now.
2014 */
2015static void __init prom_check_displays(void)
2016{
2017 char type[16], *path;
2018 phandle node;
2019 ihandle ih;
2020 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002021
2022 static unsigned char default_colors[] = {
2023 0x00, 0x00, 0x00,
2024 0x00, 0x00, 0xaa,
2025 0x00, 0xaa, 0x00,
2026 0x00, 0xaa, 0xaa,
2027 0xaa, 0x00, 0x00,
2028 0xaa, 0x00, 0xaa,
2029 0xaa, 0xaa, 0x00,
2030 0xaa, 0xaa, 0xaa,
2031 0x55, 0x55, 0x55,
2032 0x55, 0x55, 0xff,
2033 0x55, 0xff, 0x55,
2034 0x55, 0xff, 0xff,
2035 0xff, 0x55, 0x55,
2036 0xff, 0x55, 0xff,
2037 0xff, 0xff, 0x55,
2038 0xff, 0xff, 0xff
2039 };
2040 const unsigned char *clut;
2041
Anton Blanchard4da727a2009-03-31 20:06:14 +00002042 prom_debug("Looking for displays\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002043 for (node = 0; prom_next_node(&node); ) {
2044 memset(type, 0, sizeof(type));
2045 prom_getprop(node, "device_type", type, sizeof(type));
2046 if (strcmp(type, RELOC("display")) != 0)
2047 continue;
2048
2049 /* It seems OF doesn't null-terminate the path :-( */
2050 path = RELOC(prom_scratch);
2051 memset(path, 0, PROM_SCRATCH_SIZE);
2052
2053 /*
2054 * leave some room at the end of the path for appending extra
2055 * arguments
2056 */
2057 if (call_prom("package-to-path", 3, 1, node, path,
2058 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2059 continue;
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002060 prom_printf("found display : %s, opening... ", path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002061
2062 ih = call_prom("open", 1, 1, path);
2063 if (ih == 0) {
2064 prom_printf("failed\n");
2065 continue;
2066 }
2067
2068 /* Success */
2069 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002070 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002071
2072 /* Setup a usable color table when the appropriate
2073 * method is available. Should update this to set-colors */
2074 clut = RELOC(default_colors);
Benjamin Herrenschmidt3f536382011-12-14 13:55:11 +00002075 for (i = 0; i < 16; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002076 if (prom_set_color(ih, i, clut[0], clut[1],
2077 clut[2]) != 0)
2078 break;
2079
2080#ifdef CONFIG_LOGO_LINUX_CLUT224
2081 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
2082 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
2083 if (prom_set_color(ih, i + 32, clut[0], clut[1],
2084 clut[2]) != 0)
2085 break;
2086#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002087 }
2088}
2089
2090
2091/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
2092static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
2093 unsigned long needed, unsigned long align)
2094{
2095 void *ret;
2096
2097 *mem_start = _ALIGN(*mem_start, align);
2098 while ((*mem_start + needed) > *mem_end) {
2099 unsigned long room, chunk;
2100
2101 prom_debug("Chunk exhausted, claiming more at %x...\n",
2102 RELOC(alloc_bottom));
2103 room = RELOC(alloc_top) - RELOC(alloc_bottom);
2104 if (room > DEVTREE_CHUNK_SIZE)
2105 room = DEVTREE_CHUNK_SIZE;
2106 if (room < PAGE_SIZE)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002107 prom_panic("No memory for flatten_device_tree "
2108 "(no room)\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002109 chunk = alloc_up(room, 0);
2110 if (chunk == 0)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002111 prom_panic("No memory for flatten_device_tree "
2112 "(claim failed)\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002113 *mem_end = chunk + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002114 }
2115
2116 ret = (void *)*mem_start;
2117 *mem_start += needed;
2118
2119 return ret;
2120}
2121
2122#define dt_push_token(token, mem_start, mem_end) \
2123 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
2124
2125static unsigned long __init dt_find_string(char *str)
2126{
2127 char *s, *os;
2128
2129 s = os = (char *)RELOC(dt_string_start);
2130 s += 4;
2131 while (s < (char *)RELOC(dt_string_end)) {
2132 if (strcmp(s, str) == 0)
2133 return s - os;
2134 s += strlen(s) + 1;
2135 }
2136 return 0;
2137}
2138
2139/*
2140 * The Open Firmware 1275 specification states properties must be 31 bytes or
2141 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
2142 */
2143#define MAX_PROPERTY_NAME 64
2144
2145static void __init scan_dt_build_strings(phandle node,
2146 unsigned long *mem_start,
2147 unsigned long *mem_end)
2148{
2149 char *prev_name, *namep, *sstart;
2150 unsigned long soff;
2151 phandle child;
2152
2153 sstart = (char *)RELOC(dt_string_start);
2154
2155 /* get and store all property names */
2156 prev_name = RELOC("");
2157 for (;;) {
2158 /* 64 is max len of name including nul. */
2159 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
2160 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
2161 /* No more nodes: unwind alloc */
2162 *mem_start = (unsigned long)namep;
2163 break;
2164 }
2165
2166 /* skip "name" */
2167 if (strcmp(namep, RELOC("name")) == 0) {
2168 *mem_start = (unsigned long)namep;
2169 prev_name = RELOC("name");
2170 continue;
2171 }
2172 /* get/create string entry */
2173 soff = dt_find_string(namep);
2174 if (soff != 0) {
2175 *mem_start = (unsigned long)namep;
2176 namep = sstart + soff;
2177 } else {
2178 /* Trim off some if we can */
2179 *mem_start = (unsigned long)namep + strlen(namep) + 1;
2180 RELOC(dt_string_end) = *mem_start;
2181 }
2182 prev_name = namep;
2183 }
2184
2185 /* do all our children */
2186 child = call_prom("child", 1, 1, node);
2187 while (child != 0) {
2188 scan_dt_build_strings(child, mem_start, mem_end);
2189 child = call_prom("peer", 1, 1, child);
2190 }
2191}
2192
2193static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2194 unsigned long *mem_end)
2195{
2196 phandle child;
2197 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
2198 unsigned long soff;
2199 unsigned char *valp;
2200 static char pname[MAX_PROPERTY_NAME];
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002201 int l, room, has_phandle = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002202
2203 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
2204
2205 /* get the node's full name */
2206 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10002207 room = *mem_end - *mem_start;
2208 if (room > 255)
2209 room = 255;
2210 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002211 if (l >= 0) {
2212 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10002213 if (l >= room) {
2214 if (l >= *mem_end - *mem_start)
2215 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002216 call_prom("package-to-path", 3, 1, node, namep, l);
2217 }
2218 namep[l] = '\0';
2219
2220 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10002221 * middle of the path in some properties, and extract
2222 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002223 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002224 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002225 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10002226 lp = namep;
2227 else if (*p != 0)
2228 *lp++ = *p;
2229 }
2230 *lp = 0;
2231 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002232 }
2233
2234 /* get it again for debugging */
2235 path = RELOC(prom_scratch);
2236 memset(path, 0, PROM_SCRATCH_SIZE);
2237 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2238
2239 /* get and store all properties */
2240 prev_name = RELOC("");
2241 sstart = (char *)RELOC(dt_string_start);
2242 for (;;) {
2243 if (call_prom("nextprop", 3, 1, node, prev_name,
2244 RELOC(pname)) != 1)
2245 break;
2246
2247 /* skip "name" */
2248 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
2249 prev_name = RELOC("name");
2250 continue;
2251 }
2252
2253 /* find string offset */
2254 soff = dt_find_string(RELOC(pname));
2255 if (soff == 0) {
2256 prom_printf("WARNING: Can't find string index for"
2257 " <%s>, node %s\n", RELOC(pname), path);
2258 break;
2259 }
2260 prev_name = sstart + soff;
2261
2262 /* get length */
2263 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
2264
2265 /* sanity checks */
2266 if (l == PROM_ERROR)
2267 continue;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002268
2269 /* push property head */
2270 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2271 dt_push_token(l, mem_start, mem_end);
2272 dt_push_token(soff, mem_start, mem_end);
2273
2274 /* push property content */
2275 valp = make_room(mem_start, mem_end, l, 4);
2276 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
2277 *mem_start = _ALIGN(*mem_start, 4);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002278
2279 if (!strcmp(RELOC(pname), RELOC("phandle")))
2280 has_phandle = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002281 }
2282
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002283 /* Add a "linux,phandle" property if no "phandle" property already
2284 * existed (can happen with OPAL)
2285 */
2286 if (!has_phandle) {
2287 soff = dt_find_string(RELOC("linux,phandle"));
2288 if (soff == 0)
2289 prom_printf("WARNING: Can't find string index for"
2290 " <linux-phandle> node %s\n", path);
2291 else {
2292 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2293 dt_push_token(4, mem_start, mem_end);
2294 dt_push_token(soff, mem_start, mem_end);
2295 valp = make_room(mem_start, mem_end, 4, 4);
2296 *(u32 *)valp = node;
2297 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002298 }
2299
2300 /* do all our children */
2301 child = call_prom("child", 1, 1, node);
2302 while (child != 0) {
2303 scan_dt_build_struct(child, mem_start, mem_end);
2304 child = call_prom("peer", 1, 1, child);
2305 }
2306
2307 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
2308}
2309
2310static void __init flatten_device_tree(void)
2311{
2312 phandle root;
2313 unsigned long mem_start, mem_end, room;
2314 struct boot_param_header *hdr;
2315 struct prom_t *_prom = &RELOC(prom);
2316 char *namep;
2317 u64 *rsvmap;
2318
2319 /*
2320 * Check how much room we have between alloc top & bottom (+/- a
Anton Blanchardfbafd722011-07-25 20:47:51 +00002321 * few pages), crop to 1MB, as this is our "chunk" size
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002322 */
2323 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
2324 if (room > DEVTREE_CHUNK_SIZE)
2325 room = DEVTREE_CHUNK_SIZE;
2326 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
2327
2328 /* Now try to claim that */
2329 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
2330 if (mem_start == 0)
2331 prom_panic("Can't allocate initial device-tree chunk\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002332 mem_end = mem_start + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002333
2334 /* Get root of tree */
2335 root = call_prom("peer", 1, 1, (phandle)0);
2336 if (root == (phandle)0)
2337 prom_panic ("couldn't get device tree root\n");
2338
2339 /* Build header and make room for mem rsv map */
2340 mem_start = _ALIGN(mem_start, 4);
2341 hdr = make_room(&mem_start, &mem_end,
2342 sizeof(struct boot_param_header), 4);
2343 RELOC(dt_header_start) = (unsigned long)hdr;
2344 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
2345
2346 /* Start of strings */
2347 mem_start = PAGE_ALIGN(mem_start);
2348 RELOC(dt_string_start) = mem_start;
2349 mem_start += 4; /* hole */
2350
2351 /* Add "linux,phandle" in there, we'll need it */
2352 namep = make_room(&mem_start, &mem_end, 16, 1);
2353 strcpy(namep, RELOC("linux,phandle"));
2354 mem_start = (unsigned long)namep + strlen(namep) + 1;
2355
2356 /* Build string array */
2357 prom_printf("Building dt strings...\n");
2358 scan_dt_build_strings(root, &mem_start, &mem_end);
2359 RELOC(dt_string_end) = mem_start;
2360
2361 /* Build structure */
2362 mem_start = PAGE_ALIGN(mem_start);
2363 RELOC(dt_struct_start) = mem_start;
2364 prom_printf("Building dt structure...\n");
2365 scan_dt_build_struct(root, &mem_start, &mem_end);
2366 dt_push_token(OF_DT_END, &mem_start, &mem_end);
2367 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
2368
2369 /* Finish header */
2370 hdr->boot_cpuid_phys = _prom->cpu;
2371 hdr->magic = OF_DT_HEADER;
2372 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
2373 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
2374 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
2375 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
2376 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
2377 hdr->version = OF_DT_VERSION;
2378 /* Version 16 is not backward compatible */
2379 hdr->last_comp_version = 0x10;
2380
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002381 /* Copy the reserve map in */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002382 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
2383
2384#ifdef DEBUG_PROM
2385 {
2386 int i;
2387 prom_printf("reserved memory map:\n");
2388 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
2389 prom_printf(" %x - %x\n",
2390 RELOC(mem_reserve_map)[i].base,
2391 RELOC(mem_reserve_map)[i].size);
2392 }
2393#endif
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002394 /* Bump mem_reserve_cnt to cause further reservations to fail
2395 * since it's too late.
2396 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002397 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2398
2399 prom_printf("Device tree strings 0x%x -> 0x%x\n",
2400 RELOC(dt_string_start), RELOC(dt_string_end));
2401 prom_printf("Device tree struct 0x%x -> 0x%x\n",
2402 RELOC(dt_struct_start), RELOC(dt_struct_end));
2403
2404}
2405
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002406#ifdef CONFIG_PPC_MAPLE
2407/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2408 * The values are bad, and it doesn't even have the right number of cells. */
2409static void __init fixup_device_tree_maple(void)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002410{
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002411 phandle isa;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002412 u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002413 u32 isa_ranges[6];
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002414 char *name;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002415
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002416 name = "/ht@0/isa@4";
2417 isa = call_prom("finddevice", 1, 1, ADDR(name));
2418 if (!PHANDLE_VALID(isa)) {
2419 name = "/ht@0/isa@6";
2420 isa = call_prom("finddevice", 1, 1, ADDR(name));
2421 rloc = 0x01003000; /* IO space; PCI device = 6 */
2422 }
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002423 if (!PHANDLE_VALID(isa))
2424 return;
2425
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002426 if (prom_getproplen(isa, "ranges") != 12)
2427 return;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002428 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2429 == PROM_ERROR)
2430 return;
2431
2432 if (isa_ranges[0] != 0x1 ||
2433 isa_ranges[1] != 0xf4000000 ||
2434 isa_ranges[2] != 0x00010000)
2435 return;
2436
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002437 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002438
2439 isa_ranges[0] = 0x1;
2440 isa_ranges[1] = 0x0;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002441 isa_ranges[2] = rloc;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002442 isa_ranges[3] = 0x0;
2443 isa_ranges[4] = 0x0;
2444 isa_ranges[5] = 0x00010000;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002445 prom_setprop(isa, name, "ranges",
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002446 isa_ranges, sizeof(isa_ranges));
2447}
Harry Ciao8f101a02009-06-17 16:28:00 -07002448
2449#define CPC925_MC_START 0xf8000000
2450#define CPC925_MC_LENGTH 0x1000000
2451/* The values for memory-controller don't have right number of cells */
2452static void __init fixup_device_tree_maple_memory_controller(void)
2453{
2454 phandle mc;
2455 u32 mc_reg[4];
2456 char *name = "/hostbridge@f8000000";
2457 struct prom_t *_prom = &RELOC(prom);
2458 u32 ac, sc;
2459
2460 mc = call_prom("finddevice", 1, 1, ADDR(name));
2461 if (!PHANDLE_VALID(mc))
2462 return;
2463
2464 if (prom_getproplen(mc, "reg") != 8)
2465 return;
2466
2467 prom_getprop(_prom->root, "#address-cells", &ac, sizeof(ac));
2468 prom_getprop(_prom->root, "#size-cells", &sc, sizeof(sc));
2469 if ((ac != 2) || (sc != 2))
2470 return;
2471
2472 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2473 return;
2474
2475 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2476 return;
2477
2478 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2479
2480 mc_reg[0] = 0x0;
2481 mc_reg[1] = CPC925_MC_START;
2482 mc_reg[2] = 0x0;
2483 mc_reg[3] = CPC925_MC_LENGTH;
2484 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2485}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002486#else
2487#define fixup_device_tree_maple()
Harry Ciao8f101a02009-06-17 16:28:00 -07002488#define fixup_device_tree_maple_memory_controller()
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002489#endif
2490
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002491#ifdef CONFIG_PPC_CHRP
Olaf Heringe4805922007-04-04 18:20:04 +02002492/*
2493 * Pegasos and BriQ lacks the "ranges" property in the isa node
2494 * Pegasos needs decimal IRQ 14/15, not hexadecimal
Olaf Hering556ecf92007-08-18 04:27:17 +10002495 * Pegasos has the IDE configured in legacy mode, but advertised as native
Olaf Heringe4805922007-04-04 18:20:04 +02002496 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002497static void __init fixup_device_tree_chrp(void)
2498{
Olaf Heringe4805922007-04-04 18:20:04 +02002499 phandle ph;
2500 u32 prop[6];
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002501 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002502 char *name;
2503 int rc;
2504
2505 name = "/pci@80000000/isa@c";
Olaf Heringe4805922007-04-04 18:20:04 +02002506 ph = call_prom("finddevice", 1, 1, ADDR(name));
2507 if (!PHANDLE_VALID(ph)) {
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002508 name = "/pci@ff500000/isa@6";
Olaf Heringe4805922007-04-04 18:20:04 +02002509 ph = call_prom("finddevice", 1, 1, ADDR(name));
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002510 rloc = 0x01003000; /* IO space; PCI device = 6 */
2511 }
Olaf Heringe4805922007-04-04 18:20:04 +02002512 if (PHANDLE_VALID(ph)) {
2513 rc = prom_getproplen(ph, "ranges");
2514 if (rc == 0 || rc == PROM_ERROR) {
2515 prom_printf("Fixing up missing ISA range on Pegasos...\n");
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002516
Olaf Heringe4805922007-04-04 18:20:04 +02002517 prop[0] = 0x1;
2518 prop[1] = 0x0;
2519 prop[2] = rloc;
2520 prop[3] = 0x0;
2521 prop[4] = 0x0;
2522 prop[5] = 0x00010000;
2523 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2524 }
2525 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002526
Olaf Heringe4805922007-04-04 18:20:04 +02002527 name = "/pci@80000000/ide@C,1";
2528 ph = call_prom("finddevice", 1, 1, ADDR(name));
2529 if (PHANDLE_VALID(ph)) {
2530 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2531 prop[0] = 14;
2532 prop[1] = 0x0;
Olaf Hering556ecf92007-08-18 04:27:17 +10002533 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2534 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2535 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2536 if (rc == sizeof(u32)) {
2537 prop[0] &= ~0x5;
2538 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2539 }
Olaf Heringe4805922007-04-04 18:20:04 +02002540 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002541}
2542#else
2543#define fixup_device_tree_chrp()
2544#endif
2545
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002546#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002547static void __init fixup_device_tree_pmac(void)
2548{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002549 phandle u3, i2c, mpic;
2550 u32 u3_rev;
2551 u32 interrupts[2];
2552 u32 parent;
2553
2554 /* Some G5s have a missing interrupt definition, fix it up here */
2555 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2556 if (!PHANDLE_VALID(u3))
2557 return;
2558 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2559 if (!PHANDLE_VALID(i2c))
2560 return;
2561 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2562 if (!PHANDLE_VALID(mpic))
2563 return;
2564
2565 /* check if proper rev of u3 */
2566 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2567 == PROM_ERROR)
2568 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002569 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002570 return;
2571 /* does it need fixup ? */
2572 if (prom_getproplen(i2c, "interrupts") > 0)
2573 return;
2574
2575 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2576
2577 /* interrupt on this revision of u3 is number 0 and level */
2578 interrupts[0] = 0;
2579 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002580 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2581 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002582 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002583 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2584 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002585}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002586#else
2587#define fixup_device_tree_pmac()
2588#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002589
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002590#ifdef CONFIG_PPC_EFIKA
Grant Likely94d2dde2008-01-24 22:25:32 -07002591/*
2592 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2593 * to talk to the phy. If the phy-handle property is missing, then this
2594 * function is called to add the appropriate nodes and link it to the
2595 * ethernet node.
2596 */
2597static void __init fixup_device_tree_efika_add_phy(void)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002598{
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002599 u32 node;
2600 char prop[64];
Grant Likely94d2dde2008-01-24 22:25:32 -07002601 int rv;
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002602
Grant Likely94d2dde2008-01-24 22:25:32 -07002603 /* Check if /builtin/ethernet exists - bail if it doesn't */
2604 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002605 if (!PHANDLE_VALID(node))
2606 return;
2607
Grant Likely94d2dde2008-01-24 22:25:32 -07002608 /* Check if the phy-handle property exists - bail if it does */
2609 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2610 if (!rv)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002611 return;
2612
Grant Likely94d2dde2008-01-24 22:25:32 -07002613 /*
2614 * At this point the ethernet device doesn't have a phy described.
2615 * Now we need to add the missing phy node and linkage
2616 */
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002617
Grant Likely94d2dde2008-01-24 22:25:32 -07002618 /* Check for an MDIO bus node - if missing then create one */
Olaf Hering6f4347c2008-01-10 01:06:08 +11002619 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2620 if (!PHANDLE_VALID(node)) {
2621 prom_printf("Adding Ethernet MDIO node\n");
2622 call_prom("interpret", 1, 1,
2623 " s\" /builtin\" find-device"
2624 " new-device"
2625 " 1 encode-int s\" #address-cells\" property"
2626 " 0 encode-int s\" #size-cells\" property"
Grant Likely94d2dde2008-01-24 22:25:32 -07002627 " s\" mdio\" device-name"
2628 " s\" fsl,mpc5200b-mdio\" encode-string"
Olaf Hering6f4347c2008-01-10 01:06:08 +11002629 " s\" compatible\" property"
2630 " 0xf0003000 0x400 reg"
2631 " 0x2 encode-int"
2632 " 0x5 encode-int encode+"
2633 " 0x3 encode-int encode+"
2634 " s\" interrupts\" property"
2635 " finish-device");
2636 };
2637
Grant Likely94d2dde2008-01-24 22:25:32 -07002638 /* Check for a PHY device node - if missing then create one and
2639 * give it's phandle to the ethernet node */
2640 node = call_prom("finddevice", 1, 1,
2641 ADDR("/builtin/mdio/ethernet-phy"));
Olaf Hering6f4347c2008-01-10 01:06:08 +11002642 if (!PHANDLE_VALID(node)) {
2643 prom_printf("Adding Ethernet PHY node\n");
2644 call_prom("interpret", 1, 1,
2645 " s\" /builtin/mdio\" find-device"
2646 " new-device"
2647 " s\" ethernet-phy\" device-name"
2648 " 0x10 encode-int s\" reg\" property"
2649 " my-self"
2650 " ihandle>phandle"
2651 " finish-device"
2652 " s\" /builtin/ethernet\" find-device"
2653 " encode-int"
2654 " s\" phy-handle\" property"
2655 " device-end");
2656 }
Grant Likely94d2dde2008-01-24 22:25:32 -07002657}
Olaf Hering6f4347c2008-01-10 01:06:08 +11002658
Grant Likely94d2dde2008-01-24 22:25:32 -07002659static void __init fixup_device_tree_efika(void)
2660{
2661 int sound_irq[3] = { 2, 2, 0 };
2662 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2663 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2664 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2665 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2666 u32 node;
2667 char prop[64];
2668 int rv, len;
2669
2670 /* Check if we're really running on a EFIKA */
2671 node = call_prom("finddevice", 1, 1, ADDR("/"));
2672 if (!PHANDLE_VALID(node))
2673 return;
2674
2675 rv = prom_getprop(node, "model", prop, sizeof(prop));
2676 if (rv == PROM_ERROR)
2677 return;
2678 if (strcmp(prop, "EFIKA5K2"))
2679 return;
2680
2681 prom_printf("Applying EFIKA device tree fixups\n");
2682
2683 /* Claiming to be 'chrp' is death */
2684 node = call_prom("finddevice", 1, 1, ADDR("/"));
2685 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2686 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2687 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2688
David Woodhouse7f4392c2008-04-14 02:52:38 +10002689 /* CODEGEN,description is exposed in /proc/cpuinfo so
2690 fix that too */
2691 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2692 if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2693 prom_setprop(node, "/", "CODEGEN,description",
2694 "Efika 5200B PowerPC System",
2695 sizeof("Efika 5200B PowerPC System"));
2696
Grant Likely94d2dde2008-01-24 22:25:32 -07002697 /* Fixup bestcomm interrupts property */
2698 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2699 if (PHANDLE_VALID(node)) {
2700 len = prom_getproplen(node, "interrupts");
2701 if (len == 12) {
2702 prom_printf("Fixing bestcomm interrupts property\n");
2703 prom_setprop(node, "/builtin/bestcom", "interrupts",
2704 bcomm_irq, sizeof(bcomm_irq));
2705 }
2706 }
2707
2708 /* Fixup sound interrupts property */
2709 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2710 if (PHANDLE_VALID(node)) {
2711 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2712 if (rv == PROM_ERROR) {
2713 prom_printf("Adding sound interrupts property\n");
2714 prom_setprop(node, "/builtin/sound", "interrupts",
2715 sound_irq, sizeof(sound_irq));
2716 }
2717 }
2718
2719 /* Make sure ethernet phy-handle property exists */
2720 fixup_device_tree_efika_add_phy();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002721}
2722#else
2723#define fixup_device_tree_efika()
2724#endif
2725
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002726static void __init fixup_device_tree(void)
2727{
2728 fixup_device_tree_maple();
Harry Ciao8f101a02009-06-17 16:28:00 -07002729 fixup_device_tree_maple_memory_controller();
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002730 fixup_device_tree_chrp();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002731 fixup_device_tree_pmac();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002732 fixup_device_tree_efika();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002733}
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002734
2735static void __init prom_find_boot_cpu(void)
2736{
Linas Vepstase788ff12007-09-07 03:45:21 +10002737 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002738 u32 getprop_rval;
2739 ihandle prom_cpu;
2740 phandle cpu_pkg;
2741
Paul Mackerrasa575b802005-10-23 17:23:21 +10002742 _prom->cpu = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002743 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002744 return;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002745
2746 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2747
2748 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2749 _prom->cpu = getprop_rval;
2750
Michael Neuling2c48a7d2010-07-27 18:26:21 +00002751 prom_debug("Booting CPU hw index = %lu\n", _prom->cpu);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002752}
2753
2754static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2755{
2756#ifdef CONFIG_BLK_DEV_INITRD
Linas Vepstase788ff12007-09-07 03:45:21 +10002757 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002758
2759 if (r3 && r4 && r4 != 0xdeadbeef) {
2760 unsigned long val;
2761
Michael Ellerman51fae6de2005-12-04 18:39:15 +11002762 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002763 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2764
2765 val = RELOC(prom_initrd_start);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002766 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2767 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002768 val = RELOC(prom_initrd_end);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002769 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2770 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002771
2772 reserve_mem(RELOC(prom_initrd_start),
2773 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2774
2775 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2776 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2777 }
2778#endif /* CONFIG_BLK_DEV_INITRD */
2779}
2780
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002781
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002782/*
2783 * We enter here early on, when the Open Firmware prom is still
2784 * handling exceptions and the MMU hash table for us.
2785 */
2786
2787unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2788 unsigned long pp,
Paul Mackerras549e8152008-08-30 11:43:47 +10002789 unsigned long r6, unsigned long r7,
2790 unsigned long kbase)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002791{
Linas Vepstase788ff12007-09-07 03:45:21 +10002792 struct prom_t *_prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002793 unsigned long hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002794
2795#ifdef CONFIG_PPC32
Paul Mackerras549e8152008-08-30 11:43:47 +10002796 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002797 reloc_got2(offset);
2798#endif
2799
2800 _prom = &RELOC(prom);
2801
2802 /*
2803 * First zero the BSS
2804 */
2805 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2806
2807 /*
2808 * Init interface to Open Firmware, get some node references,
2809 * like /chosen
2810 */
2811 prom_init_client_services(pp);
2812
2813 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002814 * See if this OF is old enough that we need to do explicit maps
2815 * and other workarounds
2816 */
2817 prom_find_mmu();
2818
2819 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002820 * Init prom stdout device
2821 */
2822 prom_init_stdout();
2823
Benjamin Herrenschmidt151a9f42009-03-22 16:04:53 +00002824 prom_printf("Preparing to boot %s", RELOC(linux_banner));
Michael Ellermane7943fb2009-03-04 19:02:01 +00002825
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002826 /*
2827 * Get default machine type. At this point, we do not differentiate
2828 * between pSeries SMP and pSeries LPAR
2829 */
2830 RELOC(of_platform) = prom_find_machine_type();
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002831 prom_printf("Detected machine type: %x\n", RELOC(of_platform));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002832
Suzuki Poulose0f890c82011-12-14 22:57:15 +00002833#ifndef CONFIG_NONSTATIC_KERNEL
Olaf Heringadd60ef2006-03-23 22:03:57 +01002834 /* Bail if this is a kdump kernel. */
2835 if (PHYSICAL_START > 0)
2836 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
Paul Mackerras549e8152008-08-30 11:43:47 +10002837#endif
Olaf Heringadd60ef2006-03-23 22:03:57 +01002838
2839 /*
2840 * Check for an initrd
2841 */
2842 prom_check_initrd(r3, r4);
2843
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002844#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002845 /*
2846 * On pSeries, inform the firmware about our capabilities
2847 */
Paul Mackerras799d6042005-11-10 13:37:51 +11002848 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2849 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002850 prom_send_capabilities();
2851#endif
2852
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002853 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002854 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002855 */
Linas Vepstase788ff12007-09-07 03:45:21 +10002856 if (RELOC(of_platform) != PLATFORM_POWERMAC)
Paul Mackerras549e8152008-08-30 11:43:47 +10002857 copy_and_flush(0, kbase, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002858
2859 /*
2860 * Do early parsing of command line
2861 */
2862 early_cmdline_parse();
2863
2864 /*
2865 * Initialize memory management within prom_init
2866 */
2867 prom_init_mem();
2868
2869 /*
2870 * Determine which cpu is actually running right _now_
2871 */
2872 prom_find_boot_cpu();
2873
2874 /*
2875 * Initialize display devices
2876 */
2877 prom_check_displays();
2878
2879#ifdef CONFIG_PPC64
2880 /*
2881 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2882 * that uses the allocator, we need to make sure we get the top of memory
2883 * available for us here...
2884 */
2885 if (RELOC(of_platform) == PLATFORM_PSERIES)
2886 prom_initialize_tce_table();
2887#endif
2888
2889 /*
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002890 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
2891 * have a usable RTAS implementation.
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002892 */
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002893 if (RELOC(of_platform) != PLATFORM_POWERMAC &&
2894 RELOC(of_platform) != PLATFORM_OPAL)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002895 prom_instantiate_rtas();
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002896
2897#ifdef CONFIG_PPC_POWERNV
2898 /* Detect HAL and try instanciating it & doing takeover */
2899 if (RELOC(of_platform) == PLATFORM_PSERIES_LPAR) {
2900 prom_query_opal();
2901 if (RELOC(of_platform) == PLATFORM_OPAL) {
2902 prom_opal_hold_cpus();
2903 prom_opal_takeover();
2904 }
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002905 } else if (RELOC(of_platform) == PLATFORM_OPAL)
2906 prom_instantiate_opal();
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002907#endif
2908
2909 /*
2910 * On non-powermacs, put all CPUs in spin-loops.
2911 *
2912 * PowerMacs use a different mechanism to spin CPUs
2913 */
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002914 if (RELOC(of_platform) != PLATFORM_POWERMAC &&
2915 RELOC(of_platform) != PLATFORM_OPAL)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002916 prom_hold_cpus();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002917
2918 /*
2919 * Fill in some infos for use by the kernel later on
2920 */
Benjamin Krillcf687872009-07-27 22:02:39 +00002921 if (RELOC(prom_memory_limit))
2922 prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
2923 &RELOC(prom_memory_limit),
2924 sizeof(prom_memory_limit));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002925#ifdef CONFIG_PPC64
Jeremy Kerr165785e2006-11-11 17:25:18 +11002926 if (RELOC(prom_iommu_off))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002927 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2928 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002929
Jeremy Kerr165785e2006-11-11 17:25:18 +11002930 if (RELOC(prom_iommu_force_on))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002931 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2932 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002933
2934 if (RELOC(prom_tce_alloc_start)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002935 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002936 &RELOC(prom_tce_alloc_start),
2937 sizeof(prom_tce_alloc_start));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002938 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002939 &RELOC(prom_tce_alloc_end),
2940 sizeof(prom_tce_alloc_end));
2941 }
2942#endif
2943
2944 /*
2945 * Fixup any known bugs in the device-tree
2946 */
2947 fixup_device_tree();
2948
2949 /*
2950 * Now finally create the flattened device-tree
2951 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002952 prom_printf("copying OF device tree...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002953 flatten_device_tree();
2954
Paul Mackerras3825ac02005-11-08 22:48:08 +11002955 /*
2956 * in case stdin is USB and still active on IBM machines...
2957 * Unfortunately quiesce crashes on some powermacs if we have
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00002958 * closed stdin already (in particular the powerbook 101). It
2959 * appears that the OPAL version of OFW doesn't like it either.
Paul Mackerras3825ac02005-11-08 22:48:08 +11002960 */
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00002961 if (RELOC(of_platform) != PLATFORM_POWERMAC &&
2962 RELOC(of_platform) != PLATFORM_OPAL)
Paul Mackerras3825ac02005-11-08 22:48:08 +11002963 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002964
2965 /*
2966 * Call OF "quiesce" method to shut down pending DMA's from
2967 * devices etc...
2968 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002969 prom_printf("Calling quiesce...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002970 call_prom("quiesce", 0, 0);
2971
2972 /*
2973 * And finally, call the kernel passing it the flattened device
2974 * tree and NULL as r5, thus triggering the new entry point which
2975 * is common to us and kexec
2976 */
2977 hdr = RELOC(dt_header_start);
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00002978
2979 /* Don't print anything after quiesce under OPAL, it crashes OFW */
2980 if (RELOC(of_platform) != PLATFORM_OPAL) {
2981 prom_printf("returning from prom_init\n");
2982 prom_debug("->dt_header_start=0x%x\n", hdr);
2983 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002984
2985#ifdef CONFIG_PPC32
2986 reloc_got2(-offset);
2987#endif
2988
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002989#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
2990 /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
2991 __start(hdr, kbase, 0, 0, 0,
2992 RELOC(prom_opal_base), RELOC(prom_opal_entry));
2993#else
2994 __start(hdr, kbase, 0, 0, 0, 0, 0);
2995#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002996
2997 return 0;
2998}