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