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