OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [kernel/] [prom_init.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Procedures for interfacing to Open Firmware.
3
 *
4
 * Paul Mackerras       August 1996.
5
 * Copyright (C) 1996-2005 Paul Mackerras.
6
 *
7
 *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8
 *    {engebret|bergner}@us.ibm.com
9
 *
10
 *      This program is free software; you can redistribute it and/or
11
 *      modify it under the terms of the GNU General Public License
12
 *      as published by the Free Software Foundation; either version
13
 *      2 of the License, or (at your option) any later version.
14
 */
15
 
16
#undef DEBUG_PROM
17
 
18
#include <stdarg.h>
19
#include <linux/kernel.h>
20
#include <linux/string.h>
21
#include <linux/init.h>
22
#include <linux/threads.h>
23
#include <linux/spinlock.h>
24
#include <linux/types.h>
25
#include <linux/pci.h>
26
#include <linux/proc_fs.h>
27
#include <linux/stringify.h>
28
#include <linux/delay.h>
29
#include <linux/initrd.h>
30
#include <linux/bitops.h>
31
#include <asm/prom.h>
32
#include <asm/rtas.h>
33
#include <asm/page.h>
34
#include <asm/processor.h>
35
#include <asm/irq.h>
36
#include <asm/io.h>
37
#include <asm/smp.h>
38
#include <asm/system.h>
39
#include <asm/mmu.h>
40
#include <asm/pgtable.h>
41
#include <asm/pci.h>
42
#include <asm/iommu.h>
43
#include <asm/btext.h>
44
#include <asm/sections.h>
45
#include <asm/machdep.h>
46
 
47
#ifdef CONFIG_LOGO_LINUX_CLUT224
48
#include <linux/linux_logo.h>
49
extern const struct linux_logo logo_linux_clut224;
50
#endif
51
 
52
/*
53
 * Properties whose value is longer than this get excluded from our
54
 * copy of the device tree. This value does need to be big enough to
55
 * ensure that we don't lose things like the interrupt-map property
56
 * on a PCI-PCI bridge.
57
 */
58
#define MAX_PROPERTY_LENGTH     (1UL * 1024 * 1024)
59
 
60
/*
61
 * Eventually bump that one up
62
 */
63
#define DEVTREE_CHUNK_SIZE      0x100000
64
 
65
/*
66
 * This is the size of the local memory reserve map that gets copied
67
 * into the boot params passed to the kernel. That size is totally
68
 * flexible as the kernel just reads the list until it encounters an
69
 * entry with size 0, so it can be changed without breaking binary
70
 * compatibility
71
 */
72
#define MEM_RESERVE_MAP_SIZE    8
73
 
74
/*
75
 * prom_init() is called very early on, before the kernel text
76
 * and data have been mapped to KERNELBASE.  At this point the code
77
 * is running at whatever address it has been loaded at.
78
 * On ppc32 we compile with -mrelocatable, which means that references
79
 * to extern and static variables get relocated automatically.
80
 * On ppc64 we have to relocate the references explicitly with
81
 * RELOC.  (Note that strings count as static variables.)
82
 *
83
 * Because OF may have mapped I/O devices into the area starting at
84
 * KERNELBASE, particularly on CHRP machines, we can't safely call
85
 * OF once the kernel has been mapped to KERNELBASE.  Therefore all
86
 * OF calls must be done within prom_init().
87
 *
88
 * ADDR is used in calls to call_prom.  The 4th and following
89
 * arguments to call_prom should be 32-bit values.
90
 * On ppc64, 64 bit values are truncated to 32 bits (and
91
 * fortunately don't get interpreted as two arguments).
92
 */
93
#ifdef CONFIG_PPC64
94
#define RELOC(x)        (*PTRRELOC(&(x)))
95
#define ADDR(x)         (u32) add_reloc_offset((unsigned long)(x))
96
#define OF_WORKAROUNDS  0
97
#else
98
#define RELOC(x)        (x)
99
#define ADDR(x)         (u32) (x)
100
#define OF_WORKAROUNDS  of_workarounds
101
int of_workarounds;
102
#endif
103
 
104
#define OF_WA_CLAIM     1       /* do phys/virt claim separately, then map */
105
#define OF_WA_LONGTRAIL 2       /* work around longtrail bugs */
106
 
107
#define PROM_BUG() do {                                         \
108
        prom_printf("kernel BUG at %s line 0x%x!\n",            \
109
                    RELOC(__FILE__), __LINE__);                 \
110
        __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR);       \
111
} while (0)
112
 
113
#ifdef DEBUG_PROM
114
#define prom_debug(x...)        prom_printf(x)
115
#else
116
#define prom_debug(x...)
117
#endif
118
 
119
 
120
typedef u32 prom_arg_t;
121
 
122
struct prom_args {
123
        u32 service;
124
        u32 nargs;
125
        u32 nret;
126
        prom_arg_t args[10];
127
};
128
 
129
struct prom_t {
130
        ihandle root;
131
        phandle chosen;
132
        int cpu;
133
        ihandle stdout;
134
        ihandle mmumap;
135
        ihandle memory;
136
};
137
 
138
struct mem_map_entry {
139
        u64     base;
140
        u64     size;
141
};
142
 
143
typedef u32 cell_t;
144
 
145
extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
146
 
147
#ifdef CONFIG_PPC64
148
extern int enter_prom(struct prom_args *args, unsigned long entry);
149
#else
150
static inline int enter_prom(struct prom_args *args, unsigned long entry)
151
{
152
        return ((int (*)(struct prom_args *))entry)(args);
153
}
154
#endif
155
 
156
extern void copy_and_flush(unsigned long dest, unsigned long src,
157
                           unsigned long size, unsigned long offset);
158
 
159
/* prom structure */
160
static struct prom_t __initdata prom;
161
 
162
static unsigned long prom_entry __initdata;
163
 
164
#define PROM_SCRATCH_SIZE 256
165
 
166
static char __initdata of_stdout_device[256];
167
static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
168
 
169
static unsigned long __initdata dt_header_start;
170
static unsigned long __initdata dt_struct_start, dt_struct_end;
171
static unsigned long __initdata dt_string_start, dt_string_end;
172
 
173
static unsigned long __initdata prom_initrd_start, prom_initrd_end;
174
 
175
#ifdef CONFIG_PPC64
176
static int __initdata prom_iommu_force_on;
177
static int __initdata prom_iommu_off;
178
static unsigned long __initdata prom_tce_alloc_start;
179
static unsigned long __initdata prom_tce_alloc_end;
180
#endif
181
 
182
/* Platforms codes are now obsolete in the kernel. Now only used within this
183
 * file and ultimately gone too. Feel free to change them if you need, they
184
 * are not shared with anything outside of this file anymore
185
 */
186
#define PLATFORM_PSERIES        0x0100
187
#define PLATFORM_PSERIES_LPAR   0x0101
188
#define PLATFORM_LPAR           0x0001
189
#define PLATFORM_POWERMAC       0x0400
190
#define PLATFORM_GENERIC        0x0500
191
 
192
static int __initdata of_platform;
193
 
194
static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
195
 
196
static unsigned long __initdata alloc_top;
197
static unsigned long __initdata alloc_top_high;
198
static unsigned long __initdata alloc_bottom;
199
static unsigned long __initdata rmo_top;
200
static unsigned long __initdata ram_top;
201
 
202
static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
203
static int __initdata mem_reserve_cnt;
204
 
205
static cell_t __initdata regbuf[1024];
206
 
207
 
208
#define MAX_CPU_THREADS 2
209
 
210
/*
211
 * Error results ... some OF calls will return "-1" on error, some
212
 * will return 0, some will return either. To simplify, here are
213
 * macros to use with any ihandle or phandle return value to check if
214
 * it is valid
215
 */
216
 
217
#define PROM_ERROR              (-1u)
218
#define PHANDLE_VALID(p)        ((p) != 0 && (p) != PROM_ERROR)
219
#define IHANDLE_VALID(i)        ((i) != 0 && (i) != PROM_ERROR)
220
 
221
 
222
/* This is the one and *ONLY* place where we actually call open
223
 * firmware.
224
 */
225
 
226
static int __init call_prom(const char *service, int nargs, int nret, ...)
227
{
228
        int i;
229
        struct prom_args args;
230
        va_list list;
231
 
232
        args.service = ADDR(service);
233
        args.nargs = nargs;
234
        args.nret = nret;
235
 
236
        va_start(list, nret);
237
        for (i = 0; i < nargs; i++)
238
                args.args[i] = va_arg(list, prom_arg_t);
239
        va_end(list);
240
 
241
        for (i = 0; i < nret; i++)
242
                args.args[nargs+i] = 0;
243
 
244
        if (enter_prom(&args, RELOC(prom_entry)) < 0)
245
                return PROM_ERROR;
246
 
247
        return (nret > 0) ? args.args[nargs] : 0;
248
}
249
 
250
static int __init call_prom_ret(const char *service, int nargs, int nret,
251
                                prom_arg_t *rets, ...)
252
{
253
        int i;
254
        struct prom_args args;
255
        va_list list;
256
 
257
        args.service = ADDR(service);
258
        args.nargs = nargs;
259
        args.nret = nret;
260
 
261
        va_start(list, rets);
262
        for (i = 0; i < nargs; i++)
263
                args.args[i] = va_arg(list, prom_arg_t);
264
        va_end(list);
265
 
266
        for (i = 0; i < nret; i++)
267
                args.args[nargs+i] = 0;
268
 
269
        if (enter_prom(&args, RELOC(prom_entry)) < 0)
270
                return PROM_ERROR;
271
 
272
        if (rets != NULL)
273
                for (i = 1; i < nret; ++i)
274
                        rets[i-1] = args.args[nargs+i];
275
 
276
        return (nret > 0) ? args.args[nargs] : 0;
277
}
278
 
279
 
280
static void __init prom_print(const char *msg)
281
{
282
        const char *p, *q;
283
        struct prom_t *_prom = &RELOC(prom);
284
 
285
        if (_prom->stdout == 0)
286
                return;
287
 
288
        for (p = msg; *p != 0; p = q) {
289
                for (q = p; *q != 0 && *q != '\n'; ++q)
290
                        ;
291
                if (q > p)
292
                        call_prom("write", 3, 1, _prom->stdout, p, q - p);
293
                if (*q == 0)
294
                        break;
295
                ++q;
296
                call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
297
        }
298
}
299
 
300
 
301
static void __init prom_print_hex(unsigned long val)
302
{
303
        int i, nibbles = sizeof(val)*2;
304
        char buf[sizeof(val)*2+1];
305
        struct prom_t *_prom = &RELOC(prom);
306
 
307
        for (i = nibbles-1;  i >= 0;  i--) {
308
                buf[i] = (val & 0xf) + '0';
309
                if (buf[i] > '9')
310
                        buf[i] += ('a'-'0'-10);
311
                val >>= 4;
312
        }
313
        buf[nibbles] = '\0';
314
        call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
315
}
316
 
317
 
318
static void __init prom_printf(const char *format, ...)
319
{
320
        const char *p, *q, *s;
321
        va_list args;
322
        unsigned long v;
323
        struct prom_t *_prom = &RELOC(prom);
324
 
325
        va_start(args, format);
326
#ifdef CONFIG_PPC64
327
        format = PTRRELOC(format);
328
#endif
329
        for (p = format; *p != 0; p = q) {
330
                for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
331
                        ;
332
                if (q > p)
333
                        call_prom("write", 3, 1, _prom->stdout, p, q - p);
334
                if (*q == 0)
335
                        break;
336
                if (*q == '\n') {
337
                        ++q;
338
                        call_prom("write", 3, 1, _prom->stdout,
339
                                  ADDR("\r\n"), 2);
340
                        continue;
341
                }
342
                ++q;
343
                if (*q == 0)
344
                        break;
345
                switch (*q) {
346
                case 's':
347
                        ++q;
348
                        s = va_arg(args, const char *);
349
                        prom_print(s);
350
                        break;
351
                case 'x':
352
                        ++q;
353
                        v = va_arg(args, unsigned long);
354
                        prom_print_hex(v);
355
                        break;
356
                }
357
        }
358
}
359
 
360
 
361
static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
362
                                unsigned long align)
363
{
364
        struct prom_t *_prom = &RELOC(prom);
365
 
366
        if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
367
                /*
368
                 * Old OF requires we claim physical and virtual separately
369
                 * and then map explicitly (assuming virtual mode)
370
                 */
371
                int ret;
372
                prom_arg_t result;
373
 
374
                ret = call_prom_ret("call-method", 5, 2, &result,
375
                                    ADDR("claim"), _prom->memory,
376
                                    align, size, virt);
377
                if (ret != 0 || result == -1)
378
                        return -1;
379
                ret = call_prom_ret("call-method", 5, 2, &result,
380
                                    ADDR("claim"), _prom->mmumap,
381
                                    align, size, virt);
382
                if (ret != 0) {
383
                        call_prom("call-method", 4, 1, ADDR("release"),
384
                                  _prom->memory, size, virt);
385
                        return -1;
386
                }
387
                /* the 0x12 is M (coherence) + PP == read/write */
388
                call_prom("call-method", 6, 1,
389
                          ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
390
                return virt;
391
        }
392
        return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
393
                         (prom_arg_t)align);
394
}
395
 
396
static void __init __attribute__((noreturn)) prom_panic(const char *reason)
397
{
398
#ifdef CONFIG_PPC64
399
        reason = PTRRELOC(reason);
400
#endif
401
        prom_print(reason);
402
        /* Do not call exit because it clears the screen on pmac
403
         * it also causes some sort of double-fault on early pmacs */
404
        if (RELOC(of_platform) == PLATFORM_POWERMAC)
405
                asm("trap\n");
406
 
407
        /* ToDo: should put up an SRC here on p/iSeries */
408
        call_prom("exit", 0, 0);
409
 
410
        for (;;)                        /* should never get here */
411
                ;
412
}
413
 
414
 
415
static int __init prom_next_node(phandle *nodep)
416
{
417
        phandle node;
418
 
419
        if ((node = *nodep) != 0
420
            && (*nodep = call_prom("child", 1, 1, node)) != 0)
421
                return 1;
422
        if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
423
                return 1;
424
        for (;;) {
425
                if ((node = call_prom("parent", 1, 1, node)) == 0)
426
                        return 0;
427
                if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
428
                        return 1;
429
        }
430
}
431
 
432
static int inline prom_getprop(phandle node, const char *pname,
433
                               void *value, size_t valuelen)
434
{
435
        return call_prom("getprop", 4, 1, node, ADDR(pname),
436
                         (u32)(unsigned long) value, (u32) valuelen);
437
}
438
 
439
static int inline prom_getproplen(phandle node, const char *pname)
440
{
441
        return call_prom("getproplen", 2, 1, node, ADDR(pname));
442
}
443
 
444
static void add_string(char **str, const char *q)
445
{
446
        char *p = *str;
447
 
448
        while (*q)
449
                *p++ = *q++;
450
        *p++ = ' ';
451
        *str = p;
452
}
453
 
454
static char *tohex(unsigned int x)
455
{
456
        static char digits[] = "0123456789abcdef";
457
        static char result[9];
458
        int i;
459
 
460
        result[8] = 0;
461
        i = 8;
462
        do {
463
                --i;
464
                result[i] = digits[x & 0xf];
465
                x >>= 4;
466
        } while (x != 0 && i > 0);
467
        return &result[i];
468
}
469
 
470
static int __init prom_setprop(phandle node, const char *nodename,
471
                               const char *pname, void *value, size_t valuelen)
472
{
473
        char cmd[256], *p;
474
 
475
        if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
476
                return call_prom("setprop", 4, 1, node, ADDR(pname),
477
                                 (u32)(unsigned long) value, (u32) valuelen);
478
 
479
        /* gah... setprop doesn't work on longtrail, have to use interpret */
480
        p = cmd;
481
        add_string(&p, "dev");
482
        add_string(&p, nodename);
483
        add_string(&p, tohex((u32)(unsigned long) value));
484
        add_string(&p, tohex(valuelen));
485
        add_string(&p, tohex(ADDR(pname)));
486
        add_string(&p, tohex(strlen(RELOC(pname))));
487
        add_string(&p, "property");
488
        *p = 0;
489
        return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
490
}
491
 
492
/* We can't use the standard versions because of RELOC headaches. */
493
#define isxdigit(c)     (('0' <= (c) && (c) <= '9') \
494
                         || ('a' <= (c) && (c) <= 'f') \
495
                         || ('A' <= (c) && (c) <= 'F'))
496
 
497
#define isdigit(c)      ('0' <= (c) && (c) <= '9')
498
#define islower(c)      ('a' <= (c) && (c) <= 'z')
499
#define toupper(c)      (islower(c) ? ((c) - 'a' + 'A') : (c))
500
 
501
unsigned long prom_strtoul(const char *cp, const char **endp)
502
{
503
        unsigned long result = 0, base = 10, value;
504
 
505
        if (*cp == '0') {
506
                base = 8;
507
                cp++;
508
                if (toupper(*cp) == 'X') {
509
                        cp++;
510
                        base = 16;
511
                }
512
        }
513
 
514
        while (isxdigit(*cp) &&
515
               (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
516
                result = result * base + value;
517
                cp++;
518
        }
519
 
520
        if (endp)
521
                *endp = cp;
522
 
523
        return result;
524
}
525
 
526
unsigned long prom_memparse(const char *ptr, const char **retptr)
527
{
528
        unsigned long ret = prom_strtoul(ptr, retptr);
529
        int shift = 0;
530
 
531
        /*
532
         * We can't use a switch here because GCC *may* generate a
533
         * jump table which won't work, because we're not running at
534
         * the address we're linked at.
535
         */
536
        if ('G' == **retptr || 'g' == **retptr)
537
                shift = 30;
538
 
539
        if ('M' == **retptr || 'm' == **retptr)
540
                shift = 20;
541
 
542
        if ('K' == **retptr || 'k' == **retptr)
543
                shift = 10;
544
 
545
        if (shift) {
546
                ret <<= shift;
547
                (*retptr)++;
548
        }
549
 
550
        return ret;
551
}
552
 
553
/*
554
 * Early parsing of the command line passed to the kernel, used for
555
 * "mem=x" and the options that affect the iommu
556
 */
557
static void __init early_cmdline_parse(void)
558
{
559
        struct prom_t *_prom = &RELOC(prom);
560
#ifdef CONFIG_PPC64
561
        const char *opt;
562
#endif
563
        char *p;
564
        int l = 0;
565
 
566
        RELOC(prom_cmd_line[0]) = 0;
567
        p = RELOC(prom_cmd_line);
568
        if ((long)_prom->chosen > 0)
569
                l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
570
#ifdef CONFIG_CMDLINE
571
        if (l <= 0 || p[0] == '\0') /* dbl check */
572
                strlcpy(RELOC(prom_cmd_line),
573
                        RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
574
#endif /* CONFIG_CMDLINE */
575
        prom_printf("command line: %s\n", RELOC(prom_cmd_line));
576
 
577
#ifdef CONFIG_PPC64
578
        opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
579
        if (opt) {
580
                prom_printf("iommu opt is: %s\n", opt);
581
                opt += 6;
582
                while (*opt && *opt == ' ')
583
                        opt++;
584
                if (!strncmp(opt, RELOC("off"), 3))
585
                        RELOC(prom_iommu_off) = 1;
586
                else if (!strncmp(opt, RELOC("force"), 5))
587
                        RELOC(prom_iommu_force_on) = 1;
588
        }
589
#endif
590
}
591
 
592
#ifdef CONFIG_PPC_PSERIES
593
/*
594
 * There are two methods for telling firmware what our capabilities are.
595
 * Newer machines have an "ibm,client-architecture-support" method on the
596
 * root node.  For older machines, we have to call the "process-elf-header"
597
 * method in the /packages/elf-loader node, passing it a fake 32-bit
598
 * ELF header containing a couple of PT_NOTE sections that contain
599
 * structures that contain various information.
600
 */
601
 
602
/*
603
 * New method - extensible architecture description vector.
604
 *
605
 * Because the description vector contains a mix of byte and word
606
 * values, we declare it as an unsigned char array, and use this
607
 * macro to put word values in.
608
 */
609
#define W(x)    ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
610
                ((x) >> 8) & 0xff, (x) & 0xff
611
 
612
/* Option vector bits - generic bits in byte 1 */
613
#define OV_IGNORE               0x80    /* ignore this vector */
614
#define OV_CESSATION_POLICY     0x40    /* halt if unsupported option present*/
615
 
616
/* Option vector 1: processor architectures supported */
617
#define OV1_PPC_2_00            0x80    /* set if we support PowerPC 2.00 */
618
#define OV1_PPC_2_01            0x40    /* set if we support PowerPC 2.01 */
619
#define OV1_PPC_2_02            0x20    /* set if we support PowerPC 2.02 */
620
#define OV1_PPC_2_03            0x10    /* set if we support PowerPC 2.03 */
621
#define OV1_PPC_2_04            0x08    /* set if we support PowerPC 2.04 */
622
#define OV1_PPC_2_05            0x04    /* set if we support PowerPC 2.05 */
623
 
624
/* Option vector 2: Open Firmware options supported */
625
#define OV2_REAL_MODE           0x20    /* set if we want OF in real mode */
626
 
627
/* Option vector 3: processor options supported */
628
#define OV3_FP                  0x80    /* floating point */
629
#define OV3_VMX                 0x40    /* VMX/Altivec */
630
#define OV3_DFP                 0x20    /* decimal FP */
631
 
632
/* Option vector 5: PAPR/OF options supported */
633
#define OV5_LPAR                0x80    /* logical partitioning supported */
634
#define OV5_SPLPAR              0x40    /* shared-processor LPAR supported */
635
/* ibm,dynamic-reconfiguration-memory property supported */
636
#define OV5_DRCONF_MEMORY       0x20
637
#define OV5_LARGE_PAGES         0x10    /* large pages supported */
638
#define OV5_DONATE_DEDICATE_CPU 0x02    /* donate dedicated CPU support */
639
/* PCIe/MSI support.  Without MSI full PCIe is not supported */
640
#ifdef CONFIG_PCI_MSI
641
#define OV5_MSI                 0x01    /* PCIe/MSI support */
642
#else
643
#define OV5_MSI                 0x00
644
#endif /* CONFIG_PCI_MSI */
645
 
646
/*
647
 * The architecture vector has an array of PVR mask/value pairs,
648
 * followed by # option vectors - 1, followed by the option vectors.
649
 */
650
static unsigned char ibm_architecture_vec[] = {
651
        W(0xfffe0000), W(0x003a0000),   /* POWER5/POWER5+ */
652
        W(0xffff0000), W(0x003e0000),   /* POWER6 */
653
        W(0xffffffff), W(0x0f000002),   /* all 2.05-compliant */
654
        W(0xfffffffe), W(0x0f000001),   /* all 2.04-compliant and earlier */
655
        5 - 1,                          /* 5 option vectors */
656
 
657
        /* option vector 1: processor architectures supported */
658
        3 - 2,                          /* length */
659
        0,                               /* don't ignore, don't halt */
660
        OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
661
        OV1_PPC_2_04 | OV1_PPC_2_05,
662
 
663
        /* option vector 2: Open Firmware options supported */
664
        34 - 2,                         /* length */
665
        OV2_REAL_MODE,
666
        0, 0,
667
        W(0xffffffff),                  /* real_base */
668
        W(0xffffffff),                  /* real_size */
669
        W(0xffffffff),                  /* virt_base */
670
        W(0xffffffff),                  /* virt_size */
671
        W(0xffffffff),                  /* load_base */
672
        W(64),                          /* 128MB min RMA */
673
        W(0xffffffff),                  /* full client load */
674
        0,                               /* min RMA percentage of total RAM */
675
        48,                             /* max log_2(hash table size) */
676
 
677
        /* option vector 3: processor options supported */
678
        3 - 2,                          /* length */
679
        0,                               /* don't ignore, don't halt */
680
        OV3_FP | OV3_VMX | OV3_DFP,
681
 
682
        /* option vector 4: IBM PAPR implementation */
683
        2 - 2,                          /* length */
684
        0,                               /* don't halt */
685
 
686
        /* option vector 5: PAPR/OF options */
687
        3 - 2,                          /* length */
688
        0,                               /* don't ignore, don't halt */
689
        OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
690
        OV5_DONATE_DEDICATE_CPU | OV5_MSI,
691
};
692
 
693
/* Old method - ELF header with PT_NOTE sections */
694
static struct fake_elf {
695
        Elf32_Ehdr      elfhdr;
696
        Elf32_Phdr      phdr[2];
697
        struct chrpnote {
698
                u32     namesz;
699
                u32     descsz;
700
                u32     type;
701
                char    name[8];        /* "PowerPC" */
702
                struct chrpdesc {
703
                        u32     real_mode;
704
                        u32     real_base;
705
                        u32     real_size;
706
                        u32     virt_base;
707
                        u32     virt_size;
708
                        u32     load_base;
709
                } chrpdesc;
710
        } chrpnote;
711
        struct rpanote {
712
                u32     namesz;
713
                u32     descsz;
714
                u32     type;
715
                char    name[24];       /* "IBM,RPA-Client-Config" */
716
                struct rpadesc {
717
                        u32     lpar_affinity;
718
                        u32     min_rmo_size;
719
                        u32     min_rmo_percent;
720
                        u32     max_pft_size;
721
                        u32     splpar;
722
                        u32     min_load;
723
                        u32     new_mem_def;
724
                        u32     ignore_me;
725
                } rpadesc;
726
        } rpanote;
727
} fake_elf = {
728
        .elfhdr = {
729
                .e_ident = { 0x7f, 'E', 'L', 'F',
730
                             ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
731
                .e_type = ET_EXEC,      /* yeah right */
732
                .e_machine = EM_PPC,
733
                .e_version = EV_CURRENT,
734
                .e_phoff = offsetof(struct fake_elf, phdr),
735
                .e_phentsize = sizeof(Elf32_Phdr),
736
                .e_phnum = 2
737
        },
738
        .phdr = {
739
                [0] = {
740
                        .p_type = PT_NOTE,
741
                        .p_offset = offsetof(struct fake_elf, chrpnote),
742
                        .p_filesz = sizeof(struct chrpnote)
743
                }, [1] = {
744
                        .p_type = PT_NOTE,
745
                        .p_offset = offsetof(struct fake_elf, rpanote),
746
                        .p_filesz = sizeof(struct rpanote)
747
                }
748
        },
749
        .chrpnote = {
750
                .namesz = sizeof("PowerPC"),
751
                .descsz = sizeof(struct chrpdesc),
752
                .type = 0x1275,
753
                .name = "PowerPC",
754
                .chrpdesc = {
755
                        .real_mode = ~0U,       /* ~0 means "don't care" */
756
                        .real_base = ~0U,
757
                        .real_size = ~0U,
758
                        .virt_base = ~0U,
759
                        .virt_size = ~0U,
760
                        .load_base = ~0U
761
                },
762
        },
763
        .rpanote = {
764
                .namesz = sizeof("IBM,RPA-Client-Config"),
765
                .descsz = sizeof(struct rpadesc),
766
                .type = 0x12759999,
767
                .name = "IBM,RPA-Client-Config",
768
                .rpadesc = {
769
                        .lpar_affinity = 0,
770
                        .min_rmo_size = 64,     /* in megabytes */
771
                        .min_rmo_percent = 0,
772
                        .max_pft_size = 48,     /* 2^48 bytes max PFT size */
773
                        .splpar = 1,
774
                        .min_load = ~0U,
775
                        .new_mem_def = 0
776
                }
777
        }
778
};
779
 
780
static void __init prom_send_capabilities(void)
781
{
782
        ihandle elfloader, root;
783
        prom_arg_t ret;
784
 
785
        root = call_prom("open", 1, 1, ADDR("/"));
786
        if (root != 0) {
787
                /* try calling the ibm,client-architecture-support method */
788
                if (call_prom_ret("call-method", 3, 2, &ret,
789
                                  ADDR("ibm,client-architecture-support"),
790
                                  root,
791
                                  ADDR(ibm_architecture_vec)) == 0) {
792
                        /* the call exists... */
793
                        if (ret)
794
                                prom_printf("WARNING: ibm,client-architecture"
795
                                            "-support call FAILED!\n");
796
                        call_prom("close", 1, 0, root);
797
                        return;
798
                }
799
                call_prom("close", 1, 0, root);
800
        }
801
 
802
        /* no ibm,client-architecture-support call, try the old way */
803
        elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
804
        if (elfloader == 0) {
805
                prom_printf("couldn't open /packages/elf-loader\n");
806
                return;
807
        }
808
        call_prom("call-method", 3, 1, ADDR("process-elf-header"),
809
                        elfloader, ADDR(&fake_elf));
810
        call_prom("close", 1, 0, elfloader);
811
}
812
#endif
813
 
814
/*
815
 * Memory allocation strategy... our layout is normally:
816
 *
817
 *  at 14Mb or more we have vmlinux, then a gap and initrd.  In some
818
 *  rare cases, initrd might end up being before the kernel though.
819
 *  We assume this won't override the final kernel at 0, we have no
820
 *  provision to handle that in this version, but it should hopefully
821
 *  never happen.
822
 *
823
 *  alloc_top is set to the top of RMO, eventually shrink down if the
824
 *  TCEs overlap
825
 *
826
 *  alloc_bottom is set to the top of kernel/initrd
827
 *
828
 *  from there, allocations are done this way : rtas is allocated
829
 *  topmost, and the device-tree is allocated from the bottom. We try
830
 *  to grow the device-tree allocation as we progress. If we can't,
831
 *  then we fail, we don't currently have a facility to restart
832
 *  elsewhere, but that shouldn't be necessary.
833
 *
834
 *  Note that calls to reserve_mem have to be done explicitly, memory
835
 *  allocated with either alloc_up or alloc_down isn't automatically
836
 *  reserved.
837
 */
838
 
839
 
840
/*
841
 * Allocates memory in the RMO upward from the kernel/initrd
842
 *
843
 * When align is 0, this is a special case, it means to allocate in place
844
 * at the current location of alloc_bottom or fail (that is basically
845
 * extending the previous allocation). Used for the device-tree flattening
846
 */
847
static unsigned long __init alloc_up(unsigned long size, unsigned long align)
848
{
849
        unsigned long base = RELOC(alloc_bottom);
850
        unsigned long addr = 0;
851
 
852
        if (align)
853
                base = _ALIGN_UP(base, align);
854
        prom_debug("alloc_up(%x, %x)\n", size, align);
855
        if (RELOC(ram_top) == 0)
856
                prom_panic("alloc_up() called with mem not initialized\n");
857
 
858
        if (align)
859
                base = _ALIGN_UP(RELOC(alloc_bottom), align);
860
        else
861
                base = RELOC(alloc_bottom);
862
 
863
        for(; (base + size) <= RELOC(alloc_top);
864
            base = _ALIGN_UP(base + 0x100000, align)) {
865
                prom_debug("    trying: 0x%x\n\r", base);
866
                addr = (unsigned long)prom_claim(base, size, 0);
867
                if (addr != PROM_ERROR && addr != 0)
868
                        break;
869
                addr = 0;
870
                if (align == 0)
871
                        break;
872
        }
873
        if (addr == 0)
874
                return 0;
875
        RELOC(alloc_bottom) = addr;
876
 
877
        prom_debug(" -> %x\n", addr);
878
        prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
879
        prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
880
        prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
881
        prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
882
        prom_debug("  ram_top      : %x\n", RELOC(ram_top));
883
 
884
        return addr;
885
}
886
 
887
/*
888
 * Allocates memory downward, either from top of RMO, or if highmem
889
 * is set, from the top of RAM.  Note that this one doesn't handle
890
 * failures.  It does claim memory if highmem is not set.
891
 */
892
static unsigned long __init alloc_down(unsigned long size, unsigned long align,
893
                                       int highmem)
894
{
895
        unsigned long base, addr = 0;
896
 
897
        prom_debug("alloc_down(%x, %x, %s)\n", size, align,
898
                   highmem ? RELOC("(high)") : RELOC("(low)"));
899
        if (RELOC(ram_top) == 0)
900
                prom_panic("alloc_down() called with mem not initialized\n");
901
 
902
        if (highmem) {
903
                /* Carve out storage for the TCE table. */
904
                addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
905
                if (addr <= RELOC(alloc_bottom))
906
                        return 0;
907
                /* Will we bump into the RMO ? If yes, check out that we
908
                 * didn't overlap existing allocations there, if we did,
909
                 * we are dead, we must be the first in town !
910
                 */
911
                if (addr < RELOC(rmo_top)) {
912
                        /* Good, we are first */
913
                        if (RELOC(alloc_top) == RELOC(rmo_top))
914
                                RELOC(alloc_top) = RELOC(rmo_top) = addr;
915
                        else
916
                                return 0;
917
                }
918
                RELOC(alloc_top_high) = addr;
919
                goto bail;
920
        }
921
 
922
        base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
923
        for (; base > RELOC(alloc_bottom);
924
             base = _ALIGN_DOWN(base - 0x100000, align))  {
925
                prom_debug("    trying: 0x%x\n\r", base);
926
                addr = (unsigned long)prom_claim(base, size, 0);
927
                if (addr != PROM_ERROR && addr != 0)
928
                        break;
929
                addr = 0;
930
        }
931
        if (addr == 0)
932
                return 0;
933
        RELOC(alloc_top) = addr;
934
 
935
 bail:
936
        prom_debug(" -> %x\n", addr);
937
        prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
938
        prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
939
        prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
940
        prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
941
        prom_debug("  ram_top      : %x\n", RELOC(ram_top));
942
 
943
        return addr;
944
}
945
 
946
/*
947
 * Parse a "reg" cell
948
 */
949
static unsigned long __init prom_next_cell(int s, cell_t **cellp)
950
{
951
        cell_t *p = *cellp;
952
        unsigned long r = 0;
953
 
954
        /* Ignore more than 2 cells */
955
        while (s > sizeof(unsigned long) / 4) {
956
                p++;
957
                s--;
958
        }
959
        r = *p++;
960
#ifdef CONFIG_PPC64
961
        if (s > 1) {
962
                r <<= 32;
963
                r |= *(p++);
964
        }
965
#endif
966
        *cellp = p;
967
        return r;
968
}
969
 
970
/*
971
 * Very dumb function for adding to the memory reserve list, but
972
 * we don't need anything smarter at this point
973
 *
974
 * XXX Eventually check for collisions.  They should NEVER happen.
975
 * If problems seem to show up, it would be a good start to track
976
 * them down.
977
 */
978
static void __init reserve_mem(u64 base, u64 size)
979
{
980
        u64 top = base + size;
981
        unsigned long cnt = RELOC(mem_reserve_cnt);
982
 
983
        if (size == 0)
984
                return;
985
 
986
        /* We need to always keep one empty entry so that we
987
         * have our terminator with "size" set to 0 since we are
988
         * dumb and just copy this entire array to the boot params
989
         */
990
        base = _ALIGN_DOWN(base, PAGE_SIZE);
991
        top = _ALIGN_UP(top, PAGE_SIZE);
992
        size = top - base;
993
 
994
        if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
995
                prom_panic("Memory reserve map exhausted !\n");
996
        RELOC(mem_reserve_map)[cnt].base = base;
997
        RELOC(mem_reserve_map)[cnt].size = size;
998
        RELOC(mem_reserve_cnt) = cnt + 1;
999
}
1000
 
1001
/*
1002
 * Initialize memory allocation mechanism, parse "memory" nodes and
1003
 * obtain that way the top of memory and RMO to setup out local allocator
1004
 */
1005
static void __init prom_init_mem(void)
1006
{
1007
        phandle node;
1008
        char *path, type[64];
1009
        unsigned int plen;
1010
        cell_t *p, *endp;
1011
        struct prom_t *_prom = &RELOC(prom);
1012
        u32 rac, rsc;
1013
 
1014
        /*
1015
         * We iterate the memory nodes to find
1016
         * 1) top of RMO (first node)
1017
         * 2) top of memory
1018
         */
1019
        rac = 2;
1020
        prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1021
        rsc = 1;
1022
        prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1023
        prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1024
        prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1025
 
1026
        prom_debug("scanning memory:\n");
1027
        path = RELOC(prom_scratch);
1028
 
1029
        for (node = 0; prom_next_node(&node); ) {
1030
                type[0] = 0;
1031
                prom_getprop(node, "device_type", type, sizeof(type));
1032
 
1033
                if (type[0] == 0) {
1034
                        /*
1035
                         * CHRP Longtrail machines have no device_type
1036
                         * on the memory node, so check the name instead...
1037
                         */
1038
                        prom_getprop(node, "name", type, sizeof(type));
1039
                }
1040
                if (strcmp(type, RELOC("memory")))
1041
                        continue;
1042
 
1043
                plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1044
                if (plen > sizeof(regbuf)) {
1045
                        prom_printf("memory node too large for buffer !\n");
1046
                        plen = sizeof(regbuf);
1047
                }
1048
                p = RELOC(regbuf);
1049
                endp = p + (plen / sizeof(cell_t));
1050
 
1051
#ifdef DEBUG_PROM
1052
                memset(path, 0, PROM_SCRATCH_SIZE);
1053
                call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1054
                prom_debug("  node %s :\n", path);
1055
#endif /* DEBUG_PROM */
1056
 
1057
                while ((endp - p) >= (rac + rsc)) {
1058
                        unsigned long base, size;
1059
 
1060
                        base = prom_next_cell(rac, &p);
1061
                        size = prom_next_cell(rsc, &p);
1062
 
1063
                        if (size == 0)
1064
                                continue;
1065
                        prom_debug("    %x %x\n", base, size);
1066
                        if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
1067
                                RELOC(rmo_top) = size;
1068
                        if ((base + size) > RELOC(ram_top))
1069
                                RELOC(ram_top) = base + size;
1070
                }
1071
        }
1072
 
1073
        RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1074
 
1075
        /* Check if we have an initrd after the kernel, if we do move our bottom
1076
         * point to after it
1077
         */
1078
        if (RELOC(prom_initrd_start)) {
1079
                if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1080
                        RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1081
        }
1082
 
1083
        /*
1084
         * Setup our top alloc point, that is top of RMO or top of
1085
         * segment 0 when running non-LPAR.
1086
         * Some RS64 machines have buggy firmware where claims up at
1087
         * 1GB fail.  Cap at 768MB as a workaround.
1088
         * Since 768MB is plenty of room, and we need to cap to something
1089
         * reasonable on 32-bit, cap at 768MB on all machines.
1090
         */
1091
        if (!RELOC(rmo_top))
1092
                RELOC(rmo_top) = RELOC(ram_top);
1093
        RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1094
        RELOC(alloc_top) = RELOC(rmo_top);
1095
        RELOC(alloc_top_high) = RELOC(ram_top);
1096
 
1097
        prom_printf("memory layout at init:\n");
1098
        prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
1099
        prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
1100
        prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
1101
        prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
1102
        prom_printf("  ram_top      : %x\n", RELOC(ram_top));
1103
}
1104
 
1105
 
1106
/*
1107
 * Allocate room for and instantiate RTAS
1108
 */
1109
static void __init prom_instantiate_rtas(void)
1110
{
1111
        phandle rtas_node;
1112
        ihandle rtas_inst;
1113
        u32 base, entry = 0;
1114
        u32 size = 0;
1115
 
1116
        prom_debug("prom_instantiate_rtas: start...\n");
1117
 
1118
        rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1119
        prom_debug("rtas_node: %x\n", rtas_node);
1120
        if (!PHANDLE_VALID(rtas_node))
1121
                return;
1122
 
1123
        prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1124
        if (size == 0)
1125
                return;
1126
 
1127
        base = alloc_down(size, PAGE_SIZE, 0);
1128
        if (base == 0) {
1129
                prom_printf("RTAS allocation failed !\n");
1130
                return;
1131
        }
1132
 
1133
        rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1134
        if (!IHANDLE_VALID(rtas_inst)) {
1135
                prom_printf("opening rtas package failed (%x)\n", rtas_inst);
1136
                return;
1137
        }
1138
 
1139
        prom_printf("instantiating rtas at 0x%x ...", base);
1140
 
1141
        if (call_prom_ret("call-method", 3, 2, &entry,
1142
                          ADDR("instantiate-rtas"),
1143
                          rtas_inst, base) != 0
1144
            || entry == 0) {
1145
                prom_printf(" failed\n");
1146
                return;
1147
        }
1148
        prom_printf(" done\n");
1149
 
1150
        reserve_mem(base, size);
1151
 
1152
        prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1153
                     &base, sizeof(base));
1154
        prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1155
                     &entry, sizeof(entry));
1156
 
1157
        prom_debug("rtas base     = 0x%x\n", base);
1158
        prom_debug("rtas entry    = 0x%x\n", entry);
1159
        prom_debug("rtas size     = 0x%x\n", (long)size);
1160
 
1161
        prom_debug("prom_instantiate_rtas: end...\n");
1162
}
1163
 
1164
#ifdef CONFIG_PPC64
1165
/*
1166
 * Allocate room for and initialize TCE tables
1167
 */
1168
static void __init prom_initialize_tce_table(void)
1169
{
1170
        phandle node;
1171
        ihandle phb_node;
1172
        char compatible[64], type[64], model[64];
1173
        char *path = RELOC(prom_scratch);
1174
        u64 base, align;
1175
        u32 minalign, minsize;
1176
        u64 tce_entry, *tce_entryp;
1177
        u64 local_alloc_top, local_alloc_bottom;
1178
        u64 i;
1179
 
1180
        if (RELOC(prom_iommu_off))
1181
                return;
1182
 
1183
        prom_debug("starting prom_initialize_tce_table\n");
1184
 
1185
        /* Cache current top of allocs so we reserve a single block */
1186
        local_alloc_top = RELOC(alloc_top_high);
1187
        local_alloc_bottom = local_alloc_top;
1188
 
1189
        /* Search all nodes looking for PHBs. */
1190
        for (node = 0; prom_next_node(&node); ) {
1191
                compatible[0] = 0;
1192
                type[0] = 0;
1193
                model[0] = 0;
1194
                prom_getprop(node, "compatible",
1195
                             compatible, sizeof(compatible));
1196
                prom_getprop(node, "device_type", type, sizeof(type));
1197
                prom_getprop(node, "model", model, sizeof(model));
1198
 
1199
                if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1200
                        continue;
1201
 
1202
                /* Keep the old logic intact to avoid regression. */
1203
                if (compatible[0] != 0) {
1204
                        if ((strstr(compatible, RELOC("python")) == NULL) &&
1205
                            (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1206
                            (strstr(compatible, RELOC("Winnipeg")) == NULL))
1207
                                continue;
1208
                } else if (model[0] != 0) {
1209
                        if ((strstr(model, RELOC("ython")) == NULL) &&
1210
                            (strstr(model, RELOC("peedwagon")) == NULL) &&
1211
                            (strstr(model, RELOC("innipeg")) == NULL))
1212
                                continue;
1213
                }
1214
 
1215
                if (prom_getprop(node, "tce-table-minalign", &minalign,
1216
                                 sizeof(minalign)) == PROM_ERROR)
1217
                        minalign = 0;
1218
                if (prom_getprop(node, "tce-table-minsize", &minsize,
1219
                                 sizeof(minsize)) == PROM_ERROR)
1220
                        minsize = 4UL << 20;
1221
 
1222
                /*
1223
                 * Even though we read what OF wants, we just set the table
1224
                 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
1225
                 * By doing this, we avoid the pitfalls of trying to DMA to
1226
                 * MMIO space and the DMA alias hole.
1227
                 *
1228
                 * On POWER4, firmware sets the TCE region by assuming
1229
                 * each TCE table is 8MB. Using this memory for anything
1230
                 * else will impact performance, so we always allocate 8MB.
1231
                 * Anton
1232
                 */
1233
                if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1234
                        minsize = 8UL << 20;
1235
                else
1236
                        minsize = 4UL << 20;
1237
 
1238
                /* Align to the greater of the align or size */
1239
                align = max(minalign, minsize);
1240
                base = alloc_down(minsize, align, 1);
1241
                if (base == 0)
1242
                        prom_panic("ERROR, cannot find space for TCE table.\n");
1243
                if (base < local_alloc_bottom)
1244
                        local_alloc_bottom = base;
1245
 
1246
                /* It seems OF doesn't null-terminate the path :-( */
1247
                memset(path, 0, PROM_SCRATCH_SIZE);
1248
                /* Call OF to setup the TCE hardware */
1249
                if (call_prom("package-to-path", 3, 1, node,
1250
                              path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1251
                        prom_printf("package-to-path failed\n");
1252
                }
1253
 
1254
                /* Save away the TCE table attributes for later use. */
1255
                prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1256
                prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1257
 
1258
                prom_debug("TCE table: %s\n", path);
1259
                prom_debug("\tnode = 0x%x\n", node);
1260
                prom_debug("\tbase = 0x%x\n", base);
1261
                prom_debug("\tsize = 0x%x\n", minsize);
1262
 
1263
                /* Initialize the table to have a one-to-one mapping
1264
                 * over the allocated size.
1265
                 */
1266
                tce_entryp = (unsigned long *)base;
1267
                for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1268
                        tce_entry = (i << PAGE_SHIFT);
1269
                        tce_entry |= 0x3;
1270
                        *tce_entryp = tce_entry;
1271
                }
1272
 
1273
                prom_printf("opening PHB %s", path);
1274
                phb_node = call_prom("open", 1, 1, path);
1275
                if (phb_node == 0)
1276
                        prom_printf("... failed\n");
1277
                else
1278
                        prom_printf("... done\n");
1279
 
1280
                call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1281
                          phb_node, -1, minsize,
1282
                          (u32) base, (u32) (base >> 32));
1283
                call_prom("close", 1, 0, phb_node);
1284
        }
1285
 
1286
        reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1287
 
1288
        /* These are only really needed if there is a memory limit in
1289
         * effect, but we don't know so export them always. */
1290
        RELOC(prom_tce_alloc_start) = local_alloc_bottom;
1291
        RELOC(prom_tce_alloc_end) = local_alloc_top;
1292
 
1293
        /* Flag the first invalid entry */
1294
        prom_debug("ending prom_initialize_tce_table\n");
1295
}
1296
#endif
1297
 
1298
/*
1299
 * With CHRP SMP we need to use the OF to start the other processors.
1300
 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1301
 * so we have to put the processors into a holding pattern controlled
1302
 * by the kernel (not OF) before we destroy the OF.
1303
 *
1304
 * This uses a chunk of low memory, puts some holding pattern
1305
 * code there and sends the other processors off to there until
1306
 * smp_boot_cpus tells them to do something.  The holding pattern
1307
 * checks that address until its cpu # is there, when it is that
1308
 * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
1309
 * of setting those values.
1310
 *
1311
 * We also use physical address 0x4 here to tell when a cpu
1312
 * is in its holding pattern code.
1313
 *
1314
 * -- Cort
1315
 */
1316
extern void __secondary_hold(void);
1317
extern unsigned long __secondary_hold_spinloop;
1318
extern unsigned long __secondary_hold_acknowledge;
1319
 
1320
/*
1321
 * We want to reference the copy of __secondary_hold_* in the
1322
 * 0 - 0x100 address range
1323
 */
1324
#define LOW_ADDR(x)     (((unsigned long) &(x)) & 0xff)
1325
 
1326
static void __init prom_hold_cpus(void)
1327
{
1328
        unsigned long i;
1329
        unsigned int reg;
1330
        phandle node;
1331
        char type[64];
1332
        int cpuid = 0;
1333
        unsigned int interrupt_server[MAX_CPU_THREADS];
1334
        unsigned int cpu_threads, hw_cpu_num;
1335
        int propsize;
1336
        struct prom_t *_prom = &RELOC(prom);
1337
        unsigned long *spinloop
1338
                = (void *) LOW_ADDR(__secondary_hold_spinloop);
1339
        unsigned long *acknowledge
1340
                = (void *) LOW_ADDR(__secondary_hold_acknowledge);
1341
#ifdef CONFIG_PPC64
1342
        /* __secondary_hold is actually a descriptor, not the text address */
1343
        unsigned long secondary_hold
1344
                = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1345
#else
1346
        unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
1347
#endif
1348
 
1349
        prom_debug("prom_hold_cpus: start...\n");
1350
        prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
1351
        prom_debug("    1) *spinloop      = 0x%x\n", *spinloop);
1352
        prom_debug("    1) acknowledge    = 0x%x\n",
1353
                   (unsigned long)acknowledge);
1354
        prom_debug("    1) *acknowledge   = 0x%x\n", *acknowledge);
1355
        prom_debug("    1) secondary_hold = 0x%x\n", secondary_hold);
1356
 
1357
        /* Set the common spinloop variable, so all of the secondary cpus
1358
         * will block when they are awakened from their OF spinloop.
1359
         * This must occur for both SMP and non SMP kernels, since OF will
1360
         * be trashed when we move the kernel.
1361
         */
1362
        *spinloop = 0;
1363
 
1364
        /* look for cpus */
1365
        for (node = 0; prom_next_node(&node); ) {
1366
                type[0] = 0;
1367
                prom_getprop(node, "device_type", type, sizeof(type));
1368
                if (strcmp(type, RELOC("cpu")) != 0)
1369
                        continue;
1370
 
1371
                /* Skip non-configured cpus. */
1372
                if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1373
                        if (strcmp(type, RELOC("okay")) != 0)
1374
                                continue;
1375
 
1376
                reg = -1;
1377
                prom_getprop(node, "reg", &reg, sizeof(reg));
1378
 
1379
                prom_debug("\ncpuid        = 0x%x\n", cpuid);
1380
                prom_debug("cpu hw idx   = 0x%x\n", reg);
1381
 
1382
                /* Init the acknowledge var which will be reset by
1383
                 * the secondary cpu when it awakens from its OF
1384
                 * spinloop.
1385
                 */
1386
                *acknowledge = (unsigned long)-1;
1387
 
1388
                propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1389
                                        &interrupt_server,
1390
                                        sizeof(interrupt_server));
1391
                if (propsize < 0) {
1392
                        /* no property.  old hardware has no SMT */
1393
                        cpu_threads = 1;
1394
                        interrupt_server[0] = reg; /* fake it with phys id */
1395
                } else {
1396
                        /* We have a threaded processor */
1397
                        cpu_threads = propsize / sizeof(u32);
1398
                        if (cpu_threads > MAX_CPU_THREADS) {
1399
                                prom_printf("SMT: too many threads!\n"
1400
                                            "SMT: found %x, max is %x\n",
1401
                                            cpu_threads, MAX_CPU_THREADS);
1402
                                cpu_threads = 1; /* ToDo: panic? */
1403
                        }
1404
                }
1405
 
1406
                hw_cpu_num = interrupt_server[0];
1407
                if (hw_cpu_num != _prom->cpu) {
1408
                        /* Primary Thread of non-boot cpu */
1409
                        prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1410
                        call_prom("start-cpu", 3, 0, node,
1411
                                  secondary_hold, reg);
1412
 
1413
                        for (i = 0; (i < 100000000) &&
1414
                             (*acknowledge == ((unsigned long)-1)); i++ )
1415
                                mb();
1416
 
1417
                        if (*acknowledge == reg)
1418
                                prom_printf("done\n");
1419
                        else
1420
                                prom_printf("failed: %x\n", *acknowledge);
1421
                }
1422
#ifdef CONFIG_SMP
1423
                else
1424
                        prom_printf("%x : boot cpu     %x\n", cpuid, reg);
1425
#endif /* CONFIG_SMP */
1426
 
1427
                /* Reserve cpu #s for secondary threads.   They start later. */
1428
                cpuid += cpu_threads;
1429
        }
1430
 
1431
        if (cpuid > NR_CPUS)
1432
                prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1433
                            ") exceeded: ignoring extras\n");
1434
 
1435
        prom_debug("prom_hold_cpus: end...\n");
1436
}
1437
 
1438
 
1439
static void __init prom_init_client_services(unsigned long pp)
1440
{
1441
        struct prom_t *_prom = &RELOC(prom);
1442
 
1443
        /* Get a handle to the prom entry point before anything else */
1444
        RELOC(prom_entry) = pp;
1445
 
1446
        /* get a handle for the stdout device */
1447
        _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1448
        if (!PHANDLE_VALID(_prom->chosen))
1449
                prom_panic("cannot find chosen"); /* msg won't be printed :( */
1450
 
1451
        /* get device tree root */
1452
        _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1453
        if (!PHANDLE_VALID(_prom->root))
1454
                prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1455
 
1456
        _prom->mmumap = 0;
1457
}
1458
 
1459
#ifdef CONFIG_PPC32
1460
/*
1461
 * For really old powermacs, we need to map things we claim.
1462
 * For that, we need the ihandle of the mmu.
1463
 * Also, on the longtrail, we need to work around other bugs.
1464
 */
1465
static void __init prom_find_mmu(void)
1466
{
1467
        struct prom_t *_prom = &RELOC(prom);
1468
        phandle oprom;
1469
        char version[64];
1470
 
1471
        oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1472
        if (!PHANDLE_VALID(oprom))
1473
                return;
1474
        if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1475
                return;
1476
        version[sizeof(version) - 1] = 0;
1477
        /* XXX might need to add other versions here */
1478
        if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1479
                of_workarounds = OF_WA_CLAIM;
1480
        else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1481
                of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1482
                call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1483
        } else
1484
                return;
1485
        _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
1486
        prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1487
                     sizeof(_prom->mmumap));
1488
        if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1489
                of_workarounds &= ~OF_WA_CLAIM;         /* hmmm */
1490
}
1491
#else
1492
#define prom_find_mmu()
1493
#endif
1494
 
1495
static void __init prom_init_stdout(void)
1496
{
1497
        struct prom_t *_prom = &RELOC(prom);
1498
        char *path = RELOC(of_stdout_device);
1499
        char type[16];
1500
        u32 val;
1501
 
1502
        if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1503
                prom_panic("cannot find stdout");
1504
 
1505
        _prom->stdout = val;
1506
 
1507
        /* Get the full OF pathname of the stdout device */
1508
        memset(path, 0, 256);
1509
        call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1510
        val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1511
        prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1512
                     &val, sizeof(val));
1513
        prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1514
        prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1515
                     path, strlen(path) + 1);
1516
 
1517
        /* If it's a display, note it */
1518
        memset(type, 0, sizeof(type));
1519
        prom_getprop(val, "device_type", type, sizeof(type));
1520
        if (strcmp(type, RELOC("display")) == 0)
1521
                prom_setprop(val, path, "linux,boot-display", NULL, 0);
1522
}
1523
 
1524
static void __init prom_close_stdin(void)
1525
{
1526
        struct prom_t *_prom = &RELOC(prom);
1527
        ihandle val;
1528
 
1529
        if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1530
                call_prom("close", 1, 0, val);
1531
}
1532
 
1533
static int __init prom_find_machine_type(void)
1534
{
1535
        struct prom_t *_prom = &RELOC(prom);
1536
        char compat[256];
1537
        int len, i = 0;
1538
#ifdef CONFIG_PPC64
1539
        phandle rtas;
1540
        int x;
1541
#endif
1542
 
1543
        /* Look for a PowerMac */
1544
        len = prom_getprop(_prom->root, "compatible",
1545
                           compat, sizeof(compat)-1);
1546
        if (len > 0) {
1547
                compat[len] = 0;
1548
                while (i < len) {
1549
                        char *p = &compat[i];
1550
                        int sl = strlen(p);
1551
                        if (sl == 0)
1552
                                break;
1553
                        if (strstr(p, RELOC("Power Macintosh")) ||
1554
                            strstr(p, RELOC("MacRISC")))
1555
                                return PLATFORM_POWERMAC;
1556
#ifdef CONFIG_PPC64
1557
                        /* We must make sure we don't detect the IBM Cell
1558
                         * blades as pSeries due to some firmware issues,
1559
                         * so we do it here.
1560
                         */
1561
                        if (strstr(p, RELOC("IBM,CBEA")) ||
1562
                            strstr(p, RELOC("IBM,CPBW-1.0")))
1563
                                return PLATFORM_GENERIC;
1564
#endif /* CONFIG_PPC64 */
1565
                        i += sl + 1;
1566
                }
1567
        }
1568
#ifdef CONFIG_PPC64
1569
        /* If not a mac, try to figure out if it's an IBM pSeries or any other
1570
         * PAPR compliant platform. We assume it is if :
1571
         *  - /device_type is "chrp" (please, do NOT use that for future
1572
         *    non-IBM designs !
1573
         *  - it has /rtas
1574
         */
1575
        len = prom_getprop(_prom->root, "device_type",
1576
                           compat, sizeof(compat)-1);
1577
        if (len <= 0)
1578
                return PLATFORM_GENERIC;
1579
        if (strcmp(compat, RELOC("chrp")))
1580
                return PLATFORM_GENERIC;
1581
 
1582
        /* Default to pSeries. We need to know if we are running LPAR */
1583
        rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1584
        if (!PHANDLE_VALID(rtas))
1585
                return PLATFORM_GENERIC;
1586
        x = prom_getproplen(rtas, "ibm,hypertas-functions");
1587
        if (x != PROM_ERROR) {
1588
                prom_printf("Hypertas detected, assuming LPAR !\n");
1589
                return PLATFORM_PSERIES_LPAR;
1590
        }
1591
        return PLATFORM_PSERIES;
1592
#else
1593
        return PLATFORM_GENERIC;
1594
#endif
1595
}
1596
 
1597
static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1598
{
1599
        return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1600
}
1601
 
1602
/*
1603
 * If we have a display that we don't know how to drive,
1604
 * we will want to try to execute OF's open method for it
1605
 * later.  However, OF will probably fall over if we do that
1606
 * we've taken over the MMU.
1607
 * So we check whether we will need to open the display,
1608
 * and if so, open it now.
1609
 */
1610
static void __init prom_check_displays(void)
1611
{
1612
        char type[16], *path;
1613
        phandle node;
1614
        ihandle ih;
1615
        int i;
1616
 
1617
        static unsigned char default_colors[] = {
1618
                0x00, 0x00, 0x00,
1619
                0x00, 0x00, 0xaa,
1620
                0x00, 0xaa, 0x00,
1621
                0x00, 0xaa, 0xaa,
1622
                0xaa, 0x00, 0x00,
1623
                0xaa, 0x00, 0xaa,
1624
                0xaa, 0xaa, 0x00,
1625
                0xaa, 0xaa, 0xaa,
1626
                0x55, 0x55, 0x55,
1627
                0x55, 0x55, 0xff,
1628
                0x55, 0xff, 0x55,
1629
                0x55, 0xff, 0xff,
1630
                0xff, 0x55, 0x55,
1631
                0xff, 0x55, 0xff,
1632
                0xff, 0xff, 0x55,
1633
                0xff, 0xff, 0xff
1634
        };
1635
        const unsigned char *clut;
1636
 
1637
        prom_printf("Looking for displays\n");
1638
        for (node = 0; prom_next_node(&node); ) {
1639
                memset(type, 0, sizeof(type));
1640
                prom_getprop(node, "device_type", type, sizeof(type));
1641
                if (strcmp(type, RELOC("display")) != 0)
1642
                        continue;
1643
 
1644
                /* It seems OF doesn't null-terminate the path :-( */
1645
                path = RELOC(prom_scratch);
1646
                memset(path, 0, PROM_SCRATCH_SIZE);
1647
 
1648
                /*
1649
                 * leave some room at the end of the path for appending extra
1650
                 * arguments
1651
                 */
1652
                if (call_prom("package-to-path", 3, 1, node, path,
1653
                              PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1654
                        continue;
1655
                prom_printf("found display   : %s, opening ... ", path);
1656
 
1657
                ih = call_prom("open", 1, 1, path);
1658
                if (ih == 0) {
1659
                        prom_printf("failed\n");
1660
                        continue;
1661
                }
1662
 
1663
                /* Success */
1664
                prom_printf("done\n");
1665
                prom_setprop(node, path, "linux,opened", NULL, 0);
1666
 
1667
                /* Setup a usable color table when the appropriate
1668
                 * method is available. Should update this to set-colors */
1669
                clut = RELOC(default_colors);
1670
                for (i = 0; i < 32; i++, clut += 3)
1671
                        if (prom_set_color(ih, i, clut[0], clut[1],
1672
                                           clut[2]) != 0)
1673
                                break;
1674
 
1675
#ifdef CONFIG_LOGO_LINUX_CLUT224
1676
                clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1677
                for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1678
                        if (prom_set_color(ih, i + 32, clut[0], clut[1],
1679
                                           clut[2]) != 0)
1680
                                break;
1681
#endif /* CONFIG_LOGO_LINUX_CLUT224 */
1682
        }
1683
}
1684
 
1685
 
1686
/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1687
static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1688
                              unsigned long needed, unsigned long align)
1689
{
1690
        void *ret;
1691
 
1692
        *mem_start = _ALIGN(*mem_start, align);
1693
        while ((*mem_start + needed) > *mem_end) {
1694
                unsigned long room, chunk;
1695
 
1696
                prom_debug("Chunk exhausted, claiming more at %x...\n",
1697
                           RELOC(alloc_bottom));
1698
                room = RELOC(alloc_top) - RELOC(alloc_bottom);
1699
                if (room > DEVTREE_CHUNK_SIZE)
1700
                        room = DEVTREE_CHUNK_SIZE;
1701
                if (room < PAGE_SIZE)
1702
                        prom_panic("No memory for flatten_device_tree (no room)");
1703
                chunk = alloc_up(room, 0);
1704
                if (chunk == 0)
1705
                        prom_panic("No memory for flatten_device_tree (claim failed)");
1706
                *mem_end = RELOC(alloc_top);
1707
        }
1708
 
1709
        ret = (void *)*mem_start;
1710
        *mem_start += needed;
1711
 
1712
        return ret;
1713
}
1714
 
1715
#define dt_push_token(token, mem_start, mem_end) \
1716
        do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1717
 
1718
static unsigned long __init dt_find_string(char *str)
1719
{
1720
        char *s, *os;
1721
 
1722
        s = os = (char *)RELOC(dt_string_start);
1723
        s += 4;
1724
        while (s <  (char *)RELOC(dt_string_end)) {
1725
                if (strcmp(s, str) == 0)
1726
                        return s - os;
1727
                s += strlen(s) + 1;
1728
        }
1729
        return 0;
1730
}
1731
 
1732
/*
1733
 * The Open Firmware 1275 specification states properties must be 31 bytes or
1734
 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1735
 */
1736
#define MAX_PROPERTY_NAME 64
1737
 
1738
static void __init scan_dt_build_strings(phandle node,
1739
                                         unsigned long *mem_start,
1740
                                         unsigned long *mem_end)
1741
{
1742
        char *prev_name, *namep, *sstart;
1743
        unsigned long soff;
1744
        phandle child;
1745
 
1746
        sstart =  (char *)RELOC(dt_string_start);
1747
 
1748
        /* get and store all property names */
1749
        prev_name = RELOC("");
1750
        for (;;) {
1751
                /* 64 is max len of name including nul. */
1752
                namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1753
                if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1754
                        /* No more nodes: unwind alloc */
1755
                        *mem_start = (unsigned long)namep;
1756
                        break;
1757
                }
1758
 
1759
                /* skip "name" */
1760
                if (strcmp(namep, RELOC("name")) == 0) {
1761
                        *mem_start = (unsigned long)namep;
1762
                        prev_name = RELOC("name");
1763
                        continue;
1764
                }
1765
                /* get/create string entry */
1766
                soff = dt_find_string(namep);
1767
                if (soff != 0) {
1768
                        *mem_start = (unsigned long)namep;
1769
                        namep = sstart + soff;
1770
                } else {
1771
                        /* Trim off some if we can */
1772
                        *mem_start = (unsigned long)namep + strlen(namep) + 1;
1773
                        RELOC(dt_string_end) = *mem_start;
1774
                }
1775
                prev_name = namep;
1776
        }
1777
 
1778
        /* do all our children */
1779
        child = call_prom("child", 1, 1, node);
1780
        while (child != 0) {
1781
                scan_dt_build_strings(child, mem_start, mem_end);
1782
                child = call_prom("peer", 1, 1, child);
1783
        }
1784
}
1785
 
1786
static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1787
                                        unsigned long *mem_end)
1788
{
1789
        phandle child;
1790
        char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1791
        unsigned long soff;
1792
        unsigned char *valp;
1793
        static char pname[MAX_PROPERTY_NAME];
1794
        int l, room;
1795
 
1796
        dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1797
 
1798
        /* get the node's full name */
1799
        namep = (char *)*mem_start;
1800
        room = *mem_end - *mem_start;
1801
        if (room > 255)
1802
                room = 255;
1803
        l = call_prom("package-to-path", 3, 1, node, namep, room);
1804
        if (l >= 0) {
1805
                /* Didn't fit?  Get more room. */
1806
                if (l >= room) {
1807
                        if (l >= *mem_end - *mem_start)
1808
                                namep = make_room(mem_start, mem_end, l+1, 1);
1809
                        call_prom("package-to-path", 3, 1, node, namep, l);
1810
                }
1811
                namep[l] = '\0';
1812
 
1813
                /* Fixup an Apple bug where they have bogus \0 chars in the
1814
                 * middle of the path in some properties, and extract
1815
                 * the unit name (everything after the last '/').
1816
                 */
1817
                for (lp = p = namep, ep = namep + l; p < ep; p++) {
1818
                        if (*p == '/')
1819
                                lp = namep;
1820
                        else if (*p != 0)
1821
                                *lp++ = *p;
1822
                }
1823
                *lp = 0;
1824
                *mem_start = _ALIGN((unsigned long)lp + 1, 4);
1825
        }
1826
 
1827
        /* get it again for debugging */
1828
        path = RELOC(prom_scratch);
1829
        memset(path, 0, PROM_SCRATCH_SIZE);
1830
        call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1831
 
1832
        /* get and store all properties */
1833
        prev_name = RELOC("");
1834
        sstart = (char *)RELOC(dt_string_start);
1835
        for (;;) {
1836
                if (call_prom("nextprop", 3, 1, node, prev_name,
1837
                              RELOC(pname)) != 1)
1838
                        break;
1839
 
1840
                /* skip "name" */
1841
                if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1842
                        prev_name = RELOC("name");
1843
                        continue;
1844
                }
1845
 
1846
                /* find string offset */
1847
                soff = dt_find_string(RELOC(pname));
1848
                if (soff == 0) {
1849
                        prom_printf("WARNING: Can't find string index for"
1850
                                    " <%s>, node %s\n", RELOC(pname), path);
1851
                        break;
1852
                }
1853
                prev_name = sstart + soff;
1854
 
1855
                /* get length */
1856
                l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1857
 
1858
                /* sanity checks */
1859
                if (l == PROM_ERROR)
1860
                        continue;
1861
                if (l > MAX_PROPERTY_LENGTH) {
1862
                        prom_printf("WARNING: ignoring large property ");
1863
                        /* It seems OF doesn't null-terminate the path :-( */
1864
                        prom_printf("[%s] ", path);
1865
                        prom_printf("%s length 0x%x\n", RELOC(pname), l);
1866
                        continue;
1867
                }
1868
 
1869
                /* push property head */
1870
                dt_push_token(OF_DT_PROP, mem_start, mem_end);
1871
                dt_push_token(l, mem_start, mem_end);
1872
                dt_push_token(soff, mem_start, mem_end);
1873
 
1874
                /* push property content */
1875
                valp = make_room(mem_start, mem_end, l, 4);
1876
                call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1877
                *mem_start = _ALIGN(*mem_start, 4);
1878
        }
1879
 
1880
        /* Add a "linux,phandle" property. */
1881
        soff = dt_find_string(RELOC("linux,phandle"));
1882
        if (soff == 0)
1883
                prom_printf("WARNING: Can't find string index for"
1884
                            " <linux-phandle> node %s\n", path);
1885
        else {
1886
                dt_push_token(OF_DT_PROP, mem_start, mem_end);
1887
                dt_push_token(4, mem_start, mem_end);
1888
                dt_push_token(soff, mem_start, mem_end);
1889
                valp = make_room(mem_start, mem_end, 4, 4);
1890
                *(u32 *)valp = node;
1891
        }
1892
 
1893
        /* do all our children */
1894
        child = call_prom("child", 1, 1, node);
1895
        while (child != 0) {
1896
                scan_dt_build_struct(child, mem_start, mem_end);
1897
                child = call_prom("peer", 1, 1, child);
1898
        }
1899
 
1900
        dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1901
}
1902
 
1903
static void __init flatten_device_tree(void)
1904
{
1905
        phandle root;
1906
        unsigned long mem_start, mem_end, room;
1907
        struct boot_param_header *hdr;
1908
        struct prom_t *_prom = &RELOC(prom);
1909
        char *namep;
1910
        u64 *rsvmap;
1911
 
1912
        /*
1913
         * Check how much room we have between alloc top & bottom (+/- a
1914
         * few pages), crop to 4Mb, as this is our "chuck" size
1915
         */
1916
        room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1917
        if (room > DEVTREE_CHUNK_SIZE)
1918
                room = DEVTREE_CHUNK_SIZE;
1919
        prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1920
 
1921
        /* Now try to claim that */
1922
        mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1923
        if (mem_start == 0)
1924
                prom_panic("Can't allocate initial device-tree chunk\n");
1925
        mem_end = RELOC(alloc_top);
1926
 
1927
        /* Get root of tree */
1928
        root = call_prom("peer", 1, 1, (phandle)0);
1929
        if (root == (phandle)0)
1930
                prom_panic ("couldn't get device tree root\n");
1931
 
1932
        /* Build header and make room for mem rsv map */
1933
        mem_start = _ALIGN(mem_start, 4);
1934
        hdr = make_room(&mem_start, &mem_end,
1935
                        sizeof(struct boot_param_header), 4);
1936
        RELOC(dt_header_start) = (unsigned long)hdr;
1937
        rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1938
 
1939
        /* Start of strings */
1940
        mem_start = PAGE_ALIGN(mem_start);
1941
        RELOC(dt_string_start) = mem_start;
1942
        mem_start += 4; /* hole */
1943
 
1944
        /* Add "linux,phandle" in there, we'll need it */
1945
        namep = make_room(&mem_start, &mem_end, 16, 1);
1946
        strcpy(namep, RELOC("linux,phandle"));
1947
        mem_start = (unsigned long)namep + strlen(namep) + 1;
1948
 
1949
        /* Build string array */
1950
        prom_printf("Building dt strings...\n");
1951
        scan_dt_build_strings(root, &mem_start, &mem_end);
1952
        RELOC(dt_string_end) = mem_start;
1953
 
1954
        /* Build structure */
1955
        mem_start = PAGE_ALIGN(mem_start);
1956
        RELOC(dt_struct_start) = mem_start;
1957
        prom_printf("Building dt structure...\n");
1958
        scan_dt_build_struct(root, &mem_start, &mem_end);
1959
        dt_push_token(OF_DT_END, &mem_start, &mem_end);
1960
        RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1961
 
1962
        /* Finish header */
1963
        hdr->boot_cpuid_phys = _prom->cpu;
1964
        hdr->magic = OF_DT_HEADER;
1965
        hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1966
        hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1967
        hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1968
        hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1969
        hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1970
        hdr->version = OF_DT_VERSION;
1971
        /* Version 16 is not backward compatible */
1972
        hdr->last_comp_version = 0x10;
1973
 
1974
        /* Copy the reserve map in */
1975
        memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1976
 
1977
#ifdef DEBUG_PROM
1978
        {
1979
                int i;
1980
                prom_printf("reserved memory map:\n");
1981
                for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1982
                        prom_printf("  %x - %x\n",
1983
                                    RELOC(mem_reserve_map)[i].base,
1984
                                    RELOC(mem_reserve_map)[i].size);
1985
        }
1986
#endif
1987
        /* Bump mem_reserve_cnt to cause further reservations to fail
1988
         * since it's too late.
1989
         */
1990
        RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1991
 
1992
        prom_printf("Device tree strings 0x%x -> 0x%x\n",
1993
                    RELOC(dt_string_start), RELOC(dt_string_end));
1994
        prom_printf("Device tree struct  0x%x -> 0x%x\n",
1995
                    RELOC(dt_struct_start), RELOC(dt_struct_end));
1996
 
1997
}
1998
 
1999
#ifdef CONFIG_PPC_MAPLE
2000
/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2001
 * The values are bad, and it doesn't even have the right number of cells. */
2002
static void __init fixup_device_tree_maple(void)
2003
{
2004
        phandle isa;
2005
        u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
2006
        u32 isa_ranges[6];
2007
        char *name;
2008
 
2009
        name = "/ht@0/isa@4";
2010
        isa = call_prom("finddevice", 1, 1, ADDR(name));
2011
        if (!PHANDLE_VALID(isa)) {
2012
                name = "/ht@0/isa@6";
2013
                isa = call_prom("finddevice", 1, 1, ADDR(name));
2014
                rloc = 0x01003000; /* IO space; PCI device = 6 */
2015
        }
2016
        if (!PHANDLE_VALID(isa))
2017
                return;
2018
 
2019
        if (prom_getproplen(isa, "ranges") != 12)
2020
                return;
2021
        if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2022
                == PROM_ERROR)
2023
                return;
2024
 
2025
        if (isa_ranges[0] != 0x1 ||
2026
                isa_ranges[1] != 0xf4000000 ||
2027
                isa_ranges[2] != 0x00010000)
2028
                return;
2029
 
2030
        prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
2031
 
2032
        isa_ranges[0] = 0x1;
2033
        isa_ranges[1] = 0x0;
2034
        isa_ranges[2] = rloc;
2035
        isa_ranges[3] = 0x0;
2036
        isa_ranges[4] = 0x0;
2037
        isa_ranges[5] = 0x00010000;
2038
        prom_setprop(isa, name, "ranges",
2039
                        isa_ranges, sizeof(isa_ranges));
2040
}
2041
#else
2042
#define fixup_device_tree_maple()
2043
#endif
2044
 
2045
#ifdef CONFIG_PPC_CHRP
2046
/*
2047
 * Pegasos and BriQ lacks the "ranges" property in the isa node
2048
 * Pegasos needs decimal IRQ 14/15, not hexadecimal
2049
 * Pegasos has the IDE configured in legacy mode, but advertised as native
2050
 */
2051
static void __init fixup_device_tree_chrp(void)
2052
{
2053
        phandle ph;
2054
        u32 prop[6];
2055
        u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
2056
        char *name;
2057
        int rc;
2058
 
2059
        name = "/pci@80000000/isa@c";
2060
        ph = call_prom("finddevice", 1, 1, ADDR(name));
2061
        if (!PHANDLE_VALID(ph)) {
2062
                name = "/pci@ff500000/isa@6";
2063
                ph = call_prom("finddevice", 1, 1, ADDR(name));
2064
                rloc = 0x01003000; /* IO space; PCI device = 6 */
2065
        }
2066
        if (PHANDLE_VALID(ph)) {
2067
                rc = prom_getproplen(ph, "ranges");
2068
                if (rc == 0 || rc == PROM_ERROR) {
2069
                        prom_printf("Fixing up missing ISA range on Pegasos...\n");
2070
 
2071
                        prop[0] = 0x1;
2072
                        prop[1] = 0x0;
2073
                        prop[2] = rloc;
2074
                        prop[3] = 0x0;
2075
                        prop[4] = 0x0;
2076
                        prop[5] = 0x00010000;
2077
                        prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2078
                }
2079
        }
2080
 
2081
        name = "/pci@80000000/ide@C,1";
2082
        ph = call_prom("finddevice", 1, 1, ADDR(name));
2083
        if (PHANDLE_VALID(ph)) {
2084
                prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2085
                prop[0] = 14;
2086
                prop[1] = 0x0;
2087
                prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2088
                prom_printf("Fixing up IDE class-code on Pegasos...\n");
2089
                rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2090
                if (rc == sizeof(u32)) {
2091
                        prop[0] &= ~0x5;
2092
                        prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2093
                }
2094
        }
2095
}
2096
#else
2097
#define fixup_device_tree_chrp()
2098
#endif
2099
 
2100
#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2101
static void __init fixup_device_tree_pmac(void)
2102
{
2103
        phandle u3, i2c, mpic;
2104
        u32 u3_rev;
2105
        u32 interrupts[2];
2106
        u32 parent;
2107
 
2108
        /* Some G5s have a missing interrupt definition, fix it up here */
2109
        u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2110
        if (!PHANDLE_VALID(u3))
2111
                return;
2112
        i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2113
        if (!PHANDLE_VALID(i2c))
2114
                return;
2115
        mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2116
        if (!PHANDLE_VALID(mpic))
2117
                return;
2118
 
2119
        /* check if proper rev of u3 */
2120
        if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2121
            == PROM_ERROR)
2122
                return;
2123
        if (u3_rev < 0x35 || u3_rev > 0x39)
2124
                return;
2125
        /* does it need fixup ? */
2126
        if (prom_getproplen(i2c, "interrupts") > 0)
2127
                return;
2128
 
2129
        prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2130
 
2131
        /* interrupt on this revision of u3 is number 0 and level */
2132
        interrupts[0] = 0;
2133
        interrupts[1] = 1;
2134
        prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2135
                     &interrupts, sizeof(interrupts));
2136
        parent = (u32)mpic;
2137
        prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2138
                     &parent, sizeof(parent));
2139
}
2140
#else
2141
#define fixup_device_tree_pmac()
2142
#endif
2143
 
2144
#ifdef CONFIG_PPC_EFIKA
2145
/* The current fw of the Efika has a device tree needs quite a few
2146
 * fixups to be compliant with the mpc52xx bindings. It's currently
2147
 * unknown if it will ever be compliant (come on bPlan ...) so we do fixups.
2148
 * NOTE that we (barely) tolerate it because the EFIKA was out before
2149
 * the bindings were finished, for any new boards -> RTFM ! */
2150
 
2151
struct subst_entry {
2152
        char *path;
2153
        char *property;
2154
        void *value;
2155
        int value_len;
2156
};
2157
 
2158
static void __init fixup_device_tree_efika(void)
2159
{
2160
        /* Substitution table */
2161
        #define prop_cstr(x) x, sizeof(x)
2162
        int prop_sound_irq[3] = { 2, 2, 0 };
2163
        int prop_bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2164
                                     3,4,0, 3,5,0, 3,6,0, 3,7,0,
2165
                                     3,8,0, 3,9,0, 3,10,0, 3,11,0,
2166
                                     3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2167
        struct subst_entry efika_subst_table[] = {
2168
                { "/",                  "device_type",  prop_cstr("efika") },
2169
                { "/builtin",           "device_type",  prop_cstr("soc") },
2170
                { "/builtin/ata",       "compatible",   prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
2171
                { "/builtin/bestcomm",  "compatible",   prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
2172
                { "/builtin/bestcomm",  "interrupts",   prop_bcomm_irq, sizeof(prop_bcomm_irq) },
2173
                { "/builtin/ethernet",  "compatible",   prop_cstr("mpc5200b-fec\0mpc5200-fec") },
2174
                { "/builtin/pic",       "compatible",   prop_cstr("mpc5200b-pic\0mpc5200-pic") },
2175
                { "/builtin/serial",    "compatible",   prop_cstr("mpc5200b-psc-uart\0mpc5200-psc-uart") },
2176
                { "/builtin/sound",     "compatible",   prop_cstr("mpc5200b-psc-ac97\0mpc5200-psc-ac97") },
2177
                { "/builtin/sound",     "interrupts",   prop_sound_irq, sizeof(prop_sound_irq) },
2178
                { "/builtin/sram",      "compatible",   prop_cstr("mpc5200b-sram\0mpc5200-sram") },
2179
                { "/builtin/sram",      "device_type",  prop_cstr("sram") },
2180
                {}
2181
        };
2182
        #undef prop_cstr
2183
 
2184
        /* Vars */
2185
        u32 node;
2186
        char prop[64];
2187
        int rv, i;
2188
 
2189
        /* Check if we're really running on a EFIKA */
2190
        node = call_prom("finddevice", 1, 1, ADDR("/"));
2191
        if (!PHANDLE_VALID(node))
2192
                return;
2193
 
2194
        rv = prom_getprop(node, "model", prop, sizeof(prop));
2195
        if (rv == PROM_ERROR)
2196
                return;
2197
        if (strcmp(prop, "EFIKA5K2"))
2198
                return;
2199
 
2200
        prom_printf("Applying EFIKA device tree fixups\n");
2201
 
2202
        /* Process substitution table */
2203
        for (i=0; efika_subst_table[i].path; i++) {
2204
                struct subst_entry *se = &efika_subst_table[i];
2205
 
2206
                node = call_prom("finddevice", 1, 1, ADDR(se->path));
2207
                if (!PHANDLE_VALID(node)) {
2208
                        prom_printf("fixup_device_tree_efika: ",
2209
                                "skipped entry %x - not found\n", i);
2210
                        continue;
2211
                }
2212
 
2213
                rv = prom_setprop(node, se->path, se->property,
2214
                                        se->value, se->value_len );
2215
                if (rv == PROM_ERROR)
2216
                        prom_printf("fixup_device_tree_efika: ",
2217
                                "skipped entry %x - setprop error\n", i);
2218
        }
2219
 
2220
        /* Make sure ethernet mdio bus node exists */
2221
        node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2222
        if (!PHANDLE_VALID(node)) {
2223
                prom_printf("Adding Ethernet MDIO node\n");
2224
                call_prom("interpret", 1, 1,
2225
                        " s\" /builtin\" find-device"
2226
                        " new-device"
2227
                                " 1 encode-int s\" #address-cells\" property"
2228
                                " 0 encode-int s\" #size-cells\" property"
2229
                                " s\" mdio\" 2dup device-name device-type"
2230
                                " s\" mpc5200b-fec-phy\" encode-string"
2231
                                " s\" compatible\" property"
2232
                                " 0xf0003000 0x400 reg"
2233
                                " 0x2 encode-int"
2234
                                " 0x5 encode-int encode+"
2235
                                " 0x3 encode-int encode+"
2236
                                " s\" interrupts\" property"
2237
                        " finish-device");
2238
        };
2239
 
2240
        /* Make sure ethernet phy device node exist */
2241
        node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio/ethernet-phy"));
2242
        if (!PHANDLE_VALID(node)) {
2243
                prom_printf("Adding Ethernet PHY node\n");
2244
                call_prom("interpret", 1, 1,
2245
                        " s\" /builtin/mdio\" find-device"
2246
                        " new-device"
2247
                                " s\" ethernet-phy\" device-name"
2248
                                " 0x10 encode-int s\" reg\" property"
2249
                                " my-self"
2250
                                " ihandle>phandle"
2251
                        " finish-device"
2252
                        " s\" /builtin/ethernet\" find-device"
2253
                                " encode-int"
2254
                                " s\" phy-handle\" property"
2255
                        " device-end");
2256
        }
2257
 
2258
}
2259
#else
2260
#define fixup_device_tree_efika()
2261
#endif
2262
 
2263
static void __init fixup_device_tree(void)
2264
{
2265
        fixup_device_tree_maple();
2266
        fixup_device_tree_chrp();
2267
        fixup_device_tree_pmac();
2268
        fixup_device_tree_efika();
2269
}
2270
 
2271
static void __init prom_find_boot_cpu(void)
2272
{
2273
        struct prom_t *_prom = &RELOC(prom);
2274
        u32 getprop_rval;
2275
        ihandle prom_cpu;
2276
        phandle cpu_pkg;
2277
 
2278
        _prom->cpu = 0;
2279
        if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
2280
                return;
2281
 
2282
        cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2283
 
2284
        prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2285
        _prom->cpu = getprop_rval;
2286
 
2287
        prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2288
}
2289
 
2290
static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2291
{
2292
#ifdef CONFIG_BLK_DEV_INITRD
2293
        struct prom_t *_prom = &RELOC(prom);
2294
 
2295
        if (r3 && r4 && r4 != 0xdeadbeef) {
2296
                unsigned long val;
2297
 
2298
                RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
2299
                RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2300
 
2301
                val = RELOC(prom_initrd_start);
2302
                prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2303
                             &val, sizeof(val));
2304
                val = RELOC(prom_initrd_end);
2305
                prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2306
                             &val, sizeof(val));
2307
 
2308
                reserve_mem(RELOC(prom_initrd_start),
2309
                            RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2310
 
2311
                prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2312
                prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2313
        }
2314
#endif /* CONFIG_BLK_DEV_INITRD */
2315
}
2316
 
2317
/*
2318
 * We enter here early on, when the Open Firmware prom is still
2319
 * handling exceptions and the MMU hash table for us.
2320
 */
2321
 
2322
unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2323
                               unsigned long pp,
2324
                               unsigned long r6, unsigned long r7)
2325
{
2326
        struct prom_t *_prom;
2327
        unsigned long hdr;
2328
        unsigned long offset = reloc_offset();
2329
 
2330
#ifdef CONFIG_PPC32
2331
        reloc_got2(offset);
2332
#endif
2333
 
2334
        _prom = &RELOC(prom);
2335
 
2336
        /*
2337
         * First zero the BSS
2338
         */
2339
        memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2340
 
2341
        /*
2342
         * Init interface to Open Firmware, get some node references,
2343
         * like /chosen
2344
         */
2345
        prom_init_client_services(pp);
2346
 
2347
        /*
2348
         * See if this OF is old enough that we need to do explicit maps
2349
         * and other workarounds
2350
         */
2351
        prom_find_mmu();
2352
 
2353
        /*
2354
         * Init prom stdout device
2355
         */
2356
        prom_init_stdout();
2357
 
2358
        /*
2359
         * Get default machine type. At this point, we do not differentiate
2360
         * between pSeries SMP and pSeries LPAR
2361
         */
2362
        RELOC(of_platform) = prom_find_machine_type();
2363
 
2364
        /* Bail if this is a kdump kernel. */
2365
        if (PHYSICAL_START > 0)
2366
                prom_panic("Error: You can't boot a kdump kernel from OF!\n");
2367
 
2368
        /*
2369
         * Check for an initrd
2370
         */
2371
        prom_check_initrd(r3, r4);
2372
 
2373
#ifdef CONFIG_PPC_PSERIES
2374
        /*
2375
         * On pSeries, inform the firmware about our capabilities
2376
         */
2377
        if (RELOC(of_platform) == PLATFORM_PSERIES ||
2378
            RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
2379
                prom_send_capabilities();
2380
#endif
2381
 
2382
        /*
2383
         * Copy the CPU hold code
2384
         */
2385
        if (RELOC(of_platform) != PLATFORM_POWERMAC)
2386
                copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
2387
 
2388
        /*
2389
         * Do early parsing of command line
2390
         */
2391
        early_cmdline_parse();
2392
 
2393
        /*
2394
         * Initialize memory management within prom_init
2395
         */
2396
        prom_init_mem();
2397
 
2398
        /*
2399
         * Determine which cpu is actually running right _now_
2400
         */
2401
        prom_find_boot_cpu();
2402
 
2403
        /*
2404
         * Initialize display devices
2405
         */
2406
        prom_check_displays();
2407
 
2408
#ifdef CONFIG_PPC64
2409
        /*
2410
         * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2411
         * that uses the allocator, we need to make sure we get the top of memory
2412
         * available for us here...
2413
         */
2414
        if (RELOC(of_platform) == PLATFORM_PSERIES)
2415
                prom_initialize_tce_table();
2416
#endif
2417
 
2418
        /*
2419
         * On non-powermacs, try to instantiate RTAS and puts all CPUs
2420
         * in spin-loops. PowerMacs don't have a working RTAS and use
2421
         * a different way to spin CPUs
2422
         */
2423
        if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2424
                prom_instantiate_rtas();
2425
                prom_hold_cpus();
2426
        }
2427
 
2428
        /*
2429
         * Fill in some infos for use by the kernel later on
2430
         */
2431
#ifdef CONFIG_PPC64
2432
        if (RELOC(prom_iommu_off))
2433
                prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2434
                             NULL, 0);
2435
 
2436
        if (RELOC(prom_iommu_force_on))
2437
                prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2438
                             NULL, 0);
2439
 
2440
        if (RELOC(prom_tce_alloc_start)) {
2441
                prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
2442
                             &RELOC(prom_tce_alloc_start),
2443
                             sizeof(prom_tce_alloc_start));
2444
                prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
2445
                             &RELOC(prom_tce_alloc_end),
2446
                             sizeof(prom_tce_alloc_end));
2447
        }
2448
#endif
2449
 
2450
        /*
2451
         * Fixup any known bugs in the device-tree
2452
         */
2453
        fixup_device_tree();
2454
 
2455
        /*
2456
         * Now finally create the flattened device-tree
2457
         */
2458
        prom_printf("copying OF device tree ...\n");
2459
        flatten_device_tree();
2460
 
2461
        /*
2462
         * in case stdin is USB and still active on IBM machines...
2463
         * Unfortunately quiesce crashes on some powermacs if we have
2464
         * closed stdin already (in particular the powerbook 101).
2465
         */
2466
        if (RELOC(of_platform) != PLATFORM_POWERMAC)
2467
                prom_close_stdin();
2468
 
2469
        /*
2470
         * Call OF "quiesce" method to shut down pending DMA's from
2471
         * devices etc...
2472
         */
2473
        prom_printf("Calling quiesce ...\n");
2474
        call_prom("quiesce", 0, 0);
2475
 
2476
        /*
2477
         * And finally, call the kernel passing it the flattened device
2478
         * tree and NULL as r5, thus triggering the new entry point which
2479
         * is common to us and kexec
2480
         */
2481
        hdr = RELOC(dt_header_start);
2482
        prom_printf("returning from prom_init\n");
2483
        prom_debug("->dt_header_start=0x%x\n", hdr);
2484
 
2485
#ifdef CONFIG_PPC32
2486
        reloc_got2(-offset);
2487
#endif
2488
 
2489
        __start(hdr, KERNELBASE + offset, 0);
2490
 
2491
        return 0;
2492
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.