blob: a52377c68fc6c762eaa2a14cd08072aa5dfc0e06 [file] [log] [blame]
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001/*
2 * Procedures for interfacing to Open Firmware.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#undef DEBUG_PROM
17
18#include <stdarg.h>
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/init.h>
23#include <linux/threads.h>
24#include <linux/spinlock.h>
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/proc_fs.h>
28#include <linux/stringify.h>
29#include <linux/delay.h>
30#include <linux/initrd.h>
31#include <linux/bitops.h>
32#include <asm/prom.h>
33#include <asm/rtas.h>
34#include <asm/page.h>
35#include <asm/processor.h>
36#include <asm/irq.h>
37#include <asm/io.h>
38#include <asm/smp.h>
39#include <asm/system.h>
40#include <asm/mmu.h>
41#include <asm/pgtable.h>
42#include <asm/pci.h>
43#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100044#include <asm/btext.h>
45#include <asm/sections.h>
46#include <asm/machdep.h>
47
48#ifdef CONFIG_LOGO_LINUX_CLUT224
49#include <linux/linux_logo.h>
50extern const struct linux_logo logo_linux_clut224;
51#endif
52
53/*
54 * Properties whose value is longer than this get excluded from our
55 * copy of the device tree. This value does need to be big enough to
56 * ensure that we don't lose things like the interrupt-map property
57 * on a PCI-PCI bridge.
58 */
59#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
60
61/*
62 * Eventually bump that one up
63 */
64#define DEVTREE_CHUNK_SIZE 0x100000
65
66/*
67 * This is the size of the local memory reserve map that gets copied
68 * into the boot params passed to the kernel. That size is totally
69 * flexible as the kernel just reads the list until it encounters an
70 * entry with size 0, so it can be changed without breaking binary
71 * compatibility
72 */
73#define MEM_RESERVE_MAP_SIZE 8
74
75/*
76 * prom_init() is called very early on, before the kernel text
77 * and data have been mapped to KERNELBASE. At this point the code
78 * is running at whatever address it has been loaded at.
79 * On ppc32 we compile with -mrelocatable, which means that references
80 * to extern and static variables get relocated automatically.
81 * On ppc64 we have to relocate the references explicitly with
82 * RELOC. (Note that strings count as static variables.)
83 *
84 * Because OF may have mapped I/O devices into the area starting at
85 * KERNELBASE, particularly on CHRP machines, we can't safely call
86 * OF once the kernel has been mapped to KERNELBASE. Therefore all
87 * OF calls must be done within prom_init().
88 *
89 * ADDR is used in calls to call_prom. The 4th and following
90 * arguments to call_prom should be 32-bit values.
91 * On ppc64, 64 bit values are truncated to 32 bits (and
92 * fortunately don't get interpreted as two arguments).
93 */
94#ifdef CONFIG_PPC64
95#define RELOC(x) (*PTRRELOC(&(x)))
96#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
Paul Mackerrasa23414b2005-11-10 12:00:55 +110097#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100098#else
99#define RELOC(x) (x)
100#define ADDR(x) (u32) (x)
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100101#define OF_WORKAROUNDS of_workarounds
102int of_workarounds;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000103#endif
104
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100105#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
106#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
107
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000108#define PROM_BUG() do { \
109 prom_printf("kernel BUG at %s line 0x%x!\n", \
110 RELOC(__FILE__), __LINE__); \
111 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
112} while (0)
113
114#ifdef DEBUG_PROM
115#define prom_debug(x...) prom_printf(x)
116#else
117#define prom_debug(x...)
118#endif
119
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000120
121typedef u32 prom_arg_t;
122
123struct prom_args {
124 u32 service;
125 u32 nargs;
126 u32 nret;
127 prom_arg_t args[10];
128};
129
130struct prom_t {
131 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100132 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000133 int cpu;
134 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000135 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100136 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000137};
138
139struct mem_map_entry {
Kumar Galacbbcf342006-01-11 17:57:13 -0600140 u64 base;
141 u64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000142};
143
144typedef u32 cell_t;
145
146extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
147
148#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000149extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000150#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000151static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000152{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000153 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000154}
155#endif
156
157extern void copy_and_flush(unsigned long dest, unsigned long src,
158 unsigned long size, unsigned long offset);
159
160/* prom structure */
161static struct prom_t __initdata prom;
162
163static unsigned long prom_entry __initdata;
164
165#define PROM_SCRATCH_SIZE 256
166
167static char __initdata of_stdout_device[256];
168static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
169
170static unsigned long __initdata dt_header_start;
171static unsigned long __initdata dt_struct_start, dt_struct_end;
172static unsigned long __initdata dt_string_start, dt_string_end;
173
174static unsigned long __initdata prom_initrd_start, prom_initrd_end;
175
176#ifdef CONFIG_PPC64
177static int __initdata iommu_force_on;
178static int __initdata ppc64_iommu_off;
179static unsigned long __initdata prom_tce_alloc_start;
180static unsigned long __initdata prom_tce_alloc_end;
181#endif
182
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100183/* Platforms codes are now obsolete in the kernel. Now only used within this
184 * file and ultimately gone too. Feel free to change them if you need, they
185 * are not shared with anything outside of this file anymore
186 */
187#define PLATFORM_PSERIES 0x0100
188#define PLATFORM_PSERIES_LPAR 0x0101
189#define PLATFORM_LPAR 0x0001
190#define PLATFORM_POWERMAC 0x0400
191#define PLATFORM_GENERIC 0x0500
192
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000193static int __initdata of_platform;
194
195static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
196
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000197static unsigned long __initdata alloc_top;
198static unsigned long __initdata alloc_top_high;
199static unsigned long __initdata alloc_bottom;
200static unsigned long __initdata rmo_top;
201static unsigned long __initdata ram_top;
202
Michael Ellermandcee3032005-12-04 18:39:48 +1100203#ifdef CONFIG_KEXEC
204static unsigned long __initdata prom_crashk_base;
205static unsigned long __initdata prom_crashk_size;
206#endif
207
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000208static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
209static int __initdata mem_reserve_cnt;
210
211static cell_t __initdata regbuf[1024];
212
213
214#define MAX_CPU_THREADS 2
215
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000216/*
217 * Error results ... some OF calls will return "-1" on error, some
218 * will return 0, some will return either. To simplify, here are
219 * macros to use with any ihandle or phandle return value to check if
220 * it is valid
221 */
222
223#define PROM_ERROR (-1u)
224#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
225#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
226
227
228/* This is the one and *ONLY* place where we actually call open
229 * firmware.
230 */
231
232static int __init call_prom(const char *service, int nargs, int nret, ...)
233{
234 int i;
235 struct prom_args args;
236 va_list list;
237
238 args.service = ADDR(service);
239 args.nargs = nargs;
240 args.nret = nret;
241
242 va_start(list, nret);
243 for (i = 0; i < nargs; i++)
244 args.args[i] = va_arg(list, prom_arg_t);
245 va_end(list);
246
247 for (i = 0; i < nret; i++)
248 args.args[nargs+i] = 0;
249
Paul Mackerrasc49888202005-10-26 21:52:53 +1000250 if (enter_prom(&args, RELOC(prom_entry)) < 0)
251 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000252
253 return (nret > 0) ? args.args[nargs] : 0;
254}
255
256static int __init call_prom_ret(const char *service, int nargs, int nret,
257 prom_arg_t *rets, ...)
258{
259 int i;
260 struct prom_args args;
261 va_list list;
262
263 args.service = ADDR(service);
264 args.nargs = nargs;
265 args.nret = nret;
266
267 va_start(list, rets);
268 for (i = 0; i < nargs; i++)
269 args.args[i] = va_arg(list, prom_arg_t);
270 va_end(list);
271
272 for (i = 0; i < nret; i++)
Olaf Heringed1189b2005-11-29 14:04:05 +0100273 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000274
Paul Mackerrasc49888202005-10-26 21:52:53 +1000275 if (enter_prom(&args, RELOC(prom_entry)) < 0)
276 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000277
278 if (rets != NULL)
279 for (i = 1; i < nret; ++i)
Paul Mackerrasc5200c92005-10-10 22:57:03 +1000280 rets[i-1] = args.args[nargs+i];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000281
282 return (nret > 0) ? args.args[nargs] : 0;
283}
284
285
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000286static void __init prom_print(const char *msg)
287{
288 const char *p, *q;
289 struct prom_t *_prom = &RELOC(prom);
290
291 if (_prom->stdout == 0)
292 return;
293
294 for (p = msg; *p != 0; p = q) {
295 for (q = p; *q != 0 && *q != '\n'; ++q)
296 ;
297 if (q > p)
298 call_prom("write", 3, 1, _prom->stdout, p, q - p);
299 if (*q == 0)
300 break;
301 ++q;
302 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
303 }
304}
305
306
307static void __init prom_print_hex(unsigned long val)
308{
309 int i, nibbles = sizeof(val)*2;
310 char buf[sizeof(val)*2+1];
311 struct prom_t *_prom = &RELOC(prom);
312
313 for (i = nibbles-1; i >= 0; i--) {
314 buf[i] = (val & 0xf) + '0';
315 if (buf[i] > '9')
316 buf[i] += ('a'-'0'-10);
317 val >>= 4;
318 }
319 buf[nibbles] = '\0';
320 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
321}
322
323
324static void __init prom_printf(const char *format, ...)
325{
326 const char *p, *q, *s;
327 va_list args;
328 unsigned long v;
329 struct prom_t *_prom = &RELOC(prom);
330
331 va_start(args, format);
332#ifdef CONFIG_PPC64
333 format = PTRRELOC(format);
334#endif
335 for (p = format; *p != 0; p = q) {
336 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
337 ;
338 if (q > p)
339 call_prom("write", 3, 1, _prom->stdout, p, q - p);
340 if (*q == 0)
341 break;
342 if (*q == '\n') {
343 ++q;
344 call_prom("write", 3, 1, _prom->stdout,
345 ADDR("\r\n"), 2);
346 continue;
347 }
348 ++q;
349 if (*q == 0)
350 break;
351 switch (*q) {
352 case 's':
353 ++q;
354 s = va_arg(args, const char *);
355 prom_print(s);
356 break;
357 case 'x':
358 ++q;
359 v = va_arg(args, unsigned long);
360 prom_print_hex(v);
361 break;
362 }
363 }
364}
365
366
Paul Mackerrasa575b802005-10-23 17:23:21 +1000367static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
368 unsigned long align)
369{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000370 struct prom_t *_prom = &RELOC(prom);
371
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100372 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
373 /*
374 * Old OF requires we claim physical and virtual separately
375 * and then map explicitly (assuming virtual mode)
376 */
377 int ret;
378 prom_arg_t result;
379
380 ret = call_prom_ret("call-method", 5, 2, &result,
381 ADDR("claim"), _prom->memory,
382 align, size, virt);
383 if (ret != 0 || result == -1)
384 return -1;
385 ret = call_prom_ret("call-method", 5, 2, &result,
386 ADDR("claim"), _prom->mmumap,
387 align, size, virt);
388 if (ret != 0) {
389 call_prom("call-method", 4, 1, ADDR("release"),
390 _prom->memory, size, virt);
391 return -1;
392 }
393 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000394 call_prom("call-method", 6, 1,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100395 ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
396 return virt;
397 }
398 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
399 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000400}
401
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000402static void __init __attribute__((noreturn)) prom_panic(const char *reason)
403{
404#ifdef CONFIG_PPC64
405 reason = PTRRELOC(reason);
406#endif
407 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100408 /* Do not call exit because it clears the screen on pmac
409 * it also causes some sort of double-fault on early pmacs */
410 if (RELOC(of_platform) == PLATFORM_POWERMAC)
411 asm("trap\n");
412
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000413 /* ToDo: should put up an SRC here on p/iSeries */
414 call_prom("exit", 0, 0);
415
416 for (;;) /* should never get here */
417 ;
418}
419
420
421static int __init prom_next_node(phandle *nodep)
422{
423 phandle node;
424
425 if ((node = *nodep) != 0
426 && (*nodep = call_prom("child", 1, 1, node)) != 0)
427 return 1;
428 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
429 return 1;
430 for (;;) {
431 if ((node = call_prom("parent", 1, 1, node)) == 0)
432 return 0;
433 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
434 return 1;
435 }
436}
437
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100438static int inline prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000439 void *value, size_t valuelen)
440{
441 return call_prom("getprop", 4, 1, node, ADDR(pname),
442 (u32)(unsigned long) value, (u32) valuelen);
443}
444
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100445static int inline prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000446{
447 return call_prom("getproplen", 2, 1, node, ADDR(pname));
448}
449
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100450static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000451{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100452 char *p = *str;
453
454 while (*q)
455 *p++ = *q++;
456 *p++ = ' ';
457 *str = p;
458}
459
460static char *tohex(unsigned int x)
461{
462 static char digits[] = "0123456789abcdef";
463 static char result[9];
464 int i;
465
466 result[8] = 0;
467 i = 8;
468 do {
469 --i;
470 result[i] = digits[x & 0xf];
471 x >>= 4;
472 } while (x != 0 && i > 0);
473 return &result[i];
474}
475
476static int __init prom_setprop(phandle node, const char *nodename,
477 const char *pname, void *value, size_t valuelen)
478{
479 char cmd[256], *p;
480
481 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
482 return call_prom("setprop", 4, 1, node, ADDR(pname),
483 (u32)(unsigned long) value, (u32) valuelen);
484
485 /* gah... setprop doesn't work on longtrail, have to use interpret */
486 p = cmd;
487 add_string(&p, "dev");
488 add_string(&p, nodename);
489 add_string(&p, tohex((u32)(unsigned long) value));
490 add_string(&p, tohex(valuelen));
491 add_string(&p, tohex(ADDR(pname)));
492 add_string(&p, tohex(strlen(RELOC(pname))));
493 add_string(&p, "property");
494 *p = 0;
495 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000496}
497
498/* We can't use the standard versions because of RELOC headaches. */
499#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
500 || ('a' <= (c) && (c) <= 'f') \
501 || ('A' <= (c) && (c) <= 'F'))
502
503#define isdigit(c) ('0' <= (c) && (c) <= '9')
504#define islower(c) ('a' <= (c) && (c) <= 'z')
505#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
506
507unsigned long prom_strtoul(const char *cp, const char **endp)
508{
509 unsigned long result = 0, base = 10, value;
510
511 if (*cp == '0') {
512 base = 8;
513 cp++;
514 if (toupper(*cp) == 'X') {
515 cp++;
516 base = 16;
517 }
518 }
519
520 while (isxdigit(*cp) &&
521 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
522 result = result * base + value;
523 cp++;
524 }
525
526 if (endp)
527 *endp = cp;
528
529 return result;
530}
531
532unsigned long prom_memparse(const char *ptr, const char **retptr)
533{
534 unsigned long ret = prom_strtoul(ptr, retptr);
535 int shift = 0;
536
537 /*
538 * We can't use a switch here because GCC *may* generate a
539 * jump table which won't work, because we're not running at
540 * the address we're linked at.
541 */
542 if ('G' == **retptr || 'g' == **retptr)
543 shift = 30;
544
545 if ('M' == **retptr || 'm' == **retptr)
546 shift = 20;
547
548 if ('K' == **retptr || 'k' == **retptr)
549 shift = 10;
550
551 if (shift) {
552 ret <<= shift;
553 (*retptr)++;
554 }
555
556 return ret;
557}
558
559/*
560 * Early parsing of the command line passed to the kernel, used for
561 * "mem=x" and the options that affect the iommu
562 */
563static void __init early_cmdline_parse(void)
564{
565 struct prom_t *_prom = &RELOC(prom);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100566 const char *opt;
567 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000568 int l = 0;
569
570 RELOC(prom_cmd_line[0]) = 0;
571 p = RELOC(prom_cmd_line);
572 if ((long)_prom->chosen > 0)
573 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
574#ifdef CONFIG_CMDLINE
575 if (l == 0) /* dbl check */
576 strlcpy(RELOC(prom_cmd_line),
577 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
578#endif /* CONFIG_CMDLINE */
579 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
580
581#ifdef CONFIG_PPC64
582 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
583 if (opt) {
584 prom_printf("iommu opt is: %s\n", opt);
585 opt += 6;
586 while (*opt && *opt == ' ')
587 opt++;
588 if (!strncmp(opt, RELOC("off"), 3))
589 RELOC(ppc64_iommu_off) = 1;
590 else if (!strncmp(opt, RELOC("force"), 5))
591 RELOC(iommu_force_on) = 1;
592 }
593#endif
594
Michael Ellermandcee3032005-12-04 18:39:48 +1100595#ifdef CONFIG_KEXEC
596 /*
597 * crashkernel=size@addr specifies the location to reserve for
598 * crash kernel.
599 */
600 opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
601 if (opt) {
602 opt += 12;
Haren Myneni8385a6a2006-01-13 19:15:36 -0800603 RELOC(prom_crashk_size) =
604 prom_memparse(opt, (const char **)&opt);
Michael Ellermandcee3032005-12-04 18:39:48 +1100605
606 if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
607 RELOC(prom_crashk_size)) {
608 prom_printf("Warning: crashkernel size is not "
609 "aligned to 16MB\n");
610 }
611
612 /*
613 * At present, the crash kernel always run at 32MB.
614 * Just ignore whatever user passed.
615 */
616 RELOC(prom_crashk_base) = 0x2000000;
617 if (*opt == '@') {
618 prom_printf("Warning: PPC64 kdump kernel always runs "
619 "at 32 MB\n");
620 }
621 }
622#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000623}
624
625#ifdef CONFIG_PPC_PSERIES
626/*
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000627 * There are two methods for telling firmware what our capabilities are.
628 * Newer machines have an "ibm,client-architecture-support" method on the
629 * root node. For older machines, we have to call the "process-elf-header"
630 * method in the /packages/elf-loader node, passing it a fake 32-bit
631 * ELF header containing a couple of PT_NOTE sections that contain
632 * structures that contain various information.
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000633 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000634
635/*
636 * New method - extensible architecture description vector.
637 *
638 * Because the description vector contains a mix of byte and word
639 * values, we declare it as an unsigned char array, and use this
640 * macro to put word values in.
641 */
642#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
643 ((x) >> 8) & 0xff, (x) & 0xff
644
645/* Option vector bits - generic bits in byte 1 */
646#define OV_IGNORE 0x80 /* ignore this vector */
647#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
648
649/* Option vector 1: processor architectures supported */
650#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
651#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
652#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
653#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
654#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
655#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
656
657/* Option vector 2: Open Firmware options supported */
658#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
659
660/* Option vector 3: processor options supported */
661#define OV3_FP 0x80 /* floating point */
662#define OV3_VMX 0x40 /* VMX/Altivec */
663
664/* Option vector 5: PAPR/OF options supported */
665#define OV5_LPAR 0x80 /* logical partitioning supported */
666#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
667/* ibm,dynamic-reconfiguration-memory property supported */
668#define OV5_DRCONF_MEMORY 0x20
669#define OV5_LARGE_PAGES 0x10 /* large pages supported */
670
671/*
672 * The architecture vector has an array of PVR mask/value pairs,
673 * followed by # option vectors - 1, followed by the option vectors.
674 */
675static unsigned char ibm_architecture_vec[] = {
676 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
Anton Blanchard03054d52006-04-29 09:51:06 +1000677 W(0xffff0000), W(0x003e0000), /* POWER6 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000678 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
679 5 - 1, /* 5 option vectors */
680
681 /* option vector 1: processor architectures supported */
682 3 - 1, /* length */
683 0, /* don't ignore, don't halt */
684 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
685 OV1_PPC_2_04 | OV1_PPC_2_05,
686
687 /* option vector 2: Open Firmware options supported */
688 34 - 1, /* length */
689 OV2_REAL_MODE,
690 0, 0,
691 W(0xffffffff), /* real_base */
692 W(0xffffffff), /* real_size */
693 W(0xffffffff), /* virt_base */
694 W(0xffffffff), /* virt_size */
695 W(0xffffffff), /* load_base */
696 W(64), /* 128MB min RMA */
697 W(0xffffffff), /* full client load */
698 0, /* min RMA percentage of total RAM */
699 48, /* max log_2(hash table size) */
700
701 /* option vector 3: processor options supported */
702 3 - 1, /* length */
703 0, /* don't ignore, don't halt */
704 OV3_FP | OV3_VMX,
705
706 /* option vector 4: IBM PAPR implementation */
707 2 - 1, /* length */
708 0, /* don't halt */
709
710 /* option vector 5: PAPR/OF options */
711 3 - 1, /* length */
712 0, /* don't ignore, don't halt */
713 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
714};
715
716/* Old method - ELF header with PT_NOTE sections */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000717static struct fake_elf {
718 Elf32_Ehdr elfhdr;
719 Elf32_Phdr phdr[2];
720 struct chrpnote {
721 u32 namesz;
722 u32 descsz;
723 u32 type;
724 char name[8]; /* "PowerPC" */
725 struct chrpdesc {
726 u32 real_mode;
727 u32 real_base;
728 u32 real_size;
729 u32 virt_base;
730 u32 virt_size;
731 u32 load_base;
732 } chrpdesc;
733 } chrpnote;
734 struct rpanote {
735 u32 namesz;
736 u32 descsz;
737 u32 type;
738 char name[24]; /* "IBM,RPA-Client-Config" */
739 struct rpadesc {
740 u32 lpar_affinity;
741 u32 min_rmo_size;
742 u32 min_rmo_percent;
743 u32 max_pft_size;
744 u32 splpar;
745 u32 min_load;
746 u32 new_mem_def;
747 u32 ignore_me;
748 } rpadesc;
749 } rpanote;
750} fake_elf = {
751 .elfhdr = {
752 .e_ident = { 0x7f, 'E', 'L', 'F',
753 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
754 .e_type = ET_EXEC, /* yeah right */
755 .e_machine = EM_PPC,
756 .e_version = EV_CURRENT,
757 .e_phoff = offsetof(struct fake_elf, phdr),
758 .e_phentsize = sizeof(Elf32_Phdr),
759 .e_phnum = 2
760 },
761 .phdr = {
762 [0] = {
763 .p_type = PT_NOTE,
764 .p_offset = offsetof(struct fake_elf, chrpnote),
765 .p_filesz = sizeof(struct chrpnote)
766 }, [1] = {
767 .p_type = PT_NOTE,
768 .p_offset = offsetof(struct fake_elf, rpanote),
769 .p_filesz = sizeof(struct rpanote)
770 }
771 },
772 .chrpnote = {
773 .namesz = sizeof("PowerPC"),
774 .descsz = sizeof(struct chrpdesc),
775 .type = 0x1275,
776 .name = "PowerPC",
777 .chrpdesc = {
778 .real_mode = ~0U, /* ~0 means "don't care" */
779 .real_base = ~0U,
780 .real_size = ~0U,
781 .virt_base = ~0U,
782 .virt_size = ~0U,
783 .load_base = ~0U
784 },
785 },
786 .rpanote = {
787 .namesz = sizeof("IBM,RPA-Client-Config"),
788 .descsz = sizeof(struct rpadesc),
789 .type = 0x12759999,
790 .name = "IBM,RPA-Client-Config",
791 .rpadesc = {
792 .lpar_affinity = 0,
793 .min_rmo_size = 64, /* in megabytes */
794 .min_rmo_percent = 0,
795 .max_pft_size = 48, /* 2^48 bytes max PFT size */
796 .splpar = 1,
797 .min_load = ~0U,
798 .new_mem_def = 0
799 }
800 }
801};
802
803static void __init prom_send_capabilities(void)
804{
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000805 ihandle elfloader, root;
806 prom_arg_t ret;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000807
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000808 root = call_prom("open", 1, 1, ADDR("/"));
809 if (root != 0) {
810 /* try calling the ibm,client-architecture-support method */
811 if (call_prom_ret("call-method", 3, 2, &ret,
812 ADDR("ibm,client-architecture-support"),
813 ADDR(ibm_architecture_vec)) == 0) {
814 /* the call exists... */
815 if (ret)
816 prom_printf("WARNING: ibm,client-architecture"
817 "-support call FAILED!\n");
818 call_prom("close", 1, 0, root);
819 return;
820 }
821 call_prom("close", 1, 0, root);
822 }
823
824 /* no ibm,client-architecture-support call, try the old way */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000825 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
826 if (elfloader == 0) {
827 prom_printf("couldn't open /packages/elf-loader\n");
828 return;
829 }
830 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
831 elfloader, ADDR(&fake_elf));
832 call_prom("close", 1, 0, elfloader);
833}
834#endif
835
836/*
837 * Memory allocation strategy... our layout is normally:
838 *
839 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
840 * rare cases, initrd might end up being before the kernel though.
841 * We assume this won't override the final kernel at 0, we have no
842 * provision to handle that in this version, but it should hopefully
843 * never happen.
844 *
845 * alloc_top is set to the top of RMO, eventually shrink down if the
846 * TCEs overlap
847 *
848 * alloc_bottom is set to the top of kernel/initrd
849 *
850 * from there, allocations are done this way : rtas is allocated
851 * topmost, and the device-tree is allocated from the bottom. We try
852 * to grow the device-tree allocation as we progress. If we can't,
853 * then we fail, we don't currently have a facility to restart
854 * elsewhere, but that shouldn't be necessary.
855 *
856 * Note that calls to reserve_mem have to be done explicitly, memory
857 * allocated with either alloc_up or alloc_down isn't automatically
858 * reserved.
859 */
860
861
862/*
863 * Allocates memory in the RMO upward from the kernel/initrd
864 *
865 * When align is 0, this is a special case, it means to allocate in place
866 * at the current location of alloc_bottom or fail (that is basically
867 * extending the previous allocation). Used for the device-tree flattening
868 */
869static unsigned long __init alloc_up(unsigned long size, unsigned long align)
870{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000871 unsigned long base = RELOC(alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000872 unsigned long addr = 0;
873
Paul Mackerrasc49888202005-10-26 21:52:53 +1000874 if (align)
875 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000876 prom_debug("alloc_up(%x, %x)\n", size, align);
877 if (RELOC(ram_top) == 0)
878 prom_panic("alloc_up() called with mem not initialized\n");
879
880 if (align)
881 base = _ALIGN_UP(RELOC(alloc_bottom), align);
882 else
883 base = RELOC(alloc_bottom);
884
885 for(; (base + size) <= RELOC(alloc_top);
886 base = _ALIGN_UP(base + 0x100000, align)) {
887 prom_debug(" trying: 0x%x\n\r", base);
888 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000889 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000890 break;
891 addr = 0;
892 if (align == 0)
893 break;
894 }
895 if (addr == 0)
896 return 0;
897 RELOC(alloc_bottom) = addr;
898
899 prom_debug(" -> %x\n", addr);
900 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
901 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
902 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
903 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
904 prom_debug(" ram_top : %x\n", RELOC(ram_top));
905
906 return addr;
907}
908
909/*
910 * Allocates memory downward, either from top of RMO, or if highmem
911 * is set, from the top of RAM. Note that this one doesn't handle
912 * failures. It does claim memory if highmem is not set.
913 */
914static unsigned long __init alloc_down(unsigned long size, unsigned long align,
915 int highmem)
916{
917 unsigned long base, addr = 0;
918
919 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
920 highmem ? RELOC("(high)") : RELOC("(low)"));
921 if (RELOC(ram_top) == 0)
922 prom_panic("alloc_down() called with mem not initialized\n");
923
924 if (highmem) {
925 /* Carve out storage for the TCE table. */
926 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
927 if (addr <= RELOC(alloc_bottom))
928 return 0;
929 /* Will we bump into the RMO ? If yes, check out that we
930 * didn't overlap existing allocations there, if we did,
931 * we are dead, we must be the first in town !
932 */
933 if (addr < RELOC(rmo_top)) {
934 /* Good, we are first */
935 if (RELOC(alloc_top) == RELOC(rmo_top))
936 RELOC(alloc_top) = RELOC(rmo_top) = addr;
937 else
938 return 0;
939 }
940 RELOC(alloc_top_high) = addr;
941 goto bail;
942 }
943
944 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
945 for (; base > RELOC(alloc_bottom);
946 base = _ALIGN_DOWN(base - 0x100000, align)) {
947 prom_debug(" trying: 0x%x\n\r", base);
948 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000949 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000950 break;
951 addr = 0;
952 }
953 if (addr == 0)
954 return 0;
955 RELOC(alloc_top) = addr;
956
957 bail:
958 prom_debug(" -> %x\n", addr);
959 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
960 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
961 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
962 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
963 prom_debug(" ram_top : %x\n", RELOC(ram_top));
964
965 return addr;
966}
967
968/*
969 * Parse a "reg" cell
970 */
971static unsigned long __init prom_next_cell(int s, cell_t **cellp)
972{
973 cell_t *p = *cellp;
974 unsigned long r = 0;
975
976 /* Ignore more than 2 cells */
977 while (s > sizeof(unsigned long) / 4) {
978 p++;
979 s--;
980 }
981 r = *p++;
982#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +1000983 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000984 r <<= 32;
985 r |= *(p++);
986 }
987#endif
988 *cellp = p;
989 return r;
990}
991
992/*
993 * Very dumb function for adding to the memory reserve list, but
994 * we don't need anything smarter at this point
995 *
996 * XXX Eventually check for collisions. They should NEVER happen.
997 * If problems seem to show up, it would be a good start to track
998 * them down.
999 */
Kumar Galacbbcf342006-01-11 17:57:13 -06001000static void reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001001{
Kumar Galacbbcf342006-01-11 17:57:13 -06001002 u64 top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001003 unsigned long cnt = RELOC(mem_reserve_cnt);
1004
1005 if (size == 0)
1006 return;
1007
1008 /* We need to always keep one empty entry so that we
1009 * have our terminator with "size" set to 0 since we are
1010 * dumb and just copy this entire array to the boot params
1011 */
1012 base = _ALIGN_DOWN(base, PAGE_SIZE);
1013 top = _ALIGN_UP(top, PAGE_SIZE);
1014 size = top - base;
1015
1016 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1017 prom_panic("Memory reserve map exhausted !\n");
1018 RELOC(mem_reserve_map)[cnt].base = base;
1019 RELOC(mem_reserve_map)[cnt].size = size;
1020 RELOC(mem_reserve_cnt) = cnt + 1;
1021}
1022
1023/*
1024 * Initialize memory allocation mecanism, parse "memory" nodes and
1025 * obtain that way the top of memory and RMO to setup out local allocator
1026 */
1027static void __init prom_init_mem(void)
1028{
1029 phandle node;
1030 char *path, type[64];
1031 unsigned int plen;
1032 cell_t *p, *endp;
1033 struct prom_t *_prom = &RELOC(prom);
1034 u32 rac, rsc;
1035
1036 /*
1037 * We iterate the memory nodes to find
1038 * 1) top of RMO (first node)
1039 * 2) top of memory
1040 */
1041 rac = 2;
1042 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1043 rsc = 1;
1044 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1045 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1046 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1047
1048 prom_debug("scanning memory:\n");
1049 path = RELOC(prom_scratch);
1050
1051 for (node = 0; prom_next_node(&node); ) {
1052 type[0] = 0;
1053 prom_getprop(node, "device_type", type, sizeof(type));
1054
Paul Mackerrasc49888202005-10-26 21:52:53 +10001055 if (type[0] == 0) {
1056 /*
1057 * CHRP Longtrail machines have no device_type
1058 * on the memory node, so check the name instead...
1059 */
1060 prom_getprop(node, "name", type, sizeof(type));
1061 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001062 if (strcmp(type, RELOC("memory")))
1063 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001064
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001065 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1066 if (plen > sizeof(regbuf)) {
1067 prom_printf("memory node too large for buffer !\n");
1068 plen = sizeof(regbuf);
1069 }
1070 p = RELOC(regbuf);
1071 endp = p + (plen / sizeof(cell_t));
1072
1073#ifdef DEBUG_PROM
1074 memset(path, 0, PROM_SCRATCH_SIZE);
1075 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1076 prom_debug(" node %s :\n", path);
1077#endif /* DEBUG_PROM */
1078
1079 while ((endp - p) >= (rac + rsc)) {
1080 unsigned long base, size;
1081
1082 base = prom_next_cell(rac, &p);
1083 size = prom_next_cell(rsc, &p);
1084
1085 if (size == 0)
1086 continue;
1087 prom_debug(" %x %x\n", base, size);
Benjamin Herrenschmidtab1b55e2006-03-03 10:35:40 +11001088 if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001089 RELOC(rmo_top) = size;
1090 if ((base + size) > RELOC(ram_top))
1091 RELOC(ram_top) = base + size;
1092 }
1093 }
1094
1095 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1096
1097 /* Check if we have an initrd after the kernel, if we do move our bottom
1098 * point to after it
1099 */
1100 if (RELOC(prom_initrd_start)) {
1101 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1102 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1103 }
1104
1105 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001106 * Setup our top alloc point, that is top of RMO or top of
1107 * segment 0 when running non-LPAR.
1108 * Some RS64 machines have buggy firmware where claims up at
1109 * 1GB fail. Cap at 768MB as a workaround.
1110 * Since 768MB is plenty of room, and we need to cap to something
1111 * reasonable on 32-bit, cap at 768MB on all machines.
1112 */
1113 if (!RELOC(rmo_top))
1114 RELOC(rmo_top) = RELOC(ram_top);
1115 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1116 RELOC(alloc_top) = RELOC(rmo_top);
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001117 RELOC(alloc_top_high) = RELOC(ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001118
1119 prom_printf("memory layout at init:\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001120 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
1121 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
1122 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1123 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1124 prom_printf(" ram_top : %x\n", RELOC(ram_top));
Michael Ellermandcee3032005-12-04 18:39:48 +11001125#ifdef CONFIG_KEXEC
1126 if (RELOC(prom_crashk_base)) {
1127 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1128 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1129 }
1130#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001131}
1132
1133
1134/*
1135 * Allocate room for and instantiate RTAS
1136 */
1137static void __init prom_instantiate_rtas(void)
1138{
1139 phandle rtas_node;
1140 ihandle rtas_inst;
1141 u32 base, entry = 0;
1142 u32 size = 0;
1143
1144 prom_debug("prom_instantiate_rtas: start...\n");
1145
1146 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1147 prom_debug("rtas_node: %x\n", rtas_node);
1148 if (!PHANDLE_VALID(rtas_node))
1149 return;
1150
1151 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1152 if (size == 0)
1153 return;
1154
1155 base = alloc_down(size, PAGE_SIZE, 0);
1156 if (base == 0) {
1157 prom_printf("RTAS allocation failed !\n");
1158 return;
1159 }
1160
1161 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1162 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001163 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001164 return;
1165 }
1166
1167 prom_printf("instantiating rtas at 0x%x ...", base);
1168
1169 if (call_prom_ret("call-method", 3, 2, &entry,
1170 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001171 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001172 || entry == 0) {
1173 prom_printf(" failed\n");
1174 return;
1175 }
1176 prom_printf(" done\n");
1177
1178 reserve_mem(base, size);
1179
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001180 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1181 &base, sizeof(base));
1182 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1183 &entry, sizeof(entry));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001184
1185 prom_debug("rtas base = 0x%x\n", base);
1186 prom_debug("rtas entry = 0x%x\n", entry);
1187 prom_debug("rtas size = 0x%x\n", (long)size);
1188
1189 prom_debug("prom_instantiate_rtas: end...\n");
1190}
1191
1192#ifdef CONFIG_PPC64
1193/*
1194 * Allocate room for and initialize TCE tables
1195 */
1196static void __init prom_initialize_tce_table(void)
1197{
1198 phandle node;
1199 ihandle phb_node;
1200 char compatible[64], type[64], model[64];
1201 char *path = RELOC(prom_scratch);
1202 u64 base, align;
1203 u32 minalign, minsize;
1204 u64 tce_entry, *tce_entryp;
1205 u64 local_alloc_top, local_alloc_bottom;
1206 u64 i;
1207
1208 if (RELOC(ppc64_iommu_off))
1209 return;
1210
1211 prom_debug("starting prom_initialize_tce_table\n");
1212
1213 /* Cache current top of allocs so we reserve a single block */
1214 local_alloc_top = RELOC(alloc_top_high);
1215 local_alloc_bottom = local_alloc_top;
1216
1217 /* Search all nodes looking for PHBs. */
1218 for (node = 0; prom_next_node(&node); ) {
1219 compatible[0] = 0;
1220 type[0] = 0;
1221 model[0] = 0;
1222 prom_getprop(node, "compatible",
1223 compatible, sizeof(compatible));
1224 prom_getprop(node, "device_type", type, sizeof(type));
1225 prom_getprop(node, "model", model, sizeof(model));
1226
1227 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1228 continue;
1229
1230 /* Keep the old logic in tack to avoid regression. */
1231 if (compatible[0] != 0) {
1232 if ((strstr(compatible, RELOC("python")) == NULL) &&
1233 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1234 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1235 continue;
1236 } else if (model[0] != 0) {
1237 if ((strstr(model, RELOC("ython")) == NULL) &&
1238 (strstr(model, RELOC("peedwagon")) == NULL) &&
1239 (strstr(model, RELOC("innipeg")) == NULL))
1240 continue;
1241 }
1242
1243 if (prom_getprop(node, "tce-table-minalign", &minalign,
1244 sizeof(minalign)) == PROM_ERROR)
1245 minalign = 0;
1246 if (prom_getprop(node, "tce-table-minsize", &minsize,
1247 sizeof(minsize)) == PROM_ERROR)
1248 minsize = 4UL << 20;
1249
1250 /*
1251 * Even though we read what OF wants, we just set the table
1252 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1253 * By doing this, we avoid the pitfalls of trying to DMA to
1254 * MMIO space and the DMA alias hole.
1255 *
1256 * On POWER4, firmware sets the TCE region by assuming
1257 * each TCE table is 8MB. Using this memory for anything
1258 * else will impact performance, so we always allocate 8MB.
1259 * Anton
1260 */
1261 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1262 minsize = 8UL << 20;
1263 else
1264 minsize = 4UL << 20;
1265
1266 /* Align to the greater of the align or size */
1267 align = max(minalign, minsize);
1268 base = alloc_down(minsize, align, 1);
1269 if (base == 0)
1270 prom_panic("ERROR, cannot find space for TCE table.\n");
1271 if (base < local_alloc_bottom)
1272 local_alloc_bottom = base;
1273
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001274 /* It seems OF doesn't null-terminate the path :-( */
1275 memset(path, 0, sizeof(path));
1276 /* Call OF to setup the TCE hardware */
1277 if (call_prom("package-to-path", 3, 1, node,
1278 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1279 prom_printf("package-to-path failed\n");
1280 }
1281
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001282 /* Save away the TCE table attributes for later use. */
1283 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1284 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1285
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001286 prom_debug("TCE table: %s\n", path);
1287 prom_debug("\tnode = 0x%x\n", node);
1288 prom_debug("\tbase = 0x%x\n", base);
1289 prom_debug("\tsize = 0x%x\n", minsize);
1290
1291 /* Initialize the table to have a one-to-one mapping
1292 * over the allocated size.
1293 */
1294 tce_entryp = (unsigned long *)base;
1295 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1296 tce_entry = (i << PAGE_SHIFT);
1297 tce_entry |= 0x3;
1298 *tce_entryp = tce_entry;
1299 }
1300
1301 prom_printf("opening PHB %s", path);
1302 phb_node = call_prom("open", 1, 1, path);
1303 if (phb_node == 0)
1304 prom_printf("... failed\n");
1305 else
1306 prom_printf("... done\n");
1307
1308 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1309 phb_node, -1, minsize,
1310 (u32) base, (u32) (base >> 32));
1311 call_prom("close", 1, 0, phb_node);
1312 }
1313
1314 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1315
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001316 /* These are only really needed if there is a memory limit in
1317 * effect, but we don't know so export them always. */
1318 RELOC(prom_tce_alloc_start) = local_alloc_bottom;
1319 RELOC(prom_tce_alloc_end) = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001320
1321 /* Flag the first invalid entry */
1322 prom_debug("ending prom_initialize_tce_table\n");
1323}
1324#endif
1325
1326/*
1327 * With CHRP SMP we need to use the OF to start the other processors.
1328 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1329 * so we have to put the processors into a holding pattern controlled
1330 * by the kernel (not OF) before we destroy the OF.
1331 *
1332 * This uses a chunk of low memory, puts some holding pattern
1333 * code there and sends the other processors off to there until
1334 * smp_boot_cpus tells them to do something. The holding pattern
1335 * checks that address until its cpu # is there, when it is that
1336 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1337 * of setting those values.
1338 *
1339 * We also use physical address 0x4 here to tell when a cpu
1340 * is in its holding pattern code.
1341 *
1342 * -- Cort
1343 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001344extern void __secondary_hold(void);
1345extern unsigned long __secondary_hold_spinloop;
1346extern unsigned long __secondary_hold_acknowledge;
1347
1348/*
1349 * We want to reference the copy of __secondary_hold_* in the
1350 * 0 - 0x100 address range
1351 */
1352#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1353
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001354static void __init prom_hold_cpus(void)
1355{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001356 unsigned long i;
1357 unsigned int reg;
1358 phandle node;
1359 char type[64];
1360 int cpuid = 0;
1361 unsigned int interrupt_server[MAX_CPU_THREADS];
1362 unsigned int cpu_threads, hw_cpu_num;
1363 int propsize;
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001364 struct prom_t *_prom = &RELOC(prom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001365 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001366 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001367 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001368 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001369#ifdef CONFIG_PPC64
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001370 /* __secondary_hold is actually a descriptor, not the text address */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001371 unsigned long secondary_hold
1372 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1373#else
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001374 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001375#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001376
1377 prom_debug("prom_hold_cpus: start...\n");
1378 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1379 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1380 prom_debug(" 1) acknowledge = 0x%x\n",
1381 (unsigned long)acknowledge);
1382 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1383 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1384
1385 /* Set the common spinloop variable, so all of the secondary cpus
1386 * will block when they are awakened from their OF spinloop.
1387 * This must occur for both SMP and non SMP kernels, since OF will
1388 * be trashed when we move the kernel.
1389 */
1390 *spinloop = 0;
1391
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001392 /* look for cpus */
1393 for (node = 0; prom_next_node(&node); ) {
1394 type[0] = 0;
1395 prom_getprop(node, "device_type", type, sizeof(type));
1396 if (strcmp(type, RELOC("cpu")) != 0)
1397 continue;
1398
1399 /* Skip non-configured cpus. */
1400 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1401 if (strcmp(type, RELOC("okay")) != 0)
1402 continue;
1403
1404 reg = -1;
1405 prom_getprop(node, "reg", &reg, sizeof(reg));
1406
1407 prom_debug("\ncpuid = 0x%x\n", cpuid);
1408 prom_debug("cpu hw idx = 0x%x\n", reg);
1409
1410 /* Init the acknowledge var which will be reset by
1411 * the secondary cpu when it awakens from its OF
1412 * spinloop.
1413 */
1414 *acknowledge = (unsigned long)-1;
1415
1416 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1417 &interrupt_server,
1418 sizeof(interrupt_server));
1419 if (propsize < 0) {
1420 /* no property. old hardware has no SMT */
1421 cpu_threads = 1;
1422 interrupt_server[0] = reg; /* fake it with phys id */
1423 } else {
1424 /* We have a threaded processor */
1425 cpu_threads = propsize / sizeof(u32);
1426 if (cpu_threads > MAX_CPU_THREADS) {
1427 prom_printf("SMT: too many threads!\n"
1428 "SMT: found %x, max is %x\n",
1429 cpu_threads, MAX_CPU_THREADS);
1430 cpu_threads = 1; /* ToDo: panic? */
1431 }
1432 }
1433
1434 hw_cpu_num = interrupt_server[0];
1435 if (hw_cpu_num != _prom->cpu) {
1436 /* Primary Thread of non-boot cpu */
1437 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1438 call_prom("start-cpu", 3, 0, node,
1439 secondary_hold, reg);
1440
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001441 for (i = 0; (i < 100000000) &&
1442 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001443 mb();
1444
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001445 if (*acknowledge == reg)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001446 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001447 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001448 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001449 }
1450#ifdef CONFIG_SMP
1451 else
1452 prom_printf("%x : boot cpu %x\n", cpuid, reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001453#endif /* CONFIG_SMP */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001454
1455 /* Reserve cpu #s for secondary threads. They start later. */
1456 cpuid += cpu_threads;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001457 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001458
1459 if (cpuid > NR_CPUS)
1460 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1461 ") exceeded: ignoring extras\n");
1462
1463 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001464}
1465
1466
1467static void __init prom_init_client_services(unsigned long pp)
1468{
1469 struct prom_t *_prom = &RELOC(prom);
1470
1471 /* Get a handle to the prom entry point before anything else */
1472 RELOC(prom_entry) = pp;
1473
1474 /* get a handle for the stdout device */
1475 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1476 if (!PHANDLE_VALID(_prom->chosen))
1477 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1478
1479 /* get device tree root */
1480 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1481 if (!PHANDLE_VALID(_prom->root))
1482 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001483
1484 _prom->mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001485}
1486
Paul Mackerrasa575b802005-10-23 17:23:21 +10001487#ifdef CONFIG_PPC32
1488/*
1489 * For really old powermacs, we need to map things we claim.
1490 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001491 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001492 */
1493static void __init prom_find_mmu(void)
1494{
1495 struct prom_t *_prom = &RELOC(prom);
1496 phandle oprom;
1497 char version[64];
1498
1499 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1500 if (!PHANDLE_VALID(oprom))
1501 return;
1502 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1503 return;
1504 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001505 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001506 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1507 of_workarounds = OF_WA_CLAIM;
1508 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1509 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1510 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1511 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001512 return;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001513 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
Paul Mackerrasa575b802005-10-23 17:23:21 +10001514 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1515 sizeof(_prom->mmumap));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001516 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1517 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001518}
1519#else
1520#define prom_find_mmu()
1521#endif
1522
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001523static void __init prom_init_stdout(void)
1524{
1525 struct prom_t *_prom = &RELOC(prom);
1526 char *path = RELOC(of_stdout_device);
1527 char type[16];
1528 u32 val;
1529
1530 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1531 prom_panic("cannot find stdout");
1532
1533 _prom->stdout = val;
1534
1535 /* Get the full OF pathname of the stdout device */
1536 memset(path, 0, 256);
1537 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1538 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001539 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1540 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001541 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001542 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1543 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001544
1545 /* If it's a display, note it */
1546 memset(type, 0, sizeof(type));
1547 prom_getprop(val, "device_type", type, sizeof(type));
1548 if (strcmp(type, RELOC("display")) == 0)
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001549 prom_setprop(val, path, "linux,boot-display", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001550}
1551
1552static void __init prom_close_stdin(void)
1553{
1554 struct prom_t *_prom = &RELOC(prom);
1555 ihandle val;
1556
1557 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1558 call_prom("close", 1, 0, val);
1559}
1560
1561static int __init prom_find_machine_type(void)
1562{
1563 struct prom_t *_prom = &RELOC(prom);
1564 char compat[256];
1565 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001566#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001567 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001568 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11001569#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001570
1571 /* Look for a PowerMac */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001572 len = prom_getprop(_prom->root, "compatible",
1573 compat, sizeof(compat)-1);
1574 if (len > 0) {
1575 compat[len] = 0;
1576 while (i < len) {
1577 char *p = &compat[i];
1578 int sl = strlen(p);
1579 if (sl == 0)
1580 break;
1581 if (strstr(p, RELOC("Power Macintosh")) ||
Paul Mackerrasa575b802005-10-23 17:23:21 +10001582 strstr(p, RELOC("MacRISC")))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001583 return PLATFORM_POWERMAC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001584 i += sl + 1;
1585 }
1586 }
1587#ifdef CONFIG_PPC64
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001588 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1589 * PAPR compliant platform. We assume it is if :
1590 * - /device_type is "chrp" (please, do NOT use that for future
1591 * non-IBM designs !
1592 * - it has /rtas
1593 */
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001594 len = prom_getprop(_prom->root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001595 compat, sizeof(compat)-1);
1596 if (len <= 0)
1597 return PLATFORM_GENERIC;
Michael Ellerman6f806ce2006-04-07 13:56:21 +10001598 if (strncmp(compat, RELOC("chrp"), 4))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001599 return PLATFORM_GENERIC;
1600
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001601 /* Default to pSeries. We need to know if we are running LPAR */
1602 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001603 if (!PHANDLE_VALID(rtas))
1604 return PLATFORM_GENERIC;
1605 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1606 if (x != PROM_ERROR) {
1607 prom_printf("Hypertas detected, assuming LPAR !\n");
1608 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001609 }
1610 return PLATFORM_PSERIES;
1611#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11001612 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001613#endif
1614}
1615
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001616static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1617{
1618 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1619}
1620
1621/*
1622 * If we have a display that we don't know how to drive,
1623 * we will want to try to execute OF's open method for it
1624 * later. However, OF will probably fall over if we do that
1625 * we've taken over the MMU.
1626 * So we check whether we will need to open the display,
1627 * and if so, open it now.
1628 */
1629static void __init prom_check_displays(void)
1630{
1631 char type[16], *path;
1632 phandle node;
1633 ihandle ih;
1634 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001635
1636 static unsigned char default_colors[] = {
1637 0x00, 0x00, 0x00,
1638 0x00, 0x00, 0xaa,
1639 0x00, 0xaa, 0x00,
1640 0x00, 0xaa, 0xaa,
1641 0xaa, 0x00, 0x00,
1642 0xaa, 0x00, 0xaa,
1643 0xaa, 0xaa, 0x00,
1644 0xaa, 0xaa, 0xaa,
1645 0x55, 0x55, 0x55,
1646 0x55, 0x55, 0xff,
1647 0x55, 0xff, 0x55,
1648 0x55, 0xff, 0xff,
1649 0xff, 0x55, 0x55,
1650 0xff, 0x55, 0xff,
1651 0xff, 0xff, 0x55,
1652 0xff, 0xff, 0xff
1653 };
1654 const unsigned char *clut;
1655
1656 prom_printf("Looking for displays\n");
1657 for (node = 0; prom_next_node(&node); ) {
1658 memset(type, 0, sizeof(type));
1659 prom_getprop(node, "device_type", type, sizeof(type));
1660 if (strcmp(type, RELOC("display")) != 0)
1661 continue;
1662
1663 /* It seems OF doesn't null-terminate the path :-( */
1664 path = RELOC(prom_scratch);
1665 memset(path, 0, PROM_SCRATCH_SIZE);
1666
1667 /*
1668 * leave some room at the end of the path for appending extra
1669 * arguments
1670 */
1671 if (call_prom("package-to-path", 3, 1, node, path,
1672 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1673 continue;
1674 prom_printf("found display : %s, opening ... ", path);
1675
1676 ih = call_prom("open", 1, 1, path);
1677 if (ih == 0) {
1678 prom_printf("failed\n");
1679 continue;
1680 }
1681
1682 /* Success */
1683 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001684 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001685
1686 /* Setup a usable color table when the appropriate
1687 * method is available. Should update this to set-colors */
1688 clut = RELOC(default_colors);
1689 for (i = 0; i < 32; i++, clut += 3)
1690 if (prom_set_color(ih, i, clut[0], clut[1],
1691 clut[2]) != 0)
1692 break;
1693
1694#ifdef CONFIG_LOGO_LINUX_CLUT224
1695 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1696 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1697 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1698 clut[2]) != 0)
1699 break;
1700#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001701 }
1702}
1703
1704
1705/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1706static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1707 unsigned long needed, unsigned long align)
1708{
1709 void *ret;
1710
1711 *mem_start = _ALIGN(*mem_start, align);
1712 while ((*mem_start + needed) > *mem_end) {
1713 unsigned long room, chunk;
1714
1715 prom_debug("Chunk exhausted, claiming more at %x...\n",
1716 RELOC(alloc_bottom));
1717 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1718 if (room > DEVTREE_CHUNK_SIZE)
1719 room = DEVTREE_CHUNK_SIZE;
1720 if (room < PAGE_SIZE)
1721 prom_panic("No memory for flatten_device_tree (no room)");
1722 chunk = alloc_up(room, 0);
1723 if (chunk == 0)
1724 prom_panic("No memory for flatten_device_tree (claim failed)");
1725 *mem_end = RELOC(alloc_top);
1726 }
1727
1728 ret = (void *)*mem_start;
1729 *mem_start += needed;
1730
1731 return ret;
1732}
1733
1734#define dt_push_token(token, mem_start, mem_end) \
1735 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1736
1737static unsigned long __init dt_find_string(char *str)
1738{
1739 char *s, *os;
1740
1741 s = os = (char *)RELOC(dt_string_start);
1742 s += 4;
1743 while (s < (char *)RELOC(dt_string_end)) {
1744 if (strcmp(s, str) == 0)
1745 return s - os;
1746 s += strlen(s) + 1;
1747 }
1748 return 0;
1749}
1750
1751/*
1752 * The Open Firmware 1275 specification states properties must be 31 bytes or
1753 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1754 */
1755#define MAX_PROPERTY_NAME 64
1756
1757static void __init scan_dt_build_strings(phandle node,
1758 unsigned long *mem_start,
1759 unsigned long *mem_end)
1760{
1761 char *prev_name, *namep, *sstart;
1762 unsigned long soff;
1763 phandle child;
1764
1765 sstart = (char *)RELOC(dt_string_start);
1766
1767 /* get and store all property names */
1768 prev_name = RELOC("");
1769 for (;;) {
1770 /* 64 is max len of name including nul. */
1771 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1772 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1773 /* No more nodes: unwind alloc */
1774 *mem_start = (unsigned long)namep;
1775 break;
1776 }
1777
1778 /* skip "name" */
1779 if (strcmp(namep, RELOC("name")) == 0) {
1780 *mem_start = (unsigned long)namep;
1781 prev_name = RELOC("name");
1782 continue;
1783 }
1784 /* get/create string entry */
1785 soff = dt_find_string(namep);
1786 if (soff != 0) {
1787 *mem_start = (unsigned long)namep;
1788 namep = sstart + soff;
1789 } else {
1790 /* Trim off some if we can */
1791 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1792 RELOC(dt_string_end) = *mem_start;
1793 }
1794 prev_name = namep;
1795 }
1796
1797 /* do all our children */
1798 child = call_prom("child", 1, 1, node);
1799 while (child != 0) {
1800 scan_dt_build_strings(child, mem_start, mem_end);
1801 child = call_prom("peer", 1, 1, child);
1802 }
1803}
1804
1805static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1806 unsigned long *mem_end)
1807{
1808 phandle child;
1809 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1810 unsigned long soff;
1811 unsigned char *valp;
1812 static char pname[MAX_PROPERTY_NAME];
Paul Mackerrasc49888202005-10-26 21:52:53 +10001813 int l, room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001814
1815 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1816
1817 /* get the node's full name */
1818 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001819 room = *mem_end - *mem_start;
1820 if (room > 255)
1821 room = 255;
1822 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001823 if (l >= 0) {
1824 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10001825 if (l >= room) {
1826 if (l >= *mem_end - *mem_start)
1827 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001828 call_prom("package-to-path", 3, 1, node, namep, l);
1829 }
1830 namep[l] = '\0';
1831
1832 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10001833 * middle of the path in some properties, and extract
1834 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001835 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001836 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001837 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10001838 lp = namep;
1839 else if (*p != 0)
1840 *lp++ = *p;
1841 }
1842 *lp = 0;
1843 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001844 }
1845
1846 /* get it again for debugging */
1847 path = RELOC(prom_scratch);
1848 memset(path, 0, PROM_SCRATCH_SIZE);
1849 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1850
1851 /* get and store all properties */
1852 prev_name = RELOC("");
1853 sstart = (char *)RELOC(dt_string_start);
1854 for (;;) {
1855 if (call_prom("nextprop", 3, 1, node, prev_name,
1856 RELOC(pname)) != 1)
1857 break;
1858
1859 /* skip "name" */
1860 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1861 prev_name = RELOC("name");
1862 continue;
1863 }
1864
1865 /* find string offset */
1866 soff = dt_find_string(RELOC(pname));
1867 if (soff == 0) {
1868 prom_printf("WARNING: Can't find string index for"
1869 " <%s>, node %s\n", RELOC(pname), path);
1870 break;
1871 }
1872 prev_name = sstart + soff;
1873
1874 /* get length */
1875 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1876
1877 /* sanity checks */
1878 if (l == PROM_ERROR)
1879 continue;
1880 if (l > MAX_PROPERTY_LENGTH) {
1881 prom_printf("WARNING: ignoring large property ");
1882 /* It seems OF doesn't null-terminate the path :-( */
1883 prom_printf("[%s] ", path);
1884 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1885 continue;
1886 }
1887
1888 /* push property head */
1889 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1890 dt_push_token(l, mem_start, mem_end);
1891 dt_push_token(soff, mem_start, mem_end);
1892
1893 /* push property content */
1894 valp = make_room(mem_start, mem_end, l, 4);
1895 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1896 *mem_start = _ALIGN(*mem_start, 4);
1897 }
1898
1899 /* Add a "linux,phandle" property. */
1900 soff = dt_find_string(RELOC("linux,phandle"));
1901 if (soff == 0)
1902 prom_printf("WARNING: Can't find string index for"
1903 " <linux-phandle> node %s\n", path);
1904 else {
1905 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1906 dt_push_token(4, mem_start, mem_end);
1907 dt_push_token(soff, mem_start, mem_end);
1908 valp = make_room(mem_start, mem_end, 4, 4);
1909 *(u32 *)valp = node;
1910 }
1911
1912 /* do all our children */
1913 child = call_prom("child", 1, 1, node);
1914 while (child != 0) {
1915 scan_dt_build_struct(child, mem_start, mem_end);
1916 child = call_prom("peer", 1, 1, child);
1917 }
1918
1919 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1920}
1921
1922static void __init flatten_device_tree(void)
1923{
1924 phandle root;
1925 unsigned long mem_start, mem_end, room;
1926 struct boot_param_header *hdr;
1927 struct prom_t *_prom = &RELOC(prom);
1928 char *namep;
1929 u64 *rsvmap;
1930
1931 /*
1932 * Check how much room we have between alloc top & bottom (+/- a
1933 * few pages), crop to 4Mb, as this is our "chuck" size
1934 */
1935 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1936 if (room > DEVTREE_CHUNK_SIZE)
1937 room = DEVTREE_CHUNK_SIZE;
1938 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1939
1940 /* Now try to claim that */
1941 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1942 if (mem_start == 0)
1943 prom_panic("Can't allocate initial device-tree chunk\n");
1944 mem_end = RELOC(alloc_top);
1945
1946 /* Get root of tree */
1947 root = call_prom("peer", 1, 1, (phandle)0);
1948 if (root == (phandle)0)
1949 prom_panic ("couldn't get device tree root\n");
1950
1951 /* Build header and make room for mem rsv map */
1952 mem_start = _ALIGN(mem_start, 4);
1953 hdr = make_room(&mem_start, &mem_end,
1954 sizeof(struct boot_param_header), 4);
1955 RELOC(dt_header_start) = (unsigned long)hdr;
1956 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1957
1958 /* Start of strings */
1959 mem_start = PAGE_ALIGN(mem_start);
1960 RELOC(dt_string_start) = mem_start;
1961 mem_start += 4; /* hole */
1962
1963 /* Add "linux,phandle" in there, we'll need it */
1964 namep = make_room(&mem_start, &mem_end, 16, 1);
1965 strcpy(namep, RELOC("linux,phandle"));
1966 mem_start = (unsigned long)namep + strlen(namep) + 1;
1967
1968 /* Build string array */
1969 prom_printf("Building dt strings...\n");
1970 scan_dt_build_strings(root, &mem_start, &mem_end);
1971 RELOC(dt_string_end) = mem_start;
1972
1973 /* Build structure */
1974 mem_start = PAGE_ALIGN(mem_start);
1975 RELOC(dt_struct_start) = mem_start;
1976 prom_printf("Building dt structure...\n");
1977 scan_dt_build_struct(root, &mem_start, &mem_end);
1978 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1979 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1980
1981 /* Finish header */
1982 hdr->boot_cpuid_phys = _prom->cpu;
1983 hdr->magic = OF_DT_HEADER;
1984 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1985 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1986 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1987 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1988 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1989 hdr->version = OF_DT_VERSION;
1990 /* Version 16 is not backward compatible */
1991 hdr->last_comp_version = 0x10;
1992
1993 /* Reserve the whole thing and copy the reserve map in, we
1994 * also bump mem_reserve_cnt to cause further reservations to
1995 * fail since it's too late.
1996 */
1997 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1998 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1999
2000#ifdef DEBUG_PROM
2001 {
2002 int i;
2003 prom_printf("reserved memory map:\n");
2004 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
2005 prom_printf(" %x - %x\n",
2006 RELOC(mem_reserve_map)[i].base,
2007 RELOC(mem_reserve_map)[i].size);
2008 }
2009#endif
2010 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2011
2012 prom_printf("Device tree strings 0x%x -> 0x%x\n",
2013 RELOC(dt_string_start), RELOC(dt_string_end));
2014 prom_printf("Device tree struct 0x%x -> 0x%x\n",
2015 RELOC(dt_struct_start), RELOC(dt_struct_end));
2016
2017}
2018
2019
2020static void __init fixup_device_tree(void)
2021{
2022#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2023 phandle u3, i2c, mpic;
2024 u32 u3_rev;
2025 u32 interrupts[2];
2026 u32 parent;
2027
2028 /* Some G5s have a missing interrupt definition, fix it up here */
2029 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2030 if (!PHANDLE_VALID(u3))
2031 return;
2032 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2033 if (!PHANDLE_VALID(i2c))
2034 return;
2035 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2036 if (!PHANDLE_VALID(mpic))
2037 return;
2038
2039 /* check if proper rev of u3 */
2040 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2041 == PROM_ERROR)
2042 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002043 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002044 return;
2045 /* does it need fixup ? */
2046 if (prom_getproplen(i2c, "interrupts") > 0)
2047 return;
2048
2049 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2050
2051 /* interrupt on this revision of u3 is number 0 and level */
2052 interrupts[0] = 0;
2053 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002054 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2055 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002056 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002057 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2058 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002059#endif
2060}
2061
2062
2063static void __init prom_find_boot_cpu(void)
2064{
2065 struct prom_t *_prom = &RELOC(prom);
2066 u32 getprop_rval;
2067 ihandle prom_cpu;
2068 phandle cpu_pkg;
2069
Paul Mackerrasa575b802005-10-23 17:23:21 +10002070 _prom->cpu = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002071 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002072 return;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002073
2074 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2075
2076 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2077 _prom->cpu = getprop_rval;
2078
2079 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2080}
2081
2082static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2083{
2084#ifdef CONFIG_BLK_DEV_INITRD
2085 struct prom_t *_prom = &RELOC(prom);
2086
2087 if (r3 && r4 && r4 != 0xdeadbeef) {
2088 unsigned long val;
2089
Michael Ellerman51fae6d2005-12-04 18:39:15 +11002090 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002091 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2092
2093 val = RELOC(prom_initrd_start);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002094 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2095 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002096 val = RELOC(prom_initrd_end);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002097 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2098 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002099
2100 reserve_mem(RELOC(prom_initrd_start),
2101 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2102
2103 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2104 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2105 }
2106#endif /* CONFIG_BLK_DEV_INITRD */
2107}
2108
2109/*
2110 * We enter here early on, when the Open Firmware prom is still
2111 * handling exceptions and the MMU hash table for us.
2112 */
2113
2114unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2115 unsigned long pp,
2116 unsigned long r6, unsigned long r7)
2117{
2118 struct prom_t *_prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002119 unsigned long hdr;
Paul Mackerrasb42b6612005-10-10 22:37:16 +10002120 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002121
2122#ifdef CONFIG_PPC32
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002123 reloc_got2(offset);
2124#endif
2125
2126 _prom = &RELOC(prom);
2127
2128 /*
2129 * First zero the BSS
2130 */
2131 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2132
2133 /*
2134 * Init interface to Open Firmware, get some node references,
2135 * like /chosen
2136 */
2137 prom_init_client_services(pp);
2138
2139 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002140 * See if this OF is old enough that we need to do explicit maps
2141 * and other workarounds
2142 */
2143 prom_find_mmu();
2144
2145 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002146 * Init prom stdout device
2147 */
2148 prom_init_stdout();
2149
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002150 /*
2151 * Get default machine type. At this point, we do not differentiate
2152 * between pSeries SMP and pSeries LPAR
2153 */
2154 RELOC(of_platform) = prom_find_machine_type();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002155
Olaf Heringadd60ef2006-03-23 22:03:57 +01002156 /* Bail if this is a kdump kernel. */
2157 if (PHYSICAL_START > 0)
2158 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
2159
2160 /*
2161 * Check for an initrd
2162 */
2163 prom_check_initrd(r3, r4);
2164
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002165#ifdef CONFIG_PPC_PSERIES
2166 /*
2167 * On pSeries, inform the firmware about our capabilities
2168 */
Paul Mackerras799d6042005-11-10 13:37:51 +11002169 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2170 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002171 prom_send_capabilities();
2172#endif
2173
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002174 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002175 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002176 */
David Gibson55d36332005-10-13 15:46:22 +10002177 if (RELOC(of_platform) != PLATFORM_POWERMAC)
Paul Mackerras5a408322005-10-10 22:41:25 +10002178 copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002179
2180 /*
2181 * Do early parsing of command line
2182 */
2183 early_cmdline_parse();
2184
2185 /*
2186 * Initialize memory management within prom_init
2187 */
2188 prom_init_mem();
2189
Michael Ellermandcee3032005-12-04 18:39:48 +11002190#ifdef CONFIG_KEXEC
2191 if (RELOC(prom_crashk_base))
2192 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2193#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002194 /*
2195 * Determine which cpu is actually running right _now_
2196 */
2197 prom_find_boot_cpu();
2198
2199 /*
2200 * Initialize display devices
2201 */
2202 prom_check_displays();
2203
2204#ifdef CONFIG_PPC64
2205 /*
2206 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2207 * that uses the allocator, we need to make sure we get the top of memory
2208 * available for us here...
2209 */
2210 if (RELOC(of_platform) == PLATFORM_PSERIES)
2211 prom_initialize_tce_table();
2212#endif
2213
2214 /*
2215 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2216 * in spin-loops. PowerMacs don't have a working RTAS and use
2217 * a different way to spin CPUs
2218 */
2219 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2220 prom_instantiate_rtas();
2221 prom_hold_cpus();
2222 }
2223
2224 /*
2225 * Fill in some infos for use by the kernel later on
2226 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002227#ifdef CONFIG_PPC64
2228 if (RELOC(ppc64_iommu_off))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002229 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2230 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002231
2232 if (RELOC(iommu_force_on))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002233 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2234 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002235
2236 if (RELOC(prom_tce_alloc_start)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002237 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002238 &RELOC(prom_tce_alloc_start),
2239 sizeof(prom_tce_alloc_start));
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002240 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002241 &RELOC(prom_tce_alloc_end),
2242 sizeof(prom_tce_alloc_end));
2243 }
2244#endif
2245
Michael Ellermandcee3032005-12-04 18:39:48 +11002246#ifdef CONFIG_KEXEC
2247 if (RELOC(prom_crashk_base)) {
2248 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2249 PTRRELOC(&prom_crashk_base),
2250 sizeof(RELOC(prom_crashk_base)));
2251 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2252 PTRRELOC(&prom_crashk_size),
2253 sizeof(RELOC(prom_crashk_size)));
2254 }
2255#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002256 /*
2257 * Fixup any known bugs in the device-tree
2258 */
2259 fixup_device_tree();
2260
2261 /*
2262 * Now finally create the flattened device-tree
2263 */
2264 prom_printf("copying OF device tree ...\n");
2265 flatten_device_tree();
2266
Paul Mackerras3825ac02005-11-08 22:48:08 +11002267 /*
2268 * in case stdin is USB and still active on IBM machines...
2269 * Unfortunately quiesce crashes on some powermacs if we have
2270 * closed stdin already (in particular the powerbook 101).
2271 */
2272 if (RELOC(of_platform) != PLATFORM_POWERMAC)
2273 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002274
2275 /*
2276 * Call OF "quiesce" method to shut down pending DMA's from
2277 * devices etc...
2278 */
2279 prom_printf("Calling quiesce ...\n");
2280 call_prom("quiesce", 0, 0);
2281
2282 /*
2283 * And finally, call the kernel passing it the flattened device
2284 * tree and NULL as r5, thus triggering the new entry point which
2285 * is common to us and kexec
2286 */
2287 hdr = RELOC(dt_header_start);
2288 prom_printf("returning from prom_init\n");
2289 prom_debug("->dt_header_start=0x%x\n", hdr);
2290
2291#ifdef CONFIG_PPC32
2292 reloc_got2(-offset);
2293#endif
2294
Paul Mackerras35499c02005-10-22 16:02:39 +10002295 __start(hdr, KERNELBASE + offset, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002296
2297 return 0;
2298}