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