]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - arch/ppc64/kernel/prom_init.c
Linux-2.6.12-rc2
[sojka/nv-tegra/linux-3.10.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  * Memory allocation strategy... our layout is normally:
497  *
498  *  at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
499  *  might end up beeing before the kernel though. We assume this won't override
500  *  the final kernel at 0, we have no provision to handle that in this version,
501  *  but it should hopefully never happen.
502  *
503  *  alloc_top is set to the top of RMO, eventually shrink down if the TCEs overlap
504  *  alloc_bottom is set to the top of kernel/initrd
505  *
506  *  from there, allocations are done that way : rtas is allocated topmost, and
507  *  the device-tree is allocated from the bottom. We try to grow the device-tree
508  *  allocation as we progress. If we can't, then we fail, we don't currently have
509  *  a facility to restart elsewhere, but that shouldn't be necessary neither
510  *
511  *  Note that calls to reserve_mem have to be done explicitely, memory allocated
512  *  with either alloc_up or alloc_down isn't automatically reserved.
513  */
514
515
516 /*
517  * Allocates memory in the RMO upward from the kernel/initrd
518  *
519  * When align is 0, this is a special case, it means to allocate in place
520  * at the current location of alloc_bottom or fail (that is basically
521  * extending the previous allocation). Used for the device-tree flattening
522  */
523 static unsigned long __init alloc_up(unsigned long size, unsigned long align)
524 {
525         unsigned long offset = reloc_offset();
526         unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align);
527         unsigned long addr = 0;
528
529         prom_debug("alloc_up(%x, %x)\n", size, align);
530         if (RELOC(ram_top) == 0)
531                 prom_panic("alloc_up() called with mem not initialized\n");
532
533         if (align)
534                 base = _ALIGN_UP(RELOC(alloc_bottom), align);
535         else
536                 base = RELOC(alloc_bottom);
537
538         for(; (base + size) <= RELOC(alloc_top); 
539             base = _ALIGN_UP(base + 0x100000, align)) {
540                 prom_debug("    trying: 0x%x\n\r", base);
541                 addr = (unsigned long)prom_claim(base, size, 0);
542                 if ((int)addr != PROM_ERROR)
543                         break;
544                 addr = 0;
545                 if (align == 0)
546                         break;
547         }
548         if (addr == 0)
549                 return 0;
550         RELOC(alloc_bottom) = addr;
551
552         prom_debug(" -> %x\n", addr);
553         prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
554         prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
555         prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
556         prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
557         prom_debug("  ram_top      : %x\n", RELOC(ram_top));
558
559         return addr;
560 }
561
562 /*
563  * Allocates memory downard, either from top of RMO, or if highmem
564  * is set, from the top of RAM. Note that this one doesn't handle
565  * failures. In does claim memory if highmem is not set.
566  */
567 static unsigned long __init alloc_down(unsigned long size, unsigned long align,
568                                        int highmem)
569 {
570         unsigned long offset = reloc_offset();
571         unsigned long base, addr = 0;
572
573         prom_debug("alloc_down(%x, %x, %s)\n", size, align,
574                    highmem ? RELOC("(high)") : RELOC("(low)"));
575         if (RELOC(ram_top) == 0)
576                 prom_panic("alloc_down() called with mem not initialized\n");
577
578         if (highmem) {
579                 /* Carve out storage for the TCE table. */
580                 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
581                 if (addr <= RELOC(alloc_bottom))
582                         return 0;
583                 else {
584                         /* Will we bump into the RMO ? If yes, check out that we
585                          * didn't overlap existing allocations there, if we did,
586                          * we are dead, we must be the first in town !
587                          */
588                         if (addr < RELOC(rmo_top)) {
589                                 /* Good, we are first */
590                                 if (RELOC(alloc_top) == RELOC(rmo_top))
591                                         RELOC(alloc_top) = RELOC(rmo_top) = addr;
592                                 else
593                                         return 0;
594                         }
595                         RELOC(alloc_top_high) = addr;
596                 }
597                 goto bail;
598         }
599
600         base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
601         for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
602                 prom_debug("    trying: 0x%x\n\r", base);
603                 addr = (unsigned long)prom_claim(base, size, 0);
604                 if ((int)addr != PROM_ERROR)
605                         break;
606                 addr = 0;
607         }
608         if (addr == 0)
609                 return 0;
610         RELOC(alloc_top) = addr;
611
612  bail:
613         prom_debug(" -> %x\n", addr);
614         prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
615         prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
616         prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
617         prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
618         prom_debug("  ram_top      : %x\n", RELOC(ram_top));
619
620         return addr;
621 }
622
623 /*
624  * Parse a "reg" cell
625  */
626 static unsigned long __init prom_next_cell(int s, cell_t **cellp)
627 {
628         cell_t *p = *cellp;
629         unsigned long r = 0;
630
631         /* Ignore more than 2 cells */
632         while (s > 2) {
633                 p++;
634                 s--;
635         }
636         while (s) {
637                 r <<= 32;
638                 r |= *(p++);
639                 s--;
640         }
641
642         *cellp = p;
643         return r;
644 }
645
646 /*
647  * Very dumb function for adding to the memory reserve list, but
648  * we don't need anything smarter at this point
649  *
650  * XXX Eventually check for collisions. They should NEVER happen
651  * if problems seem to show up, it would be a good start to track
652  * them down.
653  */
654 static void reserve_mem(unsigned long base, unsigned long size)
655 {
656         unsigned long offset = reloc_offset();
657         unsigned long top = base + size;
658         unsigned long cnt = RELOC(mem_reserve_cnt);
659
660         if (size == 0)
661                 return;
662
663         /* We need to always keep one empty entry so that we
664          * have our terminator with "size" set to 0 since we are
665          * dumb and just copy this entire array to the boot params
666          */
667         base = _ALIGN_DOWN(base, PAGE_SIZE);
668         top = _ALIGN_UP(top, PAGE_SIZE);
669         size = top - base;
670
671         if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
672                 prom_panic("Memory reserve map exhausted !\n");
673         RELOC(mem_reserve_map)[cnt].base = base;
674         RELOC(mem_reserve_map)[cnt].size = size;
675         RELOC(mem_reserve_cnt) = cnt + 1;
676 }
677
678 /*
679  * Initialize memory allocation mecanism, parse "memory" nodes and
680  * obtain that way the top of memory and RMO to setup out local allocator
681  */
682 static void __init prom_init_mem(void)
683 {
684         phandle node;
685         char *path, type[64];
686         unsigned int plen;
687         cell_t *p, *endp;
688         unsigned long offset = reloc_offset();
689         struct prom_t *_prom = PTRRELOC(&prom);
690
691         /*
692          * We iterate the memory nodes to find
693          * 1) top of RMO (first node)
694          * 2) top of memory
695          */
696         prom_debug("root_addr_cells: %x\n", (long)_prom->root_addr_cells);
697         prom_debug("root_size_cells: %x\n", (long)_prom->root_size_cells);
698
699         prom_debug("scanning memory:\n");
700         path = RELOC(prom_scratch);
701
702         for (node = 0; prom_next_node(&node); ) {
703                 type[0] = 0;
704                 prom_getprop(node, "device_type", type, sizeof(type));
705
706                 if (strcmp(type, RELOC("memory")))
707                         continue;
708         
709                 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
710                 if (plen > sizeof(regbuf)) {
711                         prom_printf("memory node too large for buffer !\n");
712                         plen = sizeof(regbuf);
713                 }
714                 p = RELOC(regbuf);
715                 endp = p + (plen / sizeof(cell_t));
716
717 #ifdef DEBUG_PROM
718                 memset(path, 0, PROM_SCRATCH_SIZE);
719                 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
720                 prom_debug("  node %s :\n", path);
721 #endif /* DEBUG_PROM */
722
723                 while ((endp - p) >= (_prom->root_addr_cells + _prom->root_size_cells)) {
724                         unsigned long base, size;
725
726                         base = prom_next_cell(_prom->root_addr_cells, &p);
727                         size = prom_next_cell(_prom->root_size_cells, &p);
728
729                         if (size == 0)
730                                 continue;
731                         prom_debug("    %x %x\n", base, size);
732                         if (base == 0)
733                                 RELOC(rmo_top) = size;
734                         if ((base + size) > RELOC(ram_top))
735                                 RELOC(ram_top) = base + size;
736                 }
737         }
738
739         RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(klimit) - offset + 0x4000);
740
741         /* Check if we have an initrd after the kernel, if we do move our bottom
742          * point to after it
743          */
744         if (RELOC(prom_initrd_start)) {
745                 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
746                         RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
747         }
748
749         /*
750          * If prom_memory_limit is set we reduce the upper limits *except* for
751          * alloc_top_high. This must be the real top of RAM so we can put
752          * TCE's up there.
753          */
754
755         RELOC(alloc_top_high) = RELOC(ram_top);
756
757         if (RELOC(prom_memory_limit)) {
758                 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
759                         prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
760                                 RELOC(prom_memory_limit));
761                         RELOC(prom_memory_limit) = 0;
762                 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
763                         prom_printf("Ignoring mem=%x >= ram_top.\n",
764                                 RELOC(prom_memory_limit));
765                         RELOC(prom_memory_limit) = 0;
766                 } else {
767                         RELOC(ram_top) = RELOC(prom_memory_limit);
768                         RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
769                 }
770         }
771
772         /*
773          * Setup our top alloc point, that is top of RMO or top of
774          * segment 0 when running non-LPAR.
775          */
776         if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
777                 RELOC(alloc_top) = RELOC(rmo_top);
778         else
779                 RELOC(alloc_top) = RELOC(rmo_top) = min(0x40000000ul, RELOC(ram_top));
780
781         prom_printf("memory layout at init:\n");
782         prom_printf("  memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
783         prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
784         prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
785         prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
786         prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
787         prom_printf("  ram_top      : %x\n", RELOC(ram_top));
788 }
789
790
791 /*
792  * Allocate room for and instanciate RTAS
793  */
794 static void __init prom_instantiate_rtas(void)
795 {
796         unsigned long offset = reloc_offset();
797         struct prom_t *_prom = PTRRELOC(&prom);
798         phandle prom_rtas, rtas_node;
799         u32 base, entry = 0;
800         u32 size = 0;
801
802         prom_debug("prom_instantiate_rtas: start...\n");
803
804         prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
805         prom_debug("prom_rtas: %x\n", prom_rtas);
806         if (prom_rtas == (phandle) -1)
807                 return;
808
809         prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size));
810         if (size == 0)
811                 return;
812
813         base = alloc_down(size, PAGE_SIZE, 0);
814         if (base == 0) {
815                 prom_printf("RTAS allocation failed !\n");
816                 return;
817         }
818         prom_printf("instantiating rtas at 0x%x", base);
819
820         rtas_node = call_prom("open", 1, 1, ADDR("/rtas"));
821         prom_printf("...");
822
823         if (call_prom("call-method", 3, 2,
824                       ADDR("instantiate-rtas"),
825                       rtas_node, base) != PROM_ERROR) {
826                 entry = (long)_prom->args.rets[1];
827         }
828         if (entry == 0) {
829                 prom_printf(" failed\n");
830                 return;
831         }
832         prom_printf(" done\n");
833
834         reserve_mem(base, size);
835
836         prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base));
837         prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry));
838
839         prom_debug("rtas base     = 0x%x\n", base);
840         prom_debug("rtas entry    = 0x%x\n", entry);
841         prom_debug("rtas size     = 0x%x\n", (long)size);
842
843         prom_debug("prom_instantiate_rtas: end...\n");
844 }
845
846
847 /*
848  * Allocate room for and initialize TCE tables
849  */
850 static void __init prom_initialize_tce_table(void)
851 {
852         phandle node;
853         ihandle phb_node;
854         unsigned long offset = reloc_offset();
855         char compatible[64], type[64], model[64];
856         char *path = RELOC(prom_scratch);
857         u64 base, align;
858         u32 minalign, minsize;
859         u64 tce_entry, *tce_entryp;
860         u64 local_alloc_top, local_alloc_bottom;
861         u64 i;
862
863         if (RELOC(ppc64_iommu_off))
864                 return;
865
866         prom_debug("starting prom_initialize_tce_table\n");
867
868         /* Cache current top of allocs so we reserve a single block */
869         local_alloc_top = RELOC(alloc_top_high);
870         local_alloc_bottom = local_alloc_top;
871
872         /* Search all nodes looking for PHBs. */
873         for (node = 0; prom_next_node(&node); ) {
874                 compatible[0] = 0;
875                 type[0] = 0;
876                 model[0] = 0;
877                 prom_getprop(node, "compatible",
878                              compatible, sizeof(compatible));
879                 prom_getprop(node, "device_type", type, sizeof(type));
880                 prom_getprop(node, "model", model, sizeof(model));
881
882                 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
883                         continue;
884
885                 /* Keep the old logic in tack to avoid regression. */
886                 if (compatible[0] != 0) {
887                         if ((strstr(compatible, RELOC("python")) == NULL) &&
888                             (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
889                             (strstr(compatible, RELOC("Winnipeg")) == NULL))
890                                 continue;
891                 } else if (model[0] != 0) {
892                         if ((strstr(model, RELOC("ython")) == NULL) &&
893                             (strstr(model, RELOC("peedwagon")) == NULL) &&
894                             (strstr(model, RELOC("innipeg")) == NULL))
895                                 continue;
896                 }
897
898                 if (prom_getprop(node, "tce-table-minalign", &minalign,
899                                  sizeof(minalign)) == PROM_ERROR)
900                         minalign = 0;
901                 if (prom_getprop(node, "tce-table-minsize", &minsize,
902                                  sizeof(minsize)) == PROM_ERROR)
903                         minsize = 4UL << 20;
904
905                 /*
906                  * Even though we read what OF wants, we just set the table
907                  * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
908                  * By doing this, we avoid the pitfalls of trying to DMA to
909                  * MMIO space and the DMA alias hole.
910                  *
911                  * On POWER4, firmware sets the TCE region by assuming
912                  * each TCE table is 8MB. Using this memory for anything
913                  * else will impact performance, so we always allocate 8MB.
914                  * Anton
915                  */
916                 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
917                         minsize = 8UL << 20;
918                 else
919                         minsize = 4UL << 20;
920
921                 /* Align to the greater of the align or size */
922                 align = max(minalign, minsize);
923                 base = alloc_down(minsize, align, 1);
924                 if (base == 0)
925                         prom_panic("ERROR, cannot find space for TCE table.\n");
926                 if (base < local_alloc_bottom)
927                         local_alloc_bottom = base;
928
929                 /* Save away the TCE table attributes for later use. */
930                 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
931                 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
932
933                 /* It seems OF doesn't null-terminate the path :-( */
934                 memset(path, 0, sizeof(path));
935                 /* Call OF to setup the TCE hardware */
936                 if (call_prom("package-to-path", 3, 1, node,
937                               path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
938                         prom_printf("package-to-path failed\n");
939                 }
940
941                 prom_debug("TCE table: %s\n", path);
942                 prom_debug("\tnode = 0x%x\n", node);
943                 prom_debug("\tbase = 0x%x\n", base);
944                 prom_debug("\tsize = 0x%x\n", minsize);
945
946                 /* Initialize the table to have a one-to-one mapping
947                  * over the allocated size.
948                  */
949                 tce_entryp = (unsigned long *)base;
950                 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
951                         tce_entry = (i << PAGE_SHIFT);
952                         tce_entry |= 0x3;
953                         *tce_entryp = tce_entry;
954                 }
955
956                 prom_printf("opening PHB %s", path);
957                 phb_node = call_prom("open", 1, 1, path);
958                 if ( (long)phb_node <= 0)
959                         prom_printf("... failed\n");
960                 else
961                         prom_printf("... done\n");
962
963                 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
964                           phb_node, -1, minsize,
965                           (u32) base, (u32) (base >> 32));
966                 call_prom("close", 1, 0, phb_node);
967         }
968
969         reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
970
971         if (RELOC(prom_memory_limit)) {
972                 /*
973                  * We align the start to a 16MB boundary so we can map the TCE area
974                  * using large pages if possible. The end should be the top of RAM
975                  * so no need to align it.
976                  */
977                 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 0x1000000);
978                 RELOC(prom_tce_alloc_end) = local_alloc_top;
979         }
980
981         /* Flag the first invalid entry */
982         prom_debug("ending prom_initialize_tce_table\n");
983 }
984
985 /*
986  * With CHRP SMP we need to use the OF to start the other
987  * processors so we can't wait until smp_boot_cpus (the OF is
988  * trashed by then) so we have to put the processors into
989  * a holding pattern controlled by the kernel (not OF) before
990  * we destroy the OF.
991  *
992  * This uses a chunk of low memory, puts some holding pattern
993  * code there and sends the other processors off to there until
994  * smp_boot_cpus tells them to do something.  The holding pattern
995  * checks that address until its cpu # is there, when it is that
996  * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
997  * of setting those values.
998  *
999  * We also use physical address 0x4 here to tell when a cpu
1000  * is in its holding pattern code.
1001  *
1002  * Fixup comment... DRENG / PPPBBB - Peter
1003  *
1004  * -- Cort
1005  */
1006 static void __init prom_hold_cpus(void)
1007 {
1008         unsigned long i;
1009         unsigned int reg;
1010         phandle node;
1011         unsigned long offset = reloc_offset();
1012         char type[64];
1013         int cpuid = 0;
1014         unsigned int interrupt_server[MAX_CPU_THREADS];
1015         unsigned int cpu_threads, hw_cpu_num;
1016         int propsize;
1017         extern void __secondary_hold(void);
1018         extern unsigned long __secondary_hold_spinloop;
1019         extern unsigned long __secondary_hold_acknowledge;
1020         unsigned long *spinloop
1021                 = (void *)virt_to_abs(&__secondary_hold_spinloop);
1022         unsigned long *acknowledge
1023                 = (void *)virt_to_abs(&__secondary_hold_acknowledge);
1024         unsigned long secondary_hold
1025                 = virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
1026         struct prom_t *_prom = PTRRELOC(&prom);
1027
1028         prom_debug("prom_hold_cpus: start...\n");
1029         prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
1030         prom_debug("    1) *spinloop      = 0x%x\n", *spinloop);
1031         prom_debug("    1) acknowledge    = 0x%x\n",
1032                    (unsigned long)acknowledge);
1033         prom_debug("    1) *acknowledge   = 0x%x\n", *acknowledge);
1034         prom_debug("    1) secondary_hold = 0x%x\n", secondary_hold);
1035
1036         /* Set the common spinloop variable, so all of the secondary cpus
1037          * will block when they are awakened from their OF spinloop.
1038          * This must occur for both SMP and non SMP kernels, since OF will
1039          * be trashed when we move the kernel.
1040          */
1041         *spinloop = 0;
1042
1043 #ifdef CONFIG_HMT
1044         for (i=0; i < NR_CPUS; i++) {
1045                 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1046         }
1047 #endif
1048         /* look for cpus */
1049         for (node = 0; prom_next_node(&node); ) {
1050                 type[0] = 0;
1051                 prom_getprop(node, "device_type", type, sizeof(type));
1052                 if (strcmp(type, RELOC("cpu")) != 0)
1053                         continue;
1054
1055                 /* Skip non-configured cpus. */
1056                 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1057                         if (strcmp(type, RELOC("okay")) != 0)
1058                                 continue;
1059
1060                 reg = -1;
1061                 prom_getprop(node, "reg", &reg, sizeof(reg));
1062
1063                 prom_debug("\ncpuid        = 0x%x\n", cpuid);
1064                 prom_debug("cpu hw idx   = 0x%x\n", reg);
1065
1066                 /* Init the acknowledge var which will be reset by
1067                  * the secondary cpu when it awakens from its OF
1068                  * spinloop.
1069                  */
1070                 *acknowledge = (unsigned long)-1;
1071
1072                 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1073                                         &interrupt_server,
1074                                         sizeof(interrupt_server));
1075                 if (propsize < 0) {
1076                         /* no property.  old hardware has no SMT */
1077                         cpu_threads = 1;
1078                         interrupt_server[0] = reg; /* fake it with phys id */
1079                 } else {
1080                         /* We have a threaded processor */
1081                         cpu_threads = propsize / sizeof(u32);
1082                         if (cpu_threads > MAX_CPU_THREADS) {
1083                                 prom_printf("SMT: too many threads!\n"
1084                                             "SMT: found %x, max is %x\n",
1085                                             cpu_threads, MAX_CPU_THREADS);
1086                                 cpu_threads = 1; /* ToDo: panic? */
1087                         }
1088                 }
1089
1090                 hw_cpu_num = interrupt_server[0];
1091                 if (hw_cpu_num != _prom->cpu) {
1092                         /* Primary Thread of non-boot cpu */
1093                         prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1094                         call_prom("start-cpu", 3, 0, node,
1095                                   secondary_hold, reg);
1096
1097                         for ( i = 0 ; (i < 100000000) && 
1098                               (*acknowledge == ((unsigned long)-1)); i++ )
1099                                 mb();
1100
1101                         if (*acknowledge == reg) {
1102                                 prom_printf("done\n");
1103                                 /* We have to get every CPU out of OF,
1104                                  * even if we never start it. */
1105                                 if (cpuid >= NR_CPUS)
1106                                         goto next;
1107                         } else {
1108                                 prom_printf("failed: %x\n", *acknowledge);
1109                         }
1110                 }
1111 #ifdef CONFIG_SMP
1112                 else
1113                         prom_printf("%x : boot cpu     %x\n", cpuid, reg);
1114 #endif
1115 next:
1116 #ifdef CONFIG_SMP
1117                 /* Init paca for secondary threads.   They start later. */
1118                 for (i=1; i < cpu_threads; i++) {
1119                         cpuid++;
1120                         if (cpuid >= NR_CPUS)
1121                                 continue;
1122                 }
1123 #endif /* CONFIG_SMP */
1124                 cpuid++;
1125         }
1126 #ifdef CONFIG_HMT
1127         /* Only enable HMT on processors that provide support. */
1128         if (__is_processor(PV_PULSAR) || 
1129             __is_processor(PV_ICESTAR) ||
1130             __is_processor(PV_SSTAR)) {
1131                 prom_printf("    starting secondary threads\n");
1132
1133                 for (i = 0; i < NR_CPUS; i += 2) {
1134                         if (!cpu_online(i))
1135                                 continue;
1136
1137                         if (i == 0) {
1138                                 unsigned long pir = mfspr(SPRN_PIR);
1139                                 if (__is_processor(PV_PULSAR)) {
1140                                         RELOC(hmt_thread_data)[i].pir = 
1141                                                 pir & 0x1f;
1142                                 } else {
1143                                         RELOC(hmt_thread_data)[i].pir = 
1144                                                 pir & 0x3ff;
1145                                 }
1146                         }
1147                 }
1148         } else {
1149                 prom_printf("Processor is not HMT capable\n");
1150         }
1151 #endif
1152
1153         if (cpuid > NR_CPUS)
1154                 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1155                             ") exceeded: ignoring extras\n");
1156
1157         prom_debug("prom_hold_cpus: end...\n");
1158 }
1159
1160
1161 static void __init prom_init_client_services(unsigned long pp)
1162 {
1163         unsigned long offset = reloc_offset();
1164         struct prom_t *_prom = PTRRELOC(&prom);
1165
1166         /* Get a handle to the prom entry point before anything else */
1167         _prom->entry = pp;
1168
1169         /* Init default value for phys size */
1170         _prom->root_size_cells = 1;
1171         _prom->root_addr_cells = 2;
1172
1173         /* get a handle for the stdout device */
1174         _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1175         if ((long)_prom->chosen <= 0)
1176                 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1177
1178         /* get device tree root */
1179         _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1180         if ((long)_prom->root <= 0)
1181                 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1182 }
1183
1184 static void __init prom_init_stdout(void)
1185 {
1186         unsigned long offset = reloc_offset();
1187         struct prom_t *_prom = PTRRELOC(&prom);
1188         char *path = RELOC(of_stdout_device);
1189         char type[16];
1190         u32 val;
1191
1192         if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1193                 prom_panic("cannot find stdout");
1194
1195         _prom->stdout = val;
1196
1197         /* Get the full OF pathname of the stdout device */
1198         memset(path, 0, 256);
1199         call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1200         val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1201         prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
1202         prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1203         prom_setprop(_prom->chosen, "linux,stdout-path",
1204                      RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
1205
1206         /* If it's a display, note it */
1207         memset(type, 0, sizeof(type));
1208         prom_getprop(val, "device_type", type, sizeof(type));
1209         if (strcmp(type, RELOC("display")) == 0) {
1210                 _prom->disp_node = val;
1211                 prom_setprop(val, "linux,boot-display", NULL, 0);
1212         }
1213 }
1214
1215 static void __init prom_close_stdin(void)
1216 {
1217         unsigned long offset = reloc_offset();
1218         struct prom_t *_prom = PTRRELOC(&prom);
1219         ihandle val;
1220
1221         if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1222                 call_prom("close", 1, 0, val);
1223 }
1224
1225 static int __init prom_find_machine_type(void)
1226 {
1227         unsigned long offset = reloc_offset();
1228         struct prom_t *_prom = PTRRELOC(&prom);
1229         char compat[256];
1230         int len, i = 0;
1231         phandle rtas;
1232
1233         len = prom_getprop(_prom->root, "compatible",
1234                            compat, sizeof(compat)-1);
1235         if (len > 0) {
1236                 compat[len] = 0;
1237                 while (i < len) {
1238                         char *p = &compat[i];
1239                         int sl = strlen(p);
1240                         if (sl == 0)
1241                                 break;
1242                         if (strstr(p, RELOC("Power Macintosh")) ||
1243                             strstr(p, RELOC("MacRISC4")))
1244                                 return PLATFORM_POWERMAC;
1245                         if (strstr(p, RELOC("Momentum,Maple")))
1246                                 return PLATFORM_MAPLE;
1247                         i += sl + 1;
1248                 }
1249         }
1250         /* Default to pSeries. We need to know if we are running LPAR */
1251         rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1252         if (rtas != (phandle) -1) {
1253                 unsigned long x;
1254                 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1255                 if (x != PROM_ERROR) {
1256                         prom_printf("Hypertas detected, assuming LPAR !\n");
1257                         return PLATFORM_PSERIES_LPAR;
1258                 }
1259         }
1260         return PLATFORM_PSERIES;
1261 }
1262
1263 static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1264 {
1265         unsigned long offset = reloc_offset();
1266
1267         return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1268 }
1269
1270 /*
1271  * If we have a display that we don't know how to drive,
1272  * we will want to try to execute OF's open method for it
1273  * later.  However, OF will probably fall over if we do that
1274  * we've taken over the MMU.
1275  * So we check whether we will need to open the display,
1276  * and if so, open it now.
1277  */
1278 static void __init prom_check_displays(void)
1279 {
1280         unsigned long offset = reloc_offset();
1281         struct prom_t *_prom = PTRRELOC(&prom);
1282         char type[16], *path;
1283         phandle node;
1284         ihandle ih;
1285         int i;
1286
1287         static unsigned char default_colors[] = {
1288                 0x00, 0x00, 0x00,
1289                 0x00, 0x00, 0xaa,
1290                 0x00, 0xaa, 0x00,
1291                 0x00, 0xaa, 0xaa,
1292                 0xaa, 0x00, 0x00,
1293                 0xaa, 0x00, 0xaa,
1294                 0xaa, 0xaa, 0x00,
1295                 0xaa, 0xaa, 0xaa,
1296                 0x55, 0x55, 0x55,
1297                 0x55, 0x55, 0xff,
1298                 0x55, 0xff, 0x55,
1299                 0x55, 0xff, 0xff,
1300                 0xff, 0x55, 0x55,
1301                 0xff, 0x55, 0xff,
1302                 0xff, 0xff, 0x55,
1303                 0xff, 0xff, 0xff
1304         };
1305         const unsigned char *clut;
1306
1307         prom_printf("Looking for displays\n");
1308         for (node = 0; prom_next_node(&node); ) {
1309                 memset(type, 0, sizeof(type));
1310                 prom_getprop(node, "device_type", type, sizeof(type));
1311                 if (strcmp(type, RELOC("display")) != 0)
1312                         continue;
1313
1314                 /* It seems OF doesn't null-terminate the path :-( */
1315                 path = RELOC(prom_scratch);
1316                 memset(path, 0, PROM_SCRATCH_SIZE);
1317
1318                 /*
1319                  * leave some room at the end of the path for appending extra
1320                  * arguments
1321                  */
1322                 if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0)
1323                         continue;
1324                 prom_printf("found display   : %s, opening ... ", path);
1325                 
1326                 ih = call_prom("open", 1, 1, path);
1327                 if (ih == (ihandle)0 || ih == (ihandle)-1) {
1328                         prom_printf("failed\n");
1329                         continue;
1330                 }
1331
1332                 /* Success */
1333                 prom_printf("done\n");
1334                 prom_setprop(node, "linux,opened", NULL, 0);
1335
1336                 /*
1337                  * stdout wasn't a display node, pick the first we can find
1338                  * for btext
1339                  */
1340                 if (_prom->disp_node == 0)
1341                         _prom->disp_node = node;
1342
1343                 /* Setup a useable color table when the appropriate
1344                  * method is available. Should update this to set-colors */
1345                 clut = RELOC(default_colors);
1346                 for (i = 0; i < 32; i++, clut += 3)
1347                         if (prom_set_color(ih, i, clut[0], clut[1],
1348                                            clut[2]) != 0)
1349                                 break;
1350
1351 #ifdef CONFIG_LOGO_LINUX_CLUT224
1352                 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1353                 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1354                         if (prom_set_color(ih, i + 32, clut[0], clut[1],
1355                                            clut[2]) != 0)
1356                                 break;
1357 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
1358         }
1359 }
1360
1361
1362 /* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1363 static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1364                               unsigned long needed, unsigned long align)
1365 {
1366         unsigned long offset = reloc_offset();
1367         void *ret;
1368
1369         *mem_start = _ALIGN(*mem_start, align);
1370         while ((*mem_start + needed) > *mem_end) {
1371                 unsigned long room, chunk;
1372
1373                 prom_debug("Chunk exhausted, claiming more at %x...\n",
1374                            RELOC(alloc_bottom));
1375                 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1376                 if (room > DEVTREE_CHUNK_SIZE)
1377                         room = DEVTREE_CHUNK_SIZE;
1378                 if (room < PAGE_SIZE)
1379                         prom_panic("No memory for flatten_device_tree (no room)");
1380                 chunk = alloc_up(room, 0);
1381                 if (chunk == 0)
1382                         prom_panic("No memory for flatten_device_tree (claim failed)");
1383                 *mem_end = RELOC(alloc_top);
1384         }
1385
1386         ret = (void *)*mem_start;
1387         *mem_start += needed;
1388
1389         return ret;
1390 }
1391
1392 #define dt_push_token(token, mem_start, mem_end) \
1393         do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1394
1395 static unsigned long __init dt_find_string(char *str)
1396 {
1397         unsigned long offset = reloc_offset();
1398         char *s, *os;
1399
1400         s = os = (char *)RELOC(dt_string_start);
1401         s += 4;
1402         while (s <  (char *)RELOC(dt_string_end)) {
1403                 if (strcmp(s, str) == 0)
1404                         return s - os;
1405                 s += strlen(s) + 1;
1406         }
1407         return 0;
1408 }
1409
1410 static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
1411                                          unsigned long *mem_end)
1412 {
1413         unsigned long offset = reloc_offset();
1414         char *prev_name, *namep, *sstart;
1415         unsigned long soff;
1416         phandle child;
1417
1418         sstart =  (char *)RELOC(dt_string_start);
1419
1420         /* get and store all property names */
1421         prev_name = RELOC("");
1422         for (;;) {
1423                 
1424                 /* 32 is max len of name including nul. */
1425                 namep = make_room(mem_start, mem_end, 32, 1);
1426                 if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) {
1427                         /* No more nodes: unwind alloc */
1428                         *mem_start = (unsigned long)namep;
1429                         break;
1430                 }
1431                 soff = dt_find_string(namep);
1432                 if (soff != 0) {
1433                         *mem_start = (unsigned long)namep;
1434                         namep = sstart + soff;
1435                 } else {
1436                         /* Trim off some if we can */
1437                         *mem_start = (unsigned long)namep + strlen(namep) + 1;
1438                         RELOC(dt_string_end) = *mem_start;
1439                 }
1440                 prev_name = namep;
1441         }
1442
1443         /* do all our children */
1444         child = call_prom("child", 1, 1, node);
1445         while (child != (phandle)0) {
1446                 scan_dt_build_strings(child, mem_start, mem_end);
1447                 child = call_prom("peer", 1, 1, child);
1448         }
1449 }
1450
1451 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1452                                         unsigned long *mem_end)
1453 {
1454         int l, align;
1455         phandle child;
1456         char *namep, *prev_name, *sstart;
1457         unsigned long soff;
1458         unsigned char *valp;
1459         unsigned long offset = reloc_offset();
1460         char pname[32];
1461         char *path;
1462
1463         path = RELOC(prom_scratch);
1464
1465         dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1466
1467         /* get the node's full name */
1468         namep = (char *)*mem_start;
1469         l = call_prom("package-to-path", 3, 1, node,
1470                       namep, *mem_end - *mem_start);
1471         if (l >= 0) {
1472                 /* Didn't fit?  Get more room. */
1473                 if (l+1 > *mem_end - *mem_start) {
1474                         namep = make_room(mem_start, mem_end, l+1, 1);
1475                         call_prom("package-to-path", 3, 1, node, namep, l);
1476                 }
1477                 namep[l] = '\0';
1478                 *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
1479         }
1480
1481         /* get it again for debugging */
1482         memset(path, 0, PROM_SCRATCH_SIZE);
1483         call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1484
1485         /* get and store all properties */
1486         prev_name = RELOC("");
1487         sstart = (char *)RELOC(dt_string_start);
1488         for (;;) {
1489                 if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0)
1490                         break;
1491
1492                 /* find string offset */
1493                 soff = dt_find_string(pname);
1494                 if (soff == 0) {
1495                         prom_printf("WARNING: Can't find string index for <%s>, node %s\n",
1496                                     pname, path);
1497                         break;
1498                 }
1499                 prev_name = sstart + soff;
1500
1501                 /* get length */
1502                 l = call_prom("getproplen", 2, 1, node, pname);
1503
1504                 /* sanity checks */
1505                 if (l < 0)
1506                         continue;
1507                 if (l > MAX_PROPERTY_LENGTH) {
1508                         prom_printf("WARNING: ignoring large property ");
1509                         /* It seems OF doesn't null-terminate the path :-( */
1510                         prom_printf("[%s] ", path);
1511                         prom_printf("%s length 0x%x\n", pname, l);
1512                         continue;
1513                 }
1514
1515                 /* push property head */
1516                 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1517                 dt_push_token(l, mem_start, mem_end);
1518                 dt_push_token(soff, mem_start, mem_end);
1519
1520                 /* push property content */
1521                 align = (l >= 8) ? 8 : 4;
1522                 valp = make_room(mem_start, mem_end, l, align);
1523                 call_prom("getprop", 4, 1, node, pname, valp, l);
1524                 *mem_start = _ALIGN(*mem_start, 4);
1525         }
1526
1527         /* Add a "linux,phandle" property. */
1528         soff = dt_find_string(RELOC("linux,phandle"));
1529         if (soff == 0)
1530                 prom_printf("WARNING: Can't find string index for <linux-phandle>"
1531                             " node %s\n", path);
1532         else {
1533                 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1534                 dt_push_token(4, mem_start, mem_end);
1535                 dt_push_token(soff, mem_start, mem_end);
1536                 valp = make_room(mem_start, mem_end, 4, 4);
1537                 *(u32 *)valp = node;
1538         }
1539
1540         /* do all our children */
1541         child = call_prom("child", 1, 1, node);
1542         while (child != (phandle)0) {
1543                 scan_dt_build_struct(child, mem_start, mem_end);
1544                 child = call_prom("peer", 1, 1, child);
1545         }
1546
1547         dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1548 }
1549
1550 static void __init flatten_device_tree(void)
1551 {
1552         phandle root;
1553         unsigned long offset = reloc_offset();
1554         unsigned long mem_start, mem_end, room;
1555         struct boot_param_header *hdr;
1556         char *namep;
1557         u64 *rsvmap;
1558
1559         /*
1560          * Check how much room we have between alloc top & bottom (+/- a
1561          * few pages), crop to 4Mb, as this is our "chuck" size
1562          */
1563         room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1564         if (room > DEVTREE_CHUNK_SIZE)
1565                 room = DEVTREE_CHUNK_SIZE;
1566         prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1567
1568         /* Now try to claim that */
1569         mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1570         if (mem_start == 0)
1571                 prom_panic("Can't allocate initial device-tree chunk\n");
1572         mem_end = RELOC(alloc_top);
1573
1574         /* Get root of tree */
1575         root = call_prom("peer", 1, 1, (phandle)0);
1576         if (root == (phandle)0)
1577                 prom_panic ("couldn't get device tree root\n");
1578
1579         /* Build header and make room for mem rsv map */ 
1580         mem_start = _ALIGN(mem_start, 4);
1581         hdr = make_room(&mem_start, &mem_end, sizeof(struct boot_param_header), 4);
1582         RELOC(dt_header_start) = (unsigned long)hdr;
1583         rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1584
1585         /* Start of strings */
1586         mem_start = PAGE_ALIGN(mem_start);
1587         RELOC(dt_string_start) = mem_start;
1588         mem_start += 4; /* hole */
1589
1590         /* Add "linux,phandle" in there, we'll need it */
1591         namep = make_room(&mem_start, &mem_end, 16, 1);
1592         strcpy(namep, RELOC("linux,phandle"));
1593         mem_start = (unsigned long)namep + strlen(namep) + 1;
1594         RELOC(dt_string_end) = mem_start;
1595
1596         /* Build string array */
1597         prom_printf("Building dt strings...\n"); 
1598         scan_dt_build_strings(root, &mem_start, &mem_end);
1599
1600         /* Build structure */
1601         mem_start = PAGE_ALIGN(mem_start);
1602         RELOC(dt_struct_start) = mem_start;
1603         prom_printf("Building dt structure...\n"); 
1604         scan_dt_build_struct(root, &mem_start, &mem_end);
1605         dt_push_token(OF_DT_END, &mem_start, &mem_end);
1606         RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1607
1608         /* Finish header */
1609         hdr->magic = OF_DT_HEADER;
1610         hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1611         hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1612         hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1613         hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1614         hdr->version = OF_DT_VERSION;
1615         hdr->last_comp_version = 1;
1616
1617         /* Reserve the whole thing and copy the reserve map in, we
1618          * also bump mem_reserve_cnt to cause further reservations to
1619          * fail since it's too late.
1620          */
1621         reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1622         memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1623
1624 #ifdef DEBUG_PROM
1625         {
1626                 int i;
1627                 prom_printf("reserved memory map:\n");
1628                 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1629                         prom_printf("  %x - %x\n", RELOC(mem_reserve_map)[i].base,
1630                                     RELOC(mem_reserve_map)[i].size);
1631         }
1632 #endif
1633         RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1634
1635         prom_printf("Device tree strings 0x%x -> 0x%x\n",
1636                     RELOC(dt_string_start), RELOC(dt_string_end)); 
1637         prom_printf("Device tree struct  0x%x -> 0x%x\n",
1638                     RELOC(dt_struct_start), RELOC(dt_struct_end));
1639
1640  }
1641
1642 static void __init prom_find_boot_cpu(void)
1643 {
1644         unsigned long offset = reloc_offset();
1645         struct prom_t *_prom = PTRRELOC(&prom);
1646         u32 getprop_rval;
1647         ihandle prom_cpu;
1648         phandle cpu_pkg;
1649
1650         if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
1651                 prom_panic("cannot find boot cpu");
1652
1653         cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
1654
1655         prom_setprop(cpu_pkg, "linux,boot-cpu", NULL, 0);
1656         prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
1657         _prom->cpu = getprop_rval;
1658
1659         prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
1660 }
1661
1662 static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1663 {
1664 #ifdef CONFIG_BLK_DEV_INITRD
1665         unsigned long offset = reloc_offset();
1666         struct prom_t *_prom = PTRRELOC(&prom);
1667
1668         if ( r3 && r4 && r4 != 0xdeadbeef) {
1669                 u64 val;
1670
1671                 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1672                 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1673
1674                 val = (u64)RELOC(prom_initrd_start);
1675                 prom_setprop(_prom->chosen, "linux,initrd-start", &val, sizeof(val));
1676                 val = (u64)RELOC(prom_initrd_end);
1677                 prom_setprop(_prom->chosen, "linux,initrd-end", &val, sizeof(val));
1678
1679                 reserve_mem(RELOC(prom_initrd_start),
1680                             RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
1681
1682                 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
1683                 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
1684         }
1685 #endif /* CONFIG_BLK_DEV_INITRD */
1686 }
1687
1688 /*
1689  * We enter here early on, when the Open Firmware prom is still
1690  * handling exceptions and the MMU hash table for us.
1691  */
1692
1693 unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
1694                                unsigned long r6, unsigned long r7)
1695 {       
1696         unsigned long offset = reloc_offset();
1697         struct prom_t *_prom = PTRRELOC(&prom);
1698         unsigned long phys = KERNELBASE - offset;
1699         u32 getprop_rval;
1700         
1701         /*
1702          * First zero the BSS
1703          */
1704         memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
1705
1706         /*
1707          * Init interface to Open Firmware, get some node references,
1708          * like /chosen
1709          */
1710         prom_init_client_services(pp);
1711
1712         /*
1713          * Init prom stdout device
1714          */
1715         prom_init_stdout();
1716         prom_debug("klimit=0x%x\n", RELOC(klimit));
1717         prom_debug("offset=0x%x\n", offset);
1718
1719         /*
1720          * Check for an initrd
1721          */
1722         prom_check_initrd(r3, r4);
1723
1724         /*
1725          * Get default machine type. At this point, we do not differenciate
1726          * between pSeries SMP and pSeries LPAR
1727          */
1728         RELOC(of_platform) = prom_find_machine_type();
1729         getprop_rval = RELOC(of_platform);
1730         prom_setprop(_prom->chosen, "linux,platform",
1731                      &getprop_rval, sizeof(getprop_rval));
1732
1733         /*
1734          * On pSeries, copy the CPU hold code
1735          */
1736         if (RELOC(of_platform) & PLATFORM_PSERIES)
1737                 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1738
1739         /*
1740          * Get memory cells format
1741          */
1742         getprop_rval = 1;
1743         prom_getprop(_prom->root, "#size-cells",
1744                      &getprop_rval, sizeof(getprop_rval));
1745         _prom->root_size_cells = getprop_rval;
1746         getprop_rval = 2;
1747         prom_getprop(_prom->root, "#address-cells",
1748                      &getprop_rval, sizeof(getprop_rval));
1749         _prom->root_addr_cells = getprop_rval;
1750
1751         /*
1752          * Do early parsing of command line
1753          */
1754         early_cmdline_parse();
1755
1756         /*
1757          * Initialize memory management within prom_init
1758          */
1759         prom_init_mem();
1760
1761         /*
1762          * Determine which cpu is actually running right _now_
1763          */
1764         prom_find_boot_cpu();
1765
1766         /* 
1767          * Initialize display devices
1768          */
1769         prom_check_displays();
1770
1771         /*
1772          * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
1773          * that uses the allocator, we need to make sure we get the top of memory
1774          * available for us here...
1775          */
1776         if (RELOC(of_platform) == PLATFORM_PSERIES)
1777                 prom_initialize_tce_table();
1778
1779         /*
1780          * On non-powermacs, try to instantiate RTAS and puts all CPUs
1781          * in spin-loops. PowerMacs don't have a working RTAS and use
1782          * a different way to spin CPUs
1783          */
1784         if (RELOC(of_platform) != PLATFORM_POWERMAC) {
1785                 prom_instantiate_rtas();
1786                 prom_hold_cpus();
1787         }
1788
1789         /*
1790          * Fill in some infos for use by the kernel later on
1791          */
1792         if (RELOC(ppc64_iommu_off))
1793                 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
1794
1795         if (RELOC(iommu_force_on))
1796                 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
1797
1798         if (RELOC(prom_memory_limit))
1799                 prom_setprop(_prom->chosen, "linux,memory-limit",
1800                         PTRRELOC(&prom_memory_limit), sizeof(RELOC(prom_memory_limit)));
1801
1802         if (RELOC(prom_tce_alloc_start)) {
1803                 prom_setprop(_prom->chosen, "linux,tce-alloc-start",
1804                         PTRRELOC(&prom_tce_alloc_start), sizeof(RELOC(prom_tce_alloc_start)));
1805                 prom_setprop(_prom->chosen, "linux,tce-alloc-end",
1806                         PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
1807         }
1808
1809         /*
1810          * Now finally create the flattened device-tree
1811          */
1812         prom_printf("copying OF device tree ...\n");
1813         flatten_device_tree();
1814
1815         /* in case stdin is USB and still active on IBM machines... */
1816         prom_close_stdin();
1817
1818         /*
1819          * Call OF "quiesce" method to shut down pending DMA's from
1820          * devices etc...
1821          */
1822         prom_printf("Calling quiesce ...\n");
1823         call_prom("quiesce", 0, 0);
1824
1825         /*
1826          * And finally, call the kernel passing it the flattened device
1827          * tree and NULL as r5, thus triggering the new entry point which
1828          * is common to us and kexec
1829          */
1830         prom_printf("returning from prom_init\n");
1831         prom_debug("->dt_header_start=0x%x\n", RELOC(dt_header_start));
1832         prom_debug("->phys=0x%x\n", phys);
1833
1834         __start(RELOC(dt_header_start), phys, 0);
1835
1836         return 0;
1837 }
1838