]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/powerpc/kernel/prom_init.c
[PATCH] Memory Add Fixes for ppc64
[net-next-2.6.git] / arch / powerpc / kernel / prom_init.c
CommitLineData
9b6b563c
PM
1/*
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>
9b6b563c
PM
44#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))
97#else
98#define RELOC(x) (x)
99#define ADDR(x) (u32) (x)
100#endif
101
102#define PROM_BUG() do { \
103 prom_printf("kernel BUG at %s line 0x%x!\n", \
104 RELOC(__FILE__), __LINE__); \
105 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
106} while (0)
107
108#ifdef DEBUG_PROM
109#define prom_debug(x...) prom_printf(x)
110#else
111#define prom_debug(x...)
112#endif
113
114#ifdef CONFIG_PPC32
115#define PLATFORM_POWERMAC _MACH_Pmac
116#define PLATFORM_CHRP _MACH_chrp
117#endif
118
119
120typedef u32 prom_arg_t;
121
122struct prom_args {
123 u32 service;
124 u32 nargs;
125 u32 nret;
126 prom_arg_t args[10];
127};
128
129struct prom_t {
130 ihandle root;
131 ihandle chosen;
132 int cpu;
133 ihandle stdout;
a575b807 134 ihandle mmumap;
9b6b563c
PM
135};
136
137struct mem_map_entry {
138 unsigned long base;
139 unsigned long size;
140};
141
142typedef u32 cell_t;
143
144extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
145
146#ifdef CONFIG_PPC64
c4988820 147extern int enter_prom(struct prom_args *args, unsigned long entry);
9b6b563c 148#else
c4988820 149static inline int enter_prom(struct prom_args *args, unsigned long entry)
9b6b563c 150{
c4988820 151 return ((int (*)(struct prom_args *))entry)(args);
9b6b563c
PM
152}
153#endif
154
155extern void copy_and_flush(unsigned long dest, unsigned long src,
156 unsigned long size, unsigned long offset);
157
158/* prom structure */
159static struct prom_t __initdata prom;
160
161static unsigned long prom_entry __initdata;
162
163#define PROM_SCRATCH_SIZE 256
164
165static char __initdata of_stdout_device[256];
166static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
167
168static unsigned long __initdata dt_header_start;
169static unsigned long __initdata dt_struct_start, dt_struct_end;
170static unsigned long __initdata dt_string_start, dt_string_end;
171
172static unsigned long __initdata prom_initrd_start, prom_initrd_end;
173
174#ifdef CONFIG_PPC64
175static int __initdata iommu_force_on;
176static int __initdata ppc64_iommu_off;
177static unsigned long __initdata prom_tce_alloc_start;
178static unsigned long __initdata prom_tce_alloc_end;
179#endif
180
181static int __initdata of_platform;
182
183static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
184
185static unsigned long __initdata prom_memory_limit;
186
187static unsigned long __initdata alloc_top;
188static unsigned long __initdata alloc_top_high;
189static unsigned long __initdata alloc_bottom;
190static unsigned long __initdata rmo_top;
191static unsigned long __initdata ram_top;
192
193static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
194static int __initdata mem_reserve_cnt;
195
196static cell_t __initdata regbuf[1024];
197
198
199#define MAX_CPU_THREADS 2
200
201/* TO GO */
202#ifdef CONFIG_HMT
203struct {
204 unsigned int pir;
205 unsigned int threadid;
206} hmt_thread_data[NR_CPUS];
207#endif /* CONFIG_HMT */
208
209/*
210 * Error results ... some OF calls will return "-1" on error, some
211 * will return 0, some will return either. To simplify, here are
212 * macros to use with any ihandle or phandle return value to check if
213 * it is valid
214 */
215
216#define PROM_ERROR (-1u)
217#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
218#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
219
220
221/* This is the one and *ONLY* place where we actually call open
222 * firmware.
223 */
224
225static int __init call_prom(const char *service, int nargs, int nret, ...)
226{
227 int i;
228 struct prom_args args;
229 va_list list;
230
231 args.service = ADDR(service);
232 args.nargs = nargs;
233 args.nret = nret;
234
235 va_start(list, nret);
236 for (i = 0; i < nargs; i++)
237 args.args[i] = va_arg(list, prom_arg_t);
238 va_end(list);
239
240 for (i = 0; i < nret; i++)
241 args.args[nargs+i] = 0;
242
c4988820
PM
243 if (enter_prom(&args, RELOC(prom_entry)) < 0)
244 return PROM_ERROR;
9b6b563c
PM
245
246 return (nret > 0) ? args.args[nargs] : 0;
247}
248
249static int __init call_prom_ret(const char *service, int nargs, int nret,
250 prom_arg_t *rets, ...)
251{
252 int i;
253 struct prom_args args;
254 va_list list;
255
256 args.service = ADDR(service);
257 args.nargs = nargs;
258 args.nret = nret;
259
260 va_start(list, rets);
261 for (i = 0; i < nargs; i++)
262 args.args[i] = va_arg(list, prom_arg_t);
263 va_end(list);
264
265 for (i = 0; i < nret; i++)
266 rets[nargs+i] = 0;
267
c4988820
PM
268 if (enter_prom(&args, RELOC(prom_entry)) < 0)
269 return PROM_ERROR;
9b6b563c
PM
270
271 if (rets != NULL)
272 for (i = 1; i < nret; ++i)
c5200c90 273 rets[i-1] = args.args[nargs+i];
9b6b563c
PM
274
275 return (nret > 0) ? args.args[nargs] : 0;
276}
277
278
9b6b563c
PM
279static void __init prom_print(const char *msg)
280{
281 const char *p, *q;
282 struct prom_t *_prom = &RELOC(prom);
283
284 if (_prom->stdout == 0)
285 return;
286
287 for (p = msg; *p != 0; p = q) {
288 for (q = p; *q != 0 && *q != '\n'; ++q)
289 ;
290 if (q > p)
291 call_prom("write", 3, 1, _prom->stdout, p, q - p);
292 if (*q == 0)
293 break;
294 ++q;
295 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
296 }
297}
298
299
300static void __init prom_print_hex(unsigned long val)
301{
302 int i, nibbles = sizeof(val)*2;
303 char buf[sizeof(val)*2+1];
304 struct prom_t *_prom = &RELOC(prom);
305
306 for (i = nibbles-1; i >= 0; i--) {
307 buf[i] = (val & 0xf) + '0';
308 if (buf[i] > '9')
309 buf[i] += ('a'-'0'-10);
310 val >>= 4;
311 }
312 buf[nibbles] = '\0';
313 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
314}
315
316
317static void __init prom_printf(const char *format, ...)
318{
319 const char *p, *q, *s;
320 va_list args;
321 unsigned long v;
322 struct prom_t *_prom = &RELOC(prom);
323
324 va_start(args, format);
325#ifdef CONFIG_PPC64
326 format = PTRRELOC(format);
327#endif
328 for (p = format; *p != 0; p = q) {
329 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
330 ;
331 if (q > p)
332 call_prom("write", 3, 1, _prom->stdout, p, q - p);
333 if (*q == 0)
334 break;
335 if (*q == '\n') {
336 ++q;
337 call_prom("write", 3, 1, _prom->stdout,
338 ADDR("\r\n"), 2);
339 continue;
340 }
341 ++q;
342 if (*q == 0)
343 break;
344 switch (*q) {
345 case 's':
346 ++q;
347 s = va_arg(args, const char *);
348 prom_print(s);
349 break;
350 case 'x':
351 ++q;
352 v = va_arg(args, unsigned long);
353 prom_print_hex(v);
354 break;
355 }
356 }
357}
358
359
a575b807
PM
360static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
361 unsigned long align)
362{
363 int ret;
364 struct prom_t *_prom = &RELOC(prom);
365
366 ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
367 (prom_arg_t)align);
368 if (ret != -1 && _prom->mmumap != 0)
369 /* old pmacs need us to map as well */
370 call_prom("call-method", 6, 1,
371 ADDR("map"), _prom->mmumap, 0, size, virt, virt);
372 return ret;
373}
374
9b6b563c
PM
375static void __init __attribute__((noreturn)) prom_panic(const char *reason)
376{
377#ifdef CONFIG_PPC64
378 reason = PTRRELOC(reason);
379#endif
380 prom_print(reason);
381 /* ToDo: should put up an SRC here on p/iSeries */
382 call_prom("exit", 0, 0);
383
384 for (;;) /* should never get here */
385 ;
386}
387
388
389static int __init prom_next_node(phandle *nodep)
390{
391 phandle node;
392
393 if ((node = *nodep) != 0
394 && (*nodep = call_prom("child", 1, 1, node)) != 0)
395 return 1;
396 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
397 return 1;
398 for (;;) {
399 if ((node = call_prom("parent", 1, 1, node)) == 0)
400 return 0;
401 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
402 return 1;
403 }
404}
405
21fe3301 406static int inline prom_getprop(phandle node, const char *pname,
9b6b563c
PM
407 void *value, size_t valuelen)
408{
409 return call_prom("getprop", 4, 1, node, ADDR(pname),
410 (u32)(unsigned long) value, (u32) valuelen);
411}
412
21fe3301 413static int inline prom_getproplen(phandle node, const char *pname)
9b6b563c
PM
414{
415 return call_prom("getproplen", 2, 1, node, ADDR(pname));
416}
417
21fe3301 418static int inline prom_setprop(phandle node, const char *pname,
9b6b563c
PM
419 void *value, size_t valuelen)
420{
421 return call_prom("setprop", 4, 1, node, ADDR(pname),
422 (u32)(unsigned long) value, (u32) valuelen);
423}
424
425/* We can't use the standard versions because of RELOC headaches. */
426#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
427 || ('a' <= (c) && (c) <= 'f') \
428 || ('A' <= (c) && (c) <= 'F'))
429
430#define isdigit(c) ('0' <= (c) && (c) <= '9')
431#define islower(c) ('a' <= (c) && (c) <= 'z')
432#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
433
434unsigned long prom_strtoul(const char *cp, const char **endp)
435{
436 unsigned long result = 0, base = 10, value;
437
438 if (*cp == '0') {
439 base = 8;
440 cp++;
441 if (toupper(*cp) == 'X') {
442 cp++;
443 base = 16;
444 }
445 }
446
447 while (isxdigit(*cp) &&
448 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
449 result = result * base + value;
450 cp++;
451 }
452
453 if (endp)
454 *endp = cp;
455
456 return result;
457}
458
459unsigned long prom_memparse(const char *ptr, const char **retptr)
460{
461 unsigned long ret = prom_strtoul(ptr, retptr);
462 int shift = 0;
463
464 /*
465 * We can't use a switch here because GCC *may* generate a
466 * jump table which won't work, because we're not running at
467 * the address we're linked at.
468 */
469 if ('G' == **retptr || 'g' == **retptr)
470 shift = 30;
471
472 if ('M' == **retptr || 'm' == **retptr)
473 shift = 20;
474
475 if ('K' == **retptr || 'k' == **retptr)
476 shift = 10;
477
478 if (shift) {
479 ret <<= shift;
480 (*retptr)++;
481 }
482
483 return ret;
484}
485
486/*
487 * Early parsing of the command line passed to the kernel, used for
488 * "mem=x" and the options that affect the iommu
489 */
490static void __init early_cmdline_parse(void)
491{
492 struct prom_t *_prom = &RELOC(prom);
493 char *opt, *p;
494 int l = 0;
495
496 RELOC(prom_cmd_line[0]) = 0;
497 p = RELOC(prom_cmd_line);
498 if ((long)_prom->chosen > 0)
499 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
500#ifdef CONFIG_CMDLINE
501 if (l == 0) /* dbl check */
502 strlcpy(RELOC(prom_cmd_line),
503 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
504#endif /* CONFIG_CMDLINE */
505 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
506
507#ifdef CONFIG_PPC64
508 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
509 if (opt) {
510 prom_printf("iommu opt is: %s\n", opt);
511 opt += 6;
512 while (*opt && *opt == ' ')
513 opt++;
514 if (!strncmp(opt, RELOC("off"), 3))
515 RELOC(ppc64_iommu_off) = 1;
516 else if (!strncmp(opt, RELOC("force"), 5))
517 RELOC(iommu_force_on) = 1;
518 }
519#endif
520
521 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
522 if (opt) {
523 opt += 4;
524 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
525#ifdef CONFIG_PPC64
526 /* Align to 16 MB == size of ppc64 large page */
527 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
528#endif
529 }
530}
531
532#ifdef CONFIG_PPC_PSERIES
533/*
534 * To tell the firmware what our capabilities are, we have to pass
535 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
536 * that contain structures that contain the actual values.
537 */
538static struct fake_elf {
539 Elf32_Ehdr elfhdr;
540 Elf32_Phdr phdr[2];
541 struct chrpnote {
542 u32 namesz;
543 u32 descsz;
544 u32 type;
545 char name[8]; /* "PowerPC" */
546 struct chrpdesc {
547 u32 real_mode;
548 u32 real_base;
549 u32 real_size;
550 u32 virt_base;
551 u32 virt_size;
552 u32 load_base;
553 } chrpdesc;
554 } chrpnote;
555 struct rpanote {
556 u32 namesz;
557 u32 descsz;
558 u32 type;
559 char name[24]; /* "IBM,RPA-Client-Config" */
560 struct rpadesc {
561 u32 lpar_affinity;
562 u32 min_rmo_size;
563 u32 min_rmo_percent;
564 u32 max_pft_size;
565 u32 splpar;
566 u32 min_load;
567 u32 new_mem_def;
568 u32 ignore_me;
569 } rpadesc;
570 } rpanote;
571} fake_elf = {
572 .elfhdr = {
573 .e_ident = { 0x7f, 'E', 'L', 'F',
574 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
575 .e_type = ET_EXEC, /* yeah right */
576 .e_machine = EM_PPC,
577 .e_version = EV_CURRENT,
578 .e_phoff = offsetof(struct fake_elf, phdr),
579 .e_phentsize = sizeof(Elf32_Phdr),
580 .e_phnum = 2
581 },
582 .phdr = {
583 [0] = {
584 .p_type = PT_NOTE,
585 .p_offset = offsetof(struct fake_elf, chrpnote),
586 .p_filesz = sizeof(struct chrpnote)
587 }, [1] = {
588 .p_type = PT_NOTE,
589 .p_offset = offsetof(struct fake_elf, rpanote),
590 .p_filesz = sizeof(struct rpanote)
591 }
592 },
593 .chrpnote = {
594 .namesz = sizeof("PowerPC"),
595 .descsz = sizeof(struct chrpdesc),
596 .type = 0x1275,
597 .name = "PowerPC",
598 .chrpdesc = {
599 .real_mode = ~0U, /* ~0 means "don't care" */
600 .real_base = ~0U,
601 .real_size = ~0U,
602 .virt_base = ~0U,
603 .virt_size = ~0U,
604 .load_base = ~0U
605 },
606 },
607 .rpanote = {
608 .namesz = sizeof("IBM,RPA-Client-Config"),
609 .descsz = sizeof(struct rpadesc),
610 .type = 0x12759999,
611 .name = "IBM,RPA-Client-Config",
612 .rpadesc = {
613 .lpar_affinity = 0,
614 .min_rmo_size = 64, /* in megabytes */
615 .min_rmo_percent = 0,
616 .max_pft_size = 48, /* 2^48 bytes max PFT size */
617 .splpar = 1,
618 .min_load = ~0U,
619 .new_mem_def = 0
620 }
621 }
622};
623
624static void __init prom_send_capabilities(void)
625{
626 ihandle elfloader;
627
628 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
629 if (elfloader == 0) {
630 prom_printf("couldn't open /packages/elf-loader\n");
631 return;
632 }
633 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
634 elfloader, ADDR(&fake_elf));
635 call_prom("close", 1, 0, elfloader);
636}
637#endif
638
639/*
640 * Memory allocation strategy... our layout is normally:
641 *
642 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
643 * rare cases, initrd might end up being before the kernel though.
644 * We assume this won't override the final kernel at 0, we have no
645 * provision to handle that in this version, but it should hopefully
646 * never happen.
647 *
648 * alloc_top is set to the top of RMO, eventually shrink down if the
649 * TCEs overlap
650 *
651 * alloc_bottom is set to the top of kernel/initrd
652 *
653 * from there, allocations are done this way : rtas is allocated
654 * topmost, and the device-tree is allocated from the bottom. We try
655 * to grow the device-tree allocation as we progress. If we can't,
656 * then we fail, we don't currently have a facility to restart
657 * elsewhere, but that shouldn't be necessary.
658 *
659 * Note that calls to reserve_mem have to be done explicitly, memory
660 * allocated with either alloc_up or alloc_down isn't automatically
661 * reserved.
662 */
663
664
665/*
666 * Allocates memory in the RMO upward from the kernel/initrd
667 *
668 * When align is 0, this is a special case, it means to allocate in place
669 * at the current location of alloc_bottom or fail (that is basically
670 * extending the previous allocation). Used for the device-tree flattening
671 */
672static unsigned long __init alloc_up(unsigned long size, unsigned long align)
673{
c4988820 674 unsigned long base = RELOC(alloc_bottom);
9b6b563c
PM
675 unsigned long addr = 0;
676
c4988820
PM
677 if (align)
678 base = _ALIGN_UP(base, align);
9b6b563c
PM
679 prom_debug("alloc_up(%x, %x)\n", size, align);
680 if (RELOC(ram_top) == 0)
681 prom_panic("alloc_up() called with mem not initialized\n");
682
683 if (align)
684 base = _ALIGN_UP(RELOC(alloc_bottom), align);
685 else
686 base = RELOC(alloc_bottom);
687
688 for(; (base + size) <= RELOC(alloc_top);
689 base = _ALIGN_UP(base + 0x100000, align)) {
690 prom_debug(" trying: 0x%x\n\r", base);
691 addr = (unsigned long)prom_claim(base, size, 0);
c4988820 692 if (addr != PROM_ERROR && addr != 0)
9b6b563c
PM
693 break;
694 addr = 0;
695 if (align == 0)
696 break;
697 }
698 if (addr == 0)
699 return 0;
700 RELOC(alloc_bottom) = addr;
701
702 prom_debug(" -> %x\n", addr);
703 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
704 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
705 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
706 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
707 prom_debug(" ram_top : %x\n", RELOC(ram_top));
708
709 return addr;
710}
711
712/*
713 * Allocates memory downward, either from top of RMO, or if highmem
714 * is set, from the top of RAM. Note that this one doesn't handle
715 * failures. It does claim memory if highmem is not set.
716 */
717static unsigned long __init alloc_down(unsigned long size, unsigned long align,
718 int highmem)
719{
720 unsigned long base, addr = 0;
721
722 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
723 highmem ? RELOC("(high)") : RELOC("(low)"));
724 if (RELOC(ram_top) == 0)
725 prom_panic("alloc_down() called with mem not initialized\n");
726
727 if (highmem) {
728 /* Carve out storage for the TCE table. */
729 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
730 if (addr <= RELOC(alloc_bottom))
731 return 0;
732 /* Will we bump into the RMO ? If yes, check out that we
733 * didn't overlap existing allocations there, if we did,
734 * we are dead, we must be the first in town !
735 */
736 if (addr < RELOC(rmo_top)) {
737 /* Good, we are first */
738 if (RELOC(alloc_top) == RELOC(rmo_top))
739 RELOC(alloc_top) = RELOC(rmo_top) = addr;
740 else
741 return 0;
742 }
743 RELOC(alloc_top_high) = addr;
744 goto bail;
745 }
746
747 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
748 for (; base > RELOC(alloc_bottom);
749 base = _ALIGN_DOWN(base - 0x100000, align)) {
750 prom_debug(" trying: 0x%x\n\r", base);
751 addr = (unsigned long)prom_claim(base, size, 0);
c4988820 752 if (addr != PROM_ERROR && addr != 0)
9b6b563c
PM
753 break;
754 addr = 0;
755 }
756 if (addr == 0)
757 return 0;
758 RELOC(alloc_top) = addr;
759
760 bail:
761 prom_debug(" -> %x\n", addr);
762 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
763 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
764 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
765 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
766 prom_debug(" ram_top : %x\n", RELOC(ram_top));
767
768 return addr;
769}
770
771/*
772 * Parse a "reg" cell
773 */
774static unsigned long __init prom_next_cell(int s, cell_t **cellp)
775{
776 cell_t *p = *cellp;
777 unsigned long r = 0;
778
779 /* Ignore more than 2 cells */
780 while (s > sizeof(unsigned long) / 4) {
781 p++;
782 s--;
783 }
784 r = *p++;
785#ifdef CONFIG_PPC64
35499c01 786 if (s > 1) {
9b6b563c
PM
787 r <<= 32;
788 r |= *(p++);
789 }
790#endif
791 *cellp = p;
792 return r;
793}
794
795/*
796 * Very dumb function for adding to the memory reserve list, but
797 * we don't need anything smarter at this point
798 *
799 * XXX Eventually check for collisions. They should NEVER happen.
800 * If problems seem to show up, it would be a good start to track
801 * them down.
802 */
803static void reserve_mem(unsigned long base, unsigned long size)
804{
805 unsigned long top = base + size;
806 unsigned long cnt = RELOC(mem_reserve_cnt);
807
808 if (size == 0)
809 return;
810
811 /* We need to always keep one empty entry so that we
812 * have our terminator with "size" set to 0 since we are
813 * dumb and just copy this entire array to the boot params
814 */
815 base = _ALIGN_DOWN(base, PAGE_SIZE);
816 top = _ALIGN_UP(top, PAGE_SIZE);
817 size = top - base;
818
819 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
820 prom_panic("Memory reserve map exhausted !\n");
821 RELOC(mem_reserve_map)[cnt].base = base;
822 RELOC(mem_reserve_map)[cnt].size = size;
823 RELOC(mem_reserve_cnt) = cnt + 1;
824}
825
826/*
827 * Initialize memory allocation mecanism, parse "memory" nodes and
828 * obtain that way the top of memory and RMO to setup out local allocator
829 */
830static void __init prom_init_mem(void)
831{
832 phandle node;
833 char *path, type[64];
834 unsigned int plen;
835 cell_t *p, *endp;
836 struct prom_t *_prom = &RELOC(prom);
837 u32 rac, rsc;
838
839 /*
840 * We iterate the memory nodes to find
841 * 1) top of RMO (first node)
842 * 2) top of memory
843 */
844 rac = 2;
845 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
846 rsc = 1;
847 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
848 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
849 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
850
851 prom_debug("scanning memory:\n");
852 path = RELOC(prom_scratch);
853
854 for (node = 0; prom_next_node(&node); ) {
855 type[0] = 0;
856 prom_getprop(node, "device_type", type, sizeof(type));
857
c4988820
PM
858 if (type[0] == 0) {
859 /*
860 * CHRP Longtrail machines have no device_type
861 * on the memory node, so check the name instead...
862 */
863 prom_getprop(node, "name", type, sizeof(type));
864 }
9b6b563c
PM
865 if (strcmp(type, RELOC("memory")))
866 continue;
c4988820 867
9b6b563c
PM
868 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
869 if (plen > sizeof(regbuf)) {
870 prom_printf("memory node too large for buffer !\n");
871 plen = sizeof(regbuf);
872 }
873 p = RELOC(regbuf);
874 endp = p + (plen / sizeof(cell_t));
875
876#ifdef DEBUG_PROM
877 memset(path, 0, PROM_SCRATCH_SIZE);
878 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
879 prom_debug(" node %s :\n", path);
880#endif /* DEBUG_PROM */
881
882 while ((endp - p) >= (rac + rsc)) {
883 unsigned long base, size;
884
885 base = prom_next_cell(rac, &p);
886 size = prom_next_cell(rsc, &p);
887
888 if (size == 0)
889 continue;
890 prom_debug(" %x %x\n", base, size);
891 if (base == 0)
892 RELOC(rmo_top) = size;
893 if ((base + size) > RELOC(ram_top))
894 RELOC(ram_top) = base + size;
895 }
896 }
897
898 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
899
900 /* Check if we have an initrd after the kernel, if we do move our bottom
901 * point to after it
902 */
903 if (RELOC(prom_initrd_start)) {
904 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
905 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
906 }
907
908 /*
909 * If prom_memory_limit is set we reduce the upper limits *except* for
910 * alloc_top_high. This must be the real top of RAM so we can put
911 * TCE's up there.
912 */
913
914 RELOC(alloc_top_high) = RELOC(ram_top);
915
916 if (RELOC(prom_memory_limit)) {
917 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
918 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
919 RELOC(prom_memory_limit));
920 RELOC(prom_memory_limit) = 0;
921 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
922 prom_printf("Ignoring mem=%x >= ram_top.\n",
923 RELOC(prom_memory_limit));
924 RELOC(prom_memory_limit) = 0;
925 } else {
926 RELOC(ram_top) = RELOC(prom_memory_limit);
927 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
928 }
929 }
930
931 /*
932 * Setup our top alloc point, that is top of RMO or top of
933 * segment 0 when running non-LPAR.
934 * Some RS64 machines have buggy firmware where claims up at
935 * 1GB fail. Cap at 768MB as a workaround.
936 * Since 768MB is plenty of room, and we need to cap to something
937 * reasonable on 32-bit, cap at 768MB on all machines.
938 */
939 if (!RELOC(rmo_top))
940 RELOC(rmo_top) = RELOC(ram_top);
941 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
942 RELOC(alloc_top) = RELOC(rmo_top);
943
944 prom_printf("memory layout at init:\n");
945 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
946 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
947 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
948 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
949 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
950 prom_printf(" ram_top : %x\n", RELOC(ram_top));
951}
952
953
954/*
955 * Allocate room for and instantiate RTAS
956 */
957static void __init prom_instantiate_rtas(void)
958{
959 phandle rtas_node;
960 ihandle rtas_inst;
961 u32 base, entry = 0;
962 u32 size = 0;
963
964 prom_debug("prom_instantiate_rtas: start...\n");
965
966 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
967 prom_debug("rtas_node: %x\n", rtas_node);
968 if (!PHANDLE_VALID(rtas_node))
969 return;
970
971 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
972 if (size == 0)
973 return;
974
975 base = alloc_down(size, PAGE_SIZE, 0);
976 if (base == 0) {
977 prom_printf("RTAS allocation failed !\n");
978 return;
979 }
980
981 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
982 if (!IHANDLE_VALID(rtas_inst)) {
983 prom_printf("opening rtas package failed");
984 return;
985 }
986
987 prom_printf("instantiating rtas at 0x%x ...", base);
988
989 if (call_prom_ret("call-method", 3, 2, &entry,
990 ADDR("instantiate-rtas"),
991 rtas_inst, base) == PROM_ERROR
992 || entry == 0) {
993 prom_printf(" failed\n");
994 return;
995 }
996 prom_printf(" done\n");
997
998 reserve_mem(base, size);
999
1000 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
1001 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
1002
1003 prom_debug("rtas base = 0x%x\n", base);
1004 prom_debug("rtas entry = 0x%x\n", entry);
1005 prom_debug("rtas size = 0x%x\n", (long)size);
1006
1007 prom_debug("prom_instantiate_rtas: end...\n");
1008}
1009
1010#ifdef CONFIG_PPC64
1011/*
1012 * Allocate room for and initialize TCE tables
1013 */
1014static void __init prom_initialize_tce_table(void)
1015{
1016 phandle node;
1017 ihandle phb_node;
1018 char compatible[64], type[64], model[64];
1019 char *path = RELOC(prom_scratch);
1020 u64 base, align;
1021 u32 minalign, minsize;
1022 u64 tce_entry, *tce_entryp;
1023 u64 local_alloc_top, local_alloc_bottom;
1024 u64 i;
1025
1026 if (RELOC(ppc64_iommu_off))
1027 return;
1028
1029 prom_debug("starting prom_initialize_tce_table\n");
1030
1031 /* Cache current top of allocs so we reserve a single block */
1032 local_alloc_top = RELOC(alloc_top_high);
1033 local_alloc_bottom = local_alloc_top;
1034
1035 /* Search all nodes looking for PHBs. */
1036 for (node = 0; prom_next_node(&node); ) {
1037 compatible[0] = 0;
1038 type[0] = 0;
1039 model[0] = 0;
1040 prom_getprop(node, "compatible",
1041 compatible, sizeof(compatible));
1042 prom_getprop(node, "device_type", type, sizeof(type));
1043 prom_getprop(node, "model", model, sizeof(model));
1044
1045 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1046 continue;
1047
1048 /* Keep the old logic in tack to avoid regression. */
1049 if (compatible[0] != 0) {
1050 if ((strstr(compatible, RELOC("python")) == NULL) &&
1051 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1052 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1053 continue;
1054 } else if (model[0] != 0) {
1055 if ((strstr(model, RELOC("ython")) == NULL) &&
1056 (strstr(model, RELOC("peedwagon")) == NULL) &&
1057 (strstr(model, RELOC("innipeg")) == NULL))
1058 continue;
1059 }
1060
1061 if (prom_getprop(node, "tce-table-minalign", &minalign,
1062 sizeof(minalign)) == PROM_ERROR)
1063 minalign = 0;
1064 if (prom_getprop(node, "tce-table-minsize", &minsize,
1065 sizeof(minsize)) == PROM_ERROR)
1066 minsize = 4UL << 20;
1067
1068 /*
1069 * Even though we read what OF wants, we just set the table
1070 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1071 * By doing this, we avoid the pitfalls of trying to DMA to
1072 * MMIO space and the DMA alias hole.
1073 *
1074 * On POWER4, firmware sets the TCE region by assuming
1075 * each TCE table is 8MB. Using this memory for anything
1076 * else will impact performance, so we always allocate 8MB.
1077 * Anton
1078 */
1079 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1080 minsize = 8UL << 20;
1081 else
1082 minsize = 4UL << 20;
1083
1084 /* Align to the greater of the align or size */
1085 align = max(minalign, minsize);
1086 base = alloc_down(minsize, align, 1);
1087 if (base == 0)
1088 prom_panic("ERROR, cannot find space for TCE table.\n");
1089 if (base < local_alloc_bottom)
1090 local_alloc_bottom = base;
1091
1092 /* Save away the TCE table attributes for later use. */
1093 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
1094 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
1095
1096 /* It seems OF doesn't null-terminate the path :-( */
1097 memset(path, 0, sizeof(path));
1098 /* Call OF to setup the TCE hardware */
1099 if (call_prom("package-to-path", 3, 1, node,
1100 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1101 prom_printf("package-to-path failed\n");
1102 }
1103
1104 prom_debug("TCE table: %s\n", path);
1105 prom_debug("\tnode = 0x%x\n", node);
1106 prom_debug("\tbase = 0x%x\n", base);
1107 prom_debug("\tsize = 0x%x\n", minsize);
1108
1109 /* Initialize the table to have a one-to-one mapping
1110 * over the allocated size.
1111 */
1112 tce_entryp = (unsigned long *)base;
1113 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1114 tce_entry = (i << PAGE_SHIFT);
1115 tce_entry |= 0x3;
1116 *tce_entryp = tce_entry;
1117 }
1118
1119 prom_printf("opening PHB %s", path);
1120 phb_node = call_prom("open", 1, 1, path);
1121 if (phb_node == 0)
1122 prom_printf("... failed\n");
1123 else
1124 prom_printf("... done\n");
1125
1126 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1127 phb_node, -1, minsize,
1128 (u32) base, (u32) (base >> 32));
1129 call_prom("close", 1, 0, phb_node);
1130 }
1131
1132 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1133
1134 if (RELOC(prom_memory_limit)) {
1135 /*
1136 * We align the start to a 16MB boundary so we can map
1137 * the TCE area using large pages if possible.
1138 * The end should be the top of RAM so no need to align it.
1139 */
1140 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
1141 0x1000000);
1142 RELOC(prom_tce_alloc_end) = local_alloc_top;
1143 }
1144
1145 /* Flag the first invalid entry */
1146 prom_debug("ending prom_initialize_tce_table\n");
1147}
1148#endif
1149
1150/*
1151 * With CHRP SMP we need to use the OF to start the other processors.
1152 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1153 * so we have to put the processors into a holding pattern controlled
1154 * by the kernel (not OF) before we destroy the OF.
1155 *
1156 * This uses a chunk of low memory, puts some holding pattern
1157 * code there and sends the other processors off to there until
1158 * smp_boot_cpus tells them to do something. The holding pattern
1159 * checks that address until its cpu # is there, when it is that
1160 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1161 * of setting those values.
1162 *
1163 * We also use physical address 0x4 here to tell when a cpu
1164 * is in its holding pattern code.
1165 *
1166 * -- Cort
1167 */
bbd0abda
PM
1168extern void __secondary_hold(void);
1169extern unsigned long __secondary_hold_spinloop;
1170extern unsigned long __secondary_hold_acknowledge;
1171
1172/*
1173 * We want to reference the copy of __secondary_hold_* in the
1174 * 0 - 0x100 address range
1175 */
1176#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1177
9b6b563c
PM
1178static void __init prom_hold_cpus(void)
1179{
9b6b563c
PM
1180 unsigned long i;
1181 unsigned int reg;
1182 phandle node;
1183 char type[64];
1184 int cpuid = 0;
1185 unsigned int interrupt_server[MAX_CPU_THREADS];
1186 unsigned int cpu_threads, hw_cpu_num;
1187 int propsize;
bbd0abda 1188 struct prom_t *_prom = &RELOC(prom);
9b6b563c 1189 unsigned long *spinloop
bbd0abda 1190 = (void *) LOW_ADDR(__secondary_hold_spinloop);
9b6b563c 1191 unsigned long *acknowledge
bbd0abda 1192 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
9b6b563c 1193#ifdef CONFIG_PPC64
bbd0abda 1194 /* __secondary_hold is actually a descriptor, not the text address */
9b6b563c
PM
1195 unsigned long secondary_hold
1196 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1197#else
bbd0abda 1198 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
9b6b563c 1199#endif
9b6b563c
PM
1200
1201 prom_debug("prom_hold_cpus: start...\n");
1202 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1203 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1204 prom_debug(" 1) acknowledge = 0x%x\n",
1205 (unsigned long)acknowledge);
1206 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1207 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1208
1209 /* Set the common spinloop variable, so all of the secondary cpus
1210 * will block when they are awakened from their OF spinloop.
1211 * This must occur for both SMP and non SMP kernels, since OF will
1212 * be trashed when we move the kernel.
1213 */
1214 *spinloop = 0;
1215
1216#ifdef CONFIG_HMT
bbd0abda 1217 for (i = 0; i < NR_CPUS; i++)
9b6b563c 1218 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
9b6b563c
PM
1219#endif
1220 /* look for cpus */
1221 for (node = 0; prom_next_node(&node); ) {
1222 type[0] = 0;
1223 prom_getprop(node, "device_type", type, sizeof(type));
1224 if (strcmp(type, RELOC("cpu")) != 0)
1225 continue;
1226
1227 /* Skip non-configured cpus. */
1228 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1229 if (strcmp(type, RELOC("okay")) != 0)
1230 continue;
1231
1232 reg = -1;
1233 prom_getprop(node, "reg", &reg, sizeof(reg));
1234
1235 prom_debug("\ncpuid = 0x%x\n", cpuid);
1236 prom_debug("cpu hw idx = 0x%x\n", reg);
1237
1238 /* Init the acknowledge var which will be reset by
1239 * the secondary cpu when it awakens from its OF
1240 * spinloop.
1241 */
1242 *acknowledge = (unsigned long)-1;
1243
1244 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1245 &interrupt_server,
1246 sizeof(interrupt_server));
1247 if (propsize < 0) {
1248 /* no property. old hardware has no SMT */
1249 cpu_threads = 1;
1250 interrupt_server[0] = reg; /* fake it with phys id */
1251 } else {
1252 /* We have a threaded processor */
1253 cpu_threads = propsize / sizeof(u32);
1254 if (cpu_threads > MAX_CPU_THREADS) {
1255 prom_printf("SMT: too many threads!\n"
1256 "SMT: found %x, max is %x\n",
1257 cpu_threads, MAX_CPU_THREADS);
1258 cpu_threads = 1; /* ToDo: panic? */
1259 }
1260 }
1261
1262 hw_cpu_num = interrupt_server[0];
1263 if (hw_cpu_num != _prom->cpu) {
1264 /* Primary Thread of non-boot cpu */
1265 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1266 call_prom("start-cpu", 3, 0, node,
1267 secondary_hold, reg);
1268
bbd0abda
PM
1269 for (i = 0; (i < 100000000) &&
1270 (*acknowledge == ((unsigned long)-1)); i++ )
9b6b563c
PM
1271 mb();
1272
bbd0abda 1273 if (*acknowledge == reg)
9b6b563c 1274 prom_printf("done\n");
bbd0abda 1275 else
9b6b563c 1276 prom_printf("failed: %x\n", *acknowledge);
9b6b563c
PM
1277 }
1278#ifdef CONFIG_SMP
1279 else
1280 prom_printf("%x : boot cpu %x\n", cpuid, reg);
9b6b563c 1281#endif /* CONFIG_SMP */
bbd0abda
PM
1282
1283 /* Reserve cpu #s for secondary threads. They start later. */
1284 cpuid += cpu_threads;
9b6b563c
PM
1285 }
1286#ifdef CONFIG_HMT
1287 /* Only enable HMT on processors that provide support. */
1288 if (__is_processor(PV_PULSAR) ||
1289 __is_processor(PV_ICESTAR) ||
1290 __is_processor(PV_SSTAR)) {
1291 prom_printf(" starting secondary threads\n");
1292
1293 for (i = 0; i < NR_CPUS; i += 2) {
1294 if (!cpu_online(i))
1295 continue;
1296
1297 if (i == 0) {
1298 unsigned long pir = mfspr(SPRN_PIR);
1299 if (__is_processor(PV_PULSAR)) {
1300 RELOC(hmt_thread_data)[i].pir =
1301 pir & 0x1f;
1302 } else {
1303 RELOC(hmt_thread_data)[i].pir =
1304 pir & 0x3ff;
1305 }
1306 }
1307 }
1308 } else {
1309 prom_printf("Processor is not HMT capable\n");
1310 }
1311#endif
1312
1313 if (cpuid > NR_CPUS)
1314 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1315 ") exceeded: ignoring extras\n");
1316
1317 prom_debug("prom_hold_cpus: end...\n");
9b6b563c
PM
1318}
1319
1320
1321static void __init prom_init_client_services(unsigned long pp)
1322{
1323 struct prom_t *_prom = &RELOC(prom);
1324
1325 /* Get a handle to the prom entry point before anything else */
1326 RELOC(prom_entry) = pp;
1327
1328 /* get a handle for the stdout device */
1329 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1330 if (!PHANDLE_VALID(_prom->chosen))
1331 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1332
1333 /* get device tree root */
1334 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1335 if (!PHANDLE_VALID(_prom->root))
1336 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
a575b807
PM
1337
1338 _prom->mmumap = 0;
1339}
1340
1341#ifdef CONFIG_PPC32
1342/*
1343 * For really old powermacs, we need to map things we claim.
1344 * For that, we need the ihandle of the mmu.
1345 */
1346static void __init prom_find_mmu(void)
1347{
1348 struct prom_t *_prom = &RELOC(prom);
1349 phandle oprom;
1350 char version[64];
1351
1352 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1353 if (!PHANDLE_VALID(oprom))
1354 return;
1355 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1356 return;
1357 version[sizeof(version) - 1] = 0;
1358 prom_printf("OF version is '%s'\n", version);
1359 /* XXX might need to add other versions here */
1360 if (strcmp(version, "Open Firmware, 1.0.5") != 0)
1361 return;
1362 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1363 sizeof(_prom->mmumap));
9b6b563c 1364}
a575b807
PM
1365#else
1366#define prom_find_mmu()
1367#endif
9b6b563c
PM
1368
1369static void __init prom_init_stdout(void)
1370{
1371 struct prom_t *_prom = &RELOC(prom);
1372 char *path = RELOC(of_stdout_device);
1373 char type[16];
1374 u32 val;
1375
1376 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1377 prom_panic("cannot find stdout");
1378
1379 _prom->stdout = val;
1380
1381 /* Get the full OF pathname of the stdout device */
1382 memset(path, 0, 256);
1383 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1384 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1385 prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
1386 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1387 prom_setprop(_prom->chosen, "linux,stdout-path",
1388 RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
1389
1390 /* If it's a display, note it */
1391 memset(type, 0, sizeof(type));
1392 prom_getprop(val, "device_type", type, sizeof(type));
1393 if (strcmp(type, RELOC("display")) == 0)
1394 prom_setprop(val, "linux,boot-display", NULL, 0);
1395}
1396
1397static void __init prom_close_stdin(void)
1398{
1399 struct prom_t *_prom = &RELOC(prom);
1400 ihandle val;
1401
1402 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1403 call_prom("close", 1, 0, val);
1404}
1405
1406static int __init prom_find_machine_type(void)
1407{
1408 struct prom_t *_prom = &RELOC(prom);
1409 char compat[256];
1410 int len, i = 0;
21fe3301 1411#ifdef CONFIG_PPC64
9b6b563c 1412 phandle rtas;
21fe3301 1413#endif
9b6b563c
PM
1414 len = prom_getprop(_prom->root, "compatible",
1415 compat, sizeof(compat)-1);
1416 if (len > 0) {
1417 compat[len] = 0;
1418 while (i < len) {
1419 char *p = &compat[i];
1420 int sl = strlen(p);
1421 if (sl == 0)
1422 break;
1423 if (strstr(p, RELOC("Power Macintosh")) ||
a575b807 1424 strstr(p, RELOC("MacRISC")))
9b6b563c
PM
1425 return PLATFORM_POWERMAC;
1426#ifdef CONFIG_PPC64
1427 if (strstr(p, RELOC("Momentum,Maple")))
1428 return PLATFORM_MAPLE;
1429#endif
1430 i += sl + 1;
1431 }
1432 }
1433#ifdef CONFIG_PPC64
1434 /* Default to pSeries. We need to know if we are running LPAR */
1435 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1436 if (PHANDLE_VALID(rtas)) {
1437 int x = prom_getproplen(rtas, "ibm,hypertas-functions");
1438 if (x != PROM_ERROR) {
1439 prom_printf("Hypertas detected, assuming LPAR !\n");
1440 return PLATFORM_PSERIES_LPAR;
1441 }
1442 }
1443 return PLATFORM_PSERIES;
1444#else
1445 return PLATFORM_CHRP;
1446#endif
1447}
1448
9b6b563c
PM
1449static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1450{
1451 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1452}
1453
1454/*
1455 * If we have a display that we don't know how to drive,
1456 * we will want to try to execute OF's open method for it
1457 * later. However, OF will probably fall over if we do that
1458 * we've taken over the MMU.
1459 * So we check whether we will need to open the display,
1460 * and if so, open it now.
1461 */
1462static void __init prom_check_displays(void)
1463{
1464 char type[16], *path;
1465 phandle node;
1466 ihandle ih;
1467 int i;
9b6b563c
PM
1468
1469 static unsigned char default_colors[] = {
1470 0x00, 0x00, 0x00,
1471 0x00, 0x00, 0xaa,
1472 0x00, 0xaa, 0x00,
1473 0x00, 0xaa, 0xaa,
1474 0xaa, 0x00, 0x00,
1475 0xaa, 0x00, 0xaa,
1476 0xaa, 0xaa, 0x00,
1477 0xaa, 0xaa, 0xaa,
1478 0x55, 0x55, 0x55,
1479 0x55, 0x55, 0xff,
1480 0x55, 0xff, 0x55,
1481 0x55, 0xff, 0xff,
1482 0xff, 0x55, 0x55,
1483 0xff, 0x55, 0xff,
1484 0xff, 0xff, 0x55,
1485 0xff, 0xff, 0xff
1486 };
1487 const unsigned char *clut;
1488
1489 prom_printf("Looking for displays\n");
1490 for (node = 0; prom_next_node(&node); ) {
1491 memset(type, 0, sizeof(type));
1492 prom_getprop(node, "device_type", type, sizeof(type));
1493 if (strcmp(type, RELOC("display")) != 0)
1494 continue;
1495
1496 /* It seems OF doesn't null-terminate the path :-( */
1497 path = RELOC(prom_scratch);
1498 memset(path, 0, PROM_SCRATCH_SIZE);
1499
1500 /*
1501 * leave some room at the end of the path for appending extra
1502 * arguments
1503 */
1504 if (call_prom("package-to-path", 3, 1, node, path,
1505 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1506 continue;
1507 prom_printf("found display : %s, opening ... ", path);
1508
1509 ih = call_prom("open", 1, 1, path);
1510 if (ih == 0) {
1511 prom_printf("failed\n");
1512 continue;
1513 }
1514
1515 /* Success */
1516 prom_printf("done\n");
1517 prom_setprop(node, "linux,opened", NULL, 0);
1518
1519 /* Setup a usable color table when the appropriate
1520 * method is available. Should update this to set-colors */
1521 clut = RELOC(default_colors);
1522 for (i = 0; i < 32; i++, clut += 3)
1523 if (prom_set_color(ih, i, clut[0], clut[1],
1524 clut[2]) != 0)
1525 break;
1526
1527#ifdef CONFIG_LOGO_LINUX_CLUT224
1528 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1529 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1530 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1531 clut[2]) != 0)
1532 break;
1533#endif /* CONFIG_LOGO_LINUX_CLUT224 */
9b6b563c
PM
1534 }
1535}
1536
1537
1538/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1539static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1540 unsigned long needed, unsigned long align)
1541{
1542 void *ret;
1543
1544 *mem_start = _ALIGN(*mem_start, align);
1545 while ((*mem_start + needed) > *mem_end) {
1546 unsigned long room, chunk;
1547
1548 prom_debug("Chunk exhausted, claiming more at %x...\n",
1549 RELOC(alloc_bottom));
1550 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1551 if (room > DEVTREE_CHUNK_SIZE)
1552 room = DEVTREE_CHUNK_SIZE;
1553 if (room < PAGE_SIZE)
1554 prom_panic("No memory for flatten_device_tree (no room)");
1555 chunk = alloc_up(room, 0);
1556 if (chunk == 0)
1557 prom_panic("No memory for flatten_device_tree (claim failed)");
1558 *mem_end = RELOC(alloc_top);
1559 }
1560
1561 ret = (void *)*mem_start;
1562 *mem_start += needed;
1563
1564 return ret;
1565}
1566
1567#define dt_push_token(token, mem_start, mem_end) \
1568 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1569
1570static unsigned long __init dt_find_string(char *str)
1571{
1572 char *s, *os;
1573
1574 s = os = (char *)RELOC(dt_string_start);
1575 s += 4;
1576 while (s < (char *)RELOC(dt_string_end)) {
1577 if (strcmp(s, str) == 0)
1578 return s - os;
1579 s += strlen(s) + 1;
1580 }
1581 return 0;
1582}
1583
1584/*
1585 * The Open Firmware 1275 specification states properties must be 31 bytes or
1586 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1587 */
1588#define MAX_PROPERTY_NAME 64
1589
1590static void __init scan_dt_build_strings(phandle node,
1591 unsigned long *mem_start,
1592 unsigned long *mem_end)
1593{
1594 char *prev_name, *namep, *sstart;
1595 unsigned long soff;
1596 phandle child;
1597
1598 sstart = (char *)RELOC(dt_string_start);
1599
1600 /* get and store all property names */
1601 prev_name = RELOC("");
1602 for (;;) {
1603 /* 64 is max len of name including nul. */
1604 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1605 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1606 /* No more nodes: unwind alloc */
1607 *mem_start = (unsigned long)namep;
1608 break;
1609 }
1610
1611 /* skip "name" */
1612 if (strcmp(namep, RELOC("name")) == 0) {
1613 *mem_start = (unsigned long)namep;
1614 prev_name = RELOC("name");
1615 continue;
1616 }
1617 /* get/create string entry */
1618 soff = dt_find_string(namep);
1619 if (soff != 0) {
1620 *mem_start = (unsigned long)namep;
1621 namep = sstart + soff;
1622 } else {
1623 /* Trim off some if we can */
1624 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1625 RELOC(dt_string_end) = *mem_start;
1626 }
1627 prev_name = namep;
1628 }
1629
1630 /* do all our children */
1631 child = call_prom("child", 1, 1, node);
1632 while (child != 0) {
1633 scan_dt_build_strings(child, mem_start, mem_end);
1634 child = call_prom("peer", 1, 1, child);
1635 }
1636}
1637
1638static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1639 unsigned long *mem_end)
1640{
1641 phandle child;
1642 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1643 unsigned long soff;
1644 unsigned char *valp;
1645 static char pname[MAX_PROPERTY_NAME];
c4988820 1646 int l, room;
9b6b563c
PM
1647
1648 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1649
1650 /* get the node's full name */
1651 namep = (char *)*mem_start;
c4988820
PM
1652 room = *mem_end - *mem_start;
1653 if (room > 255)
1654 room = 255;
1655 l = call_prom("package-to-path", 3, 1, node, namep, room);
9b6b563c
PM
1656 if (l >= 0) {
1657 /* Didn't fit? Get more room. */
c4988820
PM
1658 if (l >= room) {
1659 if (l >= *mem_end - *mem_start)
1660 namep = make_room(mem_start, mem_end, l+1, 1);
9b6b563c
PM
1661 call_prom("package-to-path", 3, 1, node, namep, l);
1662 }
1663 namep[l] = '\0';
1664
1665 /* Fixup an Apple bug where they have bogus \0 chars in the
a575b807
PM
1666 * middle of the path in some properties, and extract
1667 * the unit name (everything after the last '/').
9b6b563c 1668 */
a575b807 1669 for (lp = p = namep, ep = namep + l; p < ep; p++) {
9b6b563c 1670 if (*p == '/')
a575b807
PM
1671 lp = namep;
1672 else if (*p != 0)
1673 *lp++ = *p;
1674 }
1675 *lp = 0;
1676 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
9b6b563c
PM
1677 }
1678
1679 /* get it again for debugging */
1680 path = RELOC(prom_scratch);
1681 memset(path, 0, PROM_SCRATCH_SIZE);
1682 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1683
1684 /* get and store all properties */
1685 prev_name = RELOC("");
1686 sstart = (char *)RELOC(dt_string_start);
1687 for (;;) {
1688 if (call_prom("nextprop", 3, 1, node, prev_name,
1689 RELOC(pname)) != 1)
1690 break;
1691
1692 /* skip "name" */
1693 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1694 prev_name = RELOC("name");
1695 continue;
1696 }
1697
1698 /* find string offset */
1699 soff = dt_find_string(RELOC(pname));
1700 if (soff == 0) {
1701 prom_printf("WARNING: Can't find string index for"
1702 " <%s>, node %s\n", RELOC(pname), path);
1703 break;
1704 }
1705 prev_name = sstart + soff;
1706
1707 /* get length */
1708 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1709
1710 /* sanity checks */
1711 if (l == PROM_ERROR)
1712 continue;
1713 if (l > MAX_PROPERTY_LENGTH) {
1714 prom_printf("WARNING: ignoring large property ");
1715 /* It seems OF doesn't null-terminate the path :-( */
1716 prom_printf("[%s] ", path);
1717 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1718 continue;
1719 }
1720
1721 /* push property head */
1722 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1723 dt_push_token(l, mem_start, mem_end);
1724 dt_push_token(soff, mem_start, mem_end);
1725
1726 /* push property content */
1727 valp = make_room(mem_start, mem_end, l, 4);
1728 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1729 *mem_start = _ALIGN(*mem_start, 4);
1730 }
1731
1732 /* Add a "linux,phandle" property. */
1733 soff = dt_find_string(RELOC("linux,phandle"));
1734 if (soff == 0)
1735 prom_printf("WARNING: Can't find string index for"
1736 " <linux-phandle> node %s\n", path);
1737 else {
1738 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1739 dt_push_token(4, mem_start, mem_end);
1740 dt_push_token(soff, mem_start, mem_end);
1741 valp = make_room(mem_start, mem_end, 4, 4);
1742 *(u32 *)valp = node;
1743 }
1744
1745 /* do all our children */
1746 child = call_prom("child", 1, 1, node);
1747 while (child != 0) {
1748 scan_dt_build_struct(child, mem_start, mem_end);
1749 child = call_prom("peer", 1, 1, child);
1750 }
1751
1752 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1753}
1754
1755static void __init flatten_device_tree(void)
1756{
1757 phandle root;
1758 unsigned long mem_start, mem_end, room;
1759 struct boot_param_header *hdr;
1760 struct prom_t *_prom = &RELOC(prom);
1761 char *namep;
1762 u64 *rsvmap;
1763
1764 /*
1765 * Check how much room we have between alloc top & bottom (+/- a
1766 * few pages), crop to 4Mb, as this is our "chuck" size
1767 */
1768 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1769 if (room > DEVTREE_CHUNK_SIZE)
1770 room = DEVTREE_CHUNK_SIZE;
1771 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1772
1773 /* Now try to claim that */
1774 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1775 if (mem_start == 0)
1776 prom_panic("Can't allocate initial device-tree chunk\n");
1777 mem_end = RELOC(alloc_top);
1778
1779 /* Get root of tree */
1780 root = call_prom("peer", 1, 1, (phandle)0);
1781 if (root == (phandle)0)
1782 prom_panic ("couldn't get device tree root\n");
1783
1784 /* Build header and make room for mem rsv map */
1785 mem_start = _ALIGN(mem_start, 4);
1786 hdr = make_room(&mem_start, &mem_end,
1787 sizeof(struct boot_param_header), 4);
1788 RELOC(dt_header_start) = (unsigned long)hdr;
1789 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1790
1791 /* Start of strings */
1792 mem_start = PAGE_ALIGN(mem_start);
1793 RELOC(dt_string_start) = mem_start;
1794 mem_start += 4; /* hole */
1795
1796 /* Add "linux,phandle" in there, we'll need it */
1797 namep = make_room(&mem_start, &mem_end, 16, 1);
1798 strcpy(namep, RELOC("linux,phandle"));
1799 mem_start = (unsigned long)namep + strlen(namep) + 1;
1800
1801 /* Build string array */
1802 prom_printf("Building dt strings...\n");
1803 scan_dt_build_strings(root, &mem_start, &mem_end);
1804 RELOC(dt_string_end) = mem_start;
1805
1806 /* Build structure */
1807 mem_start = PAGE_ALIGN(mem_start);
1808 RELOC(dt_struct_start) = mem_start;
1809 prom_printf("Building dt structure...\n");
1810 scan_dt_build_struct(root, &mem_start, &mem_end);
1811 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1812 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1813
1814 /* Finish header */
1815 hdr->boot_cpuid_phys = _prom->cpu;
1816 hdr->magic = OF_DT_HEADER;
1817 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1818 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1819 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1820 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1821 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1822 hdr->version = OF_DT_VERSION;
1823 /* Version 16 is not backward compatible */
1824 hdr->last_comp_version = 0x10;
1825
1826 /* Reserve the whole thing and copy the reserve map in, we
1827 * also bump mem_reserve_cnt to cause further reservations to
1828 * fail since it's too late.
1829 */
1830 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1831 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1832
1833#ifdef DEBUG_PROM
1834 {
1835 int i;
1836 prom_printf("reserved memory map:\n");
1837 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1838 prom_printf(" %x - %x\n",
1839 RELOC(mem_reserve_map)[i].base,
1840 RELOC(mem_reserve_map)[i].size);
1841 }
1842#endif
1843 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1844
1845 prom_printf("Device tree strings 0x%x -> 0x%x\n",
1846 RELOC(dt_string_start), RELOC(dt_string_end));
1847 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1848 RELOC(dt_struct_start), RELOC(dt_struct_end));
1849
1850}
1851
1852
1853static void __init fixup_device_tree(void)
1854{
1855#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
1856 phandle u3, i2c, mpic;
1857 u32 u3_rev;
1858 u32 interrupts[2];
1859 u32 parent;
1860
1861 /* Some G5s have a missing interrupt definition, fix it up here */
1862 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1863 if (!PHANDLE_VALID(u3))
1864 return;
1865 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1866 if (!PHANDLE_VALID(i2c))
1867 return;
1868 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1869 if (!PHANDLE_VALID(mpic))
1870 return;
1871
1872 /* check if proper rev of u3 */
1873 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
1874 == PROM_ERROR)
1875 return;
7d49697e 1876 if (u3_rev < 0x35 || u3_rev > 0x39)
9b6b563c
PM
1877 return;
1878 /* does it need fixup ? */
1879 if (prom_getproplen(i2c, "interrupts") > 0)
1880 return;
1881
1882 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
1883
1884 /* interrupt on this revision of u3 is number 0 and level */
1885 interrupts[0] = 0;
1886 interrupts[1] = 1;
1887 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1888 parent = (u32)mpic;
1889 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1890#endif
1891}
1892
1893
1894static void __init prom_find_boot_cpu(void)
1895{
1896 struct prom_t *_prom = &RELOC(prom);
1897 u32 getprop_rval;
1898 ihandle prom_cpu;
1899 phandle cpu_pkg;
1900
a575b807 1901 _prom->cpu = 0;
9b6b563c 1902 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
a575b807 1903 return;
9b6b563c
PM
1904
1905 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
1906
1907 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
1908 _prom->cpu = getprop_rval;
1909
1910 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
1911}
1912
1913static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1914{
1915#ifdef CONFIG_BLK_DEV_INITRD
1916 struct prom_t *_prom = &RELOC(prom);
1917
1918 if (r3 && r4 && r4 != 0xdeadbeef) {
1919 unsigned long val;
1920
1921 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1922 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1923
1924 val = RELOC(prom_initrd_start);
1925 prom_setprop(_prom->chosen, "linux,initrd-start", &val,
1926 sizeof(val));
1927 val = RELOC(prom_initrd_end);
1928 prom_setprop(_prom->chosen, "linux,initrd-end", &val,
1929 sizeof(val));
1930
1931 reserve_mem(RELOC(prom_initrd_start),
1932 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
1933
1934 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
1935 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
1936 }
1937#endif /* CONFIG_BLK_DEV_INITRD */
1938}
1939
1940/*
1941 * We enter here early on, when the Open Firmware prom is still
1942 * handling exceptions and the MMU hash table for us.
1943 */
1944
1945unsigned long __init prom_init(unsigned long r3, unsigned long r4,
1946 unsigned long pp,
1947 unsigned long r6, unsigned long r7)
1948{
1949 struct prom_t *_prom;
9b6b563c
PM
1950 unsigned long hdr;
1951 u32 getprop_rval;
b42b6617 1952 unsigned long offset = reloc_offset();
9b6b563c
PM
1953
1954#ifdef CONFIG_PPC32
9b6b563c
PM
1955 reloc_got2(offset);
1956#endif
1957
1958 _prom = &RELOC(prom);
1959
1960 /*
1961 * First zero the BSS
1962 */
1963 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
1964
1965 /*
1966 * Init interface to Open Firmware, get some node references,
1967 * like /chosen
1968 */
1969 prom_init_client_services(pp);
1970
1971 /*
1972 * Init prom stdout device
1973 */
1974 prom_init_stdout();
1975
a575b807
PM
1976 /*
1977 * See if this OF is old enough that we need to do explicit maps
1978 */
1979 prom_find_mmu();
1980
9b6b563c
PM
1981 /*
1982 * Check for an initrd
1983 */
1984 prom_check_initrd(r3, r4);
1985
1986 /*
1987 * Get default machine type. At this point, we do not differentiate
1988 * between pSeries SMP and pSeries LPAR
1989 */
1990 RELOC(of_platform) = prom_find_machine_type();
1991 getprop_rval = RELOC(of_platform);
1992 prom_setprop(_prom->chosen, "linux,platform",
1993 &getprop_rval, sizeof(getprop_rval));
1994
1995#ifdef CONFIG_PPC_PSERIES
1996 /*
1997 * On pSeries, inform the firmware about our capabilities
1998 */
1999 if (RELOC(of_platform) & PLATFORM_PSERIES)
2000 prom_send_capabilities();
2001#endif
2002
9b6b563c 2003 /*
f3f66f59 2004 * Copy the CPU hold code
9b6b563c 2005 */
55d36339 2006 if (RELOC(of_platform) != PLATFORM_POWERMAC)
5a408329 2007 copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
9b6b563c
PM
2008
2009 /*
2010 * Do early parsing of command line
2011 */
2012 early_cmdline_parse();
2013
2014 /*
2015 * Initialize memory management within prom_init
2016 */
2017 prom_init_mem();
2018
2019 /*
2020 * Determine which cpu is actually running right _now_
2021 */
2022 prom_find_boot_cpu();
2023
2024 /*
2025 * Initialize display devices
2026 */
2027 prom_check_displays();
2028
2029#ifdef CONFIG_PPC64
2030 /*
2031 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2032 * that uses the allocator, we need to make sure we get the top of memory
2033 * available for us here...
2034 */
2035 if (RELOC(of_platform) == PLATFORM_PSERIES)
2036 prom_initialize_tce_table();
2037#endif
2038
2039 /*
2040 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2041 * in spin-loops. PowerMacs don't have a working RTAS and use
2042 * a different way to spin CPUs
2043 */
2044 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2045 prom_instantiate_rtas();
2046 prom_hold_cpus();
2047 }
2048
2049 /*
2050 * Fill in some infos for use by the kernel later on
2051 */
2052 if (RELOC(prom_memory_limit))
2053 prom_setprop(_prom->chosen, "linux,memory-limit",
2054 &RELOC(prom_memory_limit),
2055 sizeof(prom_memory_limit));
2056#ifdef CONFIG_PPC64
2057 if (RELOC(ppc64_iommu_off))
2058 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
2059
2060 if (RELOC(iommu_force_on))
2061 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
2062
2063 if (RELOC(prom_tce_alloc_start)) {
2064 prom_setprop(_prom->chosen, "linux,tce-alloc-start",
2065 &RELOC(prom_tce_alloc_start),
2066 sizeof(prom_tce_alloc_start));
2067 prom_setprop(_prom->chosen, "linux,tce-alloc-end",
2068 &RELOC(prom_tce_alloc_end),
2069 sizeof(prom_tce_alloc_end));
2070 }
2071#endif
2072
2073 /*
2074 * Fixup any known bugs in the device-tree
2075 */
2076 fixup_device_tree();
2077
2078 /*
2079 * Now finally create the flattened device-tree
2080 */
2081 prom_printf("copying OF device tree ...\n");
2082 flatten_device_tree();
2083
2084 /* in case stdin is USB and still active on IBM machines... */
2085 prom_close_stdin();
2086
2087 /*
2088 * Call OF "quiesce" method to shut down pending DMA's from
2089 * devices etc...
2090 */
2091 prom_printf("Calling quiesce ...\n");
2092 call_prom("quiesce", 0, 0);
2093
2094 /*
2095 * And finally, call the kernel passing it the flattened device
2096 * tree and NULL as r5, thus triggering the new entry point which
2097 * is common to us and kexec
2098 */
2099 hdr = RELOC(dt_header_start);
2100 prom_printf("returning from prom_init\n");
2101 prom_debug("->dt_header_start=0x%x\n", hdr);
2102
2103#ifdef CONFIG_PPC32
2104 reloc_got2(-offset);
2105#endif
2106
35499c01 2107 __start(hdr, KERNELBASE + offset, 0);
9b6b563c
PM
2108
2109 return 0;
2110}