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