ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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 #ifdef DEBUG_IRQ
2193         if (p == NULL)
2194                 printk("hmmm, int tree for %s doesn't have ctrler\n",
2195                        np->full_name);
2196 #endif
2197         *irq = ints;
2198         *ictrler = p;
2199         return nintrc;
2200 }
2201
2202 static unsigned long __init
2203 finish_node_interrupts(struct device_node *np, unsigned long mem_start,
2204                        int measure_only)
2205 {
2206         unsigned int *ints;
2207         int intlen, intrcells;
2208         int i, j, n;
2209         unsigned int *irq, virq;
2210         struct device_node *ic;
2211
2212         ints = (unsigned int *) get_property(np, "interrupts", &intlen);
2213         if (ints == NULL)
2214                 return mem_start;
2215         intrcells = prom_n_intr_cells(np);
2216         intlen /= intrcells * sizeof(unsigned int);
2217         np->n_intrs = intlen;
2218         np->intrs = (struct interrupt_info *) mem_start;
2219         mem_start += intlen * sizeof(struct interrupt_info);
2220
2221         if (measure_only)
2222                 return mem_start;
2223
2224         for (i = 0; i < intlen; ++i) {
2225                 np->intrs[i].line = 0;
2226                 np->intrs[i].sense = 1;
2227                 n = map_interrupt(&irq, &ic, np, ints, intrcells);
2228                 if (n <= 0)
2229                         continue;
2230                 virq = virt_irq_create_mapping(irq[0]);
2231                 if (virq == NO_IRQ) {
2232                         printk(KERN_CRIT "Could not allocate interrupt "
2233                                "number for %s\n", np->full_name);
2234                 } else
2235                         np->intrs[i].line = irq_offset_up(virq);
2236
2237                 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
2238                 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
2239                         char *name = get_property(ic->parent, "name", NULL);
2240                         if (name && !strcmp(name, "u3"))
2241                                 np->intrs[i].line += 128;
2242                 }
2243                 if (n > 1)
2244                         np->intrs[i].sense = irq[1];
2245                 if (n > 2) {
2246                         printk("hmmm, got %d intr cells for %s:", n,
2247                                np->full_name);
2248                         for (j = 0; j < n; ++j)
2249                                 printk(" %d", irq[j]);
2250                         printk("\n");
2251                 }
2252                 ints += intrcells;
2253         }
2254
2255         return mem_start;
2256 }
2257
2258 static unsigned long __init
2259 interpret_pci_props(struct device_node *np, unsigned long mem_start,
2260                     int naddrc, int nsizec, int measure_only)
2261 {
2262         struct address_range *adr;
2263         struct pci_reg_property *pci_addrs;
2264         int i, l;
2265
2266         pci_addrs = (struct pci_reg_property *)
2267                 get_property(np, "assigned-addresses", &l);
2268         if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
2269                 i = 0;
2270                 adr = (struct address_range *) mem_start;
2271                 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
2272                         if (!measure_only) {
2273                                 adr[i].space = pci_addrs[i].addr.a_hi;
2274                                 adr[i].address = pci_addrs[i].addr.a_lo;
2275                                 adr[i].size = pci_addrs[i].size_lo;
2276                         }
2277                         ++i;
2278                 }
2279                 np->addrs = adr;
2280                 np->n_addrs = i;
2281                 mem_start += i * sizeof(struct address_range);
2282         }
2283         return mem_start;
2284 }
2285
2286 static unsigned long __init
2287 interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
2288                       int naddrc, int nsizec, int measure_only)
2289 {
2290         struct reg_property32 *rp;
2291         struct address_range *adr;
2292         unsigned long base_address;
2293         int i, l;
2294         struct device_node *db;
2295
2296         base_address = 0;
2297         if (!measure_only) {
2298                 for (db = np->parent; db != NULL; db = db->parent) {
2299                         if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
2300                                 base_address = db->addrs[0].address;
2301                                 break;
2302                         }
2303                 }
2304         }
2305
2306         rp = (struct reg_property32 *) get_property(np, "reg", &l);
2307         if (rp != 0 && l >= sizeof(struct reg_property32)) {
2308                 i = 0;
2309                 adr = (struct address_range *) mem_start;
2310                 while ((l -= sizeof(struct reg_property32)) >= 0) {
2311                         if (!measure_only) {
2312                                 adr[i].space = 2;
2313                                 adr[i].address = rp[i].address + base_address;
2314                                 adr[i].size = rp[i].size;
2315                         }
2316                         ++i;
2317                 }
2318                 np->addrs = adr;
2319                 np->n_addrs = i;
2320                 mem_start += i * sizeof(struct address_range);
2321         }
2322
2323         return mem_start;
2324 }
2325
2326 static unsigned long __init
2327 interpret_macio_props(struct device_node *np, unsigned long mem_start,
2328                       int naddrc, int nsizec, int measure_only)
2329 {
2330         struct reg_property32 *rp;
2331         struct address_range *adr;
2332         unsigned long base_address;
2333         int i, l;
2334         struct device_node *db;
2335
2336         base_address = 0;
2337         if (!measure_only) {
2338                 for (db = np->parent; db != NULL; db = db->parent) {
2339                         if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
2340                                 base_address = db->addrs[0].address;
2341                                 break;
2342                         }
2343                 }
2344         }
2345
2346         rp = (struct reg_property32 *) get_property(np, "reg", &l);
2347         if (rp != 0 && l >= sizeof(struct reg_property32)) {
2348                 i = 0;
2349                 adr = (struct address_range *) mem_start;
2350                 while ((l -= sizeof(struct reg_property32)) >= 0) {
2351                         if (!measure_only) {
2352                                 adr[i].space = 2;
2353                                 adr[i].address = rp[i].address + base_address;
2354                                 adr[i].size = rp[i].size;
2355                         }
2356                         ++i;
2357                 }
2358                 np->addrs = adr;
2359                 np->n_addrs = i;
2360                 mem_start += i * sizeof(struct address_range);
2361         }
2362
2363         return mem_start;
2364 }
2365
2366 static unsigned long __init
2367 interpret_isa_props(struct device_node *np, unsigned long mem_start,
2368                     int naddrc, int nsizec, int measure_only)
2369 {
2370         struct isa_reg_property *rp;
2371         struct address_range *adr;
2372         int i, l;
2373
2374         rp = (struct isa_reg_property *) get_property(np, "reg", &l);
2375         if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
2376                 i = 0;
2377                 adr = (struct address_range *) mem_start;
2378                 while ((l -= sizeof(struct reg_property)) >= 0) {
2379                         if (!measure_only) {
2380                                 adr[i].space = rp[i].space;
2381                                 adr[i].address = rp[i].address;
2382                                 adr[i].size = rp[i].size;
2383                         }
2384                         ++i;
2385                 }
2386                 np->addrs = adr;
2387                 np->n_addrs = i;
2388                 mem_start += i * sizeof(struct address_range);
2389         }
2390
2391         return mem_start;
2392 }
2393
2394 static unsigned long __init
2395 interpret_root_props(struct device_node *np, unsigned long mem_start,
2396                      int naddrc, int nsizec, int measure_only)
2397 {
2398         struct address_range *adr;
2399         int i, l;
2400         unsigned int *rp;
2401         int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
2402
2403         rp = (unsigned int *) get_property(np, "reg", &l);
2404         if (rp != 0 && l >= rpsize) {
2405                 i = 0;
2406                 adr = (struct address_range *) mem_start;
2407                 while ((l -= rpsize) >= 0) {
2408                         if (!measure_only) {
2409                                 adr[i].space = 0;
2410                                 adr[i].address = rp[naddrc - 1];
2411                                 adr[i].size = rp[naddrc + nsizec - 1];
2412                         }
2413                         ++i;
2414                         rp += naddrc + nsizec;
2415                 }
2416                 np->addrs = adr;
2417                 np->n_addrs = i;
2418                 mem_start += i * sizeof(struct address_range);
2419         }
2420
2421         return mem_start;
2422 }
2423
2424 static unsigned long __init
2425 finish_node(struct device_node *np, unsigned long mem_start,
2426             interpret_func *ifunc, int naddrc, int nsizec, int measure_only)
2427 {
2428         struct device_node *child;
2429         int *ip;
2430
2431         np->name = get_property(np, "name", 0);
2432         np->type = get_property(np, "device_type", 0);
2433
2434         if (!np->name)
2435                 np->name = "<NULL>";
2436         if (!np->type)
2437                 np->type = "<NULL>";
2438
2439         /* get the device addresses and interrupts */
2440         if (ifunc != NULL)
2441                 mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
2442
2443         mem_start = finish_node_interrupts(np, mem_start, measure_only);
2444
2445         /* Look for #address-cells and #size-cells properties. */
2446         ip = (int *) get_property(np, "#address-cells", 0);
2447         if (ip != NULL)
2448                 naddrc = *ip;
2449         ip = (int *) get_property(np, "#size-cells", 0);
2450         if (ip != NULL)
2451                 nsizec = *ip;
2452
2453         /* the f50 sets the name to 'display' and 'compatible' to what we
2454          * expect for the name -- Cort
2455          */
2456         if (!strcmp(np->name, "display"))
2457                 np->name = get_property(np, "compatible", 0);
2458
2459         if (!strcmp(np->name, "device-tree") || np->parent == NULL)
2460                 ifunc = interpret_root_props;
2461         else if (np->type == 0)
2462                 ifunc = NULL;
2463         else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
2464                 ifunc = interpret_pci_props;
2465         else if (!strcmp(np->type, "dbdma"))
2466                 ifunc = interpret_dbdma_props;
2467         else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
2468                 ifunc = interpret_macio_props;
2469         else if (!strcmp(np->type, "isa"))
2470                 ifunc = interpret_isa_props;
2471         else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
2472                 ifunc = interpret_root_props;
2473         else if (!((ifunc == interpret_dbdma_props
2474                     || ifunc == interpret_macio_props)
2475                    && (!strcmp(np->type, "escc")
2476                        || !strcmp(np->type, "media-bay"))))
2477                 ifunc = NULL;
2478
2479         for (child = np->child; child != NULL; child = child->sibling)
2480                 mem_start = finish_node(child, mem_start, ifunc,
2481                                         naddrc, nsizec, measure_only);
2482
2483         return mem_start;
2484 }
2485
2486 /*
2487  * finish_device_tree is called once things are running normally
2488  * (i.e. with text and data mapped to the address they were linked at).
2489  * It traverses the device tree and fills in the name, type,
2490  * {n_}addrs and {n_}intrs fields of each node.
2491  */
2492 void __init
2493 finish_device_tree(void)
2494 {
2495         unsigned long mem = klimit;
2496
2497         virt_irq_init();
2498
2499         dev_tree_size = finish_node(allnodes, 0, NULL, 0, 0, 1);
2500         mem = (long)abs_to_virt(lmb_alloc(dev_tree_size,
2501                                           __alignof__(struct device_node)));
2502         if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + dev_tree_size)
2503                 BUG();
2504         rtas.dev = of_find_node_by_name(NULL, "rtas");
2505 }
2506
2507 int
2508 prom_n_addr_cells(struct device_node* np)
2509 {
2510         int* ip;
2511         do {
2512                 if (np->parent)
2513                         np = np->parent;
2514                 ip = (int *) get_property(np, "#address-cells", 0);
2515                 if (ip != NULL)
2516                         return *ip;
2517         } while (np->parent);
2518         /* No #address-cells property for the root node, default to 1 */
2519         return 1;
2520 }
2521
2522 int
2523 prom_n_size_cells(struct device_node* np)
2524 {
2525         int* ip;
2526         do {
2527                 if (np->parent)
2528                         np = np->parent;
2529                 ip = (int *) get_property(np, "#size-cells", 0);
2530                 if (ip != NULL)
2531                         return *ip;
2532         } while (np->parent);
2533         /* No #size-cells property for the root node, default to 1 */
2534         return 1;
2535 }
2536
2537 /*
2538  * Work out the sense (active-low level / active-high edge)
2539  * of each interrupt from the device tree.
2540  */
2541 void __init
2542 prom_get_irq_senses(unsigned char *senses, int off, int max)
2543 {
2544         struct device_node *np;
2545         int i, j;
2546
2547         /* default to level-triggered */
2548         memset(senses, 1, max - off);
2549
2550         for (np = allnodes; np != 0; np = np->allnext) {
2551                 for (j = 0; j < np->n_intrs; j++) {
2552                         i = np->intrs[j].line;
2553                         if (i >= off && i < max)
2554                                 senses[i-off] = np->intrs[j].sense;
2555                 }
2556         }
2557 }
2558
2559 /*
2560  * Construct and return a list of the device_nodes with a given name.
2561  */
2562 struct device_node *
2563 find_devices(const char *name)
2564 {
2565         struct device_node *head, **prevp, *np;
2566
2567         prevp = &head;
2568         for (np = allnodes; np != 0; np = np->allnext) {
2569                 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
2570                         *prevp = np;
2571                         prevp = &np->next;
2572                 }
2573         }
2574         *prevp = 0;
2575         return head;
2576 }
2577
2578 /*
2579  * Construct and return a list of the device_nodes with a given type.
2580  */
2581 struct device_node *
2582 find_type_devices(const char *type)
2583 {
2584         struct device_node *head, **prevp, *np;
2585
2586         prevp = &head;
2587         for (np = allnodes; np != 0; np = np->allnext) {
2588                 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
2589                         *prevp = np;
2590                         prevp = &np->next;
2591                 }
2592         }
2593         *prevp = 0;
2594         return head;
2595 }
2596
2597 /*
2598  * Returns all nodes linked together
2599  */
2600 struct device_node *
2601 find_all_nodes(void)
2602 {
2603         struct device_node *head, **prevp, *np;
2604
2605         prevp = &head;
2606         for (np = allnodes; np != 0; np = np->allnext) {
2607                 *prevp = np;
2608                 prevp = &np->next;
2609         }
2610         *prevp = 0;
2611         return head;
2612 }
2613
2614 /* Checks if the given "compat" string matches one of the strings in
2615  * the device's "compatible" property
2616  */
2617 int
2618 device_is_compatible(struct device_node *device, const char *compat)
2619 {
2620         const char* cp;
2621         int cplen, l;
2622
2623         cp = (char *) get_property(device, "compatible", &cplen);
2624         if (cp == NULL)
2625                 return 0;
2626         while (cplen > 0) {
2627                 if (strncasecmp(cp, compat, strlen(compat)) == 0)
2628                         return 1;
2629                 l = strlen(cp) + 1;
2630                 cp += l;
2631                 cplen -= l;
2632         }
2633
2634         return 0;
2635 }
2636
2637
2638 /*
2639  * Indicates whether the root node has a given value in its
2640  * compatible property.
2641  */
2642 int
2643 machine_is_compatible(const char *compat)
2644 {
2645         struct device_node *root;
2646         int rc = 0;
2647   
2648         root = of_find_node_by_path("/");
2649         if (root) {
2650                 rc = device_is_compatible(root, compat);
2651                 of_node_put(root);
2652         }
2653         return rc;
2654 }
2655
2656 /*
2657  * Construct and return a list of the device_nodes with a given type
2658  * and compatible property.
2659  */
2660 struct device_node *
2661 find_compatible_devices(const char *type, const char *compat)
2662 {
2663         struct device_node *head, **prevp, *np;
2664
2665         prevp = &head;
2666         for (np = allnodes; np != 0; np = np->allnext) {
2667                 if (type != NULL
2668                     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
2669                         continue;
2670                 if (device_is_compatible(np, compat)) {
2671                         *prevp = np;
2672                         prevp = &np->next;
2673                 }
2674         }
2675         *prevp = 0;
2676         return head;
2677 }
2678
2679 /*
2680  * Find the device_node with a given full_name.
2681  */
2682 struct device_node *
2683 find_path_device(const char *path)
2684 {
2685         struct device_node *np;
2686
2687         for (np = allnodes; np != 0; np = np->allnext)
2688                 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
2689                         return np;
2690         return NULL;
2691 }
2692
2693 /*******
2694  *
2695  * New implementation of the OF "find" APIs, return a refcounted
2696  * object, call of_node_put() when done.  The device tree and list
2697  * are protected by a rw_lock.
2698  *
2699  * Note that property management will need some locking as well,
2700  * this isn't dealt with yet.
2701  *
2702  *******/
2703
2704 /**
2705  *      of_find_node_by_name - Find a node by its "name" property
2706  *      @from:  The node to start searching from or NULL, the node
2707  *              you pass will not be searched, only the next one
2708  *              will; typically, you pass what the previous call
2709  *              returned. of_node_put() will be called on it
2710  *      @name:  The name string to match against
2711  *
2712  *      Returns a node pointer with refcount incremented, use
2713  *      of_node_put() on it when done.
2714  */
2715 struct device_node *of_find_node_by_name(struct device_node *from,
2716         const char *name)
2717 {
2718         struct device_node *np;
2719
2720         read_lock(&devtree_lock);
2721         np = from ? from->allnext : allnodes;
2722         for (; np != 0; np = np->allnext)
2723                 if (np->name != 0 && strcasecmp(np->name, name) == 0
2724                     && of_node_get(np))
2725                         break;
2726         if (from)
2727                 of_node_put(from);
2728         read_unlock(&devtree_lock);
2729         return np;
2730 }
2731 EXPORT_SYMBOL(of_find_node_by_name);
2732
2733 /**
2734  *      of_find_node_by_type - Find a node by its "device_type" property
2735  *      @from:  The node to start searching from or NULL, the node
2736  *              you pass will not be searched, only the next one
2737  *              will; typically, you pass what the previous call
2738  *              returned. of_node_put() will be called on it
2739  *      @name:  The type string to match against
2740  *
2741  *      Returns a node pointer with refcount incremented, use
2742  *      of_node_put() on it when done.
2743  */
2744 struct device_node *of_find_node_by_type(struct device_node *from,
2745         const char *type)
2746 {
2747         struct device_node *np;
2748
2749         read_lock(&devtree_lock);
2750         np = from ? from->allnext : allnodes;
2751         for (; np != 0; np = np->allnext)
2752                 if (np->type != 0 && strcasecmp(np->type, type) == 0
2753                     && of_node_get(np))
2754                         break;
2755         if (from)
2756                 of_node_put(from);
2757         read_unlock(&devtree_lock);
2758         return np;
2759 }
2760 EXPORT_SYMBOL(of_find_node_by_type);
2761
2762 /**
2763  *      of_find_compatible_node - Find a node based on type and one of the
2764  *                                tokens in its "compatible" property
2765  *      @from:          The node to start searching from or NULL, the node
2766  *                      you pass will not be searched, only the next one
2767  *                      will; typically, you pass what the previous call
2768  *                      returned. of_node_put() will be called on it
2769  *      @type:          The type string to match "device_type" or NULL to ignore
2770  *      @compatible:    The string to match to one of the tokens in the device
2771  *                      "compatible" list.
2772  *
2773  *      Returns a node pointer with refcount incremented, use
2774  *      of_node_put() on it when done.
2775  */
2776 struct device_node *of_find_compatible_node(struct device_node *from,
2777         const char *type, const char *compatible)
2778 {
2779         struct device_node *np;
2780
2781         read_lock(&devtree_lock);
2782         np = from ? from->allnext : allnodes;
2783         for (; np != 0; np = np->allnext) {
2784                 if (type != NULL
2785                     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
2786                         continue;
2787                 if (device_is_compatible(np, compatible) && of_node_get(np))
2788                         break;
2789         }
2790         if (from)
2791                 of_node_put(from);
2792         read_unlock(&devtree_lock);
2793         return np;
2794 }
2795 EXPORT_SYMBOL(of_find_compatible_node);
2796
2797 /**
2798  *      of_find_node_by_path - Find a node matching a full OF path
2799  *      @path:  The full path to match
2800  *
2801  *      Returns a node pointer with refcount incremented, use
2802  *      of_node_put() on it when done.
2803  */
2804 struct device_node *of_find_node_by_path(const char *path)
2805 {
2806         struct device_node *np = allnodes;
2807
2808         read_lock(&devtree_lock);
2809         for (; np != 0; np = np->allnext)
2810                 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
2811                     && of_node_get(np))
2812                         break;
2813         read_unlock(&devtree_lock);
2814         return np;
2815 }
2816 EXPORT_SYMBOL(of_find_node_by_path);
2817
2818 /**
2819  *      of_find_all_nodes - Get next node in global list
2820  *      @prev:  Previous node or NULL to start iteration
2821  *              of_node_put() will be called on it
2822  *
2823  *      Returns a node pointer with refcount incremented, use
2824  *      of_node_put() on it when done.
2825  */
2826 struct device_node *of_find_all_nodes(struct device_node *prev)
2827 {
2828         struct device_node *np;
2829
2830         read_lock(&devtree_lock);
2831         np = prev ? prev->allnext : allnodes;
2832         for (; np != 0; np = np->allnext)
2833                 if (of_node_get(np))
2834                         break;
2835         if (prev)
2836                 of_node_put(prev);
2837         read_unlock(&devtree_lock);
2838         return np;
2839 }
2840 EXPORT_SYMBOL(of_find_all_nodes);
2841
2842 /**
2843  *      of_get_parent - Get a node's parent if any
2844  *      @node:  Node to get parent
2845  *
2846  *      Returns a node pointer with refcount incremented, use
2847  *      of_node_put() on it when done.
2848  */
2849 struct device_node *of_get_parent(const struct device_node *node)
2850 {
2851         struct device_node *np;
2852
2853         if (!node)
2854                 return NULL;
2855
2856         read_lock(&devtree_lock);
2857         np = of_node_get(node->parent);
2858         read_unlock(&devtree_lock);
2859         return np;
2860 }
2861 EXPORT_SYMBOL(of_get_parent);
2862
2863 /**
2864  *      of_get_next_child - Iterate a node childs
2865  *      @node:  parent node
2866  *      @prev:  previous child of the parent node, or NULL to get first
2867  *
2868  *      Returns a node pointer with refcount incremented, use
2869  *      of_node_put() on it when done.
2870  */
2871 struct device_node *of_get_next_child(const struct device_node *node,
2872         struct device_node *prev)
2873 {
2874         struct device_node *next;
2875
2876         read_lock(&devtree_lock);
2877         next = prev ? prev->sibling : node->child;
2878         for (; next != 0; next = next->sibling)
2879                 if (of_node_get(next))
2880                         break;
2881         if (prev)
2882                 of_node_put(prev);
2883         read_unlock(&devtree_lock);
2884         return next;
2885 }
2886 EXPORT_SYMBOL(of_get_next_child);
2887
2888 /**
2889  *      of_node_get - Increment refcount of a node
2890  *      @node:  Node to inc refcount, NULL is supported to
2891  *              simplify writing of callers
2892  *
2893  *      Returns the node itself or NULL if gone.
2894  */
2895 struct device_node *of_node_get(struct device_node *node)
2896 {
2897         if (node && !OF_IS_STALE(node)) {
2898                 atomic_inc(&node->_users);
2899                 return node;
2900         }
2901         return NULL;
2902 }
2903 EXPORT_SYMBOL(of_node_get);
2904
2905 /**
2906  *      of_node_cleanup - release a dynamically allocated node
2907  *      @arg:  Node to be released
2908  */
2909 static void of_node_cleanup(struct device_node *node)
2910 {
2911         struct property *prop = node->properties;
2912
2913         if (!OF_IS_DYNAMIC(node))
2914                 return;
2915         while (prop) {
2916                 struct property *next = prop->next;
2917                 kfree(prop->name);
2918                 kfree(prop->value);
2919                 kfree(prop);
2920                 prop = next;
2921         }
2922         kfree(node->intrs);
2923         kfree(node->addrs);
2924         kfree(node->full_name);
2925         kfree(node);
2926 }
2927
2928 /**
2929  *      of_node_put - Decrement refcount of a node
2930  *      @node:  Node to dec refcount, NULL is supported to
2931  *              simplify writing of callers
2932  *
2933  */
2934 void of_node_put(struct device_node *node)
2935 {
2936         if (!node)
2937                 return;
2938
2939         WARN_ON(0 == atomic_read(&node->_users));
2940
2941         if (OF_IS_STALE(node)) {
2942                 if (atomic_dec_and_test(&node->_users)) {
2943                         of_node_cleanup(node);
2944                         return;
2945                 }
2946         }
2947         else
2948                 atomic_dec(&node->_users);
2949 }
2950 EXPORT_SYMBOL(of_node_put);
2951
2952 /**
2953  *      derive_parent - basically like dirname(1)
2954  *      @path:  the full_name of a node to be added to the tree
2955  *
2956  *      Returns the node which should be the parent of the node
2957  *      described by path.  E.g., for path = "/foo/bar", returns
2958  *      the node with full_name = "/foo".
2959  */
2960 static struct device_node *derive_parent(const char *path)
2961 {
2962         struct device_node *parent = NULL;
2963         char *parent_path = "/";
2964         size_t parent_path_len = strrchr(path, '/') - path + 1;
2965
2966         /* reject if path is "/" */
2967         if (!strcmp(path, "/"))
2968                 return NULL;
2969
2970         if (strrchr(path, '/') != path) {
2971                 parent_path = kmalloc(parent_path_len, GFP_KERNEL);
2972                 if (!parent_path)
2973                         return NULL;
2974                 strlcpy(parent_path, path, parent_path_len);
2975         }
2976         parent = of_find_node_by_path(parent_path);
2977         if (strcmp(parent_path, "/"))
2978                 kfree(parent_path);
2979         return parent;
2980 }
2981
2982 /*
2983  * Routines for "runtime" addition and removal of device tree nodes.
2984  */
2985 #ifdef CONFIG_PROC_DEVICETREE
2986 /*
2987  * Add a node to /proc/device-tree.
2988  */
2989 static void add_node_proc_entries(struct device_node *np)
2990 {
2991         struct proc_dir_entry *ent;
2992
2993         ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
2994         if (ent)
2995                 proc_device_tree_add_node(np, ent);
2996 }
2997
2998 static void remove_node_proc_entries(struct device_node *np)
2999 {
3000         struct property *pp = np->properties;
3001         struct device_node *parent = np->parent;
3002
3003         while (pp) {
3004                 remove_proc_entry(pp->name, np->pde);
3005                 pp = pp->next;
3006         }
3007
3008         /* Assuming that symlinks have the same parent directory as
3009          * np->pde.
3010          */
3011         if (np->name_link)
3012                 remove_proc_entry(np->name_link->name, parent->pde);
3013         if (np->addr_link)
3014                 remove_proc_entry(np->addr_link->name, parent->pde);
3015         if (np->pde)
3016                 remove_proc_entry(np->pde->name, parent->pde);
3017 }
3018 #else /* !CONFIG_PROC_DEVICETREE */
3019 static void add_node_proc_entries(struct device_node *np)
3020 {
3021         return;
3022 }
3023
3024 static void remove_node_proc_entries(struct device_node *np)
3025 {
3026         return;
3027 }
3028 #endif /* CONFIG_PROC_DEVICETREE */
3029
3030 /*
3031  * Fix up n_intrs and intrs fields in a new device node
3032  *
3033  */
3034 static int of_finish_dynamic_node_interrupts(struct device_node *node)
3035 {
3036         int intrcells, intlen, i;
3037         unsigned *irq, *ints, virq;
3038         struct device_node *ic;
3039
3040         ints = (unsigned int *)get_property(node, "interrupts", &intlen);
3041         intrcells = prom_n_intr_cells(node);
3042         intlen /= intrcells * sizeof(unsigned int);
3043         node->n_intrs = intlen;
3044         node->intrs = kmalloc(sizeof(struct interrupt_info) * intlen,
3045                               GFP_KERNEL);
3046         if (!node->intrs)
3047                 return -ENOMEM;
3048
3049         for (i = 0; i < intlen; ++i) {
3050                 int n, j;
3051                 node->intrs[i].line = 0;
3052                 node->intrs[i].sense = 1;
3053                 n = map_interrupt(&irq, &ic, node, ints, intrcells);
3054                 if (n <= 0)
3055                         continue;
3056                 virq = virt_irq_create_mapping(irq[0]);
3057                 if (virq == NO_IRQ) {
3058                         printk(KERN_CRIT "Could not allocate interrupt "
3059                                "number for %s\n", node->full_name);
3060                         return -ENOMEM;
3061                 }
3062                 node->intrs[i].line = irq_offset_up(virq);
3063                 if (n > 1)
3064                         node->intrs[i].sense = irq[1];
3065                 if (n > 2) {
3066                         printk(KERN_DEBUG "hmmm, got %d intr cells for %s:", n,
3067                                node->full_name);
3068                         for (j = 0; j < n; ++j)
3069                                 printk(" %d", irq[j]);
3070                         printk("\n");
3071                 }
3072                 ints += intrcells;
3073         }
3074         return 0;
3075 }
3076
3077 /*
3078  * Fix up the uninitialized fields in a new device node:
3079  * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
3080  *
3081  * A lot of boot-time code is duplicated here, because functions such
3082  * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
3083  * slab allocator.
3084  *
3085  * This should probably be split up into smaller chunks.
3086  */
3087
3088 static int of_finish_dynamic_node(struct device_node *node)
3089 {
3090         struct device_node *parent = of_get_parent(node);
3091         u32 *regs;
3092         int err = 0;
3093         phandle *ibm_phandle;
3094  
3095         node->name = get_property(node, "name", 0);
3096         node->type = get_property(node, "device_type", 0);
3097
3098         if (!parent) {
3099                 err = -ENODEV;
3100                 goto out;
3101         }
3102
3103         /* We don't support that function on PowerMac, at least
3104          * not yet
3105          */
3106         if (systemcfg->platform == PLATFORM_POWERMAC)
3107                 return -ENODEV;
3108
3109         /* fix up new node's linux_phandle field */
3110         if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
3111                 node->linux_phandle = *ibm_phandle;
3112
3113         /* do the work of interpret_pci_props */
3114         if (parent->type && !strcmp(parent->type, "pci")) {
3115                 struct address_range *adr;
3116                 struct pci_reg_property *pci_addrs;
3117                 int i, l;
3118
3119                 pci_addrs = (struct pci_reg_property *)
3120                         get_property(node, "assigned-addresses", &l);
3121                 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
3122                         i = 0;
3123                         adr = kmalloc(sizeof(struct address_range) * 
3124                                       (l / sizeof(struct pci_reg_property)),
3125                                       GFP_KERNEL);
3126                         if (!adr) {
3127                                 err = -ENOMEM;
3128                                 goto out;
3129                         }
3130                         while ((l -= sizeof(struct pci_reg_property)) >= 0) {
3131                                 adr[i].space = pci_addrs[i].addr.a_hi;
3132                                 adr[i].address = pci_addrs[i].addr.a_lo;
3133                                 adr[i].size = pci_addrs[i].size_lo;
3134                                 ++i;
3135                         }
3136                         node->addrs = adr;
3137                         node->n_addrs = i;
3138                 }
3139         }
3140
3141         /* now do the work of finish_node_interrupts */
3142         if (get_property(node, "interrupts", 0)) {
3143                 err = of_finish_dynamic_node_interrupts(node);
3144                 if (err) goto out;
3145         }
3146
3147        /* now do the rough equivalent of update_dn_pci_info, this
3148         * probably is not correct for phb's, but should work for
3149         * IOAs and slots.
3150         */
3151
3152        node->phb = parent->phb;
3153
3154        regs = (u32 *)get_property(node, "reg", 0);
3155        if (regs) {
3156                node->busno = (regs[0] >> 16) & 0xff;
3157                node->devfn = (regs[0] >> 8) & 0xff;
3158        }
3159
3160         /* fixing up iommu_table */
3161
3162         if(strcmp(node->name, "pci") == 0 &&
3163                 get_property(node, "ibm,dma-window", NULL)) {
3164                 node->bussubno = node->busno;
3165                 iommu_devnode_init(node);
3166         }
3167         else
3168                 node->iommu_table = parent->iommu_table;
3169
3170 out:
3171         of_node_put(parent);
3172         return err;
3173 }
3174
3175 /*
3176  * Given a path and a property list, construct an OF device node, add
3177  * it to the device tree and global list, and place it in
3178  * /proc/device-tree.  This function may sleep.
3179  */
3180 int of_add_node(const char *path, struct property *proplist)
3181 {
3182         struct device_node *np;
3183         int err = 0;
3184
3185         np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
3186         if (!np)
3187                 return -ENOMEM;
3188
3189         memset(np, 0, sizeof(*np));
3190
3191         np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
3192         if (!np->full_name) {
3193                 kfree(np);
3194                 return -ENOMEM;
3195         }
3196         strcpy(np->full_name, path);
3197
3198         np->properties = proplist;
3199         OF_MARK_DYNAMIC(np);
3200         of_node_get(np);
3201         np->parent = derive_parent(path);
3202         if (!np->parent) {
3203                 kfree(np);
3204                 return -EINVAL; /* could also be ENOMEM, though */
3205         }
3206
3207         if (0 != (err = of_finish_dynamic_node(np))) {
3208                 kfree(np);
3209                 return err;
3210         }
3211
3212         write_lock(&devtree_lock);
3213         np->sibling = np->parent->child;
3214         np->allnext = allnodes;
3215         np->parent->child = np;
3216         allnodes = np;
3217         write_unlock(&devtree_lock);
3218
3219         add_node_proc_entries(np);
3220
3221         of_node_put(np->parent);
3222         of_node_put(np);
3223         return 0;
3224 }
3225
3226 /*
3227  * Remove an OF device node from the system.
3228  * Caller should have already "gotten" np.
3229  */
3230 int of_remove_node(struct device_node *np)
3231 {
3232         struct device_node *parent, *child;
3233
3234         parent = of_get_parent(np);
3235         if (!parent)
3236                 return -EINVAL;
3237
3238         if ((child = of_get_next_child(np, NULL))) {
3239                 of_node_put(child);
3240                 return -EBUSY;
3241         }
3242
3243         write_lock(&devtree_lock);
3244         OF_MARK_STALE(np);
3245         remove_node_proc_entries(np);
3246         if (allnodes == np)
3247                 allnodes = np->allnext;
3248         else {
3249                 struct device_node *prev;
3250                 for (prev = allnodes;
3251                      prev->allnext != np;
3252                      prev = prev->allnext)
3253                         ;
3254                 prev->allnext = np->allnext;
3255         }
3256
3257         if (parent->child == np)
3258                 parent->child = np->sibling;
3259         else {
3260                 struct device_node *prevsib;
3261                 for (prevsib = np->parent->child;
3262                      prevsib->sibling != np;
3263                      prevsib = prevsib->sibling)
3264                         ;
3265                 prevsib->sibling = np->sibling;
3266         }
3267         write_unlock(&devtree_lock);
3268         of_node_put(parent);
3269         return 0;
3270 }
3271
3272 /*
3273  * Find a property with a given name for a given node
3274  * and return the value.
3275  */
3276 unsigned char *
3277 get_property(struct device_node *np, const char *name, int *lenp)
3278 {
3279         struct property *pp;
3280
3281         for (pp = np->properties; pp != 0; pp = pp->next)
3282                 if (strcmp(pp->name, name) == 0) {
3283                         if (lenp != 0)
3284                                 *lenp = pp->length;
3285                         return pp->value;
3286                 }
3287         return 0;
3288 }
3289
3290 /*
3291  * Add a property to a node
3292  */
3293 void
3294 prom_add_property(struct device_node* np, struct property* prop)
3295 {
3296         struct property **next = &np->properties;
3297
3298         prop->next = NULL;      
3299         while (*next)
3300                 next = &(*next)->next;
3301         *next = prop;
3302 }
3303
3304 #if 0
3305 void
3306 print_properties(struct device_node *np)
3307 {
3308         struct property *pp;
3309         char *cp;
3310         int i, n;
3311
3312         for (pp = np->properties; pp != 0; pp = pp->next) {
3313                 printk(KERN_INFO "%s", pp->name);
3314                 for (i = strlen(pp->name); i < 16; ++i)
3315                         printk(" ");
3316                 cp = (char *) pp->value;
3317                 for (i = pp->length; i > 0; --i, ++cp)
3318                         if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
3319                             || (i == 1 && *cp != 0))
3320                                 break;
3321                 if (i == 0 && pp->length > 1) {
3322                         /* looks like a string */
3323                         printk(" %s\n", (char *) pp->value);
3324                 } else {
3325                         /* dump it in hex */
3326                         n = pp->length;
3327                         if (n > 64)
3328                                 n = 64;
3329                         if (pp->length % 4 == 0) {
3330                                 unsigned int *p = (unsigned int *) pp->value;
3331
3332                                 n /= 4;
3333                                 for (i = 0; i < n; ++i) {
3334                                         if (i != 0 && (i % 4) == 0)
3335                                                 printk("\n                ");
3336                                         printk(" %08x", *p++);
3337                                 }
3338                         } else {
3339                                 unsigned char *bp = pp->value;
3340
3341                                 for (i = 0; i < n; ++i) {
3342                                         if (i != 0 && (i % 16) == 0)
3343                                                 printk("\n                ");
3344                                         printk(" %02x", *bp++);
3345                                 }
3346                         }
3347                         printk("\n");
3348                         if (pp->length > 64)
3349                                 printk("                 ... (length = %d)\n",
3350                                        pp->length);
3351                 }
3352         }
3353 }
3354 #endif