This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc64 / kernel / prom.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 #if 0
19 #define DEBUG_PROM
20 #endif
21
22 #include <stdarg.h>
23 #include <linux/config.h>
24 #include <linux/kernel.h>
25 #include <linux/string.h>
26 #include <linux/init.h>
27 #include <linux/version.h>
28 #include <linux/threads.h>
29 #include <linux/spinlock.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <linux/proc_fs.h>
33 #include <linux/stringify.h>
34 #include <linux/delay.h>
35 #include <linux/initrd.h>
36 #include <asm/prom.h>
37 #include <asm/rtas.h>
38 #include <asm/lmb.h>
39 #include <asm/abs_addr.h>
40 #include <asm/page.h>
41 #include <asm/processor.h>
42 #include <asm/irq.h>
43 #include <asm/io.h>
44 #include <asm/smp.h>
45 #include <asm/system.h>
46 #include <asm/mmu.h>
47 #include <asm/pgtable.h>
48 #include <asm/bitops.h>
49 #include <asm/naca.h>
50 #include <asm/pci.h>
51 #include <asm/iommu.h>
52 #include <asm/bootinfo.h>
53 #include <asm/ppcdebug.h>
54 #include <asm/btext.h>
55 #include <asm/sections.h>
56 #include <asm/machdep.h>
57 #include "open_pic.h"
58
59 #ifdef CONFIG_LOGO_LINUX_CLUT224
60 #include <linux/linux_logo.h>
61 extern const struct linux_logo logo_linux_clut224;
62 #endif
63
64 /*
65  * Properties whose value is longer than this get excluded from our
66  * copy of the device tree. This value does need to be big enough to
67  * ensure that we don't lose things like the interrupt-map property
68  * on a PCI-PCI bridge.
69  */
70 #define MAX_PROPERTY_LENGTH     (1UL * 1024 * 1024)
71
72 /*
73  * prom_init() is called very early on, before the kernel text
74  * and data have been mapped to KERNELBASE.  At this point the code
75  * is running at whatever address it has been loaded at, so
76  * references to extern and static variables must be relocated
77  * explicitly.  The procedure reloc_offset() returns the address
78  * we're currently running at minus the address we were linked at.
79  * (Note that strings count as static variables.)
80  *
81  * Because OF may have mapped I/O devices into the area starting at
82  * KERNELBASE, particularly on CHRP machines, we can't safely call
83  * OF once the kernel has been mapped to KERNELBASE.  Therefore all
84  * OF calls should be done within prom_init(), and prom_init()
85  * and all routines called within it must be careful to relocate
86  * references as necessary.
87  *
88  * Note that the bss is cleared *after* prom_init runs, so we have
89  * to make sure that any static or extern variables it accesses
90  * are put in the data segment.
91  */
92
93
94 #define PROM_BUG() do { \
95         prom_print(RELOC("kernel BUG at ")); \
96         prom_print(RELOC(__FILE__)); \
97         prom_print(RELOC(":")); \
98         prom_print_hex(__LINE__); \
99         prom_print(RELOC("!\n")); \
100         __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
101 } while (0)
102
103
104
105 struct pci_reg_property {
106         struct pci_address addr;
107         u32 size_hi;
108         u32 size_lo;
109 };
110
111
112 struct isa_reg_property {
113         u32 space;
114         u32 address;
115         u32 size;
116 };
117
118 struct pci_intr_map {
119         struct pci_address addr;
120         u32 dunno;
121         phandle int_ctrler;
122         u32 intr;
123 };
124
125
126 typedef unsigned long interpret_func(struct device_node *, unsigned long,
127                                      int, int, int);
128
129 #ifndef FB_MAX                  /* avoid pulling in all of the fb stuff */
130 #define FB_MAX  8
131 #endif
132
133 /* prom structure */
134 struct prom_t prom;
135
136 char *prom_display_paths[FB_MAX] __initdata = { 0, };
137 phandle prom_display_nodes[FB_MAX] __initdata;
138 unsigned int prom_num_displays = 0;
139 char *of_stdout_device = 0;
140
141 static int iommu_force_on;
142 int ppc64_iommu_off;
143
144 extern struct rtas_t rtas;
145 extern unsigned long klimit;
146 extern struct lmb lmb;
147
148 #define MAX_PHB (32 * 6)  /* 32 drawers * 6 PHBs/drawer */
149 struct of_tce_table of_tce_table[MAX_PHB + 1];
150
151 char *bootpath = 0;
152 char *bootdevice = 0;
153
154 int boot_cpuid = 0;
155 #define MAX_CPU_THREADS 2
156
157 struct device_node *allnodes = 0;
158 /* use when traversing tree through the allnext, child, sibling,
159  * or parent members of struct device_node.
160  */
161 static rwlock_t devtree_lock = RW_LOCK_UNLOCKED;
162
163 extern unsigned long reloc_offset(void);
164
165 extern void enter_prom(struct prom_args *args);
166 extern void copy_and_flush(unsigned long dest, unsigned long src,
167                            unsigned long size, unsigned long offset);
168
169 unsigned long dev_tree_size;
170 unsigned long _get_PIR(void);
171
172 #ifdef CONFIG_HMT
173 struct {
174         unsigned int pir;
175         unsigned int threadid;
176 } hmt_thread_data[NR_CPUS];
177 #endif /* CONFIG_HMT */
178
179 char testString[] = "LINUX\n"; 
180
181
182 /* This is the one and *ONLY* place where we actually call open
183  * firmware from, since we need to make sure we're running in 32b
184  * mode when we do.  We switch back to 64b mode upon return.
185  */
186
187 #define PROM_ERROR      (0x00000000fffffffful)
188
189 static unsigned long __init call_prom(const char *service, int nargs, int nret, ...)
190 {
191         int i;
192         unsigned long offset = reloc_offset();
193         struct prom_t *_prom = PTRRELOC(&prom);
194         va_list list;
195         
196         _prom->args.service = (u32)LONG_LSW(service);
197         _prom->args.nargs = nargs;
198         _prom->args.nret = nret;
199         _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
200
201         va_start(list, nret);
202         for (i=0; i < nargs ;i++)
203                 _prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long));
204         va_end(list);
205
206         for (i=0; i < nret ;i++)
207                 _prom->args.rets[i] = 0;
208
209         enter_prom(&_prom->args);
210
211         return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0);
212 }
213
214
215 static void __init prom_print(const char *msg)
216 {
217         const char *p, *q;
218         unsigned long offset = reloc_offset();
219         struct prom_t *_prom = PTRRELOC(&prom);
220
221         if (_prom->stdout == 0)
222                 return;
223
224         for (p = msg; *p != 0; p = q) {
225                 for (q = p; *q != 0 && *q != '\n'; ++q)
226                         ;
227                 if (q > p)
228                         call_prom(RELOC("write"), 3, 1, _prom->stdout,
229                                   p, q - p);
230                 if (*q != 0) {
231                         ++q;
232                         call_prom(RELOC("write"), 3, 1, _prom->stdout,
233                                   RELOC("\r\n"), 2);
234                 }
235         }
236 }
237
238
239 static void __init prom_print_hex(unsigned long val)
240 {
241         int i, nibbles = sizeof(val)*2;
242         char buf[sizeof(val)*2+1];
243
244         for (i = nibbles-1;  i >= 0;  i--) {
245                 buf[i] = (val & 0xf) + '0';
246                 if (buf[i] > '9')
247                     buf[i] += ('a'-'0'-10);
248                 val >>= 4;
249         }
250         buf[nibbles] = '\0';
251         prom_print(buf);
252 }
253
254
255 static void __init prom_print_nl(void)
256 {
257         unsigned long offset = reloc_offset();
258         prom_print(RELOC("\n"));
259 }
260
261
262 static void __init prom_panic(const char *reason)
263 {
264         unsigned long offset = reloc_offset();
265
266         prom_print(reason);
267         /* ToDo: should put up an SRC here */
268         call_prom(RELOC("exit"), 0, 0);
269
270         for (;;)                        /* should never get here */
271                 ;
272 }
273
274
275 static int __init prom_next_node(phandle *nodep)
276 {
277         phandle node;
278         unsigned long offset = reloc_offset();
279
280         if ((node = *nodep) != 0
281             && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
282                 return 1;
283         if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
284                 return 1;
285         for (;;) {
286                 if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
287                         return 0;
288                 if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
289                         return 1;
290         }
291 }
292
293
294 static void __init prom_initialize_naca(void)
295 {
296         phandle node;
297         char type[64];
298         unsigned long num_cpus = 0;
299         unsigned long offset = reloc_offset();
300         struct prom_t *_prom = PTRRELOC(&prom);
301         struct naca_struct *_naca = RELOC(naca);
302         struct systemcfg *_systemcfg = RELOC(systemcfg);
303
304         /* NOTE: _naca->debug_switch is already initialized. */
305 #ifdef DEBUG_PROM
306         prom_print(RELOC("prom_initialize_naca: start...\n"));
307 #endif
308
309         _naca->pftSize = 0;     /* ilog2 of htab size.  computed below. */
310
311         for (node = 0; prom_next_node(&node); ) {
312                 type[0] = 0;
313                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
314                           type, sizeof(type));
315
316                 if (!strcmp(type, RELOC("cpu"))) {
317                         num_cpus += 1;
318
319                         /* We're assuming *all* of the CPUs have the same
320                          * d-cache and i-cache sizes... -Peter
321                          */
322                         if ( num_cpus == 1 ) {
323                                 u32 size, lsize;
324
325                                 call_prom(RELOC("getprop"), 4, 1, node,
326                                           RELOC("d-cache-size"),
327                                           &size, sizeof(size));
328
329                                 if (_systemcfg->platform == PLATFORM_POWERMAC)
330                                         call_prom(RELOC("getprop"), 4, 1, node,
331                                                   RELOC("d-cache-block-size"),
332                                                   &lsize, sizeof(lsize));
333                                 else
334                                         call_prom(RELOC("getprop"), 4, 1, node,
335                                                   RELOC("d-cache-line-size"),
336                                                   &lsize, sizeof(lsize));
337
338                                 _systemcfg->dCacheL1Size = size;
339                                 _systemcfg->dCacheL1LineSize = lsize;
340                                 _naca->dCacheL1LogLineSize = __ilog2(lsize);
341                                 _naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize;
342
343                                 call_prom(RELOC("getprop"), 4, 1, node,
344                                           RELOC("i-cache-size"),
345                                           &size, sizeof(size));
346
347                                 if (_systemcfg->platform == PLATFORM_POWERMAC)
348                                         call_prom(RELOC("getprop"), 4, 1, node,
349                                                   RELOC("i-cache-block-size"),
350                                                   &lsize, sizeof(lsize));
351                                 else
352                                         call_prom(RELOC("getprop"), 4, 1, node,
353                                                   RELOC("i-cache-line-size"),
354                                                   &lsize, sizeof(lsize));
355
356                                 _systemcfg->iCacheL1Size = size;
357                                 _systemcfg->iCacheL1LineSize = lsize;
358                                 _naca->iCacheL1LogLineSize = __ilog2(lsize);
359                                 _naca->iCacheL1LinesPerPage = PAGE_SIZE/lsize;
360
361                                 if (_systemcfg->platform == PLATFORM_PSERIES_LPAR) {
362                                         u32 pft_size[2];
363                                         call_prom(RELOC("getprop"), 4, 1, node, 
364                                                   RELOC("ibm,pft-size"),
365                                                   &pft_size, sizeof(pft_size));
366                                 /* pft_size[0] is the NUMA CEC cookie */
367                                         _naca->pftSize = pft_size[1];
368                                 }
369                         }
370                 } else if (!strcmp(type, RELOC("serial"))) {
371                         phandle isa, pci;
372                         struct isa_reg_property reg;
373                         union pci_range ranges;
374
375                         if (_systemcfg->platform == PLATFORM_POWERMAC)
376                                 continue;
377                         type[0] = 0;
378                         call_prom(RELOC("getprop"), 4, 1, node,
379                                   RELOC("ibm,aix-loc"), type, sizeof(type));
380
381                         if (strcmp(type, RELOC("S1")))
382                                 continue;
383
384                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
385                                   &reg, sizeof(reg));
386
387                         isa = call_prom(RELOC("parent"), 1, 1, node);
388                         if (!isa)
389                                 PROM_BUG();
390                         pci = call_prom(RELOC("parent"), 1, 1, isa);
391                         if (!pci)
392                                 PROM_BUG();
393
394                         call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"),
395                                   &ranges, sizeof(ranges));
396
397                         if ( _prom->encode_phys_size == 32 )
398                                 _naca->serialPortAddr = ranges.pci32.phys+reg.address;
399                         else {
400                                 _naca->serialPortAddr = 
401                                         ((((unsigned long)ranges.pci64.phys_hi) << 32) |
402                                          (ranges.pci64.phys_lo)) + reg.address;
403                         }
404                 }
405         }
406
407         if (_systemcfg->platform == PLATFORM_POWERMAC)
408                 _naca->interrupt_controller = IC_OPEN_PIC;
409         else {
410                 _naca->interrupt_controller = IC_INVALID;
411                 for (node = 0; prom_next_node(&node); ) {
412                         type[0] = 0;
413                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"),
414                                   type, sizeof(type));
415                         if (strcmp(type, RELOC("interrupt-controller")))
416                                 continue;
417                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
418                                   type, sizeof(type));
419                         if (strstr(type, RELOC("open-pic")))
420                                 _naca->interrupt_controller = IC_OPEN_PIC;
421                         else if (strstr(type, RELOC("ppc-xicp")))
422                                 _naca->interrupt_controller = IC_PPC_XIC;
423                         else
424                                 prom_print(RELOC("prom: failed to recognize"
425                                                  " interrupt-controller\n"));
426                         break;
427                 }
428         }
429
430         if (_naca->interrupt_controller == IC_INVALID) {
431                 prom_print(RELOC("prom: failed to find interrupt-controller\n"));
432                 PROM_BUG();
433         }
434
435         /* We gotta have at least 1 cpu... */
436         if ( (_systemcfg->processorCount = num_cpus) < 1 )
437                 PROM_BUG();
438
439         _systemcfg->physicalMemorySize = lmb_phys_mem_size();
440
441         if (_systemcfg->platform == PLATFORM_PSERIES ||
442             _systemcfg->platform == PLATFORM_POWERMAC) {
443                 unsigned long rnd_mem_size, pteg_count;
444
445                 /* round mem_size up to next power of 2 */
446                 rnd_mem_size = 1UL << __ilog2(_systemcfg->physicalMemorySize);
447                 if (rnd_mem_size < _systemcfg->physicalMemorySize)
448                         rnd_mem_size <<= 1;
449
450                 /* # pages / 2 */
451                 pteg_count = (rnd_mem_size >> (12 + 1));
452
453                 _naca->pftSize = __ilog2(pteg_count << 7);
454         }
455
456         if (_naca->pftSize == 0) {
457                 prom_print(RELOC("prom: failed to compute pftSize!\n"));
458                 PROM_BUG();
459         }
460
461         /* 
462          * Hardcode to GP size.  I am not sure where to get this info
463          * in general, as there does not appear to be a slb-size OF
464          * entry.  At least in Condor and earlier.  DRENG 
465          */
466         _naca->slb_size = 64;
467
468         /* Add an eye catcher and the systemcfg layout version number */
469         strcpy(_systemcfg->eye_catcher, RELOC("SYSTEMCFG:PPC64"));
470         _systemcfg->version.major = SYSTEMCFG_MAJOR;
471         _systemcfg->version.minor = SYSTEMCFG_MINOR;
472         _systemcfg->processor = _get_PVR();
473
474 #ifdef DEBUG_PROM
475         prom_print(RELOC("systemcfg->processorCount       = 0x"));
476         prom_print_hex(_systemcfg->processorCount);
477         prom_print_nl();
478
479         prom_print(RELOC("systemcfg->physicalMemorySize   = 0x"));
480         prom_print_hex(_systemcfg->physicalMemorySize);
481         prom_print_nl();
482
483         prom_print(RELOC("naca->pftSize                   = 0x"));
484         prom_print_hex(_naca->pftSize);
485         prom_print_nl();
486
487         prom_print(RELOC("systemcfg->dCacheL1LineSize     = 0x"));
488         prom_print_hex(_systemcfg->dCacheL1LineSize);
489         prom_print_nl();
490
491         prom_print(RELOC("systemcfg->iCacheL1LineSize     = 0x"));
492         prom_print_hex(_systemcfg->iCacheL1LineSize);
493         prom_print_nl();
494
495         prom_print(RELOC("naca->serialPortAddr            = 0x"));
496         prom_print_hex(_naca->serialPortAddr);
497         prom_print_nl();
498
499         prom_print(RELOC("naca->interrupt_controller      = 0x"));
500         prom_print_hex(_naca->interrupt_controller);
501         prom_print_nl();
502
503         prom_print(RELOC("systemcfg->platform             = 0x"));
504         prom_print_hex(_systemcfg->platform);
505         prom_print_nl();
506
507         prom_print(RELOC("prom_initialize_naca: end...\n"));
508 #endif
509 }
510
511
512 static void __init early_cmdline_parse(void)
513 {
514         unsigned long offset = reloc_offset();
515         char *opt;
516 #ifndef CONFIG_PMAC_DART
517         struct systemcfg *_systemcfg = RELOC(systemcfg);
518 #endif
519
520         opt = strstr(RELOC(cmd_line), RELOC("iommu="));
521         if (opt) {
522                 prom_print(RELOC("opt is:"));
523                 prom_print(opt);
524                 prom_print(RELOC("\n"));
525                 opt += 6;
526                 while (*opt && *opt == ' ')
527                         opt++;
528                 if (!strncmp(opt, RELOC("off"), 3))
529                         RELOC(ppc64_iommu_off) = 1;
530                 else if (!strncmp(opt, RELOC("force"), 5))
531                         RELOC(iommu_force_on) = 1;
532         }
533
534 #ifndef CONFIG_PMAC_DART
535         if (_systemcfg->platform == PLATFORM_POWERMAC) {
536                 RELOC(ppc64_iommu_off) = 1;
537                 prom_print(RELOC("DART disabled on PowerMac !\n"));
538         }
539 #endif
540 }
541
542 #ifdef DEBUG_PROM
543 void prom_dump_lmb(void)
544 {
545         unsigned long i;
546         unsigned long offset = reloc_offset();
547         struct lmb *_lmb  = PTRRELOC(&lmb);
548
549         prom_print(RELOC("\nprom_dump_lmb:\n"));
550         prom_print(RELOC("    memory.cnt                  = 0x"));
551         prom_print_hex(_lmb->memory.cnt);
552         prom_print_nl();
553         prom_print(RELOC("    memory.size                 = 0x"));
554         prom_print_hex(_lmb->memory.size);
555         prom_print_nl();
556         for (i=0; i < _lmb->memory.cnt ;i++) {
557                 prom_print(RELOC("    memory.region[0x"));
558                 prom_print_hex(i);
559                 prom_print(RELOC("].base       = 0x"));
560                 prom_print_hex(_lmb->memory.region[i].base);
561                 prom_print_nl();
562                 prom_print(RELOC("                      .physbase = 0x"));
563                 prom_print_hex(_lmb->memory.region[i].physbase);
564                 prom_print_nl();
565                 prom_print(RELOC("                      .size     = 0x"));
566                 prom_print_hex(_lmb->memory.region[i].size);
567                 prom_print_nl();
568         }
569
570         prom_print_nl();
571         prom_print(RELOC("    reserved.cnt                  = 0x"));
572         prom_print_hex(_lmb->reserved.cnt);
573         prom_print_nl();
574         prom_print(RELOC("    reserved.size                 = 0x"));
575         prom_print_hex(_lmb->reserved.size);
576         prom_print_nl();
577         for (i=0; i < _lmb->reserved.cnt ;i++) {
578                 prom_print(RELOC("    reserved.region[0x"));
579                 prom_print_hex(i);
580                 prom_print(RELOC("].base       = 0x"));
581                 prom_print_hex(_lmb->reserved.region[i].base);
582                 prom_print_nl();
583                 prom_print(RELOC("                      .physbase = 0x"));
584                 prom_print_hex(_lmb->reserved.region[i].physbase);
585                 prom_print_nl();
586                 prom_print(RELOC("                      .size     = 0x"));
587                 prom_print_hex(_lmb->reserved.region[i].size);
588                 prom_print_nl();
589         }
590 }
591 #endif /* DEBUG_PROM */
592
593 static void __init prom_initialize_lmb(void)
594 {
595         phandle node;
596         char type[64];
597         unsigned long i, offset = reloc_offset();
598         struct prom_t *_prom = PTRRELOC(&prom);
599         struct systemcfg *_systemcfg = RELOC(systemcfg);
600         union lmb_reg_property reg;
601         unsigned long lmb_base, lmb_size;
602         unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;
603
604         lmb_init();
605
606         /* XXX Quick HACK. Proper fix is to drop those structures and properly use
607          * #address-cells. PowerMac has #size-cell set to 1 and #address-cells to 2
608          */
609         if (_systemcfg->platform == PLATFORM_POWERMAC)
610                 bytes_per_reg = 12;
611
612         for (node = 0; prom_next_node(&node); ) {
613                 type[0] = 0;
614                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
615                           type, sizeof(type));
616
617                 if (strcmp(type, RELOC("memory")))
618                         continue;
619
620                 num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
621                         &reg, sizeof(reg)) / bytes_per_reg;
622
623                 for (i=0; i < num_regs ;i++) {
624                         if (_systemcfg->platform == PLATFORM_POWERMAC) {
625                                 lmb_base = ((unsigned long)reg.addrPM[i].address_hi) << 32;
626                                 lmb_base |= (unsigned long)reg.addrPM[i].address_lo;
627                                 lmb_size = reg.addrPM[i].size;
628                         } else if (_prom->encode_phys_size == 32) {
629                                 lmb_base = reg.addr32[i].address;
630                                 lmb_size = reg.addr32[i].size;
631                         } else {
632                                 lmb_base = reg.addr64[i].address;
633                                 lmb_size = reg.addr64[i].size;
634                         }
635
636                         /* We limit memory to 2GB if the IOMMU is off */
637                         if (RELOC(ppc64_iommu_off)) {
638                                 if (lmb_base >= 0x80000000UL)
639                                         continue;
640
641                                 if ((lmb_base + lmb_size) > 0x80000000UL)
642                                         lmb_size = 0x80000000UL - lmb_base;
643                         }
644
645                         if (lmb_add(lmb_base, lmb_size) < 0)
646                                 prom_print(RELOC("Too many LMB's, discarding this one...\n"));
647                 }
648
649         }
650
651         lmb_analyze();
652 #ifdef DEBUG_PROM
653         prom_dump_lmb();
654 #endif /* DEBUG_PROM */
655 }
656
657 static char hypertas_funcs[1024];
658
659 static void __init
660 prom_instantiate_rtas(void)
661 {
662         unsigned long offset = reloc_offset();
663         struct prom_t *_prom = PTRRELOC(&prom);
664         struct rtas_t *_rtas = PTRRELOC(&rtas);
665         struct systemcfg *_systemcfg = RELOC(systemcfg);
666         ihandle prom_rtas;
667         u32 getprop_rval;
668
669 #ifdef DEBUG_PROM
670         prom_print(RELOC("prom_instantiate_rtas: start...\n"));
671 #endif
672         prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
673         if (prom_rtas != (ihandle) -1) {
674                 unsigned long x;
675                 x = call_prom(RELOC("getprop"),
676                                   4, 1, prom_rtas,
677                                   RELOC("ibm,hypertas-functions"), 
678                                   hypertas_funcs, 
679                               sizeof(hypertas_funcs));
680
681                 if (x != PROM_ERROR) {
682                         prom_print(RELOC("Hypertas detected, assuming LPAR !\n"));
683                         _systemcfg->platform = PLATFORM_PSERIES_LPAR;
684                 }
685
686                 call_prom(RELOC("getprop"), 
687                           4, 1, prom_rtas,
688                           RELOC("rtas-size"), 
689                           &getprop_rval, 
690                           sizeof(getprop_rval));
691                 _rtas->size = getprop_rval;
692                 prom_print(RELOC("instantiating rtas"));
693                 if (_rtas->size != 0) {
694                         unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
695
696                         /* Grab some space within the first RTAS_INSTANTIATE_MAX bytes
697                          * of physical memory (or within the RMO region) because RTAS
698                          * runs in 32-bit mode and relocate off.
699                          */
700                         if ( _systemcfg->platform == PLATFORM_PSERIES_LPAR ) {
701                                 struct lmb *_lmb  = PTRRELOC(&lmb);
702                                 rtas_region = min(_lmb->rmo_size, RTAS_INSTANTIATE_MAX);
703                         }
704
705                         _rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region);
706
707                         prom_print(RELOC(" at 0x"));
708                         prom_print_hex(_rtas->base);
709
710                         prom_rtas = (ihandle)call_prom(RELOC("open"), 
711                                                 1, 1, RELOC("/rtas"));
712                         prom_print(RELOC("..."));
713
714                         if (call_prom(RELOC("call-method"), 3, 2,
715                                                       RELOC("instantiate-rtas"),
716                                                       prom_rtas,
717                                                       _rtas->base) != PROM_ERROR) {
718                                 _rtas->entry = (long)_prom->args.rets[1];
719                         }
720                         RELOC(rtas_rmo_buf)
721                                 = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE,
722                                                         rtas_region);
723                 }
724
725                 if (_rtas->entry <= 0) {
726                         prom_print(RELOC(" failed\n"));
727                 } else {
728                         prom_print(RELOC(" done\n"));
729                 }
730
731 #ifdef DEBUG_PROM
732                 prom_print(RELOC("rtas->base                 = 0x"));
733                 prom_print_hex(_rtas->base);
734                 prom_print_nl();
735                 prom_print(RELOC("rtas->entry                = 0x"));
736                 prom_print_hex(_rtas->entry);
737                 prom_print_nl();
738                 prom_print(RELOC("rtas->size                 = 0x"));
739                 prom_print_hex(_rtas->size);
740                 prom_print_nl();
741 #endif
742         }
743 #ifdef DEBUG_PROM
744         prom_print(RELOC("prom_instantiate_rtas: end...\n"));
745 #endif
746 }
747
748
749 #ifdef CONFIG_PMAC_DART
750 static void __init prom_initialize_dart_table(void)
751 {
752         unsigned long offset = reloc_offset();
753         extern unsigned long dart_tablebase;
754         extern unsigned long dart_tablesize;
755
756         /* Only reserve DART space if machine has more than 2GB of RAM
757          * or if requested with iommu=on on cmdline.
758          */
759         if (lmb_end_of_DRAM() <= 0x80000000ull && !RELOC(iommu_force_on))
760                 return;
761
762         /* 512 pages (2MB) is max DART tablesize. */
763         RELOC(dart_tablesize) = 1UL << 21;
764         /* 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
765          * will blow up an entire large page anyway in the kernel mapping
766          */
767         RELOC(dart_tablebase) = (unsigned long)
768                 abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
769
770         prom_print(RELOC("Dart at: "));
771         prom_print_hex(RELOC(dart_tablebase));
772         prom_print(RELOC("\n"));
773 }
774 #endif /* CONFIG_PMAC_DART */
775
776 static void __init prom_initialize_tce_table(void)
777 {
778         phandle node;
779         ihandle phb_node;
780         unsigned long offset = reloc_offset();
781         char compatible[64], path[64], type[64], model[64];
782         unsigned long i, table = 0;
783         unsigned long base, vbase, align;
784         unsigned int minalign, minsize;
785         struct of_tce_table *prom_tce_table = RELOC(of_tce_table);
786         unsigned long tce_entry, *tce_entryp;
787
788         if (RELOC(ppc64_iommu_off))
789                 return;
790
791 #ifdef DEBUG_PROM
792         prom_print(RELOC("starting prom_initialize_tce_table\n"));
793 #endif
794
795         /* Search all nodes looking for PHBs. */
796         for (node = 0; prom_next_node(&node); ) {
797                 if (table == MAX_PHB) {
798                         prom_print(RELOC("WARNING: PCI host bridge ignored, "
799                                          "need to increase MAX_PHB\n"));
800                         continue;
801                 }
802
803                 compatible[0] = 0;
804                 type[0] = 0;
805                 model[0] = 0;
806                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
807                           compatible, sizeof(compatible));
808                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
809                           type, sizeof(type));
810                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"),
811                           model, sizeof(model));
812
813                 /* Keep the old logic in tack to avoid regression. */
814                 if (compatible[0] != 0) {
815                         if((strstr(compatible, RELOC("python")) == NULL) &&
816                            (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
817                            (strstr(compatible, RELOC("Winnipeg")) == NULL))
818                                 continue;
819                 } else if (model[0] != 0) {
820                         if ((strstr(model, RELOC("ython")) == NULL) &&
821                             (strstr(model, RELOC("peedwagon")) == NULL) &&
822                             (strstr(model, RELOC("innipeg")) == NULL))
823                                 continue;
824                 }
825
826                 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) {
827                         continue;
828                 }
829
830                 if (call_prom(RELOC("getprop"), 4, 1, node, 
831                              RELOC("tce-table-minalign"), &minalign, 
832                              sizeof(minalign)) == PROM_ERROR) {
833                         minalign = 0;
834                 }
835
836                 if (call_prom(RELOC("getprop"), 4, 1, node, 
837                              RELOC("tce-table-minsize"), &minsize, 
838                              sizeof(minsize)) == PROM_ERROR) {
839                         minsize = 4UL << 20;
840                 }
841
842                 /*
843                  * Even though we read what OF wants, we just set the table
844                  * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
845                  * By doing this, we avoid the pitfalls of trying to DMA to
846                  * MMIO space and the DMA alias hole.
847                  *
848                  * On POWER4, firmware sets the TCE region by assuming
849                  * each TCE table is 8MB. Using this memory for anything
850                  * else will impact performance, so we always allocate 8MB.
851                  * Anton
852                  */
853                 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
854                         minsize = 8UL << 20;
855                 else
856                         minsize = 4UL << 20;
857
858                 /* Align to the greater of the align or size */
859                 align = max(minalign, minsize);
860
861                 /* Carve out storage for the TCE table. */
862                 base = lmb_alloc(minsize, align);
863
864                 if ( !base ) {
865                         prom_panic(RELOC("ERROR, cannot find space for TCE table.\n"));
866                 }
867
868                 vbase = (unsigned long)abs_to_virt(base);
869
870                 /* Save away the TCE table attributes for later use. */
871                 prom_tce_table[table].node = node;
872                 prom_tce_table[table].base = vbase;
873                 prom_tce_table[table].size = minsize;
874
875 #ifdef DEBUG_PROM
876                 prom_print(RELOC("TCE table: 0x"));
877                 prom_print_hex(table);
878                 prom_print_nl();
879
880                 prom_print(RELOC("\tnode = 0x"));
881                 prom_print_hex(node);
882                 prom_print_nl();
883
884                 prom_print(RELOC("\tbase = 0x"));
885                 prom_print_hex(vbase);
886                 prom_print_nl();
887
888                 prom_print(RELOC("\tsize = 0x"));
889                 prom_print_hex(minsize);
890                 prom_print_nl();
891 #endif
892
893                 /* Initialize the table to have a one-to-one mapping
894                  * over the allocated size.
895                  */
896                 tce_entryp = (unsigned long *)base;
897                 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
898                         tce_entry = (i << PAGE_SHIFT);
899                         tce_entry |= 0x3;
900                         *tce_entryp = tce_entry;
901                 }
902
903                 /* It seems OF doesn't null-terminate the path :-( */
904                 memset(path, 0, sizeof(path));
905                 /* Call OF to setup the TCE hardware */
906                 if (call_prom(RELOC("package-to-path"), 3, 1, node,
907                              path, sizeof(path)-1) == PROM_ERROR) {
908                         prom_print(RELOC("package-to-path failed\n"));
909                 } else {
910                         prom_print(RELOC("opening PHB "));
911                         prom_print(path);
912                 }
913
914                 phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path);
915                 if ( (long)phb_node <= 0) {
916                         prom_print(RELOC("... failed\n"));
917                 } else {
918                         prom_print(RELOC("... done\n"));
919                 }
920                 call_prom(RELOC("call-method"), 6, 0,
921                              RELOC("set-64-bit-addressing"),
922                              phb_node,
923                              -1,
924                              minsize, 
925                              base & 0xffffffff,
926                              (base >> 32) & 0xffffffff);
927                 call_prom(RELOC("close"), 1, 0, phb_node);
928
929                 table++;
930         }
931
932         /* Flag the first invalid entry */
933         prom_tce_table[table].node = 0;
934 #ifdef DEBUG_PROM
935         prom_print(RELOC("ending prom_initialize_tce_table\n"));
936 #endif
937 }
938
939 /*
940  * With CHRP SMP we need to use the OF to start the other
941  * processors so we can't wait until smp_boot_cpus (the OF is
942  * trashed by then) so we have to put the processors into
943  * a holding pattern controlled by the kernel (not OF) before
944  * we destroy the OF.
945  *
946  * This uses a chunk of low memory, puts some holding pattern
947  * code there and sends the other processors off to there until
948  * smp_boot_cpus tells them to do something.  The holding pattern
949  * checks that address until its cpu # is there, when it is that
950  * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
951  * of setting those values.
952  *
953  * We also use physical address 0x4 here to tell when a cpu
954  * is in its holding pattern code.
955  *
956  * Fixup comment... DRENG / PPPBBB - Peter
957  *
958  * -- Cort
959  */
960 static void __init prom_hold_cpus(unsigned long mem)
961 {
962         unsigned long i;
963         unsigned int reg;
964         phandle node;
965         unsigned long offset = reloc_offset();
966         char type[64], *path;
967         int cpuid = 0;
968         unsigned int interrupt_server[MAX_CPU_THREADS];
969         unsigned int cpu_threads, hw_cpu_num;
970         int propsize;
971         extern void __secondary_hold(void);
972         extern unsigned long __secondary_hold_spinloop;
973         extern unsigned long __secondary_hold_acknowledge;
974         unsigned long *spinloop
975                 = (void *)virt_to_abs(&__secondary_hold_spinloop);
976         unsigned long *acknowledge
977                 = (void *)virt_to_abs(&__secondary_hold_acknowledge);
978         unsigned long secondary_hold
979                 = virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
980         struct systemcfg *_systemcfg = RELOC(systemcfg);
981         struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
982         struct prom_t *_prom = PTRRELOC(&prom);
983 #ifdef CONFIG_SMP
984         struct naca_struct *_naca = RELOC(naca);
985 #endif
986
987         /* On pmac, we just fill out the various global bitmasks and
988          * arrays indicating our CPUs are here, they are actually started
989          * later on from pmac_smp
990          */
991         if (_systemcfg->platform == PLATFORM_POWERMAC) {
992                 for (node = 0; prom_next_node(&node); ) {
993                         type[0] = 0;
994                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
995                                   type, sizeof(type));
996                         if (strcmp(type, RELOC("cpu")) != 0)
997                                 continue;
998                         reg = -1;
999                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
1000                                   &reg, sizeof(reg));
1001                         _xPaca[cpuid].xHwProcNum = reg;
1002
1003 #ifdef CONFIG_SMP
1004                         cpu_set(cpuid, RELOC(cpu_available_map));
1005                         cpu_set(cpuid, RELOC(cpu_possible_map));
1006                         cpu_set(cpuid, RELOC(cpu_present_at_boot));
1007                         if (reg == 0)
1008                                 cpu_set(cpuid, RELOC(cpu_online_map));
1009 #endif /* CONFIG_SMP */
1010                         cpuid++;
1011                 }
1012                 return;
1013         }
1014
1015         /* Initially, we must have one active CPU. */
1016         _systemcfg->processorCount = 1;
1017
1018 #ifdef DEBUG_PROM
1019         prom_print(RELOC("prom_hold_cpus: start...\n"));
1020         prom_print(RELOC("    1) spinloop       = 0x"));
1021         prom_print_hex((unsigned long)spinloop);
1022         prom_print_nl();
1023         prom_print(RELOC("    1) *spinloop      = 0x"));
1024         prom_print_hex(*spinloop);
1025         prom_print_nl();
1026         prom_print(RELOC("    1) acknowledge    = 0x"));
1027         prom_print_hex((unsigned long)acknowledge);
1028         prom_print_nl();
1029         prom_print(RELOC("    1) *acknowledge   = 0x"));
1030         prom_print_hex(*acknowledge);
1031         prom_print_nl();
1032         prom_print(RELOC("    1) secondary_hold = 0x"));
1033         prom_print_hex(secondary_hold);
1034         prom_print_nl();
1035 #endif
1036
1037         /* Set the common spinloop variable, so all of the secondary cpus
1038          * will block when they are awakened from their OF spinloop.
1039          * This must occur for both SMP and non SMP kernels, since OF will
1040          * be trashed when we move the kernel.
1041          */
1042         *spinloop = 0;
1043
1044 #ifdef CONFIG_HMT
1045         for (i=0; i < NR_CPUS; i++) {
1046                 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1047         }
1048 #endif
1049         /* look for cpus */
1050         for (node = 0; prom_next_node(&node); ) {
1051                 type[0] = 0;
1052                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
1053                           type, sizeof(type));
1054                 if (strcmp(type, RELOC("cpu")) != 0)
1055                         continue;
1056
1057                 /* Skip non-configured cpus. */
1058                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"),
1059                           type, sizeof(type));
1060                 if (strcmp(type, RELOC("okay")) != 0)
1061                         continue;
1062
1063                 reg = -1;
1064                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
1065                           &reg, sizeof(reg));
1066
1067                 path = (char *) mem;
1068                 memset(path, 0, 256);
1069                 if ((long) call_prom(RELOC("package-to-path"), 3, 1,
1070                                      node, path, 255) == PROM_ERROR)
1071                         continue;
1072
1073 #ifdef DEBUG_PROM
1074                 prom_print_nl();
1075                 prom_print(RELOC("cpuid        = 0x"));
1076                 prom_print_hex(cpuid);
1077                 prom_print_nl();
1078                 prom_print(RELOC("cpu hw idx   = 0x"));
1079                 prom_print_hex(reg);
1080                 prom_print_nl();
1081 #endif
1082                 _xPaca[cpuid].xHwProcNum = reg;
1083
1084                 /* Init the acknowledge var which will be reset by
1085                  * the secondary cpu when it awakens from its OF
1086                  * spinloop.
1087                  */
1088                 *acknowledge = (unsigned long)-1;
1089
1090                 propsize = call_prom(RELOC("getprop"), 4, 1, node,
1091                                      RELOC("ibm,ppc-interrupt-server#s"), 
1092                                      &interrupt_server, 
1093                                      sizeof(interrupt_server));
1094                 if (propsize < 0) {
1095                         /* no property.  old hardware has no SMT */
1096                         cpu_threads = 1;
1097                         interrupt_server[0] = reg; /* fake it with phys id */
1098                 } else {
1099                         /* We have a threaded processor */
1100                         cpu_threads = propsize / sizeof(u32);
1101                         if (cpu_threads > MAX_CPU_THREADS) {
1102                                 prom_print(RELOC("SMT: too many threads!\nSMT: found "));
1103                                 prom_print_hex(cpu_threads);
1104                                 prom_print(RELOC(", max is "));
1105                                 prom_print_hex(MAX_CPU_THREADS);
1106                                 prom_print_nl();
1107                                 cpu_threads = 1; /* ToDo: panic? */
1108                         }
1109                 }
1110
1111                 hw_cpu_num = interrupt_server[0];
1112                 if (hw_cpu_num != _prom->cpu) {
1113                         /* Primary Thread of non-boot cpu */
1114                         prom_print_hex(cpuid);
1115                         prom_print(RELOC(" : starting cpu "));
1116                         prom_print(path);
1117                         prom_print(RELOC("... "));
1118                         call_prom(RELOC("start-cpu"), 3, 0, node, 
1119                                   secondary_hold, cpuid);
1120
1121                         for ( i = 0 ; (i < 100000000) && 
1122                               (*acknowledge == ((unsigned long)-1)); i++ ) ;
1123
1124                         if (*acknowledge == cpuid) {
1125                                 prom_print(RELOC("... done\n"));
1126                                 /* We have to get every CPU out of OF,
1127                                  * even if we never start it. */
1128                                 if (cpuid >= NR_CPUS)
1129                                         goto next;
1130 #ifdef CONFIG_SMP
1131                                 /* Set the number of active processors. */
1132                                 _systemcfg->processorCount++;
1133                                 cpu_set(cpuid, RELOC(cpu_available_map));
1134                                 cpu_set(cpuid, RELOC(cpu_possible_map));
1135                                 cpu_set(cpuid, RELOC(cpu_present_at_boot));
1136 #endif
1137                         } else {
1138                                 prom_print(RELOC("... failed: "));
1139                                 prom_print_hex(*acknowledge);
1140                                 prom_print_nl();
1141                         }
1142                 }
1143 #ifdef CONFIG_SMP
1144                 else {
1145                         prom_print_hex(cpuid);
1146                         prom_print(RELOC(" : booting  cpu "));
1147                         prom_print(path);
1148                         prom_print_nl();
1149                         cpu_set(cpuid, RELOC(cpu_available_map));
1150                         cpu_set(cpuid, RELOC(cpu_possible_map));
1151                         cpu_set(cpuid, RELOC(cpu_online_map));
1152                         cpu_set(cpuid, RELOC(cpu_present_at_boot));
1153                 }
1154 #endif
1155 next:
1156 #ifdef CONFIG_SMP
1157                 /* Init paca for secondary threads.   They start later. */
1158                 for (i=1; i < cpu_threads; i++) {
1159                         cpuid++;
1160                         if (cpuid >= NR_CPUS)
1161                                 continue;
1162                         _xPaca[cpuid].xHwProcNum = interrupt_server[i];
1163                         prom_print_hex(interrupt_server[i]);
1164                         prom_print(RELOC(" : preparing thread ... "));
1165                         if (_naca->smt_state) {
1166                                 cpu_set(cpuid, RELOC(cpu_available_map));
1167                                 cpu_set(cpuid, RELOC(cpu_present_at_boot));
1168                                 prom_print(RELOC("available"));
1169                         } else {
1170                                 prom_print(RELOC("not available"));
1171                         }
1172                         prom_print_nl();
1173                 }
1174 #endif
1175                 cpuid++;
1176         }
1177 #ifdef CONFIG_HMT
1178         /* Only enable HMT on processors that provide support. */
1179         if (__is_processor(PV_PULSAR) || 
1180             __is_processor(PV_ICESTAR) ||
1181             __is_processor(PV_SSTAR)) {
1182                 prom_print(RELOC("    starting secondary threads\n"));
1183
1184                 for (i = 0; i < NR_CPUS; i += 2) {
1185                         if (!cpu_online(i))
1186                                 continue;
1187
1188                         if (i == 0) {
1189                                 unsigned long pir = _get_PIR();
1190                                 if (__is_processor(PV_PULSAR)) {
1191                                         RELOC(hmt_thread_data)[i].pir = 
1192                                                 pir & 0x1f;
1193                                 } else {
1194                                         RELOC(hmt_thread_data)[i].pir = 
1195                                                 pir & 0x3ff;
1196                                 }
1197                         }
1198 /*                      cpu_set(i+1, cpu_online_map); */
1199                         cpu_set(i+1, RELOC(cpu_possible_map));
1200                 }
1201                 _systemcfg->processorCount *= 2;
1202         } else {
1203                 prom_print(RELOC("Processor is not HMT capable\n"));
1204         }
1205 #endif
1206
1207         if (cpuid >= NR_CPUS)
1208                 prom_print(RELOC("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1209                                  ") exceeded: ignoring extras\n"));
1210
1211 #ifdef DEBUG_PROM
1212         prom_print(RELOC("prom_hold_cpus: end...\n"));
1213 #endif
1214 }
1215
1216 static void __init smt_setup(void)
1217 {
1218         char *p, *q;
1219         char my_smt_enabled = SMT_DYNAMIC;
1220         ihandle prom_options = NULL;
1221         char option[9];
1222         unsigned long offset = reloc_offset();
1223         struct naca_struct *_naca = RELOC(naca);
1224         char found = 0;
1225
1226         if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) {
1227                 for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) {
1228                         q = p + 12;
1229                         if (p > RELOC(cmd_line) && p[-1] != ' ')
1230                                 continue;
1231                         found = 1;
1232                         if (q[0] == 'o' && q[1] == 'f' && 
1233                             q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) {
1234                                 my_smt_enabled = SMT_OFF;
1235                         } else if (q[0]=='o' && q[1] == 'n' && 
1236                                    (q[2] == ' ' || q[2] == '\0')) {
1237                                 my_smt_enabled = SMT_ON;
1238                         } else {
1239                                 my_smt_enabled = SMT_DYNAMIC;
1240                         } 
1241                 }
1242         }
1243         if (!found) {
1244                 prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
1245                 if (prom_options != (ihandle) -1) {
1246                         call_prom(RELOC("getprop"), 
1247                                 4, 1, prom_options,
1248                                 RELOC("ibm,smt-enabled"), 
1249                                 option, 
1250                                 sizeof(option));
1251                         if (option[0] != 0) {
1252                                 found = 1;
1253                                 if (!strcmp(option, RELOC("off")))
1254                                         my_smt_enabled = SMT_OFF;
1255                                 else if (!strcmp(option, RELOC("on")))
1256                                         my_smt_enabled = SMT_ON;
1257                                 else
1258                                         my_smt_enabled = SMT_DYNAMIC;
1259                         }
1260                 }
1261         }
1262
1263         if (!found )
1264                 my_smt_enabled = SMT_DYNAMIC; /* default to on */
1265
1266         _naca->smt_state = my_smt_enabled;
1267 }
1268
1269
1270 #ifdef CONFIG_BOOTX_TEXT
1271
1272 /* This function will enable the early boot text when doing OF booting. This
1273  * way, xmon output should work too
1274  */
1275 static void __init setup_disp_fake_bi(ihandle dp)
1276 {
1277         int width = 640, height = 480, depth = 8, pitch;
1278         unsigned address;
1279         struct pci_reg_property addrs[8];
1280         int i, naddrs;
1281         char name[64];
1282         unsigned long offset = reloc_offset();
1283         char *getprop = RELOC("getprop");
1284
1285         prom_print(RELOC("Initializing fake screen: "));
1286
1287         memset(name, 0, sizeof(name));
1288         call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name));
1289         name[sizeof(name)-1] = 0;
1290         prom_print(name);
1291         prom_print(RELOC("\n"));
1292         call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width));
1293         call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height));
1294         call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth));
1295         pitch = width * ((depth + 7) / 8);
1296         call_prom(getprop, 4, 1, dp, RELOC("linebytes"),
1297                   &pitch, sizeof(pitch));
1298         if (pitch == 1)
1299                 pitch = 0x1000;         /* for strange IBM display */
1300         address = 0;
1301
1302         prom_print(RELOC("width "));
1303         prom_print_hex(width);
1304         prom_print(RELOC(" height "));
1305         prom_print_hex(height);
1306         prom_print(RELOC(" depth "));
1307         prom_print_hex(depth);
1308         prom_print(RELOC(" linebytes "));
1309         prom_print_hex(pitch);
1310         prom_print(RELOC("\n"));
1311
1312
1313         call_prom(getprop, 4, 1, dp, RELOC("address"),
1314                   &address, sizeof(address));
1315         if (address == 0) {
1316                 /* look for an assigned address with a size of >= 1MB */
1317                 naddrs = (int) call_prom(getprop, 4, 1, dp,
1318                                 RELOC("assigned-addresses"),
1319                                 addrs, sizeof(addrs));
1320                 naddrs /= sizeof(struct pci_reg_property);
1321                 for (i = 0; i < naddrs; ++i) {
1322                         if (addrs[i].size_lo >= (1 << 20)) {
1323                                 address = addrs[i].addr.a_lo;
1324                                 /* use the BE aperture if possible */
1325                                 if (addrs[i].size_lo >= (16 << 20))
1326                                         address += (8 << 20);
1327                                 break;
1328                         }
1329                 }
1330                 if (address == 0) {
1331                         prom_print(RELOC("Failed to get address of frame buffer\n"));
1332                         return;
1333                 }
1334         }
1335         btext_setup_display(width, height, depth, pitch, address);
1336         prom_print(RELOC("Addr of fb: "));
1337         prom_print_hex(address);
1338         prom_print_nl();
1339         RELOC(boot_text_mapped) = 0;
1340 }
1341 #endif /* CONFIG_BOOTX_TEXT */
1342
1343 static void __init prom_init_client_services(unsigned long pp)
1344 {
1345         unsigned long offset = reloc_offset();
1346         struct prom_t *_prom = PTRRELOC(&prom);
1347
1348         /* Get a handle to the prom entry point before anything else */
1349         _prom->entry = pp;
1350
1351         /* Init default value for phys size */
1352         _prom->encode_phys_size = 32;
1353
1354         /* get a handle for the stdout device */
1355         _prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1,
1356                                        RELOC("/chosen"));
1357         if ((long)_prom->chosen <= 0)
1358                 prom_panic(RELOC("cannot find chosen")); /* msg won't be printed :( */
1359
1360         /* get device tree root */
1361         _prom->root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
1362         if ((long)_prom->root <= 0)
1363                 prom_panic(RELOC("cannot find device tree root")); /* msg won't be printed :( */
1364 }
1365
1366 static void __init prom_init_stdout(void)
1367 {
1368         unsigned long offset = reloc_offset();
1369         struct prom_t *_prom = PTRRELOC(&prom);
1370         u32 val;
1371
1372         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1373                             RELOC("stdout"), &val,
1374                             sizeof(val)) <= 0)
1375                 prom_panic(RELOC("cannot find stdout"));
1376
1377         _prom->stdout = (ihandle)(unsigned long)val;
1378 }
1379
1380 static int __init prom_find_machine_type(void)
1381 {
1382         unsigned long offset = reloc_offset();
1383         struct prom_t *_prom = PTRRELOC(&prom);
1384         char compat[256];
1385         int len, i = 0;
1386
1387         len = (int)(long)call_prom(RELOC("getprop"), 4, 1, _prom->root,
1388                                    RELOC("compatible"),
1389                                    compat, sizeof(compat)-1);
1390         if (len > 0) {
1391                 compat[len] = 0;
1392                 while (i < len) {
1393                         char *p = &compat[i];
1394                         int sl = strlen(p);
1395                         if (sl == 0)
1396                                 break;
1397                         if (strstr(p, RELOC("Power Macintosh")) ||
1398                             strstr(p, RELOC("MacRISC4")))
1399                                 return PLATFORM_POWERMAC;
1400                         i += sl + 1;
1401                 }
1402         }
1403         /* Default to pSeries */
1404         return PLATFORM_PSERIES;
1405 }
1406
1407 static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1408 {
1409         unsigned long offset = reloc_offset();
1410
1411         return (int)(long)call_prom(RELOC("call-method"), 6, 1,
1412                                     RELOC("color!"),
1413                                     ih,
1414                                     (void *)(long) i,
1415                                     (void *)(long) b,
1416                                     (void *)(long) g,
1417                                     (void *)(long) r );
1418 }
1419
1420 /*
1421  * If we have a display that we don't know how to drive,
1422  * we will want to try to execute OF's open method for it
1423  * later.  However, OF will probably fall over if we do that
1424  * we've taken over the MMU.
1425  * So we check whether we will need to open the display,
1426  * and if so, open it now.
1427  */
1428 static unsigned long __init check_display(unsigned long mem)
1429 {
1430         phandle node;
1431         ihandle ih;
1432         int i, j;
1433         unsigned long offset = reloc_offset();
1434         struct prom_t *_prom = PTRRELOC(&prom);
1435         char type[16], *path;
1436         static unsigned char default_colors[] = {
1437                 0x00, 0x00, 0x00,
1438                 0x00, 0x00, 0xaa,
1439                 0x00, 0xaa, 0x00,
1440                 0x00, 0xaa, 0xaa,
1441                 0xaa, 0x00, 0x00,
1442                 0xaa, 0x00, 0xaa,
1443                 0xaa, 0xaa, 0x00,
1444                 0xaa, 0xaa, 0xaa,
1445                 0x55, 0x55, 0x55,
1446                 0x55, 0x55, 0xff,
1447                 0x55, 0xff, 0x55,
1448                 0x55, 0xff, 0xff,
1449                 0xff, 0x55, 0x55,
1450                 0xff, 0x55, 0xff,
1451                 0xff, 0xff, 0x55,
1452                 0xff, 0xff, 0xff
1453         };
1454         const unsigned char *clut;
1455
1456         _prom->disp_node = 0;
1457
1458         prom_print(RELOC("Looking for displays\n"));
1459         if (RELOC(of_stdout_device) != 0) {
1460                 prom_print(RELOC("OF stdout is    : "));
1461                 prom_print(PTRRELOC(RELOC(of_stdout_device)));
1462                 prom_print(RELOC("\n"));
1463         }
1464         for (node = 0; prom_next_node(&node); ) {
1465                 type[0] = 0;
1466                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
1467                           type, sizeof(type));
1468                 if (strcmp(type, RELOC("display")) != 0)
1469                         continue;
1470                 /* It seems OF doesn't null-terminate the path :-( */
1471                 path = (char *) mem;
1472                 memset(path, 0, 256);
1473
1474                 /*
1475                  * leave some room at the end of the path for appending extra
1476                  * arguments
1477                  */
1478                 if ((long) call_prom(RELOC("package-to-path"), 3, 1,
1479                                     node, path, 250) < 0)
1480                         continue;
1481                 prom_print(RELOC("found display   : "));
1482                 prom_print(path);
1483                 prom_print(RELOC("\n"));
1484                 
1485                 /*
1486                  * If this display is the device that OF is using for stdout,
1487                  * move it to the front of the list.
1488                  */
1489                 mem += strlen(path) + 1;
1490                 i = RELOC(prom_num_displays);
1491                 RELOC(prom_num_displays) = i + 1;
1492                 if (RELOC(of_stdout_device) != 0 && i > 0
1493                     && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
1494                         for (; i > 0; --i) {
1495                                 RELOC(prom_display_paths[i])
1496                                         = RELOC(prom_display_paths[i-1]);
1497                                 RELOC(prom_display_nodes[i])
1498                                         = RELOC(prom_display_nodes[i-1]);
1499                         }
1500                         _prom->disp_node = (ihandle)(unsigned long)node;
1501                 }
1502                 RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
1503                 RELOC(prom_display_nodes[i]) = node;
1504                 if (_prom->disp_node == 0)
1505                         _prom->disp_node = (ihandle)(unsigned long)node;
1506                 if (RELOC(prom_num_displays) >= FB_MAX)
1507                         break;
1508         }
1509         prom_print(RELOC("Opening displays...\n"));
1510         for (j = RELOC(prom_num_displays) - 1; j >= 0; j--) {
1511                 path = PTRRELOC(RELOC(prom_display_paths[j]));
1512                 prom_print(RELOC("opening display : "));
1513                 prom_print(path);
1514                 ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);
1515                 if (ih == (ihandle)0 || ih == (ihandle)-1) {
1516                         prom_print(RELOC("... failed\n"));
1517                         continue;
1518                 }
1519
1520                 prom_print(RELOC("... done\n"));
1521
1522                 /* Setup a useable color table when the appropriate
1523                  * method is available. Should update this to set-colors */
1524                 clut = RELOC(default_colors);
1525                 for (i = 0; i < 32; i++, clut += 3)
1526                         if (prom_set_color(ih, i, clut[0], clut[1],
1527                                            clut[2]) != 0)
1528                                 break;
1529
1530 #ifdef CONFIG_LOGO_LINUX_CLUT224
1531                 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1532                 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1533                         if (prom_set_color(ih, i + 32, clut[0], clut[1],
1534                                            clut[2]) != 0)
1535                                 break;
1536 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
1537         }
1538         
1539         return DOUBLEWORD_ALIGN(mem);
1540 }
1541
1542 /* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1543 static void __init *__make_room(unsigned long *mem_start, unsigned long *mem_end,
1544                                 unsigned long needed, unsigned long align)
1545 {
1546         void *ret;
1547         unsigned long offset = reloc_offset();
1548
1549         *mem_start = ALIGN(*mem_start, align);
1550         if (*mem_start + needed > *mem_end) {
1551 #ifdef CONFIG_BLK_DEV_INITRD
1552                 /* FIXME: Apple OF doesn't map unclaimed mem.  If this
1553                  * ever happened on G5, we'd need to fix. */
1554                 unsigned long initrd_len;
1555
1556                 if (*mem_end != RELOC(initrd_start))
1557                         prom_panic(RELOC("No memory for copy_device_tree"));
1558
1559                 prom_print("Huge device_tree: moving initrd\n");
1560                 /* Move by 4M. */
1561                 initrd_len = RELOC(initrd_end) - RELOC(initrd_start);
1562                 *mem_end = RELOC(initrd_start) + 4 * 1024 * 1024;
1563                 memmove((void *)*mem_end, (void *)RELOC(initrd_start),
1564                         initrd_len);
1565                 RELOC(initrd_start) = *mem_end;
1566                 RELOC(initrd_end) = RELOC(initrd_start) + initrd_len;
1567 #else
1568                 prom_panic(RELOC("No memory for copy_device_tree"));
1569 #endif
1570         }
1571
1572         ret = (void *)*mem_start;
1573         *mem_start += needed;
1574
1575         return ret;
1576 }
1577
1578 #define make_room(startp, endp, type) \
1579         __make_room(startp, endp, sizeof(type), __alignof__(type))
1580
1581 static void __init
1582 inspect_node(phandle node, struct device_node *dad,
1583              unsigned long *mem_start, unsigned long *mem_end,
1584              struct device_node ***allnextpp)
1585 {
1586         int l;
1587         phandle child;
1588         struct device_node *np;
1589         struct property *pp, **prev_propp;
1590         char *prev_name, *namep;
1591         unsigned char *valp;
1592         unsigned long offset = reloc_offset();
1593
1594         np = make_room(mem_start, mem_end, struct device_node);
1595         memset(np, 0, sizeof(*np));
1596
1597         np->node = node;
1598         **allnextpp = PTRUNRELOC(np);
1599         *allnextpp = &np->allnext;
1600         if (dad != 0) {
1601                 np->parent = PTRUNRELOC(dad);
1602                 /* we temporarily use the `next' field as `last_child'. */
1603                 if (dad->next == 0)
1604                         dad->child = PTRUNRELOC(np);
1605                 else
1606                         dad->next->sibling = PTRUNRELOC(np);
1607                 dad->next = np;
1608         }
1609
1610         /* get and store all properties */
1611         prev_propp = &np->properties;
1612         prev_name = RELOC("");
1613         for (;;) {
1614                 /* 32 is max len of name including nul. */
1615                 namep = make_room(mem_start, mem_end, char[32]);
1616                 if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
1617                                      namep) <= 0) {
1618                         /* No more nodes: unwind alloc */
1619                         *mem_start = (unsigned long)namep;
1620                         break;
1621                 }
1622                 /* Trim off some if we can */
1623                 *mem_start = DOUBLEWORD_ALIGN((unsigned long)namep
1624                                              + strlen(namep) + 1);
1625                 pp = make_room(mem_start, mem_end, struct property);
1626                 pp->name = PTRUNRELOC(namep);
1627                 prev_name = namep;
1628
1629                 pp->length = call_prom(RELOC("getproplen"), 2, 1, node, namep);
1630                 if (pp->length < 0)
1631                         continue;
1632                 if (pp->length > MAX_PROPERTY_LENGTH) {
1633                         char path[128];
1634
1635                         prom_print(RELOC("WARNING: ignoring large property "));
1636                         /* It seems OF doesn't null-terminate the path :-( */
1637                         memset(path, 0, sizeof(path));
1638                         if (call_prom(RELOC("package-to-path"), 3, 1, node,
1639                             path, sizeof(path)-1) > 0)
1640                                 prom_print(path);
1641                         prom_print(namep);
1642                         prom_print(RELOC(" length 0x"));
1643                         prom_print_hex(pp->length);
1644                         prom_print_nl();
1645
1646                         continue;
1647                 }
1648                 valp = __make_room(mem_start, mem_end, pp->length, 1);
1649                 pp->value = PTRUNRELOC(valp);
1650                 call_prom(RELOC("getprop"), 4, 1, node, namep,valp,pp->length);
1651                 *prev_propp = PTRUNRELOC(pp);
1652                 prev_propp = &pp->next;
1653         }
1654
1655         /* Add a "linux_phandle" value */
1656         if (np->node) {
1657                 u32 ibm_phandle = 0;
1658                 int len;
1659
1660                 /* First see if "ibm,phandle" exists and use its value */
1661                 len = (int)
1662                         call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"),
1663                                   &ibm_phandle, sizeof(ibm_phandle));
1664                 if (len < 0) {
1665                         np->linux_phandle = np->node;
1666                 } else {
1667                         np->linux_phandle = ibm_phandle;
1668                 }
1669         }
1670
1671         *prev_propp = 0;
1672
1673         /* get the node's full name */
1674         namep = (char *)*mem_start;
1675         l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
1676                              namep, *mem_end - *mem_start);
1677         if (l >= 0) {
1678                 /* Didn't fit?  Get more room. */
1679                 if (l+1 > *mem_end - *mem_start) {
1680                         namep = __make_room(mem_start, mem_end, l+1, 1);
1681                         call_prom(RELOC("package-to-path"),3,1,node,namep,l);
1682                 }
1683                 np->full_name = PTRUNRELOC(namep);
1684                 namep[l] = '\0';
1685                 *mem_start = DOUBLEWORD_ALIGN(*mem_start + l + 1);
1686         }
1687
1688         /* do all our children */
1689         child = call_prom(RELOC("child"), 1, 1, node);
1690         while (child != (phandle)0) {
1691                 inspect_node(child, np, mem_start, mem_end,
1692                                          allnextpp);
1693                 child = call_prom(RELOC("peer"), 1, 1, child);
1694         }
1695 }
1696
1697 /*
1698  * Make a copy of the device tree from the PROM.
1699  */
1700 static unsigned long __init
1701 copy_device_tree(unsigned long mem_start)
1702 {
1703         phandle root;
1704         struct device_node **allnextp;
1705         unsigned long offset = reloc_offset();
1706         unsigned long mem_end;
1707
1708         /* We pass mem_end-mem_start to OF: keep it well under 32-bit */
1709         mem_end = mem_start + 1024*1024*1024;
1710 #ifdef CONFIG_BLK_DEV_INITRD
1711         if (RELOC(initrd_start) && RELOC(initrd_start) > mem_start)
1712                 mem_end = RELOC(initrd_start);
1713 #endif /* CONFIG_BLK_DEV_INITRD */
1714
1715         root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
1716         if (root == (phandle)0) {
1717                 prom_panic(RELOC("couldn't get device tree root\n"));
1718         }
1719         allnextp = &RELOC(allnodes);
1720         inspect_node(root, 0, &mem_start, &mem_end, &allnextp);
1721         *allnextp = 0;
1722         return mem_start;
1723 }
1724
1725 /* Verify bi_recs are good */
1726 static struct bi_record * __init prom_bi_rec_verify(struct bi_record *bi_recs)
1727 {
1728         struct bi_record *first, *last;
1729 #ifdef DEBUG_PROM
1730         unsigned long offset = reloc_offset();
1731
1732         prom_print(RELOC("birec_verify: r6=0x"));
1733         prom_print_hex((unsigned long)bi_recs);
1734         prom_print_nl();
1735         if (bi_recs != NULL) {
1736                 prom_print(RELOC("  tag=0x"));
1737                 prom_print_hex(bi_recs->tag);
1738                 prom_print_nl();
1739         }
1740 #endif /* DEBUG_PROM */
1741
1742         if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
1743                 return NULL;
1744
1745         last = (struct bi_record *)(long)bi_recs->data[0];
1746
1747 #ifdef DEBUG_PROM
1748         prom_print(RELOC("  last=0x"));
1749         prom_print_hex((unsigned long)last);
1750         prom_print_nl();
1751         if (last != NULL) {
1752                 prom_print(RELOC("  last_tag=0x"));
1753                 prom_print_hex(last->tag);
1754                 prom_print_nl();
1755         }
1756 #endif /* DEBUG_PROM */
1757
1758         if ( last == NULL || last->tag != BI_LAST )
1759                 return NULL;
1760
1761         first = (struct bi_record *)(long)last->data[0];
1762 #ifdef DEBUG_PROM
1763         prom_print(RELOC("  first=0x"));
1764         prom_print_hex((unsigned long)first);
1765         prom_print_nl();
1766 #endif /* DEBUG_PROM */
1767
1768         if ( first == NULL || first != bi_recs )
1769                 return NULL;
1770
1771         return bi_recs;
1772 }
1773
1774 static void __init prom_bi_rec_reserve(void)
1775 {
1776         unsigned long offset = reloc_offset();
1777         struct prom_t *_prom = PTRRELOC(&prom);
1778         struct bi_record *rec;
1779
1780         if ( _prom->bi_recs != NULL) {
1781
1782                 for ( rec=_prom->bi_recs;
1783                       rec->tag != BI_LAST;
1784                       rec=bi_rec_next(rec) ) {
1785 #ifdef DEBUG_PROM
1786                         prom_print(RELOC("bi: 0x"));
1787                         prom_print_hex(rec->tag);
1788                         prom_print_nl();
1789 #endif /* DEBUG_PROM */
1790                         switch (rec->tag) {
1791 #ifdef CONFIG_BLK_DEV_INITRD
1792                         case BI_INITRD:
1793                                 RELOC(initrd_start) = (unsigned long)(rec->data[0]);
1794                                 RELOC(initrd_end) = RELOC(initrd_start) + rec->data[1];
1795                                 break;
1796 #endif /* CONFIG_BLK_DEV_INITRD */
1797                         }
1798                 }
1799                 /* The next use of this field will be after relocation
1800                  * is enabled, so convert this physical address into a
1801                  * virtual address.
1802                  */
1803                 _prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
1804         }
1805 }
1806
1807 /*
1808  * We enter here early on, when the Open Firmware prom is still
1809  * handling exceptions and the MMU hash table for us.
1810  */
1811
1812 unsigned long __init
1813 prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
1814           unsigned long r6, unsigned long r7)
1815 {
1816         unsigned long mem;
1817         ihandle prom_cpu;
1818         phandle cpu_pkg;
1819         unsigned long offset = reloc_offset();
1820         long l;
1821         char *p, *d;
1822         unsigned long phys;
1823         u32 getprop_rval;
1824         struct systemcfg *_systemcfg;
1825         struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
1826         struct prom_t *_prom = PTRRELOC(&prom);
1827
1828         /* First zero the BSS -- use memset, some arches don't have
1829          * caches on yet */
1830         memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
1831
1832         /* Setup systemcfg and NACA pointers now */
1833         RELOC(systemcfg) = _systemcfg = (struct systemcfg *)(SYSTEMCFG_VIRT_ADDR - offset);
1834         RELOC(naca) = (struct naca_struct *)(NACA_VIRT_ADDR - offset);
1835
1836         /* Init interface to Open Firmware and pickup bi-recs */
1837         prom_init_client_services(pp);
1838
1839         /* Init prom stdout device */
1840         prom_init_stdout();
1841
1842 #ifdef DEBUG_PROM
1843         prom_print(RELOC("klimit=0x"));
1844         prom_print_hex(RELOC(klimit));
1845         prom_print_nl();
1846         prom_print(RELOC("offset=0x"));
1847         prom_print_hex(offset);
1848         prom_print_nl();
1849         prom_print(RELOC("->mem=0x"));
1850         prom_print_hex(RELOC(klimit) - offset);
1851         prom_print_nl();
1852 #endif /* DEBUG_PROM */
1853
1854         /* check out if we have bi_recs */
1855         _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
1856         if ( _prom->bi_recs != NULL ) {
1857                 RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs +
1858                                            _prom->bi_recs->data[1]);
1859 #ifdef DEBUG_PROM
1860                 prom_print(RELOC("bi_recs=0x"));
1861                 prom_print_hex((unsigned long)_prom->bi_recs);
1862                 prom_print_nl();
1863                 prom_print(RELOC("new mem=0x"));
1864                 prom_print_hex(RELOC(klimit) - offset);
1865                 prom_print_nl();
1866 #endif /* DEBUG_PROM */
1867         }
1868
1869         /* If we don't have birec's or didn't find them, check for an initrd
1870          * using the "yaboot" way
1871          */
1872 #ifdef CONFIG_BLK_DEV_INITRD
1873         if ( _prom->bi_recs == NULL && r3 && r4 && r4 != 0xdeadbeef) {
1874                 RELOC(initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1875                 RELOC(initrd_end) = RELOC(initrd_start) + r4;
1876                 RELOC(initrd_below_start_ok) = 1;
1877         }
1878 #endif /* CONFIG_BLK_DEV_INITRD */
1879
1880         /* Default machine type. */
1881         _systemcfg->platform = prom_find_machine_type();
1882
1883         /* On pSeries, copy the CPU hold code */
1884         if (_systemcfg->platform == PLATFORM_PSERIES)
1885                 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1886
1887         /* Start storing things at klimit */
1888         mem = RELOC(klimit) - offset;
1889
1890         /* Get the full OF pathname of the stdout device */
1891         p = (char *) mem;
1892         memset(p, 0, 256);
1893         call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
1894         RELOC(of_stdout_device) = PTRUNRELOC(p);
1895         mem += strlen(p) + 1;
1896
1897         getprop_rval = 1;
1898         call_prom(RELOC("getprop"), 4, 1,
1899                   _prom->root, RELOC("#size-cells"),
1900                   &getprop_rval, sizeof(getprop_rval));
1901         _prom->encode_phys_size = (getprop_rval == 1) ? 32 : 64;
1902
1903         /* Determine which cpu is actually running right _now_ */
1904         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1905                             RELOC("cpu"), &getprop_rval,
1906                             sizeof(getprop_rval)) <= 0)
1907                 prom_panic(RELOC("cannot find boot cpu"));
1908
1909         prom_cpu = (ihandle)(unsigned long)getprop_rval;
1910         cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
1911         call_prom(RELOC("getprop"), 4, 1,
1912                 cpu_pkg, RELOC("reg"),
1913                 &getprop_rval, sizeof(getprop_rval));
1914         _prom->cpu = (int)(unsigned long)getprop_rval;
1915         _xPaca[0].xHwProcNum = _prom->cpu;
1916
1917         RELOC(boot_cpuid) = 0;
1918
1919 #ifdef DEBUG_PROM
1920         prom_print(RELOC("Booting CPU hw index = 0x"));
1921         prom_print_hex(_prom->cpu);
1922         prom_print_nl();
1923 #endif
1924
1925         /* Get the boot device and translate it to a full OF pathname. */
1926         p = (char *) mem;
1927         l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1928                             RELOC("bootpath"), p, 1<<20);
1929         if (l > 0) {
1930                 p[l] = 0;       /* should already be null-terminated */
1931                 RELOC(bootpath) = PTRUNRELOC(p);
1932                 mem += l + 1;
1933                 d = (char *) mem;
1934                 *d = 0;
1935                 call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
1936                 RELOC(bootdevice) = PTRUNRELOC(d);
1937                 mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
1938         }
1939
1940         RELOC(cmd_line[0]) = 0;
1941         if ((long)_prom->chosen > 0) {
1942                 call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1943                           RELOC("bootargs"), p, sizeof(cmd_line));
1944                 if (p != NULL && p[0] != 0)
1945                         strlcpy(RELOC(cmd_line), p, sizeof(cmd_line));
1946         }
1947
1948         early_cmdline_parse();
1949
1950         prom_initialize_lmb();
1951
1952         prom_bi_rec_reserve();
1953
1954         mem = check_display(mem);
1955
1956         if (_systemcfg->platform != PLATFORM_POWERMAC)
1957                 prom_instantiate_rtas();
1958
1959         /* Initialize some system info into the Naca early... */
1960         prom_initialize_naca();
1961
1962         smt_setup();
1963
1964         /* If we are on an SMP machine, then we *MUST* do the
1965          * following, regardless of whether we have an SMP
1966          * kernel or not.
1967          */
1968         prom_hold_cpus(mem);
1969
1970 #ifdef DEBUG_PROM
1971         prom_print(RELOC("after basic inits, mem=0x"));
1972         prom_print_hex(mem);
1973         prom_print_nl();
1974 #ifdef CONFIG_BLK_DEV_INITRD
1975         prom_print(RELOC("initrd_start=0x"));
1976         prom_print_hex(RELOC(initrd_start));
1977         prom_print_nl();
1978         prom_print(RELOC("initrd_end=0x"));
1979         prom_print_hex(RELOC(initrd_end));
1980         prom_print_nl();
1981 #endif /* CONFIG_BLK_DEV_INITRD */
1982         prom_print(RELOC("copying OF device tree...\n"));
1983 #endif /* DEBUG_PROM */
1984         mem = copy_device_tree(mem);
1985
1986         RELOC(klimit) = mem + offset;
1987
1988 #ifdef DEBUG_PROM
1989         prom_print(RELOC("new klimit is\n"));
1990         prom_print(RELOC("klimit=0x"));
1991         prom_print_hex(RELOC(klimit));
1992         prom_print(RELOC(" ->mem=0x\n"));
1993         prom_print(RELOC("klimit=0x"));
1994         prom_print_hex(mem);
1995         prom_print_nl();
1996 #endif /* DEBUG_PROM */
1997
1998         lmb_reserve(0, __pa(RELOC(klimit)));
1999
2000 #ifdef CONFIG_BLK_DEV_INITRD
2001         if (RELOC(initrd_start)) {
2002                 unsigned long initrd_len;
2003                 initrd_len = RELOC(initrd_end) - RELOC(initrd_start);
2004
2005                 /* Move initrd if it's where we're going to copy kernel. */
2006                 if (RELOC(initrd_start) < __pa(RELOC(klimit))) {
2007                         memmove((void *)mem, (void *)RELOC(initrd_start),
2008                                 initrd_len);
2009                         RELOC(initrd_start) = mem;
2010                         RELOC(initrd_end) = mem + initrd_len;
2011                 }
2012
2013                 lmb_reserve(RELOC(initrd_start), initrd_len);
2014         }
2015 #endif /* CONFIG_BLK_DEV_INITRD */
2016
2017         if (_systemcfg->platform == PLATFORM_PSERIES)
2018                 prom_initialize_tce_table();
2019
2020 #ifdef CONFIG_PMAC_DART
2021         if (_systemcfg->platform == PLATFORM_POWERMAC)
2022                 prom_initialize_dart_table();
2023 #endif
2024
2025 #ifdef CONFIG_BOOTX_TEXT
2026         if(_prom->disp_node) {
2027                 prom_print(RELOC("Setting up bi display...\n"));
2028                 setup_disp_fake_bi(_prom->disp_node);
2029         }
2030 #endif /* CONFIG_BOOTX_TEXT */
2031
2032         prom_print(RELOC("Calling quiesce ...\n"));
2033         call_prom(RELOC("quiesce"), 0, 0);
2034         phys = KERNELBASE - offset;
2035
2036 #ifdef CONFIG_BLK_DEV_INITRD
2037         /* If we had an initrd, we convert its address to virtual */
2038         if (RELOC(initrd_start)) {
2039                 RELOC(initrd_start) = (unsigned long)__va(RELOC(initrd_start));
2040                 RELOC(initrd_end) = (unsigned long)__va(RELOC(initrd_end));
2041         }
2042 #endif /* CONFIG_BLK_DEV_INITRD */
2043
2044         prom_print(RELOC("returning from prom_init\n"));
2045         return phys;
2046 }
2047
2048 /*
2049  * Find the device_node with a given phandle.
2050  */
2051 static struct device_node * __devinit
2052 find_phandle(phandle ph)
2053 {
2054         struct device_node *np;
2055
2056         for (np = allnodes; np != 0; np = np->allnext)
2057                 if (np->linux_phandle == ph)
2058                         return np;
2059         return NULL;
2060 }
2061
2062 /*
2063  * Find the interrupt parent of a node.
2064  */
2065 static struct device_node * __devinit
2066 intr_parent(struct device_node *p)
2067 {
2068         phandle *parp;
2069
2070         parp = (phandle *) get_property(p, "interrupt-parent", NULL);
2071         if (parp == NULL)
2072                 return p->parent;
2073         return find_phandle(*parp);
2074 }
2075
2076 /*
2077  * Find out the size of each entry of the interrupts property
2078  * for a node.
2079  */
2080 static int __devinit
2081 prom_n_intr_cells(struct device_node *np)
2082 {
2083         struct device_node *p;
2084         unsigned int *icp;
2085
2086         for (p = np; (p = intr_parent(p)) != NULL; ) {
2087                 icp = (unsigned int *)
2088                         get_property(p, "#interrupt-cells", NULL);
2089                 if (icp != NULL)
2090                         return *icp;
2091                 if (get_property(p, "interrupt-controller", NULL) != NULL
2092                     || get_property(p, "interrupt-map", NULL) != NULL) {
2093                         printk("oops, node %s doesn't have #interrupt-cells\n",
2094                                p->full_name);
2095                 return 1;
2096                 }
2097         }
2098 #ifdef DEBUG_IRQ
2099         printk("prom_n_intr_cells failed for %s\n", np->full_name);
2100 #endif
2101         return 1;
2102 }
2103
2104 /*
2105  * Map an interrupt from a device up to the platform interrupt
2106  * descriptor.
2107  */
2108 static int __devinit
2109 map_interrupt(unsigned int **irq, struct device_node **ictrler,
2110               struct device_node *np, unsigned int *ints, int nintrc)
2111 {
2112         struct device_node *p, *ipar;
2113         unsigned int *imap, *imask, *ip;
2114         int i, imaplen, match;
2115         int newintrc, newaddrc;
2116         unsigned int *reg;
2117         int naddrc;
2118
2119         reg = (unsigned int *) get_property(np, "reg", NULL);
2120         naddrc = prom_n_addr_cells(np);
2121         p = intr_parent(np);
2122         while (p != NULL) {
2123                 if (get_property(p, "interrupt-controller", NULL) != NULL)
2124                         /* this node is an interrupt controller, stop here */
2125                         break;
2126                 imap = (unsigned int *)
2127                         get_property(p, "interrupt-map", &imaplen);
2128                 if (imap == NULL) {
2129                         p = intr_parent(p);
2130                         continue;
2131                 }
2132                 imask = (unsigned int *)
2133                         get_property(p, "interrupt-map-mask", NULL);
2134                 if (imask == NULL) {
2135                         printk("oops, %s has interrupt-map but no mask\n",
2136                                p->full_name);
2137                         return 0;
2138                 }
2139                 imaplen /= sizeof(unsigned int);
2140                 match = 0;
2141                 ipar = NULL;
2142                 while (imaplen > 0 && !match) {
2143                         /* check the child-interrupt field */
2144                         match = 1;
2145                         for (i = 0; i < naddrc && match; ++i)
2146                                 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
2147                         for (; i < naddrc + nintrc && match; ++i)
2148                                 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
2149                         imap += naddrc + nintrc;
2150                         imaplen -= naddrc + nintrc;
2151                         /* grab the interrupt parent */
2152                         ipar = find_phandle((phandle) *imap++);
2153                         --imaplen;
2154                         if (ipar == NULL) {
2155                                 printk("oops, no int parent %x in map of %s\n",
2156                                        imap[-1], p->full_name);
2157                                 return 0;
2158                         }
2159                         /* find the parent's # addr and intr cells */
2160                         ip = (unsigned int *)
2161                                 get_property(ipar, "#interrupt-cells", NULL);
2162                         if (ip == NULL) {
2163                                 printk("oops, no #interrupt-cells on %s\n",
2164                                        ipar->full_name);
2165                                 return 0;
2166                         }
2167                         newintrc = *ip;
2168                         ip = (unsigned int *)
2169                                 get_property(ipar, "#address-cells", NULL);
2170                         newaddrc = (ip == NULL)? 0: *ip;
2171                         imap += newaddrc + newintrc;
2172                         imaplen -= newaddrc + newintrc;
2173                 }
2174                 if (imaplen < 0) {
2175                         printk("oops, error decoding int-map on %s, len=%d\n",
2176                                p->full_name, imaplen);
2177                         return 0;
2178                 }
2179                 if (!match) {
2180 #ifdef DEBUG_IRQ
2181                         printk("oops, no match in %s int-map for %s\n",
2182                                p->full_name, np->full_name);
2183 #endif
2184                         return 0;
2185                 }
2186                 p = ipar;
2187                 naddrc = newaddrc;
2188                 nintrc = newintrc;
2189                 ints = imap - nintrc;
2190                 reg = ints - naddrc;
2191         }
2192         if (p == NULL) {
2193 #ifdef DEBUG_IRQ
2194                 printk("hmmm, int tree for %s doesn't have ctrler\n",
2195                        np->full_name);
2196 #endif
2197                 return 0;
2198         }
2199         *irq = ints;
2200         *ictrler = p;
2201         return nintrc;
2202 }
2203
2204 static unsigned long __init
2205 finish_node_interrupts(struct device_node *np, unsigned long mem_start,
2206                        int measure_only)
2207 {
2208         unsigned int *ints;
2209         int intlen, intrcells, intrcount;
2210         int i, j, n;
2211         unsigned int *irq, virq;
2212         struct device_node *ic;
2213
2214         ints = (unsigned int *) get_property(np, "interrupts", &intlen);
2215         if (ints == NULL)
2216                 return mem_start;
2217         intrcells = prom_n_intr_cells(np);
2218         intlen /= intrcells * sizeof(unsigned int);
2219         np->intrs = (struct interrupt_info *) mem_start;
2220         mem_start += intlen * sizeof(struct interrupt_info);
2221
2222         if (measure_only)
2223                 return mem_start;
2224
2225         intrcount = 0;
2226         for (i = 0; i < intlen; ++i, ints += intrcells) {
2227                 n = map_interrupt(&irq, &ic, np, ints, intrcells);
2228                 if (n <= 0)
2229                         continue;
2230
2231                 /* don't map IRQ numbers under a cascaded 8259 controller */
2232                 if (ic && device_is_compatible(ic, "chrp,iic")) {
2233                         np->intrs[intrcount].line = irq[0];
2234                 } else {
2235                         virq = virt_irq_create_mapping(irq[0]);
2236                         if (virq == NO_IRQ) {
2237                                 printk(KERN_CRIT "Could not allocate interrupt"
2238                                        " number for %s\n", np->full_name);
2239                                 continue;
2240                         }
2241                         np->intrs[intrcount].line = irq_offset_up(virq);
2242                 }
2243
2244                 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
2245                 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
2246                         char *name = get_property(ic->parent, "name", NULL);
2247                         if (name && !strcmp(name, "u3"))
2248                                 np->intrs[intrcount].line += 128;
2249                 }
2250                 np->intrs[intrcount].sense = 1;
2251                 if (n > 1)
2252                         np->intrs[intrcount].sense = irq[1];
2253                 if (n > 2) {
2254                         printk("hmmm, got %d intr cells for %s:", n,
2255                                np->full_name);
2256                         for (j = 0; j < n; ++j)
2257                                 printk(" %d", irq[j]);
2258                         printk("\n");
2259                 }
2260                 ++intrcount;
2261         }
2262         np->n_intrs = intrcount;
2263
2264         return mem_start;
2265 }
2266
2267 static unsigned long __init
2268 interpret_pci_props(struct device_node *np, unsigned long mem_start,
2269                     int naddrc, int nsizec, int measure_only)
2270 {
2271         struct address_range *adr;
2272         struct pci_reg_property *pci_addrs;
2273         int i, l;
2274
2275         pci_addrs = (struct pci_reg_property *)
2276                 get_property(np, "assigned-addresses", &l);
2277         if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
2278                 i = 0;
2279                 adr = (struct address_range *) mem_start;
2280                 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
2281                         if (!measure_only) {
2282                                 adr[i].space = pci_addrs[i].addr.a_hi;
2283                                 adr[i].address = pci_addrs[i].addr.a_lo;
2284                                 adr[i].size = pci_addrs[i].size_lo;
2285                         }
2286                         ++i;
2287                 }
2288                 np->addrs = adr;
2289                 np->n_addrs = i;
2290                 mem_start += i * sizeof(struct address_range);
2291         }
2292         return mem_start;
2293 }
2294
2295 static unsigned long __init
2296 interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
2297                       int naddrc, int nsizec, int measure_only)
2298 {
2299         struct reg_property32 *rp;
2300         struct address_range *adr;
2301         unsigned long base_address;
2302         int i, l;
2303         struct device_node *db;
2304
2305         base_address = 0;
2306         if (!measure_only) {
2307                 for (db = np->parent; db != NULL; db = db->parent) {
2308                         if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
2309                                 base_address = db->addrs[0].address;
2310                                 break;
2311                         }
2312                 }
2313         }
2314
2315         rp = (struct reg_property32 *) get_property(np, "reg", &l);
2316         if (rp != 0 && l >= sizeof(struct reg_property32)) {
2317                 i = 0;
2318                 adr = (struct address_range *) mem_start;
2319                 while ((l -= sizeof(struct reg_property32)) >= 0) {
2320                         if (!measure_only) {
2321                                 adr[i].space = 2;
2322                                 adr[i].address = rp[i].address + base_address;
2323                                 adr[i].size = rp[i].size;
2324                         }
2325                         ++i;
2326                 }
2327                 np->addrs = adr;
2328                 np->n_addrs = i;
2329                 mem_start += i * sizeof(struct address_range);
2330         }
2331
2332         return mem_start;
2333 }
2334
2335 static unsigned long __init
2336 interpret_macio_props(struct device_node *np, unsigned long mem_start,
2337                       int naddrc, int nsizec, int measure_only)
2338 {
2339         struct reg_property32 *rp;
2340         struct address_range *adr;
2341         unsigned long base_address;
2342         int i, l;
2343         struct device_node *db;
2344
2345         base_address = 0;
2346         if (!measure_only) {
2347                 for (db = np->parent; db != NULL; db = db->parent) {
2348                         if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
2349                                 base_address = db->addrs[0].address;
2350                                 break;
2351                         }
2352                 }
2353         }
2354
2355         rp = (struct reg_property32 *) get_property(np, "reg", &l);
2356         if (rp != 0 && l >= sizeof(struct reg_property32)) {
2357                 i = 0;
2358                 adr = (struct address_range *) mem_start;
2359                 while ((l -= sizeof(struct reg_property32)) >= 0) {
2360                         if (!measure_only) {
2361                                 adr[i].space = 2;
2362                                 adr[i].address = rp[i].address + base_address;
2363                                 adr[i].size = rp[i].size;
2364                         }
2365                         ++i;
2366                 }
2367                 np->addrs = adr;
2368                 np->n_addrs = i;
2369                 mem_start += i * sizeof(struct address_range);
2370         }
2371
2372         return mem_start;
2373 }
2374
2375 static unsigned long __init
2376 interpret_isa_props(struct device_node *np, unsigned long mem_start,
2377                     int naddrc, int nsizec, int measure_only)
2378 {
2379         struct isa_reg_property *rp;
2380         struct address_range *adr;
2381         int i, l;
2382
2383         rp = (struct isa_reg_property *) get_property(np, "reg", &l);
2384         if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
2385                 i = 0;
2386                 adr = (struct address_range *) mem_start;
2387                 while ((l -= sizeof(struct reg_property)) >= 0) {
2388                         if (!measure_only) {
2389                                 adr[i].space = rp[i].space;
2390                                 adr[i].address = rp[i].address;
2391                                 adr[i].size = rp[i].size;
2392                         }
2393                         ++i;
2394                 }
2395                 np->addrs = adr;
2396                 np->n_addrs = i;
2397                 mem_start += i * sizeof(struct address_range);
2398         }
2399
2400         return mem_start;
2401 }
2402
2403 static unsigned long __init
2404 interpret_root_props(struct device_node *np, unsigned long mem_start,
2405                      int naddrc, int nsizec, int measure_only)
2406 {
2407         struct address_range *adr;
2408         int i, l;
2409         unsigned int *rp;
2410         int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
2411
2412         rp = (unsigned int *) get_property(np, "reg", &l);
2413         if (rp != 0 && l >= rpsize) {
2414                 i = 0;
2415                 adr = (struct address_range *) mem_start;
2416                 while ((l -= rpsize) >= 0) {
2417                         if (!measure_only) {
2418                                 adr[i].space = 0;
2419                                 adr[i].address = rp[naddrc - 1];
2420                                 adr[i].size = rp[naddrc + nsizec - 1];
2421                         }
2422                         ++i;
2423                         rp += naddrc + nsizec;
2424                 }
2425                 np->addrs = adr;
2426                 np->n_addrs = i;
2427                 mem_start += i * sizeof(struct address_range);
2428         }
2429
2430         return mem_start;
2431 }
2432
2433 static unsigned long __init
2434 finish_node(struct device_node *np, unsigned long mem_start,
2435             interpret_func *ifunc, int naddrc, int nsizec, int measure_only)
2436 {
2437         struct device_node *child;
2438         int *ip;
2439
2440         np->name = get_property(np, "name", 0);
2441         np->type = get_property(np, "device_type", 0);
2442
2443         if (!np->name)
2444                 np->name = "<NULL>";
2445         if (!np->type)
2446                 np->type = "<NULL>";
2447
2448         /* get the device addresses and interrupts */
2449         if (ifunc != NULL)
2450                 mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
2451
2452         mem_start = finish_node_interrupts(np, mem_start, measure_only);
2453
2454         /* Look for #address-cells and #size-cells properties. */
2455         ip = (int *) get_property(np, "#address-cells", 0);
2456         if (ip != NULL)
2457                 naddrc = *ip;
2458         ip = (int *) get_property(np, "#size-cells", 0);
2459         if (ip != NULL)
2460                 nsizec = *ip;
2461
2462         /* the f50 sets the name to 'display' and 'compatible' to what we
2463          * expect for the name -- Cort
2464          */
2465         if (!strcmp(np->name, "display"))
2466                 np->name = get_property(np, "compatible", 0);
2467
2468         if (!strcmp(np->name, "device-tree") || np->parent == NULL)
2469                 ifunc = interpret_root_props;
2470         else if (np->type == 0)
2471                 ifunc = NULL;
2472         else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
2473                 ifunc = interpret_pci_props;
2474         else if (!strcmp(np->type, "dbdma"))
2475                 ifunc = interpret_dbdma_props;
2476         else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
2477                 ifunc = interpret_macio_props;
2478         else if (!strcmp(np->type, "isa"))
2479                 ifunc = interpret_isa_props;
2480         else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
2481                 ifunc = interpret_root_props;
2482         else if (!((ifunc == interpret_dbdma_props
2483                     || ifunc == interpret_macio_props)
2484                    && (!strcmp(np->type, "escc")
2485                        || !strcmp(np->type, "media-bay"))))
2486                 ifunc = NULL;
2487
2488         for (child = np->child; child != NULL; child = child->sibling)
2489                 mem_start = finish_node(child, mem_start, ifunc,
2490                                         naddrc, nsizec, measure_only);
2491
2492         return mem_start;
2493 }
2494
2495 /*
2496  * finish_device_tree is called once things are running normally
2497  * (i.e. with text and data mapped to the address they were linked at).
2498  * It traverses the device tree and fills in the name, type,
2499  * {n_}addrs and {n_}intrs fields of each node.
2500  */
2501 void __init
2502 finish_device_tree(void)
2503 {
2504         unsigned long mem = klimit;
2505
2506         virt_irq_init();
2507
2508         dev_tree_size = finish_node(allnodes, 0, NULL, 0, 0, 1);
2509         mem = (long)abs_to_virt(lmb_alloc(dev_tree_size,
2510                                           __alignof__(struct device_node)));
2511         if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + dev_tree_size)
2512                 BUG();
2513         rtas.dev = of_find_node_by_name(NULL, "rtas");
2514 }
2515
2516 int
2517 prom_n_addr_cells(struct device_node* np)
2518 {
2519         int* ip;
2520         do {
2521                 if (np->parent)
2522                         np = np->parent;
2523                 ip = (int *) get_property(np, "#address-cells", 0);
2524                 if (ip != NULL)
2525                         return *ip;
2526         } while (np->parent);
2527         /* No #address-cells property for the root node, default to 1 */
2528         return 1;
2529 }
2530
2531 int
2532 prom_n_size_cells(struct device_node* np)
2533 {
2534         int* ip;
2535         do {
2536                 if (np->parent)
2537                         np = np->parent;
2538                 ip = (int *) get_property(np, "#size-cells", 0);
2539                 if (ip != NULL)
2540                         return *ip;
2541         } while (np->parent);
2542         /* No #size-cells property for the root node, default to 1 */
2543         return 1;
2544 }
2545
2546 /*
2547  * Work out the sense (active-low level / active-high edge)
2548  * of each interrupt from the device tree.
2549  */
2550 void __init
2551 prom_get_irq_senses(unsigned char *senses, int off, int max)
2552 {
2553         struct device_node *np;
2554         int i, j;
2555
2556         /* default to level-triggered */
2557         memset(senses, 1, max - off);
2558
2559         for (np = allnodes; np != 0; np = np->allnext) {
2560                 for (j = 0; j < np->n_intrs; j++) {
2561                         i = np->intrs[j].line;
2562                         if (i >= off && i < max)
2563                                 senses[i-off] = np->intrs[j].sense;
2564                 }
2565         }
2566 }
2567
2568 /*
2569  * Construct and return a list of the device_nodes with a given name.
2570  */
2571 struct device_node *
2572 find_devices(const char *name)
2573 {
2574         struct device_node *head, **prevp, *np;
2575
2576         prevp = &head;
2577         for (np = allnodes; np != 0; np = np->allnext) {
2578                 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
2579                         *prevp = np;
2580                         prevp = &np->next;
2581                 }
2582         }
2583         *prevp = 0;
2584         return head;
2585 }
2586
2587 /*
2588  * Construct and return a list of the device_nodes with a given type.
2589  */
2590 struct device_node *
2591 find_type_devices(const char *type)
2592 {
2593         struct device_node *head, **prevp, *np;
2594
2595         prevp = &head;
2596         for (np = allnodes; np != 0; np = np->allnext) {
2597                 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
2598                         *prevp = np;
2599                         prevp = &np->next;
2600                 }
2601         }
2602         *prevp = 0;
2603         return head;
2604 }
2605
2606 /*
2607  * Returns all nodes linked together
2608  */
2609 struct device_node *
2610 find_all_nodes(void)
2611 {
2612         struct device_node *head, **prevp, *np;
2613
2614         prevp = &head;
2615         for (np = allnodes; np != 0; np = np->allnext) {
2616                 *prevp = np;
2617                 prevp = &np->next;
2618         }
2619         *prevp = 0;
2620         return head;
2621 }
2622
2623 /* Checks if the given "compat" string matches one of the strings in
2624  * the device's "compatible" property
2625  */
2626 int
2627 device_is_compatible(struct device_node *device, const char *compat)
2628 {
2629         const char* cp;
2630         int cplen, l;
2631
2632         cp = (char *) get_property(device, "compatible", &cplen);
2633         if (cp == NULL)
2634                 return 0;
2635         while (cplen > 0) {
2636                 if (strncasecmp(cp, compat, strlen(compat)) == 0)
2637                         return 1;
2638                 l = strlen(cp) + 1;
2639                 cp += l;
2640                 cplen -= l;
2641         }
2642
2643         return 0;
2644 }
2645
2646
2647 /*
2648  * Indicates whether the root node has a given value in its
2649  * compatible property.
2650  */
2651 int
2652 machine_is_compatible(const char *compat)
2653 {
2654         struct device_node *root;
2655         int rc = 0;
2656   
2657         root = of_find_node_by_path("/");
2658         if (root) {
2659                 rc = device_is_compatible(root, compat);
2660                 of_node_put(root);
2661         }
2662         return rc;
2663 }
2664
2665 /*
2666  * Construct and return a list of the device_nodes with a given type
2667  * and compatible property.
2668  */
2669 struct device_node *
2670 find_compatible_devices(const char *type, const char *compat)
2671 {
2672         struct device_node *head, **prevp, *np;
2673
2674         prevp = &head;
2675         for (np = allnodes; np != 0; np = np->allnext) {
2676                 if (type != NULL
2677                     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
2678                         continue;
2679                 if (device_is_compatible(np, compat)) {
2680                         *prevp = np;
2681                         prevp = &np->next;
2682                 }
2683         }
2684         *prevp = 0;
2685         return head;
2686 }
2687
2688 /*
2689  * Find the device_node with a given full_name.
2690  */
2691 struct device_node *
2692 find_path_device(const char *path)
2693 {
2694         struct device_node *np;
2695
2696         for (np = allnodes; np != 0; np = np->allnext)
2697                 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
2698                         return np;
2699         return NULL;
2700 }
2701
2702 /*******
2703  *
2704  * New implementation of the OF "find" APIs, return a refcounted
2705  * object, call of_node_put() when done.  The device tree and list
2706  * are protected by a rw_lock.
2707  *
2708  * Note that property management will need some locking as well,
2709  * this isn't dealt with yet.
2710  *
2711  *******/
2712
2713 /**
2714  *      of_find_node_by_name - Find a node by its "name" property
2715  *      @from:  The node to start searching from or NULL, the node
2716  *              you pass will not be searched, only the next one
2717  *              will; typically, you pass what the previous call
2718  *              returned. of_node_put() will be called on it
2719  *      @name:  The name string to match against
2720  *
2721  *      Returns a node pointer with refcount incremented, use
2722  *      of_node_put() on it when done.
2723  */
2724 struct device_node *of_find_node_by_name(struct device_node *from,
2725         const char *name)
2726 {
2727         struct device_node *np;
2728
2729         read_lock(&devtree_lock);
2730         np = from ? from->allnext : allnodes;
2731         for (; np != 0; np = np->allnext)
2732                 if (np->name != 0 && strcasecmp(np->name, name) == 0
2733                     && of_node_get(np))
2734                         break;
2735         if (from)
2736                 of_node_put(from);
2737         read_unlock(&devtree_lock);
2738         return np;
2739 }
2740 EXPORT_SYMBOL(of_find_node_by_name);
2741
2742 /**
2743  *      of_find_node_by_type - Find a node by its "device_type" property
2744  *      @from:  The node to start searching from or NULL, the node
2745  *              you pass will not be searched, only the next one
2746  *              will; typically, you pass what the previous call
2747  *              returned. of_node_put() will be called on it
2748  *      @name:  The type string to match against
2749  *
2750  *      Returns a node pointer with refcount incremented, use
2751  *      of_node_put() on it when done.
2752  */
2753 struct device_node *of_find_node_by_type(struct device_node *from,
2754         const char *type)
2755 {
2756         struct device_node *np;
2757
2758         read_lock(&devtree_lock);
2759         np = from ? from->allnext : allnodes;
2760         for (; np != 0; np = np->allnext)
2761                 if (np->type != 0 && strcasecmp(np->type, type) == 0
2762                     && of_node_get(np))
2763                         break;
2764         if (from)
2765                 of_node_put(from);
2766         read_unlock(&devtree_lock);
2767         return np;
2768 }
2769 EXPORT_SYMBOL(of_find_node_by_type);
2770
2771 /**
2772  *      of_find_compatible_node - Find a node based on type and one of the
2773  *                                tokens in its "compatible" property
2774  *      @from:          The node to start searching from or NULL, the node
2775  *                      you pass will not be searched, only the next one
2776  *                      will; typically, you pass what the previous call
2777  *                      returned. of_node_put() will be called on it
2778  *      @type:          The type string to match "device_type" or NULL to ignore
2779  *      @compatible:    The string to match to one of the tokens in the device
2780  *                      "compatible" list.
2781  *
2782  *      Returns a node pointer with refcount incremented, use
2783  *      of_node_put() on it when done.
2784  */
2785 struct device_node *of_find_compatible_node(struct device_node *from,
2786         const char *type, const char *compatible)
2787 {
2788         struct device_node *np;
2789
2790         read_lock(&devtree_lock);
2791         np = from ? from->allnext : allnodes;
2792         for (; np != 0; np = np->allnext) {
2793                 if (type != NULL
2794                     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
2795                         continue;
2796                 if (device_is_compatible(np, compatible) && of_node_get(np))
2797                         break;
2798         }
2799         if (from)
2800                 of_node_put(from);
2801         read_unlock(&devtree_lock);
2802         return np;
2803 }
2804 EXPORT_SYMBOL(of_find_compatible_node);
2805
2806 /**
2807  *      of_find_node_by_path - Find a node matching a full OF path
2808  *      @path:  The full path to match
2809  *
2810  *      Returns a node pointer with refcount incremented, use
2811  *      of_node_put() on it when done.
2812  */
2813 struct device_node *of_find_node_by_path(const char *path)
2814 {
2815         struct device_node *np = allnodes;
2816
2817         read_lock(&devtree_lock);
2818         for (; np != 0; np = np->allnext)
2819                 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
2820                     && of_node_get(np))
2821                         break;
2822         read_unlock(&devtree_lock);
2823         return np;
2824 }
2825 EXPORT_SYMBOL(of_find_node_by_path);
2826
2827 /**
2828  *      of_find_all_nodes - Get next node in global list
2829  *      @prev:  Previous node or NULL to start iteration
2830  *              of_node_put() will be called on it
2831  *
2832  *      Returns a node pointer with refcount incremented, use
2833  *      of_node_put() on it when done.
2834  */
2835 struct device_node *of_find_all_nodes(struct device_node *prev)
2836 {
2837         struct device_node *np;
2838
2839         read_lock(&devtree_lock);
2840         np = prev ? prev->allnext : allnodes;
2841         for (; np != 0; np = np->allnext)
2842                 if (of_node_get(np))
2843                         break;
2844         if (prev)
2845                 of_node_put(prev);
2846         read_unlock(&devtree_lock);
2847         return np;
2848 }
2849 EXPORT_SYMBOL(of_find_all_nodes);
2850
2851 /**
2852  *      of_get_parent - Get a node's parent if any
2853  *      @node:  Node to get parent
2854  *
2855  *      Returns a node pointer with refcount incremented, use
2856  *      of_node_put() on it when done.
2857  */
2858 struct device_node *of_get_parent(const struct device_node *node)
2859 {
2860         struct device_node *np;
2861
2862         if (!node)
2863                 return NULL;
2864
2865         read_lock(&devtree_lock);
2866         np = of_node_get(node->parent);
2867         read_unlock(&devtree_lock);
2868         return np;
2869 }
2870 EXPORT_SYMBOL(of_get_parent);
2871
2872 /**
2873  *      of_get_next_child - Iterate a node childs
2874  *      @node:  parent node
2875  *      @prev:  previous child of the parent node, or NULL to get first
2876  *
2877  *      Returns a node pointer with refcount incremented, use
2878  *      of_node_put() on it when done.
2879  */
2880 struct device_node *of_get_next_child(const struct device_node *node,
2881         struct device_node *prev)
2882 {
2883         struct device_node *next;
2884
2885         read_lock(&devtree_lock);
2886         next = prev ? prev->sibling : node->child;
2887         for (; next != 0; next = next->sibling)
2888                 if (of_node_get(next))
2889                         break;
2890         if (prev)
2891                 of_node_put(prev);
2892         read_unlock(&devtree_lock);
2893         return next;
2894 }
2895 EXPORT_SYMBOL(of_get_next_child);
2896
2897 /**
2898  *      of_node_get - Increment refcount of a node
2899  *      @node:  Node to inc refcount, NULL is supported to
2900  *              simplify writing of callers
2901  *
2902  *      Returns the node itself or NULL if gone.
2903  */
2904 struct device_node *of_node_get(struct device_node *node)
2905 {
2906         if (node && !OF_IS_STALE(node)) {
2907                 atomic_inc(&node->_users);
2908                 return node;
2909         }
2910         return NULL;
2911 }
2912 EXPORT_SYMBOL(of_node_get);
2913
2914 /**
2915  *      of_node_cleanup - release a dynamically allocated node
2916  *      @arg:  Node to be released
2917  */
2918 static void of_node_cleanup(struct device_node *node)
2919 {
2920         struct property *prop = node->properties;
2921
2922         if (!OF_IS_DYNAMIC(node))
2923                 return;
2924         while (prop) {
2925                 struct property *next = prop->next;
2926                 kfree(prop->name);
2927                 kfree(prop->value);
2928                 kfree(prop);
2929                 prop = next;
2930         }
2931         kfree(node->intrs);
2932         kfree(node->addrs);
2933         kfree(node->full_name);
2934         kfree(node);
2935 }
2936
2937 /**
2938  *      of_node_put - Decrement refcount of a node
2939  *      @node:  Node to dec refcount, NULL is supported to
2940  *              simplify writing of callers
2941  *
2942  */
2943 void of_node_put(struct device_node *node)
2944 {
2945         if (!node)
2946                 return;
2947
2948         WARN_ON(0 == atomic_read(&node->_users));
2949
2950         if (OF_IS_STALE(node)) {
2951                 if (atomic_dec_and_test(&node->_users)) {
2952                         of_node_cleanup(node);
2953                         return;
2954                 }
2955         }
2956         else
2957                 atomic_dec(&node->_users);
2958 }
2959 EXPORT_SYMBOL(of_node_put);
2960
2961 /**
2962  *      derive_parent - basically like dirname(1)
2963  *      @path:  the full_name of a node to be added to the tree
2964  *
2965  *      Returns the node which should be the parent of the node
2966  *      described by path.  E.g., for path = "/foo/bar", returns
2967  *      the node with full_name = "/foo".
2968  */
2969 static struct device_node *derive_parent(const char *path)
2970 {
2971         struct device_node *parent = NULL;
2972         char *parent_path = "/";
2973         size_t parent_path_len = strrchr(path, '/') - path + 1;
2974
2975         /* reject if path is "/" */
2976         if (!strcmp(path, "/"))
2977                 return NULL;
2978
2979         if (strrchr(path, '/') != path) {
2980                 parent_path = kmalloc(parent_path_len, GFP_KERNEL);
2981                 if (!parent_path)
2982                         return NULL;
2983                 strlcpy(parent_path, path, parent_path_len);
2984         }
2985         parent = of_find_node_by_path(parent_path);
2986         if (strcmp(parent_path, "/"))
2987                 kfree(parent_path);
2988         return parent;
2989 }
2990
2991 /*
2992  * Routines for "runtime" addition and removal of device tree nodes.
2993  */
2994 #ifdef CONFIG_PROC_DEVICETREE
2995 /*
2996  * Add a node to /proc/device-tree.
2997  */
2998 static void add_node_proc_entries(struct device_node *np)
2999 {
3000         struct proc_dir_entry *ent;
3001
3002         ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
3003         if (ent)
3004                 proc_device_tree_add_node(np, ent);
3005 }
3006
3007 static void remove_node_proc_entries(struct device_node *np)
3008 {
3009         struct property *pp = np->properties;
3010         struct device_node *parent = np->parent;
3011
3012         while (pp) {
3013                 remove_proc_entry(pp->name, np->pde);
3014                 pp = pp->next;
3015         }
3016
3017         /* Assuming that symlinks have the same parent directory as
3018          * np->pde.
3019          */
3020         if (np->name_link)
3021                 remove_proc_entry(np->name_link->name, parent->pde);
3022         if (np->addr_link)
3023                 remove_proc_entry(np->addr_link->name, parent->pde);
3024         if (np->pde)
3025                 remove_proc_entry(np->pde->name, parent->pde);
3026 }
3027 #else /* !CONFIG_PROC_DEVICETREE */
3028 static void add_node_proc_entries(struct device_node *np)
3029 {
3030         return;
3031 }
3032
3033 static void remove_node_proc_entries(struct device_node *np)
3034 {
3035         return;
3036 }
3037 #endif /* CONFIG_PROC_DEVICETREE */
3038
3039 /*
3040  * Fix up n_intrs and intrs fields in a new device node
3041  *
3042  */
3043 static int of_finish_dynamic_node_interrupts(struct device_node *node)
3044 {
3045         int intrcells, intlen, i;
3046         unsigned *irq, *ints, virq;
3047         struct device_node *ic;
3048
3049         ints = (unsigned int *)get_property(node, "interrupts", &intlen);
3050         intrcells = prom_n_intr_cells(node);
3051         intlen /= intrcells * sizeof(unsigned int);
3052         node->n_intrs = intlen;
3053         node->intrs = kmalloc(sizeof(struct interrupt_info) * intlen,
3054                               GFP_KERNEL);
3055         if (!node->intrs)
3056                 return -ENOMEM;
3057
3058         for (i = 0; i < intlen; ++i) {
3059                 int n, j;
3060                 node->intrs[i].line = 0;
3061                 node->intrs[i].sense = 1;
3062                 n = map_interrupt(&irq, &ic, node, ints, intrcells);
3063                 if (n <= 0)
3064                         continue;
3065                 virq = virt_irq_create_mapping(irq[0]);
3066                 if (virq == NO_IRQ) {
3067                         printk(KERN_CRIT "Could not allocate interrupt "
3068                                "number for %s\n", node->full_name);
3069                         return -ENOMEM;
3070                 }
3071                 node->intrs[i].line = irq_offset_up(virq);
3072                 if (n > 1)
3073                         node->intrs[i].sense = irq[1];
3074                 if (n > 2) {
3075                         printk(KERN_DEBUG "hmmm, got %d intr cells for %s:", n,
3076                                node->full_name);
3077                         for (j = 0; j < n; ++j)
3078                                 printk(" %d", irq[j]);
3079                         printk("\n");
3080                 }
3081                 ints += intrcells;
3082         }
3083         return 0;
3084 }
3085
3086 /*
3087  * Fix up the uninitialized fields in a new device node:
3088  * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
3089  *
3090  * A lot of boot-time code is duplicated here, because functions such
3091  * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
3092  * slab allocator.
3093  *
3094  * This should probably be split up into smaller chunks.
3095  */
3096
3097 static int of_finish_dynamic_node(struct device_node *node)
3098 {
3099         struct device_node *parent = of_get_parent(node);
3100         u32 *regs;
3101         int err = 0;
3102         phandle *ibm_phandle;
3103  
3104         node->name = get_property(node, "name", 0);
3105         node->type = get_property(node, "device_type", 0);
3106
3107         if (!parent) {
3108                 err = -ENODEV;
3109                 goto out;
3110         }
3111
3112         /* We don't support that function on PowerMac, at least
3113          * not yet
3114          */
3115         if (systemcfg->platform == PLATFORM_POWERMAC)
3116                 return -ENODEV;
3117
3118         /* fix up new node's linux_phandle field */
3119         if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
3120                 node->linux_phandle = *ibm_phandle;
3121
3122         /* do the work of interpret_pci_props */
3123         if (parent->type && !strcmp(parent->type, "pci")) {
3124                 struct address_range *adr;
3125                 struct pci_reg_property *pci_addrs;
3126                 int i, l;
3127
3128                 pci_addrs = (struct pci_reg_property *)
3129                         get_property(node, "assigned-addresses", &l);
3130                 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
3131                         i = 0;
3132                         adr = kmalloc(sizeof(struct address_range) * 
3133                                       (l / sizeof(struct pci_reg_property)),
3134                                       GFP_KERNEL);
3135                         if (!adr) {
3136                                 err = -ENOMEM;
3137                                 goto out;
3138                         }
3139                         while ((l -= sizeof(struct pci_reg_property)) >= 0) {
3140                                 adr[i].space = pci_addrs[i].addr.a_hi;
3141                                 adr[i].address = pci_addrs[i].addr.a_lo;
3142                                 adr[i].size = pci_addrs[i].size_lo;
3143                                 ++i;
3144                         }
3145                         node->addrs = adr;
3146                         node->n_addrs = i;
3147                 }
3148         }
3149
3150         /* now do the work of finish_node_interrupts */
3151         if (get_property(node, "interrupts", 0)) {
3152                 err = of_finish_dynamic_node_interrupts(node);
3153                 if (err) goto out;
3154         }
3155
3156        /* now do the rough equivalent of update_dn_pci_info, this
3157         * probably is not correct for phb's, but should work for
3158         * IOAs and slots.
3159         */
3160
3161        node->phb = parent->phb;
3162
3163        regs = (u32 *)get_property(node, "reg", 0);
3164        if (regs) {
3165                node->busno = (regs[0] >> 16) & 0xff;
3166                node->devfn = (regs[0] >> 8) & 0xff;
3167        }
3168
3169         /* fixing up iommu_table */
3170
3171         if(strcmp(node->name, "pci") == 0 &&
3172                 get_property(node, "ibm,dma-window", NULL)) {
3173                 node->bussubno = node->busno;
3174                 iommu_devnode_init(node);
3175         }
3176         else
3177                 node->iommu_table = parent->iommu_table;
3178
3179 out:
3180         of_node_put(parent);
3181         return err;
3182 }
3183
3184 /*
3185  * Given a path and a property list, construct an OF device node, add
3186  * it to the device tree and global list, and place it in
3187  * /proc/device-tree.  This function may sleep.
3188  */
3189 int of_add_node(const char *path, struct property *proplist)
3190 {
3191         struct device_node *np;
3192         int err = 0;
3193
3194         np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
3195         if (!np)
3196                 return -ENOMEM;
3197
3198         memset(np, 0, sizeof(*np));
3199
3200         np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
3201         if (!np->full_name) {
3202                 kfree(np);
3203                 return -ENOMEM;
3204         }
3205         strcpy(np->full_name, path);
3206
3207         np->properties = proplist;
3208         OF_MARK_DYNAMIC(np);
3209         of_node_get(np);
3210         np->parent = derive_parent(path);
3211         if (!np->parent) {
3212                 kfree(np);
3213                 return -EINVAL; /* could also be ENOMEM, though */
3214         }
3215
3216         if (0 != (err = of_finish_dynamic_node(np))) {
3217                 kfree(np);
3218                 return err;
3219         }
3220
3221         write_lock(&devtree_lock);
3222         np->sibling = np->parent->child;
3223         np->allnext = allnodes;
3224         np->parent->child = np;
3225         allnodes = np;
3226         write_unlock(&devtree_lock);
3227
3228         add_node_proc_entries(np);
3229
3230         of_node_put(np->parent);
3231         of_node_put(np);
3232         return 0;
3233 }
3234
3235 /*
3236  * Remove an OF device node from the system.
3237  * Caller should have already "gotten" np.
3238  */
3239 int of_remove_node(struct device_node *np)
3240 {
3241         struct device_node *parent, *child;
3242
3243         parent = of_get_parent(np);
3244         if (!parent)
3245                 return -EINVAL;
3246
3247         if ((child = of_get_next_child(np, NULL))) {
3248                 of_node_put(child);
3249                 return -EBUSY;
3250         }
3251
3252         write_lock(&devtree_lock);
3253         OF_MARK_STALE(np);
3254         remove_node_proc_entries(np);
3255         if (allnodes == np)
3256                 allnodes = np->allnext;
3257         else {
3258                 struct device_node *prev;
3259                 for (prev = allnodes;
3260                      prev->allnext != np;
3261                      prev = prev->allnext)
3262                         ;
3263                 prev->allnext = np->allnext;
3264         }
3265
3266         if (parent->child == np)
3267                 parent->child = np->sibling;
3268         else {
3269                 struct device_node *prevsib;
3270                 for (prevsib = np->parent->child;
3271                      prevsib->sibling != np;
3272                      prevsib = prevsib->sibling)
3273                         ;
3274                 prevsib->sibling = np->sibling;
3275         }
3276         write_unlock(&devtree_lock);
3277         of_node_put(parent);
3278         return 0;
3279 }
3280
3281 /*
3282  * Find a property with a given name for a given node
3283  * and return the value.
3284  */
3285 unsigned char *
3286 get_property(struct device_node *np, const char *name, int *lenp)
3287 {
3288         struct property *pp;
3289
3290         for (pp = np->properties; pp != 0; pp = pp->next)
3291                 if (strcmp(pp->name, name) == 0) {
3292                         if (lenp != 0)
3293                                 *lenp = pp->length;
3294                         return pp->value;
3295                 }
3296         return 0;
3297 }
3298
3299 /*
3300  * Add a property to a node
3301  */
3302 void
3303 prom_add_property(struct device_node* np, struct property* prop)
3304 {
3305         struct property **next = &np->properties;
3306
3307         prop->next = NULL;      
3308         while (*next)
3309                 next = &(*next)->next;
3310         *next = prop;
3311 }
3312
3313 #if 0
3314 void
3315 print_properties(struct device_node *np)
3316 {
3317         struct property *pp;
3318         char *cp;
3319         int i, n;
3320
3321         for (pp = np->properties; pp != 0; pp = pp->next) {
3322                 printk(KERN_INFO "%s", pp->name);
3323                 for (i = strlen(pp->name); i < 16; ++i)
3324                         printk(" ");
3325                 cp = (char *) pp->value;
3326                 for (i = pp->length; i > 0; --i, ++cp)
3327                         if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
3328                             || (i == 1 && *cp != 0))
3329                                 break;
3330                 if (i == 0 && pp->length > 1) {
3331                         /* looks like a string */
3332                         printk(" %s\n", (char *) pp->value);
3333                 } else {
3334                         /* dump it in hex */
3335                         n = pp->length;
3336                         if (n > 64)
3337                                 n = 64;
3338                         if (pp->length % 4 == 0) {
3339                                 unsigned int *p = (unsigned int *) pp->value;
3340
3341                                 n /= 4;
3342                                 for (i = 0; i < n; ++i) {
3343                                         if (i != 0 && (i % 4) == 0)
3344                                                 printk("\n                ");
3345                                         printk(" %08x", *p++);
3346                                 }
3347                         } else {
3348                                 unsigned char *bp = pp->value;
3349
3350                                 for (i = 0; i < n; ++i) {
3351                                         if (i != 0 && (i % 16) == 0)
3352                                                 printk("\n                ");
3353                                         printk(" %02x", *bp++);
3354                                 }
3355                         }
3356                         printk("\n");
3357                         if (pp->length > 64)
3358                                 printk("                 ... (length = %d)\n",
3359                                        pp->length);
3360                 }
3361         }
3362 }
3363 #endif