1 /* - undefined for user space
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_YABOOT
20 #endif
21 
22 #if 0
23 #define DEBUG_PROM
24 #endif
25 
26 #include <stdarg.h>
27 #include <linux/config.h>
28 #include <linux/kernel.h>
29 #include <linux/string.h>
30 #include <linux/init.h>
31 #include <linux/version.h>
32 #include <linux/threads.h>
33 #include <linux/spinlock.h>
34 #include <linux/blk.h>
35 
36 #ifdef DEBUG_YABOOT
37 #define call_yaboot(FUNC,...) \
38 	do { \
39 		if (FUNC) {					\
40 			struct prom_t *_prom = PTRRELOC(&prom);	\
41 			unsigned long prom_entry = _prom->entry;\
42 			_prom->entry = (unsigned long)(FUNC);	\
43 			enter_prom(__VA_ARGS__); 		\
44 			_prom->entry = prom_entry;		\
45 		}						\
46 	} while (0)
47 #else
48 #define call_yaboot(FUNC,...) do { ; } while (0)
49 #endif
50 
51 #include <asm/init.h>
52 #include <linux/types.h>
53 #include <linux/pci.h>
54 #include <asm/prom.h>
55 #include <asm/rtas.h>
56 #include <asm/lmb.h>
57 #include <asm/abs_addr.h>
58 #include <asm/page.h>
59 #include <asm/processor.h>
60 #include <asm/irq.h>
61 #include <asm/io.h>
62 #include <asm/smp.h>
63 #include <asm/system.h>
64 #include <asm/mmu.h>
65 #include <asm/pgtable.h>
66 #include <asm/bitops.h>
67 #include <asm/naca.h>
68 #include <asm/pci.h>
69 #include "open_pic.h"
70 #include <asm/bootinfo.h>
71 #include <asm/ppcdebug.h>
72 
73 #ifdef CONFIG_FB
74 #include <asm/linux_logo.h>
75 #endif
76 
77 extern char _end[];
78 
79 /*
80  * prom_init() is called very early on, before the kernel text
81  * and data have been mapped to KERNELBASE.  At this point the code
82  * is running at whatever address it has been loaded at, so
83  * references to extern and static variables must be relocated
84  * explicitly.  The procedure reloc_offset() returns the address
85  * we're currently running at minus the address we were linked at.
86  * (Note that strings count as static variables.)
87  *
88  * Because OF may have mapped I/O devices into the area starting at
89  * KERNELBASE, particularly on CHRP machines, we can't safely call
90  * OF once the kernel has been mapped to KERNELBASE.  Therefore all
91  * OF calls should be done within prom_init(), and prom_init()
92  * and all routines called within it must be careful to relocate
93  * references as necessary.
94  *
95  * Note that the bss is cleared *after* prom_init runs, so we have
96  * to make sure that any static or extern variables it accesses
97  * are put in the data segment.
98  */
99 
100 
101 #define PROM_BUG() do { \
102         prom_print(RELOC("kernel BUG at ")); \
103         prom_print(RELOC(__FILE__)); \
104         prom_print(RELOC(":")); \
105         prom_print_hex(__LINE__); \
106         prom_print(RELOC("!\n")); \
107         __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
108 } while (0)
109 
110 
111 
112 struct pci_reg_property {
113 	struct pci_address addr;
114 	u32 size_hi;
115 	u32 size_lo;
116 };
117 
118 
119 struct isa_reg_property {
120 	u32 space;
121 	u32 address;
122 	u32 size;
123 };
124 
125 struct pci_intr_map {
126 	struct pci_address addr;
127 	u32 dunno;
128 	phandle int_ctrler;
129 	u32 intr;
130 };
131 
132 
133 typedef unsigned long interpret_func(struct device_node *, unsigned long,
134 				     int, int);
135 #if 0
136 static interpret_func interpret_pci_props;
137 #endif
138 static unsigned long interpret_pci_props(struct device_node *, unsigned long,
139 					 int, int);
140 
141 static interpret_func interpret_isa_props;
142 static interpret_func interpret_root_props;
143 
144 #ifndef FB_MAX			/* avoid pulling in all of the fb stuff */
145 #define FB_MAX	8
146 #endif
147 
148 
149 struct prom_t prom = {
150 	0,			/* entry */
151 	0,			/* chosen */
152 	0,			/* cpu */
153 	0,			/* stdout */
154 	0,			/* disp_node */
155 	{0,0,0,{0},NULL},	/* args */
156 	0,			/* version */
157 	32,			/* encode_phys_size */
158 	0			/* bi_rec pointer */
159 #ifdef DEBUG_YABOOT
160 	,NULL			/* yaboot */
161 #endif
162 };
163 
164 
165 char *prom_display_paths[FB_MAX] __initdata = { 0, };
166 unsigned int prom_num_displays = 0;
167 char *of_stdout_device = 0;
168 
169 extern struct rtas_t rtas;
170 extern unsigned long klimit;
171 extern struct lmb lmb;
172 #ifdef CONFIG_MSCHUNKS
173 extern struct msChunks msChunks;
174 #endif /* CONFIG_MSCHUNKS */
175 
176 #define MAX_PHB 16 * 3  // 16 Towers * 3 PHBs/tower
177 struct _of_tce_table of_tce_table[MAX_PHB + 1] = {{0, 0, 0}};
178 
179 char *bootpath = 0;
180 char *bootdevice = 0;
181 
182 #define MAX_CPU_THREADS 2
183 
184 struct device_node *allnodes = 0;
185 
186 static unsigned long call_prom(const char *service, int nargs, int nret, ...);
187 static void prom_exit(void);
188 static unsigned long copy_device_tree(unsigned long);
189 static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
190 				  unsigned long, struct device_node ***);
191 static unsigned long finish_node(struct device_node *, unsigned long,
192 				 interpret_func *, int, int);
193 static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
194 static unsigned long check_display(unsigned long);
195 static int prom_next_node(phandle *);
196 static struct bi_record * prom_bi_rec_verify(struct bi_record *);
197 static unsigned long prom_bi_rec_reserve(unsigned long);
198 static struct device_node *find_phandle(phandle);
199 
200 #ifdef CONFIG_MSCHUNKS
201 static unsigned long prom_initialize_mschunks(unsigned long);
202 #ifdef DEBUG_PROM
203 void prom_dump_mschunks_mapping(void);
204 #endif /* DEBUG_PROM */
205 #endif /* CONFIG_MSCHUNKS */
206 #ifdef DEBUG_PROM
207 void prom_dump_lmb(void);
208 #endif
209 
210 extern unsigned long reloc_offset(void);
211 
212 extern void enter_prom(void *dummy,...);
213 
214 void cacheable_memzero(void *, unsigned int);
215 
216 #ifndef CONFIG_CMDLINE
217 #define CONFIG_CMDLINE ""
218 #endif
219 char cmd_line[512] = CONFIG_CMDLINE;
220 unsigned long dev_tree_size;
221 
222 #ifdef CONFIG_HMT
223 struct {
224 	unsigned int pir;
225 	unsigned int threadid;
226 } hmt_thread_data[NR_CPUS] = {0};
227 #endif /* CONFIG_HMT */
228 
229 char testString[] = "LINUX\n";
230 
231 
232 /* This is the one and *ONLY* place where we actually call open
233  * firmware from, since we need to make sure we're running in 32b
234  * mode when we do.  We switch back to 64b mode upon return.
235  */
236 
237 static unsigned long __init
call_prom(const char * service,int nargs,int nret,...)238 call_prom(const char *service, int nargs, int nret, ...)
239 {
240 	int i;
241 	unsigned long offset = reloc_offset();
242 	struct prom_t *_prom = PTRRELOC(&prom);
243 	va_list list;
244 
245 	_prom->args.service = (u32)LONG_LSW(service);
246 	_prom->args.nargs = nargs;
247 	_prom->args.nret = nret;
248         _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
249 
250         va_start(list, nret);
251 	for (i=0; i < nargs ;i++)
252 		_prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long));
253         va_end(list);
254 
255 	for (i=0; i < nret ;i++)
256 		_prom->args.rets[i] = 0;
257 
258 	enter_prom(&_prom->args);
259 
260 	return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0);
261 }
262 
263 
264 static void __init
prom_exit()265 prom_exit()
266 {
267 	unsigned long offset = reloc_offset();
268 
269 	call_prom(RELOC("exit"), 0, 0);
270 
271 	for (;;)			/* should never get here */
272 		;
273 }
274 
275 void __init
prom_enter(void)276 prom_enter(void)
277 {
278 	unsigned long offset = reloc_offset();
279 
280 	call_prom(RELOC("enter"), 0, 0);
281 }
282 
283 
284 void __init
prom_print(const char * msg)285 prom_print(const char *msg)
286 {
287 	const char *p, *q;
288 	unsigned long offset = reloc_offset();
289 	struct prom_t *_prom = PTRRELOC(&prom);
290 
291 	if (_prom->stdout == 0)
292 		return;
293 
294 	for (p = msg; *p != 0; p = q) {
295 		for (q = p; *q != 0 && *q != '\n'; ++q)
296 			;
297 		if (q > p)
298 			call_prom(RELOC("write"), 3, 1, _prom->stdout,
299 				  p, q - p);
300 		if (*q != 0) {
301 			++q;
302 			call_prom(RELOC("write"), 3, 1, _prom->stdout,
303 				  RELOC("\r\n"), 2);
304 		}
305 	}
306 }
307 
308 void
prom_print_hex(unsigned long val)309 prom_print_hex(unsigned long val)
310 {
311         int i, nibbles = sizeof(val)*2;
312         char buf[sizeof(val)*2+1];
313 
314         for (i = nibbles-1;  i >= 0;  i--) {
315                 buf[i] = (val & 0xf) + '0';
316                 if (buf[i] > '9')
317                     buf[i] += ('a'-'0'-10);
318                 val >>= 4;
319         }
320         buf[nibbles] = '\0';
321 	prom_print(buf);
322 }
323 
324 void
prom_print_nl(void)325 prom_print_nl(void)
326 {
327 	unsigned long offset = reloc_offset();
328 	prom_print(RELOC("\n"));
329 }
330 
331 
332 static unsigned long
prom_initialize_naca(unsigned long mem)333 prom_initialize_naca(unsigned long mem)
334 {
335 	phandle node;
336 	char type[64];
337         unsigned long num_cpus = 0;
338         unsigned long offset = reloc_offset();
339 	struct prom_t *_prom = PTRRELOC(&prom);
340         struct naca_struct *_naca = RELOC(naca);
341         struct systemcfg *_systemcfg = RELOC(systemcfg);
342 
343 	/* NOTE: _naca->debug_switch is already initialized. */
344 #ifdef DEBUG_PROM
345 	prom_print(RELOC("prom_initialize_naca: start...\n"));
346 #endif
347 
348 	_naca->pftSize = 0;	/* ilog2 of htab size.  computed below. */
349 
350         for (node = 0; prom_next_node(&node); ) {
351                 type[0] = 0;
352                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
353                           type, sizeof(type));
354 
355                 if (!strcmp(type, RELOC("cpu"))) {
356 			num_cpus += 1;
357 
358 			/* We're assuming *all* of the CPUs have the same
359 			 * d-cache and i-cache sizes... -Peter
360 			 */
361 			if ( num_cpus == 1 ) {
362 				u32 size, lsize, sets;
363 
364 				call_prom(RELOC("getprop"), 4, 1, node,
365 					  RELOC("d-cache-size"),
366 					  &size, sizeof(size));
367 
368 				call_prom(RELOC("getprop"), 4, 1, node,
369 					  RELOC("d-cache-line-size"),
370 					  &lsize, sizeof(lsize));
371 
372 				_systemcfg->dCacheL1Size = size;
373 				_systemcfg->dCacheL1LineSize = lsize;
374 				_naca->dCacheL1LogLineSize = __ilog2(lsize);
375 				_naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize;
376 
377 				call_prom(RELOC("getprop"), 4, 1, node,
378 					  RELOC("i-cache-size"),
379 					  &size, sizeof(size));
380 
381 				call_prom(RELOC("getprop"), 4, 1, node,
382 					  RELOC("i-cache-line-size"),
383 					  &lsize, sizeof(lsize));
384 
385 				_systemcfg->iCacheL1Size = size;
386 				_systemcfg->iCacheL1LineSize = lsize;
387 				_naca->iCacheL1LogLineSize = __ilog2(lsize);
388 				_naca->iCacheL1LinesPerPage = PAGE_SIZE/lsize;
389 
390 				if (_systemcfg->platform == PLATFORM_PSERIES_LPAR) {
391 					u32 pft_size[2];
392 					call_prom(RELOC("getprop"), 4, 1, node,
393 						  RELOC("ibm,pft-size"),
394 						  &pft_size, sizeof(pft_size));
395 				/* pft_size[0] is the NUMA CEC cookie */
396 					_naca->pftSize = pft_size[1];
397 				}
398 			}
399                 } else if (!strcmp(type, RELOC("serial"))) {
400 			phandle isa, pci;
401 			struct isa_reg_property reg;
402 			union pci_range ranges;
403 
404 			type[0] = 0;
405 			call_prom(RELOC("getprop"), 4, 1, node,
406 				  RELOC("ibm,aix-loc"), type, sizeof(type));
407 
408 			if (strcmp(type, RELOC("S1")))
409 				continue;
410 
411 			call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
412 				  &reg, sizeof(reg));
413 
414 			isa = call_prom(RELOC("parent"), 1, 1, node);
415 			if (!isa)
416 				PROM_BUG();
417 			pci = call_prom(RELOC("parent"), 1, 1, isa);
418 			if (!pci)
419 				PROM_BUG();
420 
421 			call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"),
422 				  &ranges, sizeof(ranges));
423 
424 			if ( _prom->encode_phys_size == 32 )
425 				_naca->serialPortAddr = ranges.pci32.phys+reg.address;
426 			else {
427 				_naca->serialPortAddr =
428 					((((unsigned long)ranges.pci64.phys_hi) << 32) |
429 					 (ranges.pci64.phys_lo)) + reg.address;
430 			}
431                 }
432 	}
433 
434 	_naca->interrupt_controller = IC_INVALID;
435         for (node = 0; prom_next_node(&node); ) {
436                 type[0] = 0;
437                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"),
438                           type, sizeof(type));
439                 if (strcmp(type, RELOC("interrupt-controller"))) {
440 			continue;
441 		}
442                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
443                           type, sizeof(type));
444                 if (strstr(type, RELOC("open-pic"))) {
445 			_naca->interrupt_controller = IC_OPEN_PIC;
446 		} else if (strstr(type, RELOC("ppc-xicp"))) {
447 			_naca->interrupt_controller = IC_PPC_XIC;
448 		} else {
449 			prom_print(RELOC("prom: failed to recognize interrupt-controller\n"));
450 		}
451 		break;
452 	}
453 
454 	if (_naca->interrupt_controller == IC_INVALID) {
455 		prom_print(RELOC("prom: failed to find interrupt-controller\n"));
456 		PROM_BUG();
457 	}
458 
459 	/* We gotta have at least 1 cpu... */
460         if ( (_systemcfg->processorCount = num_cpus) < 1 )
461                 PROM_BUG();
462 
463 	_systemcfg->physicalMemorySize = lmb_phys_mem_size();
464 
465 	if (_systemcfg->platform == PLATFORM_PSERIES) {
466 		unsigned long rnd_mem_size, pteg_count;
467 
468 		/* round mem_size up to next power of 2 */
469 		rnd_mem_size = 1UL << __ilog2(_systemcfg->physicalMemorySize);
470 		if (rnd_mem_size < _systemcfg->physicalMemorySize)
471 			rnd_mem_size <<= 1;
472 
473 		/* # pages / 2 */
474 		pteg_count = (rnd_mem_size >> (12 + 1));
475 
476 		_naca->pftSize = __ilog2(pteg_count << 7);
477 	}
478 
479 	if (_naca->pftSize == 0) {
480 		prom_print(RELOC("prom: failed to compute pftSize!\n"));
481 		PROM_BUG();
482 	}
483 
484 	/*
485 	 * Hardcode to GP size.  I am not sure where to get this info
486 	 * in general, as there does not appear to be a slb-size OF
487 	 * entry.  At least in Condor and earlier.  DRENG
488 	 */
489 	_naca->slb_size = 64;
490 
491 	/* Add an eye catcher and the systemcfg layout version number */
492 	strcpy(_systemcfg->eye_catcher, RELOC("SYSTEMCFG:PPC64"));
493 	_systemcfg->version.major = SYSTEMCFG_MAJOR;
494 	_systemcfg->version.minor = SYSTEMCFG_MINOR;
495 	_systemcfg->processor = _get_PVR();
496 
497 #ifdef DEBUG_PROM
498         prom_print(RELOC("systemcfg->processorCount       = 0x"));
499         prom_print_hex(_systemcfg->processorCount);
500         prom_print_nl();
501 
502         prom_print(RELOC("systemcfg->physicalMemorySize   = 0x"));
503         prom_print_hex(_systemcfg->physicalMemorySize);
504         prom_print_nl();
505 
506         prom_print(RELOC("naca->pftSize                   = 0x"));
507         prom_print_hex(_naca->pftSize);
508         prom_print_nl();
509 
510         prom_print(RELOC("systemcfg->dCacheL1LineSize     = 0x"));
511         prom_print_hex(_systemcfg->dCacheL1LineSize);
512         prom_print_nl();
513 
514         prom_print(RELOC("systemcfg->iCacheL1LineSize     = 0x"));
515         prom_print_hex(_systemcfg->iCacheL1LineSize);
516         prom_print_nl();
517 
518         prom_print(RELOC("naca->serialPortAddr            = 0x"));
519         prom_print_hex(_naca->serialPortAddr);
520         prom_print_nl();
521 
522         prom_print(RELOC("naca->interrupt_controller      = 0x"));
523         prom_print_hex(_naca->interrupt_controller);
524         prom_print_nl();
525 
526         prom_print(RELOC("systemcfg->platform             = 0x"));
527         prom_print_hex(_systemcfg->platform);
528         prom_print_nl();
529 
530 	prom_print(RELOC("prom_initialize_naca: end...\n"));
531 #endif
532 
533 	return mem;
534 }
535 
536 
537 static unsigned long __init
prom_initialize_lmb(unsigned long mem)538 prom_initialize_lmb(unsigned long mem)
539 {
540 	phandle node;
541 	char type[64];
542         unsigned long i, offset = reloc_offset();
543 	struct prom_t *_prom = PTRRELOC(&prom);
544 	union lmb_reg_property reg;
545 	unsigned long lmb_base, lmb_size;
546 	unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;
547 
548 #ifdef CONFIG_MSCHUNKS
549 	unsigned long max_addr = 0;
550 #if 1
551 	/* Fix me: 630 3G-4G IO hack here... -Peter (PPPBBB) */
552 	unsigned long io_base = 3UL<<30;
553 	unsigned long io_size = 1UL<<30;
554 	unsigned long have_630 = 1;	/* assume we have a 630 */
555 
556 #else
557 	unsigned long io_base = <real io base here>;
558 	unsigned long io_size = <real io size here>;
559 #endif
560 #endif /* CONFIG_MSCHUNKS */
561 
562 	lmb_init();
563 
564         for (node = 0; prom_next_node(&node); ) {
565                 type[0] = 0;
566                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
567                           type, sizeof(type));
568 
569                 if (strcmp(type, RELOC("memory")))
570 			continue;
571 
572 		num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
573 			&reg, sizeof(reg)) / bytes_per_reg;
574 
575 		for (i=0; i < num_regs ;i++) {
576 			if (_prom->encode_phys_size == 32) {
577 				lmb_base = reg.addr32[i].address;
578 				lmb_size = reg.addr32[i].size;
579 			} else {
580 				lmb_base = reg.addr64[i].address;
581 				lmb_size = reg.addr64[i].size;
582 			}
583 
584 #ifdef CONFIG_MSCHUNKS
585 			if ( lmb_addrs_overlap(lmb_base,lmb_size,
586 						io_base,io_size) ) {
587 				/* If we really have dram here, then we don't
588 			 	 * have a 630! -Peter
589 			 	 */
590 				have_630 = 0;
591 			}
592 #endif /* CONFIG_MSCHUNKS */
593 			if ( lmb_add(lmb_base, lmb_size) < 0 )
594 				prom_print(RELOC("Too many LMB's, discarding this one...\n"));
595 #ifdef CONFIG_MSCHUNKS
596 			else if ( max_addr < (lmb_base+lmb_size-1) )
597 				max_addr = lmb_base+lmb_size-1;
598 #endif /* CONFIG_MSCHUNKS */
599 		}
600 
601 	}
602 
603 #ifdef CONFIG_MSCHUNKS
604 	if ( have_630 && lmb_addrs_overlap(0,max_addr,io_base,io_size) )
605 		lmb_add_io(io_base, io_size);
606 #endif /* CONFIG_MSCHUNKS */
607 
608 	lmb_analyze();
609 #ifdef DEBUG_PROM
610 	prom_dump_lmb();
611 #endif /* DEBUG_PROM */
612 
613 #ifdef CONFIG_MSCHUNKS
614 	mem = prom_initialize_mschunks(mem);
615 #ifdef DEBUG_PROM
616 	prom_dump_mschunks_mapping();
617 #endif /* DEBUG_PROM */
618 #endif /* CONFIG_MSCHUNKS */
619 
620 	return mem;
621 }
622 
623 
624 static void __init
prom_instantiate_rtas(void)625 prom_instantiate_rtas(void)
626 {
627 	unsigned long offset = reloc_offset();
628 	struct prom_t *_prom = PTRRELOC(&prom);
629 	struct rtas_t *_rtas = PTRRELOC(&rtas);
630 	struct naca_struct *_naca = RELOC(naca);
631 	struct systemcfg *_systemcfg = RELOC(systemcfg);
632 	ihandle prom_rtas;
633         u32 getprop_rval;
634 
635 #ifdef DEBUG_PROM
636 	prom_print(RELOC("prom_instantiate_rtas: start...\n"));
637 #endif
638 	prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
639 	if (prom_rtas != (ihandle) -1) {
640 		char hypertas_funcs[1024];
641 		int  rc;
642 
643 		if ((rc = call_prom(RELOC("getprop"),
644 				  4, 1, prom_rtas,
645 				  RELOC("ibm,hypertas-functions"),
646 				  hypertas_funcs,
647 				  sizeof(hypertas_funcs))) > 0) {
648 			_systemcfg->platform = PLATFORM_PSERIES_LPAR;
649 		}
650 
651 		call_prom(RELOC("getprop"),
652 			  4, 1, prom_rtas,
653 			  RELOC("rtas-size"),
654 			  &getprop_rval,
655 			  sizeof(getprop_rval));
656 	        _rtas->size = getprop_rval;
657 		prom_print(RELOC("instantiating rtas"));
658 		if (_rtas->size != 0) {
659 			unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
660 
661 			/* Grab some space within the first RTAS_INSTANTIATE_MAX bytes
662 			 * of physical memory (or within the RMO region) because RTAS
663 			 * runs in 32-bit mode and relocate off.
664 			 */
665 			if ( _systemcfg->platform == PLATFORM_PSERIES_LPAR ) {
666 				struct lmb *_lmb  = PTRRELOC(&lmb);
667 				rtas_region = min(_lmb->rmo_size, RTAS_INSTANTIATE_MAX);
668 			}
669 			_rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region);
670 
671 			prom_print(RELOC(" at 0x"));
672 			prom_print_hex(_rtas->base);
673 
674 			prom_rtas = (ihandle)call_prom(RELOC("open"),
675 					      	1, 1, RELOC("/rtas"));
676 			prom_print(RELOC("..."));
677 
678 			if ((long)call_prom(RELOC("call-method"), 3, 2,
679 						      RELOC("instantiate-rtas"),
680 						      prom_rtas,
681 						      _rtas->base) >= 0) {
682 				_rtas->entry = (long)_prom->args.rets[1];
683 			}
684 		}
685 
686 		if (_rtas->entry <= 0) {
687 			prom_print(RELOC(" failed\n"));
688 		} else {
689 			prom_print(RELOC(" done\n"));
690 		}
691 
692 #ifdef DEBUG_PROM
693         	prom_print(RELOC("rtas->base                 = 0x"));
694         	prom_print_hex(_rtas->base);
695         	prom_print_nl();
696         	prom_print(RELOC("rtas->entry                = 0x"));
697         	prom_print_hex(_rtas->entry);
698         	prom_print_nl();
699         	prom_print(RELOC("rtas->size                 = 0x"));
700         	prom_print_hex(_rtas->size);
701         	prom_print_nl();
702 #endif
703 	}
704 #ifdef DEBUG_PROM
705 	prom_print(RELOC("prom_instantiate_rtas: end...\n"));
706 #endif
707 }
708 
prom_strtoul(const char * cp)709 unsigned long prom_strtoul(const char *cp)
710 {
711 	unsigned long result = 0,value;
712 
713 	while (*cp) {
714 		value = *cp-'0';
715 		result = result*10 + value;
716 		cp++;
717 	}
718 
719 	return result;
720 }
721 
722 
723 #ifdef CONFIG_MSCHUNKS
724 static unsigned long
prom_initialize_mschunks(unsigned long mem)725 prom_initialize_mschunks(unsigned long mem)
726 {
727         unsigned long offset = reloc_offset();
728 	struct lmb *_lmb  = PTRRELOC(&lmb);
729 	struct msChunks *_msChunks = PTRRELOC(&msChunks);
730 	unsigned long i, pchunk = 0;
731 	unsigned long addr_range = _lmb->memory.size + _lmb->memory.iosize;
732 	unsigned long chunk_size = _lmb->memory.lcd_size;
733 
734 
735 	mem = msChunks_alloc(mem, addr_range / chunk_size, chunk_size);
736 
737 	/* First create phys -> abs mapping for memory/dram */
738 	for (i=0; i < _lmb->memory.cnt ;i++) {
739 		unsigned long base = _lmb->memory.region[i].base;
740 		unsigned long size = _lmb->memory.region[i].size;
741 		unsigned long achunk = addr_to_chunk(base);
742 		unsigned long end_achunk = addr_to_chunk(base+size);
743 
744 		if(_lmb->memory.region[i].type != LMB_MEMORY_AREA)
745 			continue;
746 
747 		_lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
748 		for (; achunk < end_achunk ;) {
749 			PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
750 		}
751 	}
752 
753 #ifdef CONFIG_MSCHUNKS
754 	/* Now create phys -> abs mapping for IO */
755 	for (i=0; i < _lmb->memory.cnt ;i++) {
756 		unsigned long base = _lmb->memory.region[i].base;
757 		unsigned long size = _lmb->memory.region[i].size;
758 		unsigned long achunk = addr_to_chunk(base);
759 		unsigned long end_achunk = addr_to_chunk(base+size);
760 
761 		if(_lmb->memory.region[i].type != LMB_IO_AREA)
762 			continue;
763 
764 		_lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
765 		for (; achunk < end_achunk ;) {
766 			PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
767 		}
768 	}
769 #endif /* CONFIG_MSCHUNKS */
770 
771 	return mem;
772 }
773 
774 #ifdef DEBUG_PROM
775 void
prom_dump_mschunks_mapping(void)776 prom_dump_mschunks_mapping(void)
777 {
778         unsigned long offset = reloc_offset();
779 	struct msChunks *_msChunks = PTRRELOC(&msChunks);
780 	unsigned long chunk;
781 
782         prom_print(RELOC("\nprom_dump_mschunks_mapping:\n"));
783         prom_print(RELOC("    msChunks.num_chunks         = 0x"));
784         prom_print_hex(_msChunks->num_chunks);
785 	prom_print_nl();
786         prom_print(RELOC("    msChunks.chunk_size         = 0x"));
787         prom_print_hex(_msChunks->chunk_size);
788 	prom_print_nl();
789         prom_print(RELOC("    msChunks.chunk_shift        = 0x"));
790         prom_print_hex(_msChunks->chunk_shift);
791 	prom_print_nl();
792         prom_print(RELOC("    msChunks.chunk_mask         = 0x"));
793         prom_print_hex(_msChunks->chunk_mask);
794 	prom_print_nl();
795         prom_print(RELOC("    msChunks.abs                = 0x"));
796         prom_print_hex(_msChunks->abs);
797 	prom_print_nl();
798 
799         prom_print(RELOC("    msChunks mapping:\n"));
800 	for(chunk=0; chunk < _msChunks->num_chunks ;chunk++) {
801         	prom_print(RELOC("        phys 0x"));
802         	prom_print_hex(chunk);
803         	prom_print(RELOC(" -> abs 0x"));
804         	prom_print_hex(PTRRELOC(_msChunks->abs)[chunk]);
805 		prom_print_nl();
806 	}
807 
808 }
809 #endif /* DEBUG_PROM */
810 #endif /* CONFIG_MSCHUNKS */
811 
812 #ifdef DEBUG_PROM
813 void
prom_dump_lmb(void)814 prom_dump_lmb(void)
815 {
816         unsigned long i;
817         unsigned long offset = reloc_offset();
818 	struct lmb *_lmb  = PTRRELOC(&lmb);
819 
820         prom_print(RELOC("\nprom_dump_lmb:\n"));
821         prom_print(RELOC("    memory.cnt                  = 0x"));
822         prom_print_hex(_lmb->memory.cnt);
823 	prom_print_nl();
824         prom_print(RELOC("    memory.size                 = 0x"));
825         prom_print_hex(_lmb->memory.size);
826 	prom_print_nl();
827         prom_print(RELOC("    memory.lcd_size             = 0x"));
828         prom_print_hex(_lmb->memory.lcd_size);
829 	prom_print_nl();
830         for (i=0; i < _lmb->memory.cnt ;i++) {
831                 prom_print(RELOC("    memory.region[0x"));
832 		prom_print_hex(i);
833 		prom_print(RELOC("].base       = 0x"));
834                 prom_print_hex(_lmb->memory.region[i].base);
835 		prom_print_nl();
836                 prom_print(RELOC("                      .physbase = 0x"));
837                 prom_print_hex(_lmb->memory.region[i].physbase);
838 		prom_print_nl();
839                 prom_print(RELOC("                      .size     = 0x"));
840                 prom_print_hex(_lmb->memory.region[i].size);
841 		prom_print_nl();
842                 prom_print(RELOC("                      .type     = 0x"));
843                 prom_print_hex(_lmb->memory.region[i].type);
844 		prom_print_nl();
845         }
846 
847 	prom_print_nl();
848         prom_print(RELOC("    reserved.cnt                  = 0x"));
849         prom_print_hex(_lmb->reserved.cnt);
850 	prom_print_nl();
851         prom_print(RELOC("    reserved.size                 = 0x"));
852         prom_print_hex(_lmb->reserved.size);
853 	prom_print_nl();
854         prom_print(RELOC("    reserved.lcd_size             = 0x"));
855         prom_print_hex(_lmb->reserved.lcd_size);
856 	prom_print_nl();
857         for (i=0; i < _lmb->reserved.cnt ;i++) {
858                 prom_print(RELOC("    reserved.region[0x"));
859 		prom_print_hex(i);
860 		prom_print(RELOC("].base       = 0x"));
861                 prom_print_hex(_lmb->reserved.region[i].base);
862 		prom_print_nl();
863                 prom_print(RELOC("                      .physbase = 0x"));
864                 prom_print_hex(_lmb->reserved.region[i].physbase);
865 		prom_print_nl();
866                 prom_print(RELOC("                      .size     = 0x"));
867                 prom_print_hex(_lmb->reserved.region[i].size);
868 		prom_print_nl();
869                 prom_print(RELOC("                      .type     = 0x"));
870                 prom_print_hex(_lmb->reserved.region[i].type);
871 		prom_print_nl();
872         }
873 }
874 #endif /* DEBUG_PROM */
875 
876 
877 void
prom_initialize_tce_table(void)878 prom_initialize_tce_table(void)
879 {
880 	phandle node;
881 	ihandle phb_node;
882         unsigned long offset = reloc_offset();
883 	char compatible[64], path[64], type[64], model[64];
884 	unsigned long i, table = 0;
885 	unsigned long base, vbase, align;
886 	unsigned int minalign, minsize;
887 	struct _of_tce_table *prom_tce_table = RELOC(of_tce_table);
888 	unsigned long tce_entry, *tce_entryp;
889 
890 #ifdef DEBUG_PROM
891 	prom_print(RELOC("starting prom_initialize_tce_table\n"));
892 #endif
893 
894 	/* Search all nodes looking for PHBs. */
895 	for (node = 0; prom_next_node(&node); ) {
896 		compatible[0] = 0;
897 		type[0] = 0;
898 		model[0] = 0;
899 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
900 			  compatible, sizeof(compatible));
901 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
902 			  type, sizeof(type));
903 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"),
904 			  model, sizeof(model));
905 
906 		/* Keep the old logic in tack to avoid regression. */
907 		if (compatible[0] != 0) {
908 			if((strstr(compatible, RELOC("python")) == NULL) &&
909 			   (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
910 			   (strstr(compatible, RELOC("Winnipeg")) == NULL))
911 				continue;
912 		} else if (model[0] != 0) {
913 			if ((strstr(model, RELOC("ython")) == NULL) &&
914 			    (strstr(model, RELOC("peedwagon")) == NULL) &&
915 			    (strstr(model, RELOC("innipeg")) == NULL))
916 				continue;
917 		}
918 
919 		if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) {
920 			continue;
921 		}
922 
923 		if (call_prom(RELOC("getprop"), 4, 1, node,
924 			     RELOC("tce-table-minalign"), &minalign,
925 			     sizeof(minalign)) < 0) {
926 			minalign = 0;
927 		}
928 
929 		if (call_prom(RELOC("getprop"), 4, 1, node,
930 			     RELOC("tce-table-minsize"), &minsize,
931 			     sizeof(minsize)) < 0) {
932 			minsize = 4UL << 20;
933 		}
934 
935 		/* Even though we read what OF wants, we just set the table
936 		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
937 		 * By doing this, we avoid the pitfalls of trying to DMA to
938 		 * MMIO space and the DMA alias hole.
939 		 */
940 		minsize = 8UL << 20;
941 
942 		/* Align to the greater of the align or size */
943 		align = (minalign < minsize) ? minsize : minalign;
944 
945 		/* Carve out storage for the TCE table. */
946 		base = lmb_alloc(minsize, align);
947 
948 		if ( !base ) {
949 			prom_print(RELOC("ERROR, cannot find space for TCE table.\n"));
950 			prom_exit();
951 		}
952 
953 		vbase = absolute_to_virt(base);
954 
955 		/* Save away the TCE table attributes for later use. */
956 		prom_tce_table[table].node = node;
957 		prom_tce_table[table].base = vbase;
958 		prom_tce_table[table].size = minsize;
959 
960 #ifdef DEBUG_PROM
961 		prom_print(RELOC("TCE table: 0x"));
962 		prom_print_hex(table);
963 		prom_print_nl();
964 
965 		prom_print(RELOC("\tnode = 0x"));
966 		prom_print_hex(node);
967 		prom_print_nl();
968 
969 		prom_print(RELOC("\tbase = 0x"));
970 		prom_print_hex(vbase);
971 		prom_print_nl();
972 
973 		prom_print(RELOC("\tsize = 0x"));
974 		prom_print_hex(minsize);
975 		prom_print_nl();
976 #endif
977 
978 		/* Initialize the table to have a one-to-one mapping
979 		 * over the allocated size.
980 		 */
981 		tce_entryp = (unsigned long *)base;
982 		for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
983 			tce_entry = (i << PAGE_SHIFT);
984 			tce_entry |= 0x3;
985 			*tce_entryp = tce_entry;
986 		}
987 
988 		/* Call OF to setup the TCE hardware */
989 		if (call_prom(RELOC("package-to-path"), 3, 1, node,
990                              path, 255) <= 0) {
991                         prom_print(RELOC("package-to-path failed\n"));
992                 } else {
993                         prom_print(RELOC("opened "));
994                         prom_print(path);
995                         prom_print_nl();
996                 }
997 
998                 phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path);
999                 if ( (long)phb_node <= 0) {
1000                         prom_print(RELOC("open failed\n"));
1001                 } else {
1002                         prom_print(RELOC("open success\n"));
1003                 }
1004                 call_prom(RELOC("call-method"), 6, 0,
1005                              RELOC("set-64-bit-addressing"),
1006 			     phb_node,
1007 			     -1,
1008                              minsize,
1009                              base & 0xffffffff,
1010                              (base >> 32) & 0xffffffff);
1011                 call_prom(RELOC("close"), 1, 0, phb_node);
1012 
1013 		table++;
1014 	}
1015 
1016 	/* Flag the first invalid entry */
1017 	prom_tce_table[table].node = 0;
1018 #ifdef DEBUG_PROM
1019 	prom_print(RELOC("ending prom_initialize_tce_table\n"));
1020 #endif
1021 }
1022 
1023 /*
1024  * With CHRP SMP we need to use the OF to start the other
1025  * processors so we can't wait until smp_boot_cpus (the OF is
1026  * trashed by then) so we have to put the processors into
1027  * a holding pattern controlled by the kernel (not OF) before
1028  * we destroy the OF.
1029  *
1030  * This uses a chunk of low memory, puts some holding pattern
1031  * code there and sends the other processors off to there until
1032  * smp_boot_cpus tells them to do something.  The holding pattern
1033  * checks that address until its cpu # is there, when it is that
1034  * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
1035  * of setting those values.
1036  *
1037  * We also use physical address 0x4 here to tell when a cpu
1038  * is in its holding pattern code.
1039  *
1040  * Fixup comment... DRENG / PPPBBB - Peter
1041  *
1042  * -- Cort
1043  */
1044 static void
prom_hold_cpus(unsigned long mem)1045 prom_hold_cpus(unsigned long mem)
1046 {
1047 	unsigned long i;
1048 	unsigned int reg;
1049 	phandle node;
1050 	unsigned long offset = reloc_offset();
1051 	char type[64], *path;
1052 	int cpuid = 0;
1053 	unsigned int interrupt_server[MAX_CPU_THREADS];
1054 	unsigned int cpu_threads, hw_cpu_num;
1055 	int propsize;
1056 	extern void __secondary_hold(void);
1057         extern unsigned long __secondary_hold_spinloop;
1058         extern unsigned long __secondary_hold_acknowledge;
1059         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
1060         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
1061         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
1062         struct naca_struct *_naca = RELOC(naca);
1063         struct systemcfg *_systemcfg = RELOC(systemcfg);
1064 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
1065 	struct prom_t *_prom = PTRRELOC(&prom);
1066 
1067 	/* Initially, we must have one active CPU. */
1068 	_systemcfg->processorCount = 1;
1069 
1070 #ifdef DEBUG_PROM
1071 	prom_print(RELOC("prom_hold_cpus: start...\n"));
1072 	prom_print(RELOC("    1) spinloop       = 0x"));
1073 	prom_print_hex(spinloop);
1074 	prom_print_nl();
1075 	prom_print(RELOC("    1) *spinloop      = 0x"));
1076 	prom_print_hex(*spinloop);
1077 	prom_print_nl();
1078 	prom_print(RELOC("    1) acknowledge    = 0x"));
1079 	prom_print_hex(acknowledge);
1080 	prom_print_nl();
1081 	prom_print(RELOC("    1) *acknowledge   = 0x"));
1082 	prom_print_hex(*acknowledge);
1083 	prom_print_nl();
1084 	prom_print(RELOC("    1) secondary_hold = 0x"));
1085 	prom_print_hex(secondary_hold);
1086 	prom_print_nl();
1087 #endif
1088 
1089         /* Set the common spinloop variable, so all of the secondary cpus
1090 	 * will block when they are awakened from their OF spinloop.
1091 	 * This must occur for both SMP and non SMP kernels, since OF will
1092 	 * be trashed when we move the kernel.
1093          */
1094         *spinloop = 0;
1095 
1096 #ifdef CONFIG_HMT
1097 	for (i=0; i < NR_CPUS; i++) {
1098 		RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1099 	}
1100 #endif
1101 	/* look for cpus */
1102 	for (node = 0; prom_next_node(&node); ) {
1103 		type[0] = 0;
1104 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
1105 			  type, sizeof(type));
1106 		if (strcmp(type, RELOC("cpu")) != 0)
1107 			continue;
1108 
1109 		/* Skip non-configured cpus. */
1110 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"),
1111 			  type, sizeof(type));
1112 		if (strcmp(type, RELOC("okay")) != 0)
1113 			continue;
1114 
1115                 reg = -1;
1116 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
1117 			  &reg, sizeof(reg));
1118 
1119 		path = (char *) mem;
1120 		memset(path, 0, 256);
1121 		if ((long) call_prom(RELOC("package-to-path"), 3, 1,
1122 				     node, path, 255) < 0)
1123 			continue;
1124 
1125 #ifdef DEBUG_PROM
1126 		prom_print_nl();
1127 		prom_print(RELOC("cpuid        = 0x"));
1128 		prom_print_hex(cpuid);
1129 		prom_print_nl();
1130 		prom_print(RELOC("cpu hw idx   = 0x"));
1131 		prom_print_hex(reg);
1132 		prom_print_nl();
1133 #endif
1134 		_xPaca[cpuid].xHwProcNum = reg;
1135 
1136 		/* Init the acknowledge var which will be reset by
1137 		 * the secondary cpu when it awakens from its OF
1138 		 * spinloop.
1139 		 */
1140 		*acknowledge = (unsigned long)-1;
1141 
1142 		propsize = call_prom(RELOC("getprop"), 4, 1, node,
1143 				     RELOC("ibm,ppc-interrupt-server#s"),
1144 				     &interrupt_server,
1145 				     sizeof(interrupt_server));
1146 		if (propsize < 0) {
1147 			/* no property.  old hardware has no SMT */
1148 			cpu_threads = 1;
1149 			interrupt_server[0] = reg; /* fake it with phys id */
1150 		} else {
1151 			/* We have a threaded processor */
1152 			cpu_threads = propsize / sizeof(u32);
1153 			if (cpu_threads > MAX_CPU_THREADS) {
1154 				prom_print(RELOC("SMT: too many threads!\nSMT: found "));
1155 				prom_print_hex(cpu_threads);
1156 				prom_print(RELOC(", max is "));
1157 				prom_print_hex(MAX_CPU_THREADS);
1158 				prom_print_nl();
1159 				cpu_threads = 1; /* ToDo: panic? */
1160 			}
1161 		}
1162 
1163 		hw_cpu_num = interrupt_server[0];
1164 		if (hw_cpu_num != _prom->cpu) {
1165 			/* Primary Thread of non-boot cpu */
1166 			prom_print_hex(cpuid);
1167 			prom_print(RELOC(" : starting cpu "));
1168 			prom_print(path);
1169 			prom_print(RELOC(" ... "));
1170 			call_prom(RELOC("start-cpu"), 3, 0, node,
1171 				  secondary_hold, cpuid);
1172 
1173 			for(i = 0; (i < 100000000) &&
1174 			  (*acknowledge == ((unsigned long)-1)); i++ );
1175 
1176 			if (*acknowledge == cpuid) {
1177 				prom_print(RELOC("ok\n"));
1178 				/* Set the number of active processors. */
1179 				_systemcfg->processorCount++;
1180 				_xPaca[cpuid].active = 1;
1181 				_xPaca[cpuid].available = 1;
1182 			} else {
1183 				prom_print(RELOC("failed: "));
1184 				prom_print_hex(*acknowledge);
1185 				prom_print_nl();
1186 				/* prom_panic(RELOC("cpu failed to start")); */
1187 			}
1188 		} else {
1189 			prom_print_hex(cpuid);
1190 			prom_print(RELOC(" : booting  cpu "));
1191 			prom_print(path);
1192 			prom_print_nl();
1193 		}
1194 
1195 		/* Init paca for secondary threads.   They start later. */
1196 		for (i=1; i < cpu_threads; i++) {
1197 			cpuid++;
1198 			_xPaca[cpuid].xHwProcNum = interrupt_server[i];
1199 			prom_print_hex(interrupt_server[i]);
1200 			prom_print(RELOC(" : preparing thread ... "));
1201 			if (_naca->smt_state) {
1202 				_xPaca[cpuid].available = 1;
1203 				prom_print(RELOC("available"));
1204 			} else {
1205 				prom_print(RELOC("not available"));
1206 			}
1207 			prom_print_nl();
1208 		}
1209 		cpuid++;
1210 	}
1211 #ifdef CONFIG_HMT
1212 	/* Only enable HMT on processors that provide support. */
1213 	if (__is_processor(PV_PULSAR) ||
1214 	    __is_processor(PV_ICESTAR) ||
1215 	    __is_processor(PV_SSTAR)) {
1216 		prom_print(RELOC("    starting secondary threads\n"));
1217 
1218 		for (i=0; i < _systemcfg->processorCount ;i++) {
1219 			unsigned long threadid = _systemcfg->processorCount*2-1-i;
1220 
1221 			if (i == 0) {
1222 				unsigned long pir = _get_PIR();
1223 				if (__is_processor(PV_PULSAR)) {
1224 					RELOC(hmt_thread_data)[i].pir =
1225 						pir & 0x1f;
1226 				} else {
1227 					RELOC(hmt_thread_data)[i].pir =
1228 						pir & 0x3ff;
1229 				}
1230 			}
1231 
1232 			RELOC(hmt_thread_data)[i].threadid = threadid;
1233 #ifdef DEBUG_PROM
1234 			prom_print(RELOC("        cpuid 0x"));
1235 			prom_print_hex(i);
1236 			prom_print(RELOC(" maps to threadid 0x"));
1237 			prom_print_hex(threadid);
1238 			prom_print_nl();
1239 			prom_print(RELOC(" pir 0x"));
1240 			prom_print_hex(RELOC(hmt_thread_data)[i].pir);
1241 			prom_print_nl();
1242 #endif
1243 			_xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1;
1244 		}
1245 		_systemcfg->processorCount *= 2;
1246 	} else {
1247 		prom_print(RELOC("Processor is not HMT capable\n"));
1248 	}
1249 #endif
1250 
1251 #ifdef DEBUG_PROM
1252 	prom_print(RELOC("prom_hold_cpus: end...\n"));
1253 #endif
1254 }
1255 
1256 static void
smt_setup(void)1257 smt_setup(void)
1258 {
1259 	char *p, *q;
1260 	char my_smt_enabled = SMT_DYNAMIC;
1261 	unsigned long my_smt_snooze_delay;
1262 	ihandle prom_options = NULL;
1263 	char option[9];
1264 	unsigned long offset = reloc_offset();
1265 	struct naca_struct *_naca = RELOC(naca);
1266 	char found = 0;
1267 
1268 	if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) {
1269 		for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) {
1270 			q = p + 12;
1271 			if (p > RELOC(cmd_line) && p[-1] != ' ')
1272 				continue;
1273 			found = 1;
1274 			if (q[0] == 'o' && q[1] == 'f' &&
1275 			    q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) {
1276 				my_smt_enabled = SMT_OFF;
1277 			} else if (q[0]=='o' && q[1] == 'n' &&
1278 				   (q[2] == ' ' || q[2] == '\0')) {
1279 				my_smt_enabled = SMT_ON;
1280 			} else {
1281 				my_smt_enabled = SMT_DYNAMIC;
1282 			}
1283 		}
1284 	}
1285 	if (!found) {
1286 		prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
1287 		if (prom_options != (ihandle) -1) {
1288 			call_prom(RELOC("getprop"),
1289 				4, 1, prom_options,
1290 				RELOC("ibm,smt-enabled"),
1291 				option, sizeof(option));
1292 			if (option[0] != 0) {
1293 				found = 1;
1294 				if (!strcmp(option, "off"))
1295 					my_smt_enabled = SMT_OFF;
1296 				else if (!strcmp(option, "on"))
1297 					my_smt_enabled = SMT_ON;
1298 				else
1299 					my_smt_enabled = SMT_DYNAMIC;
1300 			}
1301 		}
1302 	}
1303 
1304 	if (!found )
1305 		my_smt_enabled = SMT_DYNAMIC; /* default to on */
1306 
1307 	found = 0;
1308 	if (my_smt_enabled) {
1309 		if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) {
1310 			for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) {
1311 				q = p + 17;
1312 				if (p > RELOC(cmd_line) && p[-1] != ' ')
1313 					continue;
1314 				found = 1;
1315 				/* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
1316 				my_smt_snooze_delay = 0;
1317 				while (*q >= '0' && *q <= '9') {
1318 					my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
1319 					q++;
1320 				}
1321 			}
1322 		}
1323 
1324 		if (!found) {
1325 			prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
1326 			if (prom_options != (ihandle) -1) {
1327 				call_prom(RELOC("getprop"),
1328 					4, 1, prom_options,
1329 					RELOC("ibm,smt-snooze-delay"),
1330 					option, sizeof(option));
1331 				if (option[0] != 0) {
1332 					found = 1;
1333 					/* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
1334 					my_smt_snooze_delay = 0;
1335 					q = option;
1336 					while (*q >= '0' && *q <= '9') {
1337 						my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
1338 						q++;
1339 					}
1340 				}
1341 			}
1342 		}
1343 
1344 		if (!found) {
1345 			my_smt_snooze_delay = 30000; /* default value */
1346 		}
1347 	} else {
1348 		my_smt_snooze_delay = 0; /* default value */
1349 	}
1350 	_naca->smt_snooze_delay = my_smt_snooze_delay;
1351 	_naca->smt_state = my_smt_enabled;
1352 }
1353 
1354 #ifdef CONFIG_PPCDBG
1355 extern char *trace_names[];	/* defined in udbg.c -- need a better interface */
1356 
parse_ppcdbg_optionlist(const char * cmd,const char * cmdend)1357 void parse_ppcdbg_optionlist(const char *cmd,
1358 				    const char *cmdend)
1359 {
1360 	unsigned long offset = reloc_offset();
1361 	char **_trace_names = PTRRELOC(&trace_names[0]);
1362 	const char *all = RELOC("all");
1363         struct naca_struct *_naca = RELOC(naca);
1364 	const char *p, *pend;
1365 	int onoff, i, cmdidx;
1366 	unsigned long mask;
1367 	char cmdbuf[30];
1368 
1369 	for (p = cmd, pend = strchr(p, ',');
1370 	     p < cmdend;
1371 	     pend = strchr(p, ',')) {
1372 		if (pend == NULL || pend > cmdend)
1373 			pend = cmdend;
1374 		onoff = 1;	/* default */
1375 		if (*p == '+' || *p == '-') {
1376 			/* explicit on or off */
1377 			onoff = (*p == '+');
1378 			p++;
1379 		}
1380 		/* parse out p..pend here */
1381 		if (pend - p < sizeof(cmdbuf)) {
1382 			strncpy(cmdbuf, p, pend - p);
1383 			cmdbuf[pend - p] = '\0';
1384 			for (cmdidx = -1, i = 0; i < PPCDBG_NUM_FLAGS; i++) {
1385 				if (_trace_names[i] &&
1386 				    (strcmp(PTRRELOC(_trace_names[i]), cmdbuf) == 0)) {
1387 					cmdidx = i;
1388 					break;
1389 				}
1390 			}
1391 			mask = 0;
1392 			if (cmdidx >= 0) {
1393 				mask = (1 << cmdidx);
1394 			} else if (strcmp(cmdbuf, all) == 0) {
1395 				mask = PPCDBG_ALL;
1396 			} else {
1397 				prom_print(RELOC("ppcdbg: unknown debug: "));
1398 				prom_print(cmdbuf);
1399 				prom_print_nl();
1400 			}
1401 			if (mask) {
1402 				if (onoff)
1403 					_naca->debug_switch |= mask;
1404 				else
1405 					_naca->debug_switch &= ~mask;
1406 			}
1407 		}
1408 		p = pend+1;
1409 	}
1410 }
1411 
1412 /*
1413  * Parse ppcdbg= cmdline option.
1414  *
1415  * Option names are listed in <asm/ppcdebug.h> in the trace_names
1416  * table.  Multiple names may be listed separated by commas (no whitespace),
1417  * and each option may be preceeded by a + or - to force on or off state.
1418  * The special option "all" may also be used.  They are processed strictly
1419  * left to right.  Multiple ppcdbg= options are the command line are treated
1420  * as a single option list.
1421  *
1422  * Examples:  ppcdbg=phb_init,buswalk
1423  *            ppcdbg=all,-mm,-tce
1424  *
1425  * ToDo: add "group" names that map to common combinations of flags.
1426  */
parse_ppcdbg_cmd_line(const char * line)1427 void parse_ppcdbg_cmd_line(const char *line)
1428 {
1429 	unsigned long offset = reloc_offset();
1430 	const char *ppcdbgopt = RELOC("ppcdbg=");
1431 	struct naca_struct *_naca = RELOC(naca);
1432 	const char *cmd, *end;
1433 
1434 	_naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */
1435 	cmd = line;
1436 	while (cmd && (cmd = strstr(cmd, ppcdbgopt)) != NULL) {
1437 		cmd += 7;	/* skip ppcdbg= */
1438 		for (end = cmd;
1439 		     *end != '\0' && *end != '\t' && *end != ' ';
1440 		     end++)
1441 			; /* scan to whitespace or end */
1442 		parse_ppcdbg_optionlist(cmd, end);
1443 	}
1444 }
1445 #endif /* CONFIG_PPCDBG */
1446 
1447 
1448 /*
1449  * Do minimal cmd_line parsing for early boot options.
1450  */
1451 static void __init
prom_parse_cmd_line(char * line)1452 prom_parse_cmd_line(char *line)
1453 {
1454 #ifdef CONFIG_PPCDBG
1455 	parse_ppcdbg_cmd_line(line);
1456 #endif
1457 }
1458 
1459 /*
1460  * We enter here early on, when the Open Firmware prom is still
1461  * handling exceptions and the MMU hash table for us.
1462  */
1463 
1464 unsigned long __init
prom_init(unsigned long r3,unsigned long r4,unsigned long pp,unsigned long r6,unsigned long r7,yaboot_debug_t * yaboot)1465 prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
1466 	  unsigned long r6, unsigned long r7, yaboot_debug_t *yaboot)
1467 {
1468 	int chrp = 0;
1469 	unsigned long mem;
1470 	ihandle prom_mmu, prom_op, prom_root, prom_cpu;
1471 	phandle cpu_pkg;
1472 	unsigned long offset = reloc_offset();
1473 	long l, sz;
1474 	char *p, *d;
1475  	unsigned long phys;
1476         u32 getprop_rval;
1477         struct systemcfg *_systemcfg = RELOC(systemcfg);
1478 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
1479 	struct prom_t *_prom = PTRRELOC(&prom);
1480 	char *_cmd_line = PTRRELOC(&cmd_line[0]);
1481 
1482 	/* Default machine type. */
1483 	_systemcfg->platform = PLATFORM_PSERIES;
1484 
1485 	/* Get a handle to the prom entry point before anything else */
1486 	_prom->entry = pp;
1487 	_prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
1488 	if ( _prom->bi_recs != NULL ) {
1489 		RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]);
1490 	}
1491 
1492 #ifdef DEBUG_YABOOT
1493 	call_yaboot(yaboot->dummy,offset>>32,offset&0xffffffff);
1494 	call_yaboot(yaboot->printf, RELOC("offset = 0x%08x%08x\n"), LONG_MSW(offset), LONG_LSW(offset));
1495 #endif
1496 
1497  	/* Default */
1498  	phys = KERNELBASE - offset;
1499 
1500 #ifdef DEBUG_YABOOT
1501 	call_yaboot(yaboot->printf, RELOC("phys = 0x%08x%08x\n"), LONG_MSW(phys), LONG_LSW(phys));
1502 #endif
1503 
1504 
1505 #ifdef DEBUG_YABOOT
1506 	_prom->yaboot = yaboot;
1507 	call_yaboot(yaboot->printf, RELOC("pp = 0x%08x%08x\n"), LONG_MSW(pp), LONG_LSW(pp));
1508 	call_yaboot(yaboot->printf, RELOC("prom = 0x%08x%08x\n"), LONG_MSW(_prom->entry), LONG_LSW(_prom->entry));
1509 #endif
1510 
1511 	/* First get a handle for the stdout device */
1512 	_prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1,
1513 				       RELOC("/chosen"));
1514 
1515 #ifdef DEBUG_YABOOT
1516 	call_yaboot(yaboot->printf, RELOC("prom->chosen = 0x%08x%08x\n"), LONG_MSW(_prom->chosen), LONG_LSW(_prom->chosen));
1517 #endif
1518 
1519 	if ((long)_prom->chosen <= 0)
1520 		prom_exit();
1521 
1522         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1523 			    RELOC("stdout"), &getprop_rval,
1524 			    sizeof(getprop_rval)) <= 0)
1525                 prom_exit();
1526 
1527         _prom->stdout = (ihandle)(unsigned long)getprop_rval;
1528 
1529 #ifdef DEBUG_YABOOT
1530         if (_prom->stdout == 0) {
1531 	    call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
1532         }
1533 
1534 	call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
1535 #endif
1536 
1537 #ifdef DEBUG_YABOOT
1538 	call_yaboot(yaboot->printf, RELOC("Location: 0x11\n"));
1539 #endif
1540 
1541 	mem = RELOC(klimit) - offset;
1542 #ifdef DEBUG_YABOOT
1543 	call_yaboot(yaboot->printf, RELOC("Location: 0x11b\n"));
1544 #endif
1545 
1546 	/* Get the full OF pathname of the stdout device */
1547 	p = (char *) mem;
1548 	memset(p, 0, 256);
1549 	call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
1550 	RELOC(of_stdout_device) = PTRUNRELOC(p);
1551 	mem += strlen(p) + 1;
1552 
1553 	getprop_rval = 1;
1554 	prom_root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
1555 	if (prom_root != (ihandle)-1) {
1556                 call_prom(RELOC("getprop"), 4, 1,
1557                     prom_root, RELOC("#size-cells"),
1558 		    &getprop_rval, sizeof(getprop_rval));
1559 	}
1560 	_prom->encode_phys_size = (getprop_rval==1) ? 32 : 64;
1561 
1562 	/* Fetch the cmd_line */
1563 	sz = (long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1564 			    RELOC("bootargs"), _cmd_line,
1565 			    sizeof(cmd_line)-1);
1566 	if (sz > 0)
1567 		_cmd_line[sz] = '\0';
1568         if (sz <=1 )
1569                 strcpy(_cmd_line,RELOC(CONFIG_CMDLINE));
1570 
1571 	prom_parse_cmd_line(_cmd_line);
1572 
1573 #ifdef DEBUG_PROM
1574 	prom_print(RELOC("DRENG:    Detect OF version...\n"));
1575 #endif
1576 	/* Find the OF version */
1577 	prom_op = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));
1578 	if (prom_op != (ihandle)-1) {
1579 		char model[64];
1580 		sz = (long)call_prom(RELOC("getprop"), 4, 1, prom_op,
1581 				    RELOC("model"), model, 64);
1582 		if (sz > 0) {
1583 			char *c;
1584 			/* hack to skip the ibm chrp firmware # */
1585 			if ( strncmp(model,RELOC("IBM"),3) ) {
1586 				for (c = model; *c; c++)
1587 					if (*c >= '0' && *c <= '9') {
1588 						_prom->version = *c - '0';
1589 						break;
1590 					}
1591 			}
1592 			else
1593 				chrp = 1;
1594 		}
1595 	}
1596 	if (_prom->version >= 3)
1597 		prom_print(RELOC("OF Version 3 detected.\n"));
1598 
1599 
1600 	/* Determine which cpu is actually running right _now_ */
1601         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1602 			    RELOC("cpu"), &getprop_rval,
1603 			    sizeof(getprop_rval)) <= 0)
1604                 prom_exit();
1605 
1606 	prom_cpu = (ihandle)(unsigned long)getprop_rval;
1607 	cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
1608 	call_prom(RELOC("getprop"), 4, 1,
1609 		cpu_pkg, RELOC("reg"),
1610 		&getprop_rval, sizeof(getprop_rval));
1611 	_prom->cpu = (int)(unsigned long)getprop_rval;
1612 	_xPaca[0].xHwProcNum = _prom->cpu;
1613 
1614 #ifdef DEBUG_PROM
1615   	prom_print(RELOC("Booting CPU hw index = 0x"));
1616   	prom_print_hex(_prom->cpu);
1617   	prom_print_nl();
1618 #endif
1619 
1620 	/* Get the boot device and translate it to a full OF pathname. */
1621 	p = (char *) mem;
1622 	l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
1623 			    RELOC("bootpath"), p, 1<<20);
1624 	if (l > 0) {
1625 		p[l] = 0;	/* should already be null-terminated */
1626 		RELOC(bootpath) = PTRUNRELOC(p);
1627 		mem += l + 1;
1628 		d = (char *) mem;
1629 		*d = 0;
1630 		call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
1631 		RELOC(bootdevice) = PTRUNRELOC(d);
1632 		mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
1633 	}
1634 
1635 	mem = prom_initialize_lmb(mem);
1636 
1637 	mem = prom_bi_rec_reserve(mem);
1638 
1639 	mem = check_display(mem);
1640 
1641 	prom_instantiate_rtas();
1642 
1643         /* Initialize some system info into the Naca early... */
1644         mem = prom_initialize_naca(mem);
1645 
1646 	smt_setup();
1647 
1648         /* If we are on an SMP machine, then we *MUST* do the
1649          * following, regardless of whether we have an SMP
1650          * kernel or not.
1651          */
1652 	prom_hold_cpus(mem);
1653 
1654 #ifdef DEBUG_PROM
1655 	prom_print(RELOC("copying OF device tree...\n"));
1656 #endif
1657 	mem = copy_device_tree(mem);
1658 
1659 	RELOC(klimit) = mem + offset;
1660 
1661 	lmb_reserve(0, __pa(RELOC(klimit)));
1662 
1663 	if (_systemcfg->platform == PLATFORM_PSERIES)
1664 		prom_initialize_tce_table();
1665 
1666  	if ((long) call_prom(RELOC("getprop"), 4, 1,
1667 				_prom->chosen,
1668 				RELOC("mmu"),
1669 				&getprop_rval,
1670 				sizeof(getprop_rval)) <= 0) {
1671 		prom_print(RELOC(" no MMU found\n"));
1672                 prom_exit();
1673 	}
1674 
1675 	/* We assume the phys. address size is 3 cells */
1676 	prom_mmu = (ihandle)(unsigned long)getprop_rval;
1677 
1678 	if ((long)call_prom(RELOC("call-method"), 4, 4,
1679 				RELOC("translate"),
1680 				prom_mmu,
1681 				(void *)(KERNELBASE - offset),
1682 				(void *)1) != 0) {
1683 		prom_print(RELOC(" (translate failed) "));
1684 	} else {
1685 		prom_print(RELOC(" (translate ok) "));
1686 		phys = (unsigned long)_prom->args.rets[3];
1687 	}
1688 
1689 	/* If OpenFirmware version >= 3, then use quiesce call */
1690 	if (_prom->version >= 3) {
1691 		prom_print(RELOC("Calling quiesce ...\n"));
1692 		call_prom(RELOC("quiesce"), 0, 0);
1693 		phys = KERNELBASE - offset;
1694 	}
1695 
1696 	prom_print(RELOC("returning from prom_init\n"));
1697 	return phys;
1698 }
1699 
1700 
1701 static int
prom_set_color(ihandle ih,int i,int r,int g,int b)1702 prom_set_color(ihandle ih, int i, int r, int g, int b)
1703 {
1704 	unsigned long offset = reloc_offset();
1705 
1706 	return (int)(long)call_prom(RELOC("call-method"), 6, 1,
1707 		                    RELOC("color!"),
1708                                     ih,
1709                                     (void *)(long) i,
1710                                     (void *)(long) b,
1711                                     (void *)(long) g,
1712                                     (void *)(long) r );
1713 }
1714 
1715 /*
1716  * If we have a display that we don't know how to drive,
1717  * we will want to try to execute OF's open method for it
1718  * later.  However, OF will probably fall over if we do that
1719  * we've taken over the MMU.
1720  * So we check whether we will need to open the display,
1721  * and if so, open it now.
1722  */
1723 static unsigned long __init
check_display(unsigned long mem)1724 check_display(unsigned long mem)
1725 {
1726 	phandle node;
1727 	ihandle ih;
1728 	int i;
1729 	unsigned long offset = reloc_offset();
1730         struct prom_t *_prom = PTRRELOC(&prom);
1731 	char type[64], *path;
1732 	static unsigned char default_colors[] = {
1733 		0x00, 0x00, 0x00,
1734 		0x00, 0x00, 0xaa,
1735 		0x00, 0xaa, 0x00,
1736 		0x00, 0xaa, 0xaa,
1737 		0xaa, 0x00, 0x00,
1738 		0xaa, 0x00, 0xaa,
1739 		0xaa, 0xaa, 0x00,
1740 		0xaa, 0xaa, 0xaa,
1741 		0x55, 0x55, 0x55,
1742 		0x55, 0x55, 0xff,
1743 		0x55, 0xff, 0x55,
1744 		0x55, 0xff, 0xff,
1745 		0xff, 0x55, 0x55,
1746 		0xff, 0x55, 0xff,
1747 		0xff, 0xff, 0x55,
1748 		0xff, 0xff, 0xff
1749 	};
1750 
1751 	_prom->disp_node = 0;
1752 
1753 	for (node = 0; prom_next_node(&node); ) {
1754 		type[0] = 0;
1755 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
1756 			  type, sizeof(type));
1757 		if (strcmp(type, RELOC("display")) != 0)
1758 			continue;
1759 		/* It seems OF doesn't null-terminate the path :-( */
1760 		path = (char *) mem;
1761 		memset(path, 0, 256);
1762 		if ((long) call_prom(RELOC("package-to-path"), 3, 1,
1763 				    node, path, 255) < 0)
1764 			continue;
1765 		prom_print(RELOC("opening display "));
1766 		prom_print(path);
1767 		ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);
1768 		if (ih == (ihandle)0 || ih == (ihandle)-1) {
1769 			prom_print(RELOC("... failed\n"));
1770 			continue;
1771 		}
1772 		prom_print(RELOC("... ok\n"));
1773 
1774 		if (_prom->disp_node == 0)
1775 			_prom->disp_node = (ihandle)(unsigned long)node;
1776 
1777 		/* Setup a useable color table when the appropriate
1778 		 * method is available. Should update this to set-colors */
1779 		for (i = 0; i < 32; i++)
1780 			if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
1781 					   RELOC(default_colors)[i*3+1],
1782 					   RELOC(default_colors)[i*3+2]) != 0)
1783 				break;
1784 
1785 #ifdef CONFIG_FB
1786 		for (i = 0; i < LINUX_LOGO_COLORS; i++)
1787 			if (prom_set_color(ih, i + 32,
1788 					   RELOC(linux_logo_red)[i],
1789 					   RELOC(linux_logo_green)[i],
1790 					   RELOC(linux_logo_blue)[i]) != 0)
1791 				break;
1792 #endif /* CONFIG_FB */
1793 
1794 		/*
1795 		 * If this display is the device that OF is using for stdout,
1796 		 * move it to the front of the list.
1797 		 */
1798 		mem += strlen(path) + 1;
1799 		i = RELOC(prom_num_displays)++;
1800 		if (RELOC(of_stdout_device) != 0 && i > 0
1801 		    && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
1802 			for (; i > 0; --i)
1803 				RELOC(prom_display_paths[i]) = RELOC(prom_display_paths[i-1]);
1804 		}
1805 		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
1806 		if (RELOC(prom_num_displays) >= FB_MAX)
1807 			break;
1808 	}
1809 	return DOUBLEWORD_ALIGN(mem);
1810 }
1811 
1812 static int __init
prom_next_node(phandle * nodep)1813 prom_next_node(phandle *nodep)
1814 {
1815 	phandle node;
1816 	unsigned long offset = reloc_offset();
1817 
1818 	if ((node = *nodep) != 0
1819 	    && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
1820 		return 1;
1821 	if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
1822 		return 1;
1823 	for (;;) {
1824 		if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
1825 			return 0;
1826 		if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
1827 			return 1;
1828 	}
1829 }
1830 
1831 /*
1832  * Make a copy of the device tree from the PROM.
1833  */
1834 static unsigned long __init
copy_device_tree(unsigned long mem_start)1835 copy_device_tree(unsigned long mem_start)
1836 {
1837 	phandle root;
1838 	unsigned long new_start;
1839 	struct device_node **allnextp;
1840 	unsigned long offset = reloc_offset();
1841 	unsigned long mem_end = mem_start + (8<<20);
1842 
1843 	root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
1844 	if (root == (phandle)0) {
1845 		prom_print(RELOC("couldn't get device tree root\n"));
1846 		prom_exit();
1847 	}
1848 	allnextp = &RELOC(allnodes);
1849 	mem_start = DOUBLEWORD_ALIGN(mem_start);
1850 	new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
1851 	*allnextp = 0;
1852 	return new_start;
1853 }
1854 
1855 __init
1856 static unsigned long
inspect_node(phandle node,struct device_node * dad,unsigned long mem_start,unsigned long mem_end,struct device_node *** allnextpp)1857 inspect_node(phandle node, struct device_node *dad,
1858 	     unsigned long mem_start, unsigned long mem_end,
1859 	     struct device_node ***allnextpp)
1860 {
1861 	int l;
1862 	phandle child;
1863 	struct device_node *np;
1864 	struct property *pp, **prev_propp;
1865 	char *prev_name, *namep;
1866 	unsigned char *valp;
1867 	unsigned long offset = reloc_offset();
1868 
1869 	np = (struct device_node *) mem_start;
1870 	mem_start += sizeof(struct device_node);
1871 	memset(np, 0, sizeof(*np));
1872 	np->node = node;
1873 	**allnextpp = PTRUNRELOC(np);
1874 	*allnextpp = &np->allnext;
1875 	if (dad != 0) {
1876 		np->parent = PTRUNRELOC(dad);
1877 		/* we temporarily use the `next' field as `last_child'. */
1878 		if (dad->next == 0)
1879 			dad->child = PTRUNRELOC(np);
1880 		else
1881 			dad->next->sibling = PTRUNRELOC(np);
1882 		dad->next = np;
1883 	}
1884 
1885 	/* get and store all properties */
1886 	prev_propp = &np->properties;
1887 	prev_name = RELOC("");
1888 	for (;;) {
1889 		pp = (struct property *) mem_start;
1890 		namep = (char *) (pp + 1);
1891 		pp->name = PTRUNRELOC(namep);
1892 		if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
1893 				    namep) <= 0)
1894 			break;
1895 		mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);
1896 		prev_name = namep;
1897 		valp = (unsigned char *) mem_start;
1898 		pp->value = PTRUNRELOC(valp);
1899 		pp->length = (int)(long)
1900 			call_prom(RELOC("getprop"), 4, 1, node, namep,
1901 				  valp, mem_end - mem_start);
1902 		if (pp->length < 0)
1903 			continue;
1904 		mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
1905 		*prev_propp = PTRUNRELOC(pp);
1906 		prev_propp = &pp->next;
1907 	}
1908 
1909 	/* Add a "linux_phandle" value */
1910 	if (np->node != NULL) {
1911 		u32 ibm_phandle = 0;
1912 		int len;
1913 
1914 		/* First see if "ibm,phandle" exists and use its value */
1915 		len = (int) call_prom(RELOC("getprop"), 4, 1, node,
1916 				      RELOC("ibm,phandle"),
1917 				      &ibm_phandle, sizeof(ibm_phandle));
1918 		if (len < 0) {
1919 			np->linux_phandle = np->node;
1920 		} else {
1921 			np->linux_phandle = ibm_phandle;
1922 		}
1923 	}
1924 
1925 	*prev_propp = 0;
1926 
1927 	/* get the node's full name */
1928 	l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
1929 			    (char *) mem_start, mem_end - mem_start);
1930 	if (l >= 0) {
1931 		np->full_name = PTRUNRELOC((char *) mem_start);
1932 		*(char *)(mem_start + l) = 0;
1933 		mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);
1934 	}
1935 
1936 	/* do all our children */
1937 	child = call_prom(RELOC("child"), 1, 1, node);
1938 	while (child != (phandle)0) {
1939 		mem_start = inspect_node(child, np, mem_start, mem_end,
1940 					 allnextpp);
1941 		child = call_prom(RELOC("peer"), 1, 1, child);
1942 	}
1943 
1944 	return mem_start;
1945 }
1946 
1947 /*
1948  * finish_device_tree is called once things are running normally
1949  * (i.e. with text and data mapped to the address they were linked at).
1950  * It traverses the device tree and fills in the name, type,
1951  * {n_}addrs and {n_}intrs fields of each node.
1952  */
1953 void __init
finish_device_tree(void)1954 finish_device_tree(void)
1955 {
1956 	unsigned long mem = klimit;
1957 
1958 	mem = finish_node(allnodes, mem, NULL, 0, 0);
1959 	dev_tree_size = mem - (unsigned long) allnodes;
1960 
1961 	mem = _ALIGN(mem, PAGE_SIZE);
1962 	lmb_reserve(__pa(klimit), mem-klimit);
1963 
1964 	klimit = mem;
1965 
1966 	rtas.dev = find_devices("rtas");
1967 }
1968 
1969 static unsigned long __init
finish_node(struct device_node * np,unsigned long mem_start,interpret_func * ifunc,int naddrc,int nsizec)1970 finish_node(struct device_node *np, unsigned long mem_start,
1971 	    interpret_func *ifunc, int naddrc, int nsizec)
1972 {
1973 	struct device_node *child;
1974 	int *ip;
1975 
1976 	np->name = get_property(np, "name", 0);
1977 	np->type = get_property(np, "device_type", 0);
1978 
1979 	/* get the device addresses and interrupts */
1980 	if (ifunc != NULL) {
1981 	  mem_start = ifunc(np, mem_start, naddrc, nsizec);
1982 	}
1983 	mem_start = finish_node_interrupts(np, mem_start);
1984 
1985 	/* Look for #address-cells and #size-cells properties. */
1986 	ip = (int *) get_property(np, "#address-cells", 0);
1987 	if (ip != NULL)
1988 		naddrc = *ip;
1989 	ip = (int *) get_property(np, "#size-cells", 0);
1990 	if (ip != NULL)
1991 		nsizec = *ip;
1992 
1993 	/* the f50 sets the name to 'display' and 'compatible' to what we
1994 	 * expect for the name -- Cort
1995 	 */
1996 	ifunc = NULL;
1997 	if (!strcmp(np->name, "display"))
1998 		np->name = get_property(np, "compatible", 0);
1999 
2000 	if (!strcmp(np->name, "device-tree") || np->parent == NULL)
2001 		ifunc = interpret_root_props;
2002 	else if (np->type == 0)
2003 		ifunc = NULL;
2004 	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
2005 		ifunc = interpret_pci_props;
2006 	else if (!strcmp(np->type, "isa"))
2007 		ifunc = interpret_isa_props;
2008 
2009 	for (child = np->child; child != NULL; child = child->sibling)
2010 		mem_start = finish_node(child, mem_start, ifunc,
2011 					naddrc, nsizec);
2012 
2013 	return mem_start;
2014 }
2015 
2016 /* This routine walks the interrupt tree for a given device node and gather
2017  * all necessary informations according to the draft interrupt mapping
2018  * for CHRP. The current version was only tested on Apple "Core99" machines
2019  * and may not handle cascaded controllers correctly.
2020  */
2021 __init
2022 static unsigned long
finish_node_interrupts(struct device_node * np,unsigned long mem_start)2023 finish_node_interrupts(struct device_node *np, unsigned long mem_start)
2024 {
2025 	/* Finish this node */
2026 	unsigned int *isizep, *asizep, *interrupts, *map, *map_mask, *reg;
2027 	phandle *parent, map_parent;
2028 	struct device_node *node, *parent_node;
2029 	int l, isize, ipsize, asize, map_size, regpsize;
2030 
2031 	/* Currently, we don't look at all nodes with no "interrupts" property */
2032 
2033 	interrupts = (unsigned int *)get_property(np, "interrupts", &l);
2034 	if (interrupts == NULL)
2035 		return mem_start;
2036 	ipsize = l>>2;
2037 
2038 	reg = (unsigned int *)get_property(np, "reg", &l);
2039 	regpsize = l>>2;
2040 
2041 	/* We assume default interrupt cell size is 1 (bugus ?) */
2042 	isize = 1;
2043 	node = np;
2044 
2045 	do {
2046 	    /* We adjust the cell size if the current parent contains an #interrupt-cells
2047 	     * property */
2048 	    isizep = (unsigned int *)get_property(node, "#interrupt-cells", &l);
2049 	    if (isizep)
2050 	    	isize = *isizep;
2051 
2052 	    /* We don't do interrupt cascade (ISA) for now, we stop on the first
2053 	     * controller found
2054 	     */
2055 	    if (get_property(node, "interrupt-controller", &l)) {
2056 	    	int i,j;
2057 
2058 	    	np->intrs = (struct interrupt_info *) mem_start;
2059 		np->n_intrs = ipsize / isize;
2060 		mem_start += np->n_intrs * sizeof(struct interrupt_info);
2061 		for (i = 0; i < np->n_intrs; ++i) {
2062 		    np->intrs[i].line = irq_offset_up(*interrupts++);
2063 		    np->intrs[i].sense = 1;
2064 		    if (isize > 1)
2065 		        np->intrs[i].sense = *interrupts++;
2066 		    for (j=2; j<isize; j++)
2067 		    	interrupts++;
2068 		}
2069 		return mem_start;
2070 	    }
2071 	    /* We lookup for an interrupt-map. This code can only handle one interrupt
2072 	     * per device in the map. We also don't handle #address-cells in the parent
2073 	     * I skip the pci node itself here, may not be necessary but I don't like it's
2074 	     * reg property.
2075 	     */
2076 	    if (np != node)
2077 	        map = (unsigned int *)get_property(node, "interrupt-map", &l);
2078 	     else
2079 	     	map = NULL;
2080 	    if (map && l) {
2081 	    	int i, found, temp_isize, temp_asize;
2082 	        map_size = l>>2;
2083 	        map_mask = (unsigned int *)get_property(node, "interrupt-map-mask", &l);
2084 	        asizep = (unsigned int *)get_property(node, "#address-cells", &l);
2085 	        if (asizep && l == sizeof(unsigned int))
2086 	            asize = *asizep;
2087 	        else
2088 	            asize = 0;
2089 	        found = 0;
2090 	        while (map_size>0 && !found) {
2091 	            found = 1;
2092 	            for (i=0; i<asize; i++) {
2093 	            	unsigned int mask = map_mask ? map_mask[i] : 0xffffffff;
2094 	            	if (!reg || (i>=regpsize) || ((mask & *map) != (mask & reg[i])))
2095 	           	    found = 0;
2096 	           	map++;
2097 	           	map_size--;
2098 	            }
2099 	            for (i=0; i<isize; i++) {
2100 	            	unsigned int mask = map_mask ? map_mask[i+asize] : 0xffffffff;
2101 	            	if ((mask & *map) != (mask & interrupts[i]))
2102 	            	    found = 0;
2103 	            	map++;
2104 	            	map_size--;
2105 	            }
2106 	            map_parent = *((phandle *)map);
2107 	            map+=1; map_size-=1;
2108 	            parent_node = find_phandle(map_parent);
2109 	            temp_isize = isize;
2110 		    temp_asize = 0;
2111 	            if (parent_node) {
2112 			isizep = (unsigned int *)get_property(parent_node, "#interrupt-cells", &l);
2113 	    		if (isizep)
2114 	    		    temp_isize = *isizep;
2115 			asizep = (unsigned int *)get_property(parent_node, "#address-cells", &l);
2116 			if (asizep && l == sizeof(unsigned int))
2117 				temp_asize = *asizep;
2118 	            }
2119 	            if (!found) {
2120 			map += temp_isize + temp_asize;
2121 			map_size -= temp_isize + temp_asize;
2122 	            }
2123 	        }
2124 	        if (found) {
2125 		    /* Mapped to a new parent.  Use the reg and interrupts specified in
2126 		     * the map as the new search parameters.  Then search from the parent.
2127 		     */
2128 	            node = parent_node;
2129 		    reg = map;
2130 		    regpsize = temp_asize;
2131 		    interrupts = map + temp_asize;
2132 		    ipsize = temp_isize;
2133 		    continue;
2134 	        }
2135 	    }
2136 	    /* We look for an explicit interrupt-parent.
2137 	     */
2138 	    parent = (phandle *)get_property(node, "interrupt-parent", &l);
2139 	    if (parent && (l == sizeof(phandle)) &&
2140 	    	(parent_node = find_phandle(*parent))) {
2141 	    	node = parent_node;
2142 	    	continue;
2143 	    }
2144 	    /* Default, get real parent */
2145 	    node = node->parent;
2146 	} while (node);
2147 
2148 	return mem_start;
2149 }
2150 
2151 int
prom_n_addr_cells(struct device_node * np)2152 prom_n_addr_cells(struct device_node* np)
2153 {
2154 	int* ip;
2155 	do {
2156 		if (np->parent)
2157 			np = np->parent;
2158 		ip = (int *) get_property(np, "#address-cells", 0);
2159 		if (ip != NULL)
2160 			return *ip;
2161 	} while (np->parent);
2162 	/* No #address-cells property for the root node, default to 1 */
2163 	return 1;
2164 }
2165 
2166 int
prom_n_size_cells(struct device_node * np)2167 prom_n_size_cells(struct device_node* np)
2168 {
2169 	int* ip;
2170 	do {
2171 		if (np->parent)
2172 			np = np->parent;
2173 		ip = (int *) get_property(np, "#size-cells", 0);
2174 		if (ip != NULL)
2175 			return *ip;
2176 	} while (np->parent);
2177 	/* No #size-cells property for the root node, default to 1 */
2178 	return 1;
2179 }
2180 
2181 static unsigned long __init
interpret_pci_props(struct device_node * np,unsigned long mem_start,int naddrc,int nsizec)2182 interpret_pci_props(struct device_node *np, unsigned long mem_start,
2183 		    int naddrc, int nsizec)
2184 {
2185 	struct address_range *adr;
2186 	struct pci_reg_property *pci_addrs;
2187 	int i, l;
2188 
2189 	pci_addrs = (struct pci_reg_property *)
2190 		get_property(np, "assigned-addresses", &l);
2191 	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
2192 		i = 0;
2193 		adr = (struct address_range *) mem_start;
2194 		while ((l -= sizeof(struct pci_reg_property)) >= 0) {
2195 			adr[i].space = pci_addrs[i].addr.a_hi;
2196 			adr[i].address = pci_addrs[i].addr.a_lo;
2197 			adr[i].size = pci_addrs[i].size_lo;
2198 			++i;
2199 		}
2200 		np->addrs = adr;
2201 		np->n_addrs = i;
2202 		mem_start += i * sizeof(struct address_range);
2203 	}
2204 	return mem_start;
2205 }
2206 
2207 static unsigned long __init
interpret_isa_props(struct device_node * np,unsigned long mem_start,int naddrc,int nsizec)2208 interpret_isa_props(struct device_node *np, unsigned long mem_start,
2209 		    int naddrc, int nsizec)
2210 {
2211 	struct isa_reg_property *rp;
2212 	struct address_range *adr;
2213 	int i, l;
2214 
2215 	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
2216 	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
2217 		i = 0;
2218 		adr = (struct address_range *) mem_start;
2219 		while ((l -= sizeof(struct reg_property)) >= 0) {
2220 			adr[i].space = rp[i].space;
2221 			adr[i].address = rp[i].address
2222 				+ (adr[i].space? 0: _ISA_MEM_BASE);
2223 			adr[i].size = rp[i].size;
2224 			++i;
2225 		}
2226 		np->addrs = adr;
2227 		np->n_addrs = i;
2228 		mem_start += i * sizeof(struct address_range);
2229 	}
2230 
2231 	return mem_start;
2232 }
2233 
2234 static unsigned long __init
interpret_root_props(struct device_node * np,unsigned long mem_start,int naddrc,int nsizec)2235 interpret_root_props(struct device_node *np, unsigned long mem_start,
2236 		     int naddrc, int nsizec)
2237 {
2238 	struct address_range *adr;
2239 	int i, l;
2240 	unsigned int *rp;
2241 	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
2242 
2243 	rp = (unsigned int *) get_property(np, "reg", &l);
2244 	if (rp != 0 && l >= rpsize) {
2245 		i = 0;
2246 		adr = (struct address_range *) mem_start;
2247 		while ((l -= rpsize) >= 0) {
2248 			adr[i].space = 0;
2249 			adr[i].address = rp[naddrc - 1];
2250 			adr[i].size = rp[naddrc + nsizec - 1];
2251 			++i;
2252 			rp += naddrc + nsizec;
2253 		}
2254 		np->addrs = adr;
2255 		np->n_addrs = i;
2256 		mem_start += i * sizeof(struct address_range);
2257 	}
2258 
2259 	return mem_start;
2260 }
2261 
2262 /*
2263  * Work out the sense (active-low level / active-high edge)
2264  * of each interrupt from the device tree.
2265  */
2266 void __init
prom_get_irq_senses(unsigned char * senses,int off,int max)2267 prom_get_irq_senses(unsigned char *senses, int off, int max)
2268 {
2269 	struct device_node *np;
2270 	int i, j;
2271 
2272 	/* default to level-triggered */
2273 	memset(senses, 1, max - off);
2274 
2275 	for (np = allnodes; np != 0; np = np->allnext) {
2276 		for (j = 0; j < np->n_intrs; j++) {
2277 			i = np->intrs[j].line;
2278 			if (i >= off && i < max)
2279 				senses[i-off] = np->intrs[j].sense;
2280 		}
2281 	}
2282 }
2283 
2284 /*
2285  * Construct and return a list of the device_nodes with a given name.
2286  */
2287 struct device_node *
find_devices(const char * name)2288 find_devices(const char *name)
2289 {
2290 	struct device_node *head, **prevp, *np;
2291 
2292 	prevp = &head;
2293 	for (np = allnodes; np != 0; np = np->allnext) {
2294 		if (np->name != 0 && strcasecmp(np->name, name) == 0) {
2295 			*prevp = np;
2296 			prevp = &np->next;
2297 		}
2298 	}
2299 	*prevp = 0;
2300 	return head;
2301 }
2302 
2303 /*
2304  * Construct and return a list of the device_nodes with a given type.
2305  */
2306 struct device_node *
find_type_devices(const char * type)2307 find_type_devices(const char *type)
2308 {
2309 	struct device_node *head, **prevp, *np;
2310 
2311 	prevp = &head;
2312 	for (np = allnodes; np != 0; np = np->allnext) {
2313 		if (np->type != 0 && strcasecmp(np->type, type) == 0) {
2314 			*prevp = np;
2315 			prevp = &np->next;
2316 		}
2317 	}
2318 	*prevp = 0;
2319 	return head;
2320 }
2321 
2322 /*
2323  * Returns all nodes linked together
2324  */
2325 struct device_node * __openfirmware
find_all_nodes(void)2326 find_all_nodes(void)
2327 {
2328 	struct device_node *head, **prevp, *np;
2329 
2330 	prevp = &head;
2331 	for (np = allnodes; np != 0; np = np->allnext) {
2332 		*prevp = np;
2333 		prevp = &np->next;
2334 	}
2335 	*prevp = 0;
2336 	return head;
2337 }
2338 
2339 /* Checks if the given "compat" string matches one of the strings in
2340  * the device's "compatible" property
2341  */
2342 int
device_is_compatible(struct device_node * device,const char * compat)2343 device_is_compatible(struct device_node *device, const char *compat)
2344 {
2345 	const char* cp;
2346 	int cplen, l;
2347 
2348 	cp = (char *) get_property(device, "compatible", &cplen);
2349 	if (cp == NULL)
2350 		return 0;
2351 	while (cplen > 0) {
2352 		if (strncasecmp(cp, compat, strlen(compat)) == 0)
2353 			return 1;
2354 		l = strlen(cp) + 1;
2355 		cp += l;
2356 		cplen -= l;
2357 	}
2358 
2359 	return 0;
2360 }
2361 
2362 
2363 /*
2364  * Indicates whether the root node has a given value in its
2365  * compatible property.
2366  */
2367 int
machine_is_compatible(const char * compat)2368 machine_is_compatible(const char *compat)
2369 {
2370 	struct device_node *root;
2371 
2372 	root = find_path_device("/");
2373 	if (root == 0)
2374 		return 0;
2375 	return device_is_compatible(root, compat);
2376 }
2377 
2378 /*
2379  * Construct and return a list of the device_nodes with a given type
2380  * and compatible property.
2381  */
2382 struct device_node *
find_compatible_devices(const char * type,const char * compat)2383 find_compatible_devices(const char *type, const char *compat)
2384 {
2385 	struct device_node *head, **prevp, *np;
2386 
2387 	prevp = &head;
2388 	for (np = allnodes; np != 0; np = np->allnext) {
2389 		if (type != NULL
2390 		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
2391 			continue;
2392 		if (device_is_compatible(np, compat)) {
2393 			*prevp = np;
2394 			prevp = &np->next;
2395 		}
2396 	}
2397 	*prevp = 0;
2398 	return head;
2399 }
2400 
2401 /*
2402  * Find the device_node with a given full_name.
2403  */
2404 struct device_node *
find_path_device(const char * path)2405 find_path_device(const char *path)
2406 {
2407 	struct device_node *np;
2408 
2409 	for (np = allnodes; np != 0; np = np->allnext)
2410 		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
2411 			return np;
2412 	return NULL;
2413 }
2414 
2415 /*
2416  * Find the device_node with a given phandle.
2417  */
2418 static struct device_node * __init
find_phandle(phandle ph)2419 find_phandle(phandle ph)
2420 {
2421 	struct device_node *np;
2422 
2423 	for (np = allnodes; np != 0; np = np->allnext)
2424 		if (np->linux_phandle == ph)
2425 			return np;
2426 	return NULL;
2427 }
2428 
2429 /*
2430  * Find a property with a given name for a given node
2431  * and return the value.
2432  */
2433 unsigned char *
get_property(struct device_node * np,const char * name,int * lenp)2434 get_property(struct device_node *np, const char *name, int *lenp)
2435 {
2436 	struct property *pp;
2437 
2438 	for (pp = np->properties; pp != 0; pp = pp->next)
2439 		if (strcmp(pp->name, name) == 0) {
2440 			if (lenp != 0)
2441 				*lenp = pp->length;
2442 			return pp->value;
2443 		}
2444 	return 0;
2445 }
2446 
2447 /*
2448  * Add a property to a node
2449  */
2450 void __openfirmware
prom_add_property(struct device_node * np,struct property * prop)2451 prom_add_property(struct device_node* np, struct property* prop)
2452 {
2453 	struct property **next = &np->properties;
2454 
2455 	prop->next = NULL;
2456 	while (*next)
2457 		next = &(*next)->next;
2458 	*next = prop;
2459 }
2460 
2461 #if 0
2462 void __openfirmware
2463 print_properties(struct device_node *np)
2464 {
2465 	struct property *pp;
2466 	char *cp;
2467 	int i, n;
2468 
2469 	for (pp = np->properties; pp != 0; pp = pp->next) {
2470 		printk(KERN_INFO "%s", pp->name);
2471 		for (i = strlen(pp->name); i < 16; ++i)
2472 			printk(" ");
2473 		cp = (char *) pp->value;
2474 		for (i = pp->length; i > 0; --i, ++cp)
2475 			if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
2476 			    || (i == 1 && *cp != 0))
2477 				break;
2478 		if (i == 0 && pp->length > 1) {
2479 			/* looks like a string */
2480 			printk(" %s\n", (char *) pp->value);
2481 		} else {
2482 			/* dump it in hex */
2483 			n = pp->length;
2484 			if (n > 64)
2485 				n = 64;
2486 			if (pp->length % 4 == 0) {
2487 				unsigned int *p = (unsigned int *) pp->value;
2488 
2489 				n /= 4;
2490 				for (i = 0; i < n; ++i) {
2491 					if (i != 0 && (i % 4) == 0)
2492 						printk("\n                ");
2493 					printk(" %08x", *p++);
2494 				}
2495 			} else {
2496 				unsigned char *bp = pp->value;
2497 
2498 				for (i = 0; i < n; ++i) {
2499 					if (i != 0 && (i % 16) == 0)
2500 						printk("\n                ");
2501 					printk(" %02x", *bp++);
2502 				}
2503 			}
2504 			printk("\n");
2505 			if (pp->length > 64)
2506 				printk("                 ... (length = %d)\n",
2507 				       pp->length);
2508 		}
2509 	}
2510 }
2511 #endif
2512 
2513 
2514 void __init
abort(void)2515 abort(void)
2516 {
2517 #ifdef CONFIG_XMON
2518 	xmon(NULL);
2519 #endif
2520 	for (;;)
2521 		prom_exit();
2522 }
2523 
2524 
2525 /* Verify bi_recs are good */
2526 static struct bi_record *
prom_bi_rec_verify(struct bi_record * bi_recs)2527 prom_bi_rec_verify(struct bi_record *bi_recs)
2528 {
2529 	struct bi_record *first, *last;
2530 
2531 	if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
2532 		return NULL;
2533 
2534 	last = (struct bi_record *)bi_recs->data[0];
2535 	if ( last == NULL || last->tag != BI_LAST )
2536 		return NULL;
2537 
2538 	first = (struct bi_record *)last->data[0];
2539 	if ( first == NULL || first != bi_recs )
2540 		return NULL;
2541 
2542 	return bi_recs;
2543 }
2544 
2545 static unsigned long
prom_bi_rec_reserve(unsigned long mem)2546 prom_bi_rec_reserve(unsigned long mem)
2547 {
2548 	unsigned long offset = reloc_offset();
2549 	struct prom_t *_prom = PTRRELOC(&prom);
2550 	struct bi_record *rec;
2551 
2552 	if ( _prom->bi_recs != NULL) {
2553 
2554 		for ( rec=_prom->bi_recs;
2555 		      rec->tag != BI_LAST;
2556 		      rec=bi_rec_next(rec) ) {
2557 			switch (rec->tag) {
2558 #ifdef CONFIG_BLK_DEV_INITRD
2559 			case BI_INITRD:
2560 				lmb_reserve(rec->data[0], rec->data[1]);
2561 				break;
2562 #endif /* CONFIG_BLK_DEV_INITRD */
2563 			}
2564 		}
2565 		/* The next use of this field will be after relocation
2566 	 	 * is enabled, so convert this physical address into a
2567 	 	 * virtual address.
2568 	 	 */
2569 		_prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
2570 	}
2571 
2572 	return mem;
2573 }
2574 
2575