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