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