aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/prom_init.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-14 01:30:17 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-14 01:30:17 -0500
commit7568cb4ef6c507164b65b01f972a3bd026898ae1 (patch)
treeba608f4c84d8765d5a1491c345f6dc265b5ec4ea /arch/ppc64/kernel/prom_init.c
parentc55377ee73f6efeb373ae06f6e918d87660b4852 (diff)
powerpc: Move most remaining ppc64 files over to arch/powerpc
Also deletes files in arch/ppc64 that are no longer used now that we don't compile with ARCH=ppc64 any more. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc64/kernel/prom_init.c')
-rw-r--r--arch/ppc64/kernel/prom_init.c2051
1 files changed, 0 insertions, 2051 deletions
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
deleted file mode 100644
index 6375f40b23db..000000000000
--- a/arch/ppc64/kernel/prom_init.c
+++ /dev/null
@@ -1,2051 +0,0 @@
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#undef DEBUG_PROM
19
20#include <stdarg.h>
21#include <linux/config.h>
22#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/threads.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28#include <linux/pci.h>
29#include <linux/proc_fs.h>
30#include <linux/stringify.h>
31#include <linux/delay.h>
32#include <linux/initrd.h>
33#include <linux/bitops.h>
34#include <asm/prom.h>
35#include <asm/rtas.h>
36#include <asm/abs_addr.h>
37#include <asm/page.h>
38#include <asm/processor.h>
39#include <asm/irq.h>
40#include <asm/io.h>
41#include <asm/smp.h>
42#include <asm/system.h>
43#include <asm/mmu.h>
44#include <asm/pgtable.h>
45#include <asm/pci.h>
46#include <asm/iommu.h>
47#include <asm/btext.h>
48#include <asm/sections.h>
49#include <asm/machdep.h>
50
51#ifdef CONFIG_LOGO_LINUX_CLUT224
52#include <linux/linux_logo.h>
53extern const struct linux_logo logo_linux_clut224;
54#endif
55
56/*
57 * Properties whose value is longer than this get excluded from our
58 * copy of the device tree. This value does need to be big enough to
59 * ensure that we don't lose things like the interrupt-map property
60 * on a PCI-PCI bridge.
61 */
62#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
63
64/*
65 * Eventually bump that one up
66 */
67#define DEVTREE_CHUNK_SIZE 0x100000
68
69/*
70 * This is the size of the local memory reserve map that gets copied
71 * into the boot params passed to the kernel. That size is totally
72 * flexible as the kernel just reads the list until it encounters an
73 * entry with size 0, so it can be changed without breaking binary
74 * compatibility
75 */
76#define MEM_RESERVE_MAP_SIZE 8
77
78/*
79 * prom_init() is called very early on, before the kernel text
80 * and data have been mapped to KERNELBASE. At this point the code
81 * is running at whatever address it has been loaded at, so
82 * references to extern and static variables must be relocated
83 * explicitly. The procedure reloc_offset() returns the address
84 * we're currently running at minus the address we were linked at.
85 * (Note that strings count as static variables.)
86 *
87 * Because OF may have mapped I/O devices into the area starting at
88 * KERNELBASE, particularly on CHRP machines, we can't safely call
89 * OF once the kernel has been mapped to KERNELBASE. Therefore all
90 * OF calls should be done within prom_init(), and prom_init()
91 * and all routines called within it must be careful to relocate
92 * references as necessary.
93 *
94 * Note that the bss is cleared *after* prom_init runs, so we have
95 * to make sure that any static or extern variables it accesses
96 * are put in the data segment.
97 */
98
99
100#define PROM_BUG() do { \
101 prom_printf("kernel BUG at %s line 0x%x!\n", \
102 RELOC(__FILE__), __LINE__); \
103 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
104} while (0)
105
106#ifdef DEBUG_PROM
107#define prom_debug(x...) prom_printf(x)
108#else
109#define prom_debug(x...)
110#endif
111
112
113typedef u32 prom_arg_t;
114
115struct prom_args {
116 u32 service;
117 u32 nargs;
118 u32 nret;
119 prom_arg_t args[10];
120 prom_arg_t *rets; /* Pointer to return values in args[16]. */
121};
122
123struct prom_t {
124 unsigned long entry;
125 ihandle root;
126 ihandle chosen;
127 int cpu;
128 ihandle stdout;
129 ihandle disp_node;
130 struct prom_args args;
131 unsigned long version;
132 unsigned long root_size_cells;
133 unsigned long root_addr_cells;
134};
135
136struct pci_reg_property {
137 struct pci_address addr;
138 u32 size_hi;
139 u32 size_lo;
140};
141
142struct mem_map_entry {
143 u64 base;
144 u64 size;
145};
146
147typedef u32 cell_t;
148
149extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
150
151extern void enter_prom(struct prom_args *args, unsigned long entry);
152extern void copy_and_flush(unsigned long dest, unsigned long src,
153 unsigned long size, unsigned long offset);
154
155extern unsigned long klimit;
156
157/* prom structure */
158static struct prom_t __initdata prom;
159
160#define PROM_SCRATCH_SIZE 256
161
162static char __initdata of_stdout_device[256];
163static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
164
165static unsigned long __initdata dt_header_start;
166static unsigned long __initdata dt_struct_start, dt_struct_end;
167static unsigned long __initdata dt_string_start, dt_string_end;
168
169static unsigned long __initdata prom_initrd_start, prom_initrd_end;
170
171static int __initdata iommu_force_on;
172static int __initdata ppc64_iommu_off;
173static int __initdata of_platform;
174
175static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
176
177static unsigned long __initdata prom_memory_limit;
178static unsigned long __initdata prom_tce_alloc_start;
179static unsigned long __initdata prom_tce_alloc_end;
180
181static unsigned long __initdata alloc_top;
182static unsigned long __initdata alloc_top_high;
183static unsigned long __initdata alloc_bottom;
184static unsigned long __initdata rmo_top;
185static unsigned long __initdata ram_top;
186
187static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
188static int __initdata mem_reserve_cnt;
189
190static cell_t __initdata regbuf[1024];
191
192
193#define MAX_CPU_THREADS 2
194
195/* TO GO */
196#ifdef CONFIG_HMT
197struct {
198 unsigned int pir;
199 unsigned int threadid;
200} hmt_thread_data[NR_CPUS];
201#endif /* CONFIG_HMT */
202
203/*
204 * This are used in calls to call_prom. The 4th and following
205 * arguments to call_prom should be 32-bit values. 64 bit values
206 * are truncated to 32 bits (and fortunately don't get interpreted
207 * as two arguments).
208 */
209#define ADDR(x) (u32) ((unsigned long)(x) - offset)
210
211/*
212 * Error results ... some OF calls will return "-1" on error, some
213 * will return 0, some will return either. To simplify, here are
214 * macros to use with any ihandle or phandle return value to check if
215 * it is valid
216 */
217
218#define PROM_ERROR (-1u)
219#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
220#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
221
222
223/* This is the one and *ONLY* place where we actually call open
224 * firmware from, since we need to make sure we're running in 32b
225 * mode when we do. We switch back to 64b mode upon return.
226 */
227
228static int __init call_prom(const char *service, int nargs, int nret, ...)
229{
230 int i;
231 unsigned long offset = reloc_offset();
232 struct prom_t *_prom = PTRRELOC(&prom);
233 va_list list;
234
235 _prom->args.service = ADDR(service);
236 _prom->args.nargs = nargs;
237 _prom->args.nret = nret;
238 _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
239
240 va_start(list, nret);
241 for (i=0; i < nargs; i++)
242 _prom->args.args[i] = va_arg(list, prom_arg_t);
243 va_end(list);
244
245 for (i=0; i < nret ;i++)
246 _prom->args.rets[i] = 0;
247
248 enter_prom(&_prom->args, _prom->entry);
249
250 return (nret > 0) ? _prom->args.rets[0] : 0;
251}
252
253
254static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
255 unsigned long align)
256{
257 return (unsigned int)call_prom("claim", 3, 1,
258 (prom_arg_t)virt, (prom_arg_t)size,
259 (prom_arg_t)align);
260}
261
262static void __init prom_print(const char *msg)
263{
264 const char *p, *q;
265 unsigned long offset = reloc_offset();
266 struct prom_t *_prom = PTRRELOC(&prom);
267
268 if (_prom->stdout == 0)
269 return;
270
271 for (p = msg; *p != 0; p = q) {
272 for (q = p; *q != 0 && *q != '\n'; ++q)
273 ;
274 if (q > p)
275 call_prom("write", 3, 1, _prom->stdout, p, q - p);
276 if (*q == 0)
277 break;
278 ++q;
279 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
280 }
281}
282
283
284static void __init prom_print_hex(unsigned long val)
285{
286 unsigned long offset = reloc_offset();
287 int i, nibbles = sizeof(val)*2;
288 char buf[sizeof(val)*2+1];
289 struct prom_t *_prom = PTRRELOC(&prom);
290
291 for (i = nibbles-1; i >= 0; i--) {
292 buf[i] = (val & 0xf) + '0';
293 if (buf[i] > '9')
294 buf[i] += ('a'-'0'-10);
295 val >>= 4;
296 }
297 buf[nibbles] = '\0';
298 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
299}
300
301
302static void __init prom_printf(const char *format, ...)
303{
304 unsigned long offset = reloc_offset();
305 const char *p, *q, *s;
306 va_list args;
307 unsigned long v;
308 struct prom_t *_prom = PTRRELOC(&prom);
309
310 va_start(args, format);
311 for (p = PTRRELOC(format); *p != 0; p = q) {
312 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
313 ;
314 if (q > p)
315 call_prom("write", 3, 1, _prom->stdout, p, q - p);
316 if (*q == 0)
317 break;
318 if (*q == '\n') {
319 ++q;
320 call_prom("write", 3, 1, _prom->stdout,
321 ADDR("\r\n"), 2);
322 continue;
323 }
324 ++q;
325 if (*q == 0)
326 break;
327 switch (*q) {
328 case 's':
329 ++q;
330 s = va_arg(args, const char *);
331 prom_print(s);
332 break;
333 case 'x':
334 ++q;
335 v = va_arg(args, unsigned long);
336 prom_print_hex(v);
337 break;
338 }
339 }
340}
341
342
343static void __init __attribute__((noreturn)) prom_panic(const char *reason)
344{
345 unsigned long offset = reloc_offset();
346
347 prom_print(PTRRELOC(reason));
348 /* ToDo: should put up an SRC here */
349 call_prom("exit", 0, 0);
350
351 for (;;) /* should never get here */
352 ;
353}
354
355
356static int __init prom_next_node(phandle *nodep)
357{
358 phandle node;
359
360 if ((node = *nodep) != 0
361 && (*nodep = call_prom("child", 1, 1, node)) != 0)
362 return 1;
363 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
364 return 1;
365 for (;;) {
366 if ((node = call_prom("parent", 1, 1, node)) == 0)
367 return 0;
368 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
369 return 1;
370 }
371}
372
373static int __init prom_getprop(phandle node, const char *pname,
374 void *value, size_t valuelen)
375{
376 unsigned long offset = reloc_offset();
377
378 return call_prom("getprop", 4, 1, node, ADDR(pname),
379 (u32)(unsigned long) value, (u32) valuelen);
380}
381
382static int __init prom_getproplen(phandle node, const char *pname)
383{
384 unsigned long offset = reloc_offset();
385
386 return call_prom("getproplen", 2, 1, node, ADDR(pname));
387}
388
389static int __init prom_setprop(phandle node, const char *pname,
390 void *value, size_t valuelen)
391{
392 unsigned long offset = reloc_offset();
393
394 return call_prom("setprop", 4, 1, node, ADDR(pname),
395 (u32)(unsigned long) value, (u32) valuelen);
396}
397
398/* We can't use the standard versions because of RELOC headaches. */
399#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
400 || ('a' <= (c) && (c) <= 'f') \
401 || ('A' <= (c) && (c) <= 'F'))
402
403#define isdigit(c) ('0' <= (c) && (c) <= '9')
404#define islower(c) ('a' <= (c) && (c) <= 'z')
405#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
406
407unsigned long prom_strtoul(const char *cp, const char **endp)
408{
409 unsigned long result = 0, base = 10, value;
410
411 if (*cp == '0') {
412 base = 8;
413 cp++;
414 if (toupper(*cp) == 'X') {
415 cp++;
416 base = 16;
417 }
418 }
419
420 while (isxdigit(*cp) &&
421 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
422 result = result * base + value;
423 cp++;
424 }
425
426 if (endp)
427 *endp = cp;
428
429 return result;
430}
431
432unsigned long prom_memparse(const char *ptr, const char **retptr)
433{
434 unsigned long ret = prom_strtoul(ptr, retptr);
435 int shift = 0;
436
437 /*
438 * We can't use a switch here because GCC *may* generate a
439 * jump table which won't work, because we're not running at
440 * the address we're linked at.
441 */
442 if ('G' == **retptr || 'g' == **retptr)
443 shift = 30;
444
445 if ('M' == **retptr || 'm' == **retptr)
446 shift = 20;
447
448 if ('K' == **retptr || 'k' == **retptr)
449 shift = 10;
450
451 if (shift) {
452 ret <<= shift;
453 (*retptr)++;
454 }
455
456 return ret;
457}
458
459/*
460 * Early parsing of the command line passed to the kernel, used for
461 * "mem=x" and the options that affect the iommu
462 */
463static void __init early_cmdline_parse(void)
464{
465 unsigned long offset = reloc_offset();
466 struct prom_t *_prom = PTRRELOC(&prom);
467 char *opt, *p;
468 int l = 0;
469
470 RELOC(prom_cmd_line[0]) = 0;
471 p = RELOC(prom_cmd_line);
472 if ((long)_prom->chosen > 0)
473 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
474#ifdef CONFIG_CMDLINE
475 if (l == 0) /* dbl check */
476 strlcpy(RELOC(prom_cmd_line),
477 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
478#endif /* CONFIG_CMDLINE */
479 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
480
481 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
482 if (opt) {
483 prom_printf("iommu opt is: %s\n", opt);
484 opt += 6;
485 while (*opt && *opt == ' ')
486 opt++;
487 if (!strncmp(opt, RELOC("off"), 3))
488 RELOC(ppc64_iommu_off) = 1;
489 else if (!strncmp(opt, RELOC("force"), 5))
490 RELOC(iommu_force_on) = 1;
491 }
492
493 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
494 if (opt) {
495 opt += 4;
496 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
497 /* Align to 16 MB == size of large page */
498 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
499 }
500}
501
502/*
503 * To tell the firmware what our capabilities are, we have to pass
504 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
505 * that contain structures that contain the actual values.
506 */
507static struct fake_elf {
508 Elf32_Ehdr elfhdr;
509 Elf32_Phdr phdr[2];
510 struct chrpnote {
511 u32 namesz;
512 u32 descsz;
513 u32 type;
514 char name[8]; /* "PowerPC" */
515 struct chrpdesc {
516 u32 real_mode;
517 u32 real_base;
518 u32 real_size;
519 u32 virt_base;
520 u32 virt_size;
521 u32 load_base;
522 } chrpdesc;
523 } chrpnote;
524 struct rpanote {
525 u32 namesz;
526 u32 descsz;
527 u32 type;
528 char name[24]; /* "IBM,RPA-Client-Config" */
529 struct rpadesc {
530 u32 lpar_affinity;
531 u32 min_rmo_size;
532 u32 min_rmo_percent;
533 u32 max_pft_size;
534 u32 splpar;
535 u32 min_load;
536 u32 new_mem_def;
537 u32 ignore_me;
538 } rpadesc;
539 } rpanote;
540} fake_elf = {
541 .elfhdr = {
542 .e_ident = { 0x7f, 'E', 'L', 'F',
543 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
544 .e_type = ET_EXEC, /* yeah right */
545 .e_machine = EM_PPC,
546 .e_version = EV_CURRENT,
547 .e_phoff = offsetof(struct fake_elf, phdr),
548 .e_phentsize = sizeof(Elf32_Phdr),
549 .e_phnum = 2
550 },
551 .phdr = {
552 [0] = {
553 .p_type = PT_NOTE,
554 .p_offset = offsetof(struct fake_elf, chrpnote),
555 .p_filesz = sizeof(struct chrpnote)
556 }, [1] = {
557 .p_type = PT_NOTE,
558 .p_offset = offsetof(struct fake_elf, rpanote),
559 .p_filesz = sizeof(struct rpanote)
560 }
561 },
562 .chrpnote = {
563 .namesz = sizeof("PowerPC"),
564 .descsz = sizeof(struct chrpdesc),
565 .type = 0x1275,
566 .name = "PowerPC",
567 .chrpdesc = {
568 .real_mode = ~0U, /* ~0 means "don't care" */
569 .real_base = ~0U,
570 .real_size = ~0U,
571 .virt_base = ~0U,
572 .virt_size = ~0U,
573 .load_base = ~0U
574 },
575 },
576 .rpanote = {
577 .namesz = sizeof("IBM,RPA-Client-Config"),
578 .descsz = sizeof(struct rpadesc),
579 .type = 0x12759999,
580 .name = "IBM,RPA-Client-Config",
581 .rpadesc = {
582 .lpar_affinity = 0,
583 .min_rmo_size = 64, /* in megabytes */
584 .min_rmo_percent = 0,
585 .max_pft_size = 48, /* 2^48 bytes max PFT size */
586 .splpar = 1,
587 .min_load = ~0U,
588 .new_mem_def = 0
589 }
590 }
591};
592
593static void __init prom_send_capabilities(void)
594{
595 unsigned long offset = reloc_offset();
596 ihandle elfloader;
597
598 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
599 if (elfloader == 0) {
600 prom_printf("couldn't open /packages/elf-loader\n");
601 return;
602 }
603 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
604 elfloader, ADDR(&fake_elf));
605 call_prom("close", 1, 0, elfloader);
606}
607
608/*
609 * Memory allocation strategy... our layout is normally:
610 *
611 * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
612 * might end up beeing before the kernel though. We assume this won't override
613 * the final kernel at 0, we have no provision to handle that in this version,
614 * but it should hopefully never happen.
615 *
616 * alloc_top is set to the top of RMO, eventually shrink down if the TCEs overlap
617 * alloc_bottom is set to the top of kernel/initrd
618 *
619 * from there, allocations are done that way : rtas is allocated topmost, and
620 * the device-tree is allocated from the bottom. We try to grow the device-tree
621 * allocation as we progress. If we can't, then we fail, we don't currently have
622 * a facility to restart elsewhere, but that shouldn't be necessary neither
623 *
624 * Note that calls to reserve_mem have to be done explicitely, memory allocated
625 * with either alloc_up or alloc_down isn't automatically reserved.
626 */
627
628
629/*
630 * Allocates memory in the RMO upward from the kernel/initrd
631 *
632 * When align is 0, this is a special case, it means to allocate in place
633 * at the current location of alloc_bottom or fail (that is basically
634 * extending the previous allocation). Used for the device-tree flattening
635 */
636static unsigned long __init alloc_up(unsigned long size, unsigned long align)
637{
638 unsigned long offset = reloc_offset();
639 unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align);
640 unsigned long addr = 0;
641
642 prom_debug("alloc_up(%x, %x)\n", size, align);
643 if (RELOC(ram_top) == 0)
644 prom_panic("alloc_up() called with mem not initialized\n");
645
646 if (align)
647 base = _ALIGN_UP(RELOC(alloc_bottom), align);
648 else
649 base = RELOC(alloc_bottom);
650
651 for(; (base + size) <= RELOC(alloc_top);
652 base = _ALIGN_UP(base + 0x100000, align)) {
653 prom_debug(" trying: 0x%x\n\r", base);
654 addr = (unsigned long)prom_claim(base, size, 0);
655 if (addr != PROM_ERROR)
656 break;
657 addr = 0;
658 if (align == 0)
659 break;
660 }
661 if (addr == 0)
662 return 0;
663 RELOC(alloc_bottom) = addr;
664
665 prom_debug(" -> %x\n", addr);
666 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
667 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
668 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
669 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
670 prom_debug(" ram_top : %x\n", RELOC(ram_top));
671
672 return addr;
673}
674
675/*
676 * Allocates memory downard, either from top of RMO, or if highmem
677 * is set, from the top of RAM. Note that this one doesn't handle
678 * failures. In does claim memory if highmem is not set.
679 */
680static unsigned long __init alloc_down(unsigned long size, unsigned long align,
681 int highmem)
682{
683 unsigned long offset = reloc_offset();
684 unsigned long base, addr = 0;
685
686 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
687 highmem ? RELOC("(high)") : RELOC("(low)"));
688 if (RELOC(ram_top) == 0)
689 prom_panic("alloc_down() called with mem not initialized\n");
690
691 if (highmem) {
692 /* Carve out storage for the TCE table. */
693 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
694 if (addr <= RELOC(alloc_bottom))
695 return 0;
696 else {
697 /* Will we bump into the RMO ? If yes, check out that we
698 * didn't overlap existing allocations there, if we did,
699 * we are dead, we must be the first in town !
700 */
701 if (addr < RELOC(rmo_top)) {
702 /* Good, we are first */
703 if (RELOC(alloc_top) == RELOC(rmo_top))
704 RELOC(alloc_top) = RELOC(rmo_top) = addr;
705 else
706 return 0;
707 }
708 RELOC(alloc_top_high) = addr;
709 }
710 goto bail;
711 }
712
713 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
714 for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) {
715 prom_debug(" trying: 0x%x\n\r", base);
716 addr = (unsigned long)prom_claim(base, size, 0);
717 if (addr != PROM_ERROR)
718 break;
719 addr = 0;
720 }
721 if (addr == 0)
722 return 0;
723 RELOC(alloc_top) = addr;
724
725 bail:
726 prom_debug(" -> %x\n", addr);
727 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
728 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
729 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
730 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
731 prom_debug(" ram_top : %x\n", RELOC(ram_top));
732
733 return addr;
734}
735
736/*
737 * Parse a "reg" cell
738 */
739static unsigned long __init prom_next_cell(int s, cell_t **cellp)
740{
741 cell_t *p = *cellp;
742 unsigned long r = 0;
743
744 /* Ignore more than 2 cells */
745 while (s > 2) {
746 p++;
747 s--;
748 }
749 while (s) {
750 r <<= 32;
751 r |= *(p++);
752 s--;
753 }
754
755 *cellp = p;
756 return r;
757}
758
759/*
760 * Very dumb function for adding to the memory reserve list, but
761 * we don't need anything smarter at this point
762 *
763 * XXX Eventually check for collisions. They should NEVER happen
764 * if problems seem to show up, it would be a good start to track
765 * them down.
766 */
767static void reserve_mem(unsigned long base, unsigned long size)
768{
769 unsigned long offset = reloc_offset();
770 unsigned long top = base + size;
771 unsigned long cnt = RELOC(mem_reserve_cnt);
772
773 if (size == 0)
774 return;
775
776 /* We need to always keep one empty entry so that we
777 * have our terminator with "size" set to 0 since we are
778 * dumb and just copy this entire array to the boot params
779 */
780 base = _ALIGN_DOWN(base, PAGE_SIZE);
781 top = _ALIGN_UP(top, PAGE_SIZE);
782 size = top - base;
783
784 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
785 prom_panic("Memory reserve map exhausted !\n");
786 RELOC(mem_reserve_map)[cnt].base = base;
787 RELOC(mem_reserve_map)[cnt].size = size;
788 RELOC(mem_reserve_cnt) = cnt + 1;
789}
790
791/*
792 * Initialize memory allocation mecanism, parse "memory" nodes and
793 * obtain that way the top of memory and RMO to setup out local allocator
794 */
795static void __init prom_init_mem(void)
796{
797 phandle node;
798 char *path, type[64];
799 unsigned int plen;
800 cell_t *p, *endp;
801 unsigned long offset = reloc_offset();
802 struct prom_t *_prom = PTRRELOC(&prom);
803
804 /*
805 * We iterate the memory nodes to find
806 * 1) top of RMO (first node)
807 * 2) top of memory
808 */
809 prom_debug("root_addr_cells: %x\n", (long)_prom->root_addr_cells);
810 prom_debug("root_size_cells: %x\n", (long)_prom->root_size_cells);
811
812 prom_debug("scanning memory:\n");
813 path = RELOC(prom_scratch);
814
815 for (node = 0; prom_next_node(&node); ) {
816 type[0] = 0;
817 prom_getprop(node, "device_type", type, sizeof(type));
818
819 if (strcmp(type, RELOC("memory")))
820 continue;
821
822 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
823 if (plen > sizeof(regbuf)) {
824 prom_printf("memory node too large for buffer !\n");
825 plen = sizeof(regbuf);
826 }
827 p = RELOC(regbuf);
828 endp = p + (plen / sizeof(cell_t));
829
830#ifdef DEBUG_PROM
831 memset(path, 0, PROM_SCRATCH_SIZE);
832 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
833 prom_debug(" node %s :\n", path);
834#endif /* DEBUG_PROM */
835
836 while ((endp - p) >= (_prom->root_addr_cells + _prom->root_size_cells)) {
837 unsigned long base, size;
838
839 base = prom_next_cell(_prom->root_addr_cells, &p);
840 size = prom_next_cell(_prom->root_size_cells, &p);
841
842 if (size == 0)
843 continue;
844 prom_debug(" %x %x\n", base, size);
845 if (base == 0)
846 RELOC(rmo_top) = size;
847 if ((base + size) > RELOC(ram_top))
848 RELOC(ram_top) = base + size;
849 }
850 }
851
852 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(klimit) - offset + 0x4000);
853
854 /* Check if we have an initrd after the kernel, if we do move our bottom
855 * point to after it
856 */
857 if (RELOC(prom_initrd_start)) {
858 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
859 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
860 }
861
862 /*
863 * If prom_memory_limit is set we reduce the upper limits *except* for
864 * alloc_top_high. This must be the real top of RAM so we can put
865 * TCE's up there.
866 */
867
868 RELOC(alloc_top_high) = RELOC(ram_top);
869
870 if (RELOC(prom_memory_limit)) {
871 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
872 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
873 RELOC(prom_memory_limit));
874 RELOC(prom_memory_limit) = 0;
875 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
876 prom_printf("Ignoring mem=%x >= ram_top.\n",
877 RELOC(prom_memory_limit));
878 RELOC(prom_memory_limit) = 0;
879 } else {
880 RELOC(ram_top) = RELOC(prom_memory_limit);
881 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
882 }
883 }
884
885 /*
886 * Setup our top alloc point, that is top of RMO or top of
887 * segment 0 when running non-LPAR.
888 */
889 if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
890 RELOC(alloc_top) = RELOC(rmo_top);
891 else
892 /* Some RS64 machines have buggy firmware where claims up at 1GB
893 * fails. Cap at 768MB as a workaround. Still plenty of room.
894 */
895 RELOC(alloc_top) = RELOC(rmo_top) = min(0x30000000ul, RELOC(ram_top));
896
897 prom_printf("memory layout at init:\n");
898 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
899 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
900 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
901 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
902 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
903 prom_printf(" ram_top : %x\n", RELOC(ram_top));
904}
905
906
907/*
908 * Allocate room for and instanciate RTAS
909 */
910static void __init prom_instantiate_rtas(void)
911{
912 unsigned long offset = reloc_offset();
913 struct prom_t *_prom = PTRRELOC(&prom);
914 phandle rtas_node;
915 ihandle rtas_inst;
916 u32 base, entry = 0;
917 u32 size = 0;
918
919 prom_debug("prom_instantiate_rtas: start...\n");
920
921 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
922 prom_debug("rtas_node: %x\n", rtas_node);
923 if (!PHANDLE_VALID(rtas_node))
924 return;
925
926 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
927 if (size == 0)
928 return;
929
930 base = alloc_down(size, PAGE_SIZE, 0);
931 if (base == 0) {
932 prom_printf("RTAS allocation failed !\n");
933 return;
934 }
935
936 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
937 if (!IHANDLE_VALID(rtas_inst)) {
938 prom_printf("opening rtas package failed");
939 return;
940 }
941
942 prom_printf("instantiating rtas at 0x%x ...", base);
943
944 if (call_prom("call-method", 3, 2,
945 ADDR("instantiate-rtas"),
946 rtas_inst, base) != PROM_ERROR) {
947 entry = (long)_prom->args.rets[1];
948 }
949 if (entry == 0) {
950 prom_printf(" failed\n");
951 return;
952 }
953 prom_printf(" done\n");
954
955 reserve_mem(base, size);
956
957 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
958 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
959
960 prom_debug("rtas base = 0x%x\n", base);
961 prom_debug("rtas entry = 0x%x\n", entry);
962 prom_debug("rtas size = 0x%x\n", (long)size);
963
964 prom_debug("prom_instantiate_rtas: end...\n");
965}
966
967
968/*
969 * Allocate room for and initialize TCE tables
970 */
971static void __init prom_initialize_tce_table(void)
972{
973 phandle node;
974 ihandle phb_node;
975 unsigned long offset = reloc_offset();
976 char compatible[64], type[64], model[64];
977 char *path = RELOC(prom_scratch);
978 u64 base, align;
979 u32 minalign, minsize;
980 u64 tce_entry, *tce_entryp;
981 u64 local_alloc_top, local_alloc_bottom;
982 u64 i;
983
984 if (RELOC(ppc64_iommu_off))
985 return;
986
987 prom_debug("starting prom_initialize_tce_table\n");
988
989 /* Cache current top of allocs so we reserve a single block */
990 local_alloc_top = RELOC(alloc_top_high);
991 local_alloc_bottom = local_alloc_top;
992
993 /* Search all nodes looking for PHBs. */
994 for (node = 0; prom_next_node(&node); ) {
995 compatible[0] = 0;
996 type[0] = 0;
997 model[0] = 0;
998 prom_getprop(node, "compatible",
999 compatible, sizeof(compatible));
1000 prom_getprop(node, "device_type", type, sizeof(type));
1001 prom_getprop(node, "model", model, sizeof(model));
1002
1003 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1004 continue;
1005
1006 /* Keep the old logic in tack to avoid regression. */
1007 if (compatible[0] != 0) {
1008 if ((strstr(compatible, RELOC("python")) == NULL) &&
1009 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1010 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1011 continue;
1012 } else if (model[0] != 0) {
1013 if ((strstr(model, RELOC("ython")) == NULL) &&
1014 (strstr(model, RELOC("peedwagon")) == NULL) &&
1015 (strstr(model, RELOC("innipeg")) == NULL))
1016 continue;
1017 }
1018
1019 if (prom_getprop(node, "tce-table-minalign", &minalign,
1020 sizeof(minalign)) == PROM_ERROR)
1021 minalign = 0;
1022 if (prom_getprop(node, "tce-table-minsize", &minsize,
1023 sizeof(minsize)) == PROM_ERROR)
1024 minsize = 4UL << 20;
1025
1026 /*
1027 * Even though we read what OF wants, we just set the table
1028 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1029 * By doing this, we avoid the pitfalls of trying to DMA to
1030 * MMIO space and the DMA alias hole.
1031 *
1032 * On POWER4, firmware sets the TCE region by assuming
1033 * each TCE table is 8MB. Using this memory for anything
1034 * else will impact performance, so we always allocate 8MB.
1035 * Anton
1036 */
1037 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1038 minsize = 8UL << 20;
1039 else
1040 minsize = 4UL << 20;
1041
1042 /* Align to the greater of the align or size */
1043 align = max(minalign, minsize);
1044 base = alloc_down(minsize, align, 1);
1045 if (base == 0)
1046 prom_panic("ERROR, cannot find space for TCE table.\n");
1047 if (base < local_alloc_bottom)
1048 local_alloc_bottom = base;
1049
1050 /* Save away the TCE table attributes for later use. */
1051 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
1052 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
1053
1054 /* It seems OF doesn't null-terminate the path :-( */
1055 memset(path, 0, sizeof(path));
1056 /* Call OF to setup the TCE hardware */
1057 if (call_prom("package-to-path", 3, 1, node,
1058 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1059 prom_printf("package-to-path failed\n");
1060 }
1061
1062 prom_debug("TCE table: %s\n", path);
1063 prom_debug("\tnode = 0x%x\n", node);
1064 prom_debug("\tbase = 0x%x\n", base);
1065 prom_debug("\tsize = 0x%x\n", minsize);
1066
1067 /* Initialize the table to have a one-to-one mapping
1068 * over the allocated size.
1069 */
1070 tce_entryp = (unsigned long *)base;
1071 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1072 tce_entry = (i << PAGE_SHIFT);
1073 tce_entry |= 0x3;
1074 *tce_entryp = tce_entry;
1075 }
1076
1077 prom_printf("opening PHB %s", path);
1078 phb_node = call_prom("open", 1, 1, path);
1079 if (phb_node == 0)
1080 prom_printf("... failed\n");
1081 else
1082 prom_printf("... done\n");
1083
1084 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1085 phb_node, -1, minsize,
1086 (u32) base, (u32) (base >> 32));
1087 call_prom("close", 1, 0, phb_node);
1088 }
1089
1090 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1091
1092 if (RELOC(prom_memory_limit)) {
1093 /*
1094 * We align the start to a 16MB boundary so we can map the TCE area
1095 * using large pages if possible. The end should be the top of RAM
1096 * so no need to align it.
1097 */
1098 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 0x1000000);
1099 RELOC(prom_tce_alloc_end) = local_alloc_top;
1100 }
1101
1102 /* Flag the first invalid entry */
1103 prom_debug("ending prom_initialize_tce_table\n");
1104}
1105
1106/*
1107 * With CHRP SMP we need to use the OF to start the other
1108 * processors so we can't wait until smp_boot_cpus (the OF is
1109 * trashed by then) so we have to put the processors into
1110 * a holding pattern controlled by the kernel (not OF) before
1111 * we destroy the OF.
1112 *
1113 * This uses a chunk of low memory, puts some holding pattern
1114 * code there and sends the other processors off to there until
1115 * smp_boot_cpus tells them to do something. The holding pattern
1116 * checks that address until its cpu # is there, when it is that
1117 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1118 * of setting those values.
1119 *
1120 * We also use physical address 0x4 here to tell when a cpu
1121 * is in its holding pattern code.
1122 *
1123 * Fixup comment... DRENG / PPPBBB - Peter
1124 *
1125 * -- Cort
1126 */
1127static void __init prom_hold_cpus(void)
1128{
1129 unsigned long i;
1130 unsigned int reg;
1131 phandle node;
1132 unsigned long offset = reloc_offset();
1133 char type[64];
1134 int cpuid = 0;
1135 unsigned int interrupt_server[MAX_CPU_THREADS];
1136 unsigned int cpu_threads, hw_cpu_num;
1137 int propsize;
1138 extern void __secondary_hold(void);
1139 extern unsigned long __secondary_hold_spinloop;
1140 extern unsigned long __secondary_hold_acknowledge;
1141 unsigned long *spinloop
1142 = (void *)virt_to_abs(&__secondary_hold_spinloop);
1143 unsigned long *acknowledge
1144 = (void *)virt_to_abs(&__secondary_hold_acknowledge);
1145 unsigned long secondary_hold
1146 = virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
1147 struct prom_t *_prom = PTRRELOC(&prom);
1148
1149 prom_debug("prom_hold_cpus: start...\n");
1150 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1151 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1152 prom_debug(" 1) acknowledge = 0x%x\n",
1153 (unsigned long)acknowledge);
1154 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1155 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1156
1157 /* Set the common spinloop variable, so all of the secondary cpus
1158 * will block when they are awakened from their OF spinloop.
1159 * This must occur for both SMP and non SMP kernels, since OF will
1160 * be trashed when we move the kernel.
1161 */
1162 *spinloop = 0;
1163
1164#ifdef CONFIG_HMT
1165 for (i=0; i < NR_CPUS; i++) {
1166 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1167 }
1168#endif
1169 /* look for cpus */
1170 for (node = 0; prom_next_node(&node); ) {
1171 type[0] = 0;
1172 prom_getprop(node, "device_type", type, sizeof(type));
1173 if (strcmp(type, RELOC("cpu")) != 0)
1174 continue;
1175
1176 /* Skip non-configured cpus. */
1177 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1178 if (strcmp(type, RELOC("okay")) != 0)
1179 continue;
1180
1181 reg = -1;
1182 prom_getprop(node, "reg", &reg, sizeof(reg));
1183
1184 prom_debug("\ncpuid = 0x%x\n", cpuid);
1185 prom_debug("cpu hw idx = 0x%x\n", reg);
1186
1187 /* Init the acknowledge var which will be reset by
1188 * the secondary cpu when it awakens from its OF
1189 * spinloop.
1190 */
1191 *acknowledge = (unsigned long)-1;
1192
1193 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1194 &interrupt_server,
1195 sizeof(interrupt_server));
1196 if (propsize < 0) {
1197 /* no property. old hardware has no SMT */
1198 cpu_threads = 1;
1199 interrupt_server[0] = reg; /* fake it with phys id */
1200 } else {
1201 /* We have a threaded processor */
1202 cpu_threads = propsize / sizeof(u32);
1203 if (cpu_threads > MAX_CPU_THREADS) {
1204 prom_printf("SMT: too many threads!\n"
1205 "SMT: found %x, max is %x\n",
1206 cpu_threads, MAX_CPU_THREADS);
1207 cpu_threads = 1; /* ToDo: panic? */
1208 }
1209 }
1210
1211 hw_cpu_num = interrupt_server[0];
1212 if (hw_cpu_num != _prom->cpu) {
1213 /* Primary Thread of non-boot cpu */
1214 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1215 call_prom("start-cpu", 3, 0, node,
1216 secondary_hold, reg);
1217
1218 for ( i = 0 ; (i < 100000000) &&
1219 (*acknowledge == ((unsigned long)-1)); i++ )
1220 mb();
1221
1222 if (*acknowledge == reg) {
1223 prom_printf("done\n");
1224 /* We have to get every CPU out of OF,
1225 * even if we never start it. */
1226 if (cpuid >= NR_CPUS)
1227 goto next;
1228 } else {
1229 prom_printf("failed: %x\n", *acknowledge);
1230 }
1231 }
1232#ifdef CONFIG_SMP
1233 else
1234 prom_printf("%x : boot cpu %x\n", cpuid, reg);
1235#endif
1236next:
1237#ifdef CONFIG_SMP
1238 /* Init paca for secondary threads. They start later. */
1239 for (i=1; i < cpu_threads; i++) {
1240 cpuid++;
1241 if (cpuid >= NR_CPUS)
1242 continue;
1243 }
1244#endif /* CONFIG_SMP */
1245 cpuid++;
1246 }
1247#ifdef CONFIG_HMT
1248 /* Only enable HMT on processors that provide support. */
1249 if (__is_processor(PV_PULSAR) ||
1250 __is_processor(PV_ICESTAR) ||
1251 __is_processor(PV_SSTAR)) {
1252 prom_printf(" starting secondary threads\n");
1253
1254 for (i = 0; i < NR_CPUS; i += 2) {
1255 if (!cpu_online(i))
1256 continue;
1257
1258 if (i == 0) {
1259 unsigned long pir = mfspr(SPRN_PIR);
1260 if (__is_processor(PV_PULSAR)) {
1261 RELOC(hmt_thread_data)[i].pir =
1262 pir & 0x1f;
1263 } else {
1264 RELOC(hmt_thread_data)[i].pir =
1265 pir & 0x3ff;
1266 }
1267 }
1268 }
1269 } else {
1270 prom_printf("Processor is not HMT capable\n");
1271 }
1272#endif
1273
1274 if (cpuid > NR_CPUS)
1275 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1276 ") exceeded: ignoring extras\n");
1277
1278 prom_debug("prom_hold_cpus: end...\n");
1279}
1280
1281
1282static void __init prom_init_client_services(unsigned long pp)
1283{
1284 unsigned long offset = reloc_offset();
1285 struct prom_t *_prom = PTRRELOC(&prom);
1286
1287 /* Get a handle to the prom entry point before anything else */
1288 _prom->entry = pp;
1289
1290 /* Init default value for phys size */
1291 _prom->root_size_cells = 1;
1292 _prom->root_addr_cells = 2;
1293
1294 /* get a handle for the stdout device */
1295 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1296 if (!PHANDLE_VALID(_prom->chosen))
1297 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1298
1299 /* get device tree root */
1300 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1301 if (!PHANDLE_VALID(_prom->root))
1302 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1303}
1304
1305static void __init prom_init_stdout(void)
1306{
1307 unsigned long offset = reloc_offset();
1308 struct prom_t *_prom = PTRRELOC(&prom);
1309 char *path = RELOC(of_stdout_device);
1310 char type[16];
1311 u32 val;
1312
1313 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1314 prom_panic("cannot find stdout");
1315
1316 _prom->stdout = val;
1317
1318 /* Get the full OF pathname of the stdout device */
1319 memset(path, 0, 256);
1320 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1321 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1322 prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
1323 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1324 prom_setprop(_prom->chosen, "linux,stdout-path",
1325 RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
1326
1327 /* If it's a display, note it */
1328 memset(type, 0, sizeof(type));
1329 prom_getprop(val, "device_type", type, sizeof(type));
1330 if (strcmp(type, RELOC("display")) == 0) {
1331 _prom->disp_node = val;
1332 prom_setprop(val, "linux,boot-display", NULL, 0);
1333 }
1334}
1335
1336static void __init prom_close_stdin(void)
1337{
1338 unsigned long offset = reloc_offset();
1339 struct prom_t *_prom = PTRRELOC(&prom);
1340 ihandle val;
1341
1342 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1343 call_prom("close", 1, 0, val);
1344}
1345
1346static int __init prom_find_machine_type(void)
1347{
1348 unsigned long offset = reloc_offset();
1349 struct prom_t *_prom = PTRRELOC(&prom);
1350 char compat[256];
1351 int len, i = 0;
1352 phandle rtas;
1353
1354 len = prom_getprop(_prom->root, "compatible",
1355 compat, sizeof(compat)-1);
1356 if (len > 0) {
1357 compat[len] = 0;
1358 while (i < len) {
1359 char *p = &compat[i];
1360 int sl = strlen(p);
1361 if (sl == 0)
1362 break;
1363 if (strstr(p, RELOC("Power Macintosh")) ||
1364 strstr(p, RELOC("MacRISC4")))
1365 return PLATFORM_POWERMAC;
1366 if (strstr(p, RELOC("Momentum,Maple")))
1367 return PLATFORM_MAPLE;
1368 i += sl + 1;
1369 }
1370 }
1371 /* Default to pSeries. We need to know if we are running LPAR */
1372 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1373 if (PHANDLE_VALID(rtas)) {
1374 int x = prom_getproplen(rtas, "ibm,hypertas-functions");
1375 if (x != PROM_ERROR) {
1376 prom_printf("Hypertas detected, assuming LPAR !\n");
1377 return PLATFORM_PSERIES_LPAR;
1378 }
1379 }
1380 return PLATFORM_PSERIES;
1381}
1382
1383static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1384{
1385 unsigned long offset = reloc_offset();
1386
1387 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1388}
1389
1390/*
1391 * If we have a display that we don't know how to drive,
1392 * we will want to try to execute OF's open method for it
1393 * later. However, OF will probably fall over if we do that
1394 * we've taken over the MMU.
1395 * So we check whether we will need to open the display,
1396 * and if so, open it now.
1397 */
1398static void __init prom_check_displays(void)
1399{
1400 unsigned long offset = reloc_offset();
1401 struct prom_t *_prom = PTRRELOC(&prom);
1402 char type[16], *path;
1403 phandle node;
1404 ihandle ih;
1405 int i;
1406
1407 static unsigned char default_colors[] = {
1408 0x00, 0x00, 0x00,
1409 0x00, 0x00, 0xaa,
1410 0x00, 0xaa, 0x00,
1411 0x00, 0xaa, 0xaa,
1412 0xaa, 0x00, 0x00,
1413 0xaa, 0x00, 0xaa,
1414 0xaa, 0xaa, 0x00,
1415 0xaa, 0xaa, 0xaa,
1416 0x55, 0x55, 0x55,
1417 0x55, 0x55, 0xff,
1418 0x55, 0xff, 0x55,
1419 0x55, 0xff, 0xff,
1420 0xff, 0x55, 0x55,
1421 0xff, 0x55, 0xff,
1422 0xff, 0xff, 0x55,
1423 0xff, 0xff, 0xff
1424 };
1425 const unsigned char *clut;
1426
1427 prom_printf("Looking for displays\n");
1428 for (node = 0; prom_next_node(&node); ) {
1429 memset(type, 0, sizeof(type));
1430 prom_getprop(node, "device_type", type, sizeof(type));
1431 if (strcmp(type, RELOC("display")) != 0)
1432 continue;
1433
1434 /* It seems OF doesn't null-terminate the path :-( */
1435 path = RELOC(prom_scratch);
1436 memset(path, 0, PROM_SCRATCH_SIZE);
1437
1438 /*
1439 * leave some room at the end of the path for appending extra
1440 * arguments
1441 */
1442 if (call_prom("package-to-path", 3, 1, node, path,
1443 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1444 continue;
1445 prom_printf("found display : %s, opening ... ", path);
1446
1447 ih = call_prom("open", 1, 1, path);
1448 if (ih == 0) {
1449 prom_printf("failed\n");
1450 continue;
1451 }
1452
1453 /* Success */
1454 prom_printf("done\n");
1455 prom_setprop(node, "linux,opened", NULL, 0);
1456
1457 /*
1458 * stdout wasn't a display node, pick the first we can find
1459 * for btext
1460 */
1461 if (_prom->disp_node == 0)
1462 _prom->disp_node = node;
1463
1464 /* Setup a useable color table when the appropriate
1465 * method is available. Should update this to set-colors */
1466 clut = RELOC(default_colors);
1467 for (i = 0; i < 32; i++, clut += 3)
1468 if (prom_set_color(ih, i, clut[0], clut[1],
1469 clut[2]) != 0)
1470 break;
1471
1472#ifdef CONFIG_LOGO_LINUX_CLUT224
1473 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1474 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1475 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1476 clut[2]) != 0)
1477 break;
1478#endif /* CONFIG_LOGO_LINUX_CLUT224 */
1479 }
1480}
1481
1482
1483/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1484static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1485 unsigned long needed, unsigned long align)
1486{
1487 unsigned long offset = reloc_offset();
1488 void *ret;
1489
1490 *mem_start = _ALIGN(*mem_start, align);
1491 while ((*mem_start + needed) > *mem_end) {
1492 unsigned long room, chunk;
1493
1494 prom_debug("Chunk exhausted, claiming more at %x...\n",
1495 RELOC(alloc_bottom));
1496 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1497 if (room > DEVTREE_CHUNK_SIZE)
1498 room = DEVTREE_CHUNK_SIZE;
1499 if (room < PAGE_SIZE)
1500 prom_panic("No memory for flatten_device_tree (no room)");
1501 chunk = alloc_up(room, 0);
1502 if (chunk == 0)
1503 prom_panic("No memory for flatten_device_tree (claim failed)");
1504 *mem_end = RELOC(alloc_top);
1505 }
1506
1507 ret = (void *)*mem_start;
1508 *mem_start += needed;
1509
1510 return ret;
1511}
1512
1513#define dt_push_token(token, mem_start, mem_end) \
1514 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1515
1516static unsigned long __init dt_find_string(char *str)
1517{
1518 unsigned long offset = reloc_offset();
1519 char *s, *os;
1520
1521 s = os = (char *)RELOC(dt_string_start);
1522 s += 4;
1523 while (s < (char *)RELOC(dt_string_end)) {
1524 if (strcmp(s, str) == 0)
1525 return s - os;
1526 s += strlen(s) + 1;
1527 }
1528 return 0;
1529}
1530
1531/*
1532 * The Open Firmware 1275 specification states properties must be 31 bytes or
1533 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1534 */
1535#define MAX_PROPERTY_NAME 64
1536
1537static void __init scan_dt_build_strings(phandle node,
1538 unsigned long *mem_start,
1539 unsigned long *mem_end)
1540{
1541 unsigned long offset = reloc_offset();
1542 char *prev_name, *namep, *sstart;
1543 unsigned long soff;
1544 phandle child;
1545
1546 sstart = (char *)RELOC(dt_string_start);
1547
1548 /* get and store all property names */
1549 prev_name = RELOC("");
1550 for (;;) {
1551 /* 64 is max len of name including nul. */
1552 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1553 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1554 /* No more nodes: unwind alloc */
1555 *mem_start = (unsigned long)namep;
1556 break;
1557 }
1558
1559 /* skip "name" */
1560 if (strcmp(namep, RELOC("name")) == 0) {
1561 *mem_start = (unsigned long)namep;
1562 prev_name = RELOC("name");
1563 continue;
1564 }
1565 /* get/create string entry */
1566 soff = dt_find_string(namep);
1567 if (soff != 0) {
1568 *mem_start = (unsigned long)namep;
1569 namep = sstart + soff;
1570 } else {
1571 /* Trim off some if we can */
1572 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1573 RELOC(dt_string_end) = *mem_start;
1574 }
1575 prev_name = namep;
1576 }
1577
1578 /* do all our children */
1579 child = call_prom("child", 1, 1, node);
1580 while (child != 0) {
1581 scan_dt_build_strings(child, mem_start, mem_end);
1582 child = call_prom("peer", 1, 1, child);
1583 }
1584}
1585
1586static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1587 unsigned long *mem_end)
1588{
1589 phandle child;
1590 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1591 unsigned long soff;
1592 unsigned char *valp;
1593 unsigned long offset = reloc_offset();
1594 static char pname[MAX_PROPERTY_NAME];
1595 int l;
1596
1597 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1598
1599 /* get the node's full name */
1600 namep = (char *)*mem_start;
1601 l = call_prom("package-to-path", 3, 1, node,
1602 namep, *mem_end - *mem_start);
1603 if (l >= 0) {
1604 /* Didn't fit? Get more room. */
1605 if ((l+1) > (*mem_end - *mem_start)) {
1606 namep = make_room(mem_start, mem_end, l+1, 1);
1607 call_prom("package-to-path", 3, 1, node, namep, l);
1608 }
1609 namep[l] = '\0';
1610
1611 /* Fixup an Apple bug where they have bogus \0 chars in the
1612 * middle of the path in some properties
1613 */
1614 for (p = namep, ep = namep + l; p < ep; p++)
1615 if (*p == '\0') {
1616 memmove(p, p+1, ep - p);
1617 ep--; l--; p--;
1618 }
1619
1620 /* now try to extract the unit name in that mess */
1621 for (p = namep, lp = NULL; *p; p++)
1622 if (*p == '/')
1623 lp = p + 1;
1624 if (lp != NULL)
1625 memmove(namep, lp, strlen(lp) + 1);
1626 *mem_start = _ALIGN(((unsigned long) namep) +
1627 strlen(namep) + 1, 4);
1628 }
1629
1630 /* get it again for debugging */
1631 path = RELOC(prom_scratch);
1632 memset(path, 0, PROM_SCRATCH_SIZE);
1633 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1634
1635 /* get and store all properties */
1636 prev_name = RELOC("");
1637 sstart = (char *)RELOC(dt_string_start);
1638 for (;;) {
1639 if (call_prom("nextprop", 3, 1, node, prev_name,
1640 RELOC(pname)) != 1)
1641 break;
1642
1643 /* skip "name" */
1644 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1645 prev_name = RELOC("name");
1646 continue;
1647 }
1648
1649 /* find string offset */
1650 soff = dt_find_string(RELOC(pname));
1651 if (soff == 0) {
1652 prom_printf("WARNING: Can't find string index for"
1653 " <%s>, node %s\n", RELOC(pname), path);
1654 break;
1655 }
1656 prev_name = sstart + soff;
1657
1658 /* get length */
1659 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1660
1661 /* sanity checks */
1662 if (l == PROM_ERROR)
1663 continue;
1664 if (l > MAX_PROPERTY_LENGTH) {
1665 prom_printf("WARNING: ignoring large property ");
1666 /* It seems OF doesn't null-terminate the path :-( */
1667 prom_printf("[%s] ", path);
1668 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1669 continue;
1670 }
1671
1672 /* push property head */
1673 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1674 dt_push_token(l, mem_start, mem_end);
1675 dt_push_token(soff, mem_start, mem_end);
1676
1677 /* push property content */
1678 valp = make_room(mem_start, mem_end, l, 4);
1679 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1680 *mem_start = _ALIGN(*mem_start, 4);
1681 }
1682
1683 /* Add a "linux,phandle" property. */
1684 soff = dt_find_string(RELOC("linux,phandle"));
1685 if (soff == 0)
1686 prom_printf("WARNING: Can't find string index for"
1687 " <linux-phandle> node %s\n", path);
1688 else {
1689 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1690 dt_push_token(4, mem_start, mem_end);
1691 dt_push_token(soff, mem_start, mem_end);
1692 valp = make_room(mem_start, mem_end, 4, 4);
1693 *(u32 *)valp = node;
1694 }
1695
1696 /* do all our children */
1697 child = call_prom("child", 1, 1, node);
1698 while (child != 0) {
1699 scan_dt_build_struct(child, mem_start, mem_end);
1700 child = call_prom("peer", 1, 1, child);
1701 }
1702
1703 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1704}
1705
1706static void __init flatten_device_tree(void)
1707{
1708 phandle root;
1709 unsigned long offset = reloc_offset();
1710 unsigned long mem_start, mem_end, room;
1711 struct boot_param_header *hdr;
1712 struct prom_t *_prom = PTRRELOC(&prom);
1713 char *namep;
1714 u64 *rsvmap;
1715
1716 /*
1717 * Check how much room we have between alloc top & bottom (+/- a
1718 * few pages), crop to 4Mb, as this is our "chuck" size
1719 */
1720 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1721 if (room > DEVTREE_CHUNK_SIZE)
1722 room = DEVTREE_CHUNK_SIZE;
1723 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1724
1725 /* Now try to claim that */
1726 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1727 if (mem_start == 0)
1728 prom_panic("Can't allocate initial device-tree chunk\n");
1729 mem_end = RELOC(alloc_top);
1730
1731 /* Get root of tree */
1732 root = call_prom("peer", 1, 1, (phandle)0);
1733 if (root == (phandle)0)
1734 prom_panic ("couldn't get device tree root\n");
1735
1736 /* Build header and make room for mem rsv map */
1737 mem_start = _ALIGN(mem_start, 4);
1738 hdr = make_room(&mem_start, &mem_end,
1739 sizeof(struct boot_param_header), 4);
1740 RELOC(dt_header_start) = (unsigned long)hdr;
1741 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1742
1743 /* Start of strings */
1744 mem_start = PAGE_ALIGN(mem_start);
1745 RELOC(dt_string_start) = mem_start;
1746 mem_start += 4; /* hole */
1747
1748 /* Add "linux,phandle" in there, we'll need it */
1749 namep = make_room(&mem_start, &mem_end, 16, 1);
1750 strcpy(namep, RELOC("linux,phandle"));
1751 mem_start = (unsigned long)namep + strlen(namep) + 1;
1752
1753 /* Build string array */
1754 prom_printf("Building dt strings...\n");
1755 scan_dt_build_strings(root, &mem_start, &mem_end);
1756 RELOC(dt_string_end) = mem_start;
1757
1758 /* Build structure */
1759 mem_start = PAGE_ALIGN(mem_start);
1760 RELOC(dt_struct_start) = mem_start;
1761 prom_printf("Building dt structure...\n");
1762 scan_dt_build_struct(root, &mem_start, &mem_end);
1763 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1764 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1765
1766 /* Finish header */
1767 hdr->boot_cpuid_phys = _prom->cpu;
1768 hdr->magic = OF_DT_HEADER;
1769 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1770 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1771 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1772 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1773 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1774 hdr->version = OF_DT_VERSION;
1775 /* Version 16 is not backward compatible */
1776 hdr->last_comp_version = 0x10;
1777
1778 /* Reserve the whole thing and copy the reserve map in, we
1779 * also bump mem_reserve_cnt to cause further reservations to
1780 * fail since it's too late.
1781 */
1782 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1783 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1784
1785#ifdef DEBUG_PROM
1786 {
1787 int i;
1788 prom_printf("reserved memory map:\n");
1789 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1790 prom_printf(" %x - %x\n", RELOC(mem_reserve_map)[i].base,
1791 RELOC(mem_reserve_map)[i].size);
1792 }
1793#endif
1794 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1795
1796 prom_printf("Device tree strings 0x%x -> 0x%x\n",
1797 RELOC(dt_string_start), RELOC(dt_string_end));
1798 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1799 RELOC(dt_struct_start), RELOC(dt_struct_end));
1800
1801}
1802
1803
1804static void __init fixup_device_tree(void)
1805{
1806 unsigned long offset = reloc_offset();
1807 phandle u3, i2c, mpic;
1808 u32 u3_rev;
1809 u32 interrupts[2];
1810 u32 parent;
1811
1812 /* Some G5s have a missing interrupt definition, fix it up here */
1813 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1814 if (!PHANDLE_VALID(u3))
1815 return;
1816 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1817 if (!PHANDLE_VALID(i2c))
1818 return;
1819 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1820 if (!PHANDLE_VALID(mpic))
1821 return;
1822
1823 /* check if proper rev of u3 */
1824 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
1825 == PROM_ERROR)
1826 return;
1827 if (u3_rev < 0x35 || u3_rev > 0x39)
1828 return;
1829 /* does it need fixup ? */
1830 if (prom_getproplen(i2c, "interrupts") > 0)
1831 return;
1832
1833 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
1834
1835 /* interrupt on this revision of u3 is number 0 and level */
1836 interrupts[0] = 0;
1837 interrupts[1] = 1;
1838 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1839 parent = (u32)mpic;
1840 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1841}
1842
1843
1844static void __init prom_find_boot_cpu(void)
1845{
1846 unsigned long offset = reloc_offset();
1847 struct prom_t *_prom = PTRRELOC(&prom);
1848 u32 getprop_rval;
1849 ihandle prom_cpu;
1850 phandle cpu_pkg;
1851
1852 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
1853 prom_panic("cannot find boot cpu");
1854
1855 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
1856
1857 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
1858 _prom->cpu = getprop_rval;
1859
1860 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
1861}
1862
1863static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1864{
1865#ifdef CONFIG_BLK_DEV_INITRD
1866 unsigned long offset = reloc_offset();
1867 struct prom_t *_prom = PTRRELOC(&prom);
1868
1869 if ( r3 && r4 && r4 != 0xdeadbeef) {
1870 u64 val;
1871
1872 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1873 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1874
1875 val = (u64)RELOC(prom_initrd_start);
1876 prom_setprop(_prom->chosen, "linux,initrd-start", &val, sizeof(val));
1877 val = (u64)RELOC(prom_initrd_end);
1878 prom_setprop(_prom->chosen, "linux,initrd-end", &val, sizeof(val));
1879
1880 reserve_mem(RELOC(prom_initrd_start),
1881 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
1882
1883 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
1884 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
1885 }
1886#endif /* CONFIG_BLK_DEV_INITRD */
1887}
1888
1889/*
1890 * We enter here early on, when the Open Firmware prom is still
1891 * handling exceptions and the MMU hash table for us.
1892 */
1893
1894unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
1895 unsigned long r6, unsigned long r7)
1896{
1897 unsigned long offset = reloc_offset();
1898 struct prom_t *_prom = PTRRELOC(&prom);
1899 unsigned long phys = KERNELBASE - offset;
1900 u32 getprop_rval;
1901
1902 /*
1903 * First zero the BSS
1904 */
1905 memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
1906
1907 /*
1908 * Init interface to Open Firmware, get some node references,
1909 * like /chosen
1910 */
1911 prom_init_client_services(pp);
1912
1913 /*
1914 * Init prom stdout device
1915 */
1916 prom_init_stdout();
1917 prom_debug("klimit=0x%x\n", RELOC(klimit));
1918 prom_debug("offset=0x%x\n", offset);
1919
1920 /*
1921 * Check for an initrd
1922 */
1923 prom_check_initrd(r3, r4);
1924
1925 /*
1926 * Get default machine type. At this point, we do not differenciate
1927 * between pSeries SMP and pSeries LPAR
1928 */
1929 RELOC(of_platform) = prom_find_machine_type();
1930 getprop_rval = RELOC(of_platform);
1931 prom_setprop(_prom->chosen, "linux,platform",
1932 &getprop_rval, sizeof(getprop_rval));
1933
1934 /*
1935 * On pSeries, inform the firmware about our capabilities
1936 */
1937 if (RELOC(of_platform) == PLATFORM_PSERIES ||
1938 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
1939 prom_send_capabilities();
1940
1941 /*
1942 * On pSeries and Cell, copy the CPU hold code
1943 */
1944 if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_CELL))
1945 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1946
1947 /*
1948 * Get memory cells format
1949 */
1950 getprop_rval = 1;
1951 prom_getprop(_prom->root, "#size-cells",
1952 &getprop_rval, sizeof(getprop_rval));
1953 _prom->root_size_cells = getprop_rval;
1954 getprop_rval = 2;
1955 prom_getprop(_prom->root, "#address-cells",
1956 &getprop_rval, sizeof(getprop_rval));
1957 _prom->root_addr_cells = getprop_rval;
1958
1959 /*
1960 * Do early parsing of command line
1961 */
1962 early_cmdline_parse();
1963
1964 /*
1965 * Initialize memory management within prom_init
1966 */
1967 prom_init_mem();
1968
1969 /*
1970 * Determine which cpu is actually running right _now_
1971 */
1972 prom_find_boot_cpu();
1973
1974 /*
1975 * Initialize display devices
1976 */
1977 prom_check_displays();
1978
1979 /*
1980 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
1981 * that uses the allocator, we need to make sure we get the top of memory
1982 * available for us here...
1983 */
1984 if (RELOC(of_platform) == PLATFORM_PSERIES)
1985 prom_initialize_tce_table();
1986
1987 /*
1988 * On non-powermacs, try to instantiate RTAS and puts all CPUs
1989 * in spin-loops. PowerMacs don't have a working RTAS and use
1990 * a different way to spin CPUs
1991 */
1992 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
1993 prom_instantiate_rtas();
1994 prom_hold_cpus();
1995 }
1996
1997 /*
1998 * Fill in some infos for use by the kernel later on
1999 */
2000 if (RELOC(ppc64_iommu_off))
2001 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
2002
2003 if (RELOC(iommu_force_on))
2004 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
2005
2006 if (RELOC(prom_memory_limit))
2007 prom_setprop(_prom->chosen, "linux,memory-limit",
2008 PTRRELOC(&prom_memory_limit), sizeof(RELOC(prom_memory_limit)));
2009
2010 if (RELOC(prom_tce_alloc_start)) {
2011 prom_setprop(_prom->chosen, "linux,tce-alloc-start",
2012 PTRRELOC(&prom_tce_alloc_start), sizeof(RELOC(prom_tce_alloc_start)));
2013 prom_setprop(_prom->chosen, "linux,tce-alloc-end",
2014 PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
2015 }
2016
2017 /*
2018 * Fixup any known bugs in the device-tree
2019 */
2020 fixup_device_tree();
2021
2022 /*
2023 * Now finally create the flattened device-tree
2024 */
2025 prom_printf("copying OF device tree ...\n");
2026 flatten_device_tree();
2027
2028 /* in case stdin is USB and still active on IBM machines... */
2029 prom_close_stdin();
2030
2031 /*
2032 * Call OF "quiesce" method to shut down pending DMA's from
2033 * devices etc...
2034 */
2035 prom_printf("Calling quiesce ...\n");
2036 call_prom("quiesce", 0, 0);
2037
2038 /*
2039 * And finally, call the kernel passing it the flattened device
2040 * tree and NULL as r5, thus triggering the new entry point which
2041 * is common to us and kexec
2042 */
2043 prom_printf("returning from prom_init\n");
2044 prom_debug("->dt_header_start=0x%x\n", RELOC(dt_header_start));
2045 prom_debug("->phys=0x%x\n", phys);
2046
2047 __start(RELOC(dt_header_start), phys, 0);
2048
2049 return 0;
2050}
2051