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