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