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