0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #undef DEBUG_PROM
0013
0014
0015 #define __NO_FORTIFY
0016
0017 #include <linux/stdarg.h>
0018 #include <linux/kernel.h>
0019 #include <linux/string.h>
0020 #include <linux/init.h>
0021 #include <linux/threads.h>
0022 #include <linux/spinlock.h>
0023 #include <linux/types.h>
0024 #include <linux/pci.h>
0025 #include <linux/proc_fs.h>
0026 #include <linux/delay.h>
0027 #include <linux/initrd.h>
0028 #include <linux/bitops.h>
0029 #include <linux/pgtable.h>
0030 #include <linux/printk.h>
0031 #include <linux/of.h>
0032 #include <linux/of_fdt.h>
0033 #include <asm/prom.h>
0034 #include <asm/rtas.h>
0035 #include <asm/page.h>
0036 #include <asm/processor.h>
0037 #include <asm/interrupt.h>
0038 #include <asm/irq.h>
0039 #include <asm/io.h>
0040 #include <asm/smp.h>
0041 #include <asm/mmu.h>
0042 #include <asm/iommu.h>
0043 #include <asm/btext.h>
0044 #include <asm/sections.h>
0045 #include <asm/setup.h>
0046 #include <asm/asm-prototypes.h>
0047 #include <asm/ultravisor-api.h>
0048
0049 #include <linux/linux_logo.h>
0050
0051
0052 #define __prombss __section(".bss.prominit")
0053
0054
0055
0056
0057 #define DEVTREE_CHUNK_SIZE 0x100000
0058
0059
0060
0061
0062
0063
0064
0065
0066 #define MEM_RESERVE_MAP_SIZE 8
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 #define ADDR(x) (u32)(unsigned long)(x)
0088
0089 #ifdef CONFIG_PPC64
0090 #define OF_WORKAROUNDS 0
0091 #else
0092 #define OF_WORKAROUNDS of_workarounds
0093 static int of_workarounds __prombss;
0094 #endif
0095
0096 #define OF_WA_CLAIM 1
0097 #define OF_WA_LONGTRAIL 2
0098
0099 #define PROM_BUG() do { \
0100 prom_printf("kernel BUG at %s line 0x%x!\n", \
0101 __FILE__, __LINE__); \
0102 __builtin_trap(); \
0103 } while (0)
0104
0105 #ifdef DEBUG_PROM
0106 #define prom_debug(x...) prom_printf(x)
0107 #else
0108 #define prom_debug(x...) do { } while (0)
0109 #endif
0110
0111
0112 typedef u32 prom_arg_t;
0113
0114 struct prom_args {
0115 __be32 service;
0116 __be32 nargs;
0117 __be32 nret;
0118 __be32 args[10];
0119 };
0120
0121 struct prom_t {
0122 ihandle root;
0123 phandle chosen;
0124 int cpu;
0125 ihandle stdout;
0126 ihandle mmumap;
0127 ihandle memory;
0128 };
0129
0130 struct mem_map_entry {
0131 __be64 base;
0132 __be64 size;
0133 };
0134
0135 typedef __be32 cell_t;
0136
0137 extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
0138 unsigned long r6, unsigned long r7, unsigned long r8,
0139 unsigned long r9);
0140
0141 #ifdef CONFIG_PPC64
0142 extern int enter_prom(struct prom_args *args, unsigned long entry);
0143 #else
0144 static inline int enter_prom(struct prom_args *args, unsigned long entry)
0145 {
0146 return ((int (*)(struct prom_args *))entry)(args);
0147 }
0148 #endif
0149
0150 extern void copy_and_flush(unsigned long dest, unsigned long src,
0151 unsigned long size, unsigned long offset);
0152
0153
0154 static struct prom_t __prombss prom;
0155
0156 static unsigned long __prombss prom_entry;
0157
0158 static char __prombss of_stdout_device[256];
0159 static char __prombss prom_scratch[256];
0160
0161 static unsigned long __prombss dt_header_start;
0162 static unsigned long __prombss dt_struct_start, dt_struct_end;
0163 static unsigned long __prombss dt_string_start, dt_string_end;
0164
0165 static unsigned long __prombss prom_initrd_start, prom_initrd_end;
0166
0167 #ifdef CONFIG_PPC64
0168 static int __prombss prom_iommu_force_on;
0169 static int __prombss prom_iommu_off;
0170 static unsigned long __prombss prom_tce_alloc_start;
0171 static unsigned long __prombss prom_tce_alloc_end;
0172 #endif
0173
0174 #ifdef CONFIG_PPC_PSERIES
0175 static bool __prombss prom_radix_disable;
0176 static bool __prombss prom_radix_gtse_disable;
0177 static bool __prombss prom_xive_disable;
0178 #endif
0179
0180 #ifdef CONFIG_PPC_SVM
0181 static bool __prombss prom_svm_enable;
0182 #endif
0183
0184 struct platform_support {
0185 bool hash_mmu;
0186 bool radix_mmu;
0187 bool radix_gtse;
0188 bool xive;
0189 };
0190
0191
0192
0193
0194
0195 #define PLATFORM_PSERIES 0x0100
0196 #define PLATFORM_PSERIES_LPAR 0x0101
0197 #define PLATFORM_LPAR 0x0001
0198 #define PLATFORM_POWERMAC 0x0400
0199 #define PLATFORM_GENERIC 0x0500
0200
0201 static int __prombss of_platform;
0202
0203 static char __prombss prom_cmd_line[COMMAND_LINE_SIZE];
0204
0205 static unsigned long __prombss prom_memory_limit;
0206
0207 static unsigned long __prombss alloc_top;
0208 static unsigned long __prombss alloc_top_high;
0209 static unsigned long __prombss alloc_bottom;
0210 static unsigned long __prombss rmo_top;
0211 static unsigned long __prombss ram_top;
0212
0213 static struct mem_map_entry __prombss mem_reserve_map[MEM_RESERVE_MAP_SIZE];
0214 static int __prombss mem_reserve_cnt;
0215
0216 static cell_t __prombss regbuf[1024];
0217
0218 static bool __prombss rtas_has_query_cpu_stopped;
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 #define PROM_ERROR (-1u)
0229 #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
0230 #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
0231
0232
0233
0234 static int __init prom_strcmp(const char *cs, const char *ct)
0235 {
0236 unsigned char c1, c2;
0237
0238 while (1) {
0239 c1 = *cs++;
0240 c2 = *ct++;
0241 if (c1 != c2)
0242 return c1 < c2 ? -1 : 1;
0243 if (!c1)
0244 break;
0245 }
0246 return 0;
0247 }
0248
0249 static ssize_t __init prom_strscpy_pad(char *dest, const char *src, size_t n)
0250 {
0251 ssize_t rc;
0252 size_t i;
0253
0254 if (n == 0 || n > INT_MAX)
0255 return -E2BIG;
0256
0257
0258 for (i = 0; i < n && src[i] != '\0'; i++)
0259 dest[i] = src[i];
0260
0261 rc = i;
0262
0263
0264 if (rc == n) {
0265
0266 i--;
0267 rc = -E2BIG;
0268 }
0269
0270 for (; i < n; i++)
0271 dest[i] = '\0';
0272
0273 return rc;
0274 }
0275
0276 static int __init prom_strncmp(const char *cs, const char *ct, size_t count)
0277 {
0278 unsigned char c1, c2;
0279
0280 while (count) {
0281 c1 = *cs++;
0282 c2 = *ct++;
0283 if (c1 != c2)
0284 return c1 < c2 ? -1 : 1;
0285 if (!c1)
0286 break;
0287 count--;
0288 }
0289 return 0;
0290 }
0291
0292 static size_t __init prom_strlen(const char *s)
0293 {
0294 const char *sc;
0295
0296 for (sc = s; *sc != '\0'; ++sc)
0297 ;
0298 return sc - s;
0299 }
0300
0301 static int __init prom_memcmp(const void *cs, const void *ct, size_t count)
0302 {
0303 const unsigned char *su1, *su2;
0304 int res = 0;
0305
0306 for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
0307 if ((res = *su1 - *su2) != 0)
0308 break;
0309 return res;
0310 }
0311
0312 static char __init *prom_strstr(const char *s1, const char *s2)
0313 {
0314 size_t l1, l2;
0315
0316 l2 = prom_strlen(s2);
0317 if (!l2)
0318 return (char *)s1;
0319 l1 = prom_strlen(s1);
0320 while (l1 >= l2) {
0321 l1--;
0322 if (!prom_memcmp(s1, s2, l2))
0323 return (char *)s1;
0324 s1++;
0325 }
0326 return NULL;
0327 }
0328
0329 static size_t __init prom_strlcat(char *dest, const char *src, size_t count)
0330 {
0331 size_t dsize = prom_strlen(dest);
0332 size_t len = prom_strlen(src);
0333 size_t res = dsize + len;
0334
0335
0336 if (dsize >= count)
0337 return count;
0338
0339 dest += dsize;
0340 count -= dsize;
0341 if (len >= count)
0342 len = count-1;
0343 memcpy(dest, src, len);
0344 dest[len] = 0;
0345 return res;
0346
0347 }
0348
0349 #ifdef CONFIG_PPC_PSERIES
0350 static int __init prom_strtobool(const char *s, bool *res)
0351 {
0352 if (!s)
0353 return -EINVAL;
0354
0355 switch (s[0]) {
0356 case 'y':
0357 case 'Y':
0358 case '1':
0359 *res = true;
0360 return 0;
0361 case 'n':
0362 case 'N':
0363 case '0':
0364 *res = false;
0365 return 0;
0366 case 'o':
0367 case 'O':
0368 switch (s[1]) {
0369 case 'n':
0370 case 'N':
0371 *res = true;
0372 return 0;
0373 case 'f':
0374 case 'F':
0375 *res = false;
0376 return 0;
0377 default:
0378 break;
0379 }
0380 break;
0381 default:
0382 break;
0383 }
0384
0385 return -EINVAL;
0386 }
0387 #endif
0388
0389
0390
0391
0392
0393 static int __init call_prom(const char *service, int nargs, int nret, ...)
0394 {
0395 int i;
0396 struct prom_args args;
0397 va_list list;
0398
0399 args.service = cpu_to_be32(ADDR(service));
0400 args.nargs = cpu_to_be32(nargs);
0401 args.nret = cpu_to_be32(nret);
0402
0403 va_start(list, nret);
0404 for (i = 0; i < nargs; i++)
0405 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
0406 va_end(list);
0407
0408 for (i = 0; i < nret; i++)
0409 args.args[nargs+i] = 0;
0410
0411 if (enter_prom(&args, prom_entry) < 0)
0412 return PROM_ERROR;
0413
0414 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
0415 }
0416
0417 static int __init call_prom_ret(const char *service, int nargs, int nret,
0418 prom_arg_t *rets, ...)
0419 {
0420 int i;
0421 struct prom_args args;
0422 va_list list;
0423
0424 args.service = cpu_to_be32(ADDR(service));
0425 args.nargs = cpu_to_be32(nargs);
0426 args.nret = cpu_to_be32(nret);
0427
0428 va_start(list, rets);
0429 for (i = 0; i < nargs; i++)
0430 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
0431 va_end(list);
0432
0433 for (i = 0; i < nret; i++)
0434 args.args[nargs+i] = 0;
0435
0436 if (enter_prom(&args, prom_entry) < 0)
0437 return PROM_ERROR;
0438
0439 if (rets != NULL)
0440 for (i = 1; i < nret; ++i)
0441 rets[i-1] = be32_to_cpu(args.args[nargs+i]);
0442
0443 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
0444 }
0445
0446
0447 static void __init prom_print(const char *msg)
0448 {
0449 const char *p, *q;
0450
0451 if (prom.stdout == 0)
0452 return;
0453
0454 for (p = msg; *p != 0; p = q) {
0455 for (q = p; *q != 0 && *q != '\n'; ++q)
0456 ;
0457 if (q > p)
0458 call_prom("write", 3, 1, prom.stdout, p, q - p);
0459 if (*q == 0)
0460 break;
0461 ++q;
0462 call_prom("write", 3, 1, prom.stdout, ADDR("\r\n"), 2);
0463 }
0464 }
0465
0466
0467
0468
0469
0470
0471 static void __init prom_print_hex(unsigned long val)
0472 {
0473 int i, nibbles = sizeof(val)*2;
0474 char buf[sizeof(val)*2+1];
0475
0476 for (i = nibbles-1; i >= 0; i--) {
0477 buf[i] = (val & 0xf) + '0';
0478 if (buf[i] > '9')
0479 buf[i] += ('a'-'0'-10);
0480 val >>= 4;
0481 }
0482 buf[nibbles] = '\0';
0483 call_prom("write", 3, 1, prom.stdout, buf, nibbles);
0484 }
0485
0486
0487 #define UL_DIGITS 21
0488 static void __init prom_print_dec(unsigned long val)
0489 {
0490 int i, size;
0491 char buf[UL_DIGITS+1];
0492
0493 for (i = UL_DIGITS-1; i >= 0; i--) {
0494 buf[i] = (val % 10) + '0';
0495 val = val/10;
0496 if (val == 0)
0497 break;
0498 }
0499
0500 size = UL_DIGITS - i;
0501 call_prom("write", 3, 1, prom.stdout, buf+i, size);
0502 }
0503
0504 __printf(1, 2)
0505 static void __init prom_printf(const char *format, ...)
0506 {
0507 const char *p, *q, *s;
0508 va_list args;
0509 unsigned long v;
0510 long vs;
0511 int n = 0;
0512
0513 va_start(args, format);
0514 for (p = format; *p != 0; p = q) {
0515 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
0516 ;
0517 if (q > p)
0518 call_prom("write", 3, 1, prom.stdout, p, q - p);
0519 if (*q == 0)
0520 break;
0521 if (*q == '\n') {
0522 ++q;
0523 call_prom("write", 3, 1, prom.stdout,
0524 ADDR("\r\n"), 2);
0525 continue;
0526 }
0527 ++q;
0528 if (*q == 0)
0529 break;
0530 while (*q == 'l') {
0531 ++q;
0532 ++n;
0533 }
0534 switch (*q) {
0535 case 's':
0536 ++q;
0537 s = va_arg(args, const char *);
0538 prom_print(s);
0539 break;
0540 case 'x':
0541 ++q;
0542 switch (n) {
0543 case 0:
0544 v = va_arg(args, unsigned int);
0545 break;
0546 case 1:
0547 v = va_arg(args, unsigned long);
0548 break;
0549 case 2:
0550 default:
0551 v = va_arg(args, unsigned long long);
0552 break;
0553 }
0554 prom_print_hex(v);
0555 break;
0556 case 'u':
0557 ++q;
0558 switch (n) {
0559 case 0:
0560 v = va_arg(args, unsigned int);
0561 break;
0562 case 1:
0563 v = va_arg(args, unsigned long);
0564 break;
0565 case 2:
0566 default:
0567 v = va_arg(args, unsigned long long);
0568 break;
0569 }
0570 prom_print_dec(v);
0571 break;
0572 case 'd':
0573 ++q;
0574 switch (n) {
0575 case 0:
0576 vs = va_arg(args, int);
0577 break;
0578 case 1:
0579 vs = va_arg(args, long);
0580 break;
0581 case 2:
0582 default:
0583 vs = va_arg(args, long long);
0584 break;
0585 }
0586 if (vs < 0) {
0587 prom_print("-");
0588 vs = -vs;
0589 }
0590 prom_print_dec(vs);
0591 break;
0592 }
0593 }
0594 va_end(args);
0595 }
0596
0597
0598 static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
0599 unsigned long align)
0600 {
0601
0602 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
0603
0604
0605
0606
0607 int ret;
0608 prom_arg_t result;
0609
0610 ret = call_prom_ret("call-method", 5, 2, &result,
0611 ADDR("claim"), prom.memory,
0612 align, size, virt);
0613 if (ret != 0 || result == -1)
0614 return -1;
0615 ret = call_prom_ret("call-method", 5, 2, &result,
0616 ADDR("claim"), prom.mmumap,
0617 align, size, virt);
0618 if (ret != 0) {
0619 call_prom("call-method", 4, 1, ADDR("release"),
0620 prom.memory, size, virt);
0621 return -1;
0622 }
0623
0624 call_prom("call-method", 6, 1,
0625 ADDR("map"), prom.mmumap, 0x12, size, virt, virt);
0626 return virt;
0627 }
0628 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
0629 (prom_arg_t)align);
0630 }
0631
0632 static void __init __attribute__((noreturn)) prom_panic(const char *reason)
0633 {
0634 prom_print(reason);
0635
0636
0637 if (of_platform == PLATFORM_POWERMAC)
0638 asm("trap\n");
0639
0640
0641 call_prom("exit", 0, 0);
0642
0643 for (;;)
0644 ;
0645 }
0646
0647
0648 static int __init prom_next_node(phandle *nodep)
0649 {
0650 phandle node;
0651
0652 if ((node = *nodep) != 0
0653 && (*nodep = call_prom("child", 1, 1, node)) != 0)
0654 return 1;
0655 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
0656 return 1;
0657 for (;;) {
0658 if ((node = call_prom("parent", 1, 1, node)) == 0)
0659 return 0;
0660 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
0661 return 1;
0662 }
0663 }
0664
0665 static inline int __init prom_getprop(phandle node, const char *pname,
0666 void *value, size_t valuelen)
0667 {
0668 return call_prom("getprop", 4, 1, node, ADDR(pname),
0669 (u32)(unsigned long) value, (u32) valuelen);
0670 }
0671
0672 static inline int __init prom_getproplen(phandle node, const char *pname)
0673 {
0674 return call_prom("getproplen", 2, 1, node, ADDR(pname));
0675 }
0676
0677 static void __init add_string(char **str, const char *q)
0678 {
0679 char *p = *str;
0680
0681 while (*q)
0682 *p++ = *q++;
0683 *p++ = ' ';
0684 *str = p;
0685 }
0686
0687 static char *__init tohex(unsigned int x)
0688 {
0689 static const char digits[] __initconst = "0123456789abcdef";
0690 static char result[9] __prombss;
0691 int i;
0692
0693 result[8] = 0;
0694 i = 8;
0695 do {
0696 --i;
0697 result[i] = digits[x & 0xf];
0698 x >>= 4;
0699 } while (x != 0 && i > 0);
0700 return &result[i];
0701 }
0702
0703 static int __init prom_setprop(phandle node, const char *nodename,
0704 const char *pname, void *value, size_t valuelen)
0705 {
0706 char cmd[256], *p;
0707
0708 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
0709 return call_prom("setprop", 4, 1, node, ADDR(pname),
0710 (u32)(unsigned long) value, (u32) valuelen);
0711
0712
0713 p = cmd;
0714 add_string(&p, "dev");
0715 add_string(&p, nodename);
0716 add_string(&p, tohex((u32)(unsigned long) value));
0717 add_string(&p, tohex(valuelen));
0718 add_string(&p, tohex(ADDR(pname)));
0719 add_string(&p, tohex(prom_strlen(pname)));
0720 add_string(&p, "property");
0721 *p = 0;
0722 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
0723 }
0724
0725
0726 #define prom_isxdigit(c) \
0727 (('0' <= (c) && (c) <= '9') || ('a' <= (c) && (c) <= 'f') || ('A' <= (c) && (c) <= 'F'))
0728
0729 #define prom_isdigit(c) ('0' <= (c) && (c) <= '9')
0730 #define prom_islower(c) ('a' <= (c) && (c) <= 'z')
0731 #define prom_toupper(c) (prom_islower(c) ? ((c) - 'a' + 'A') : (c))
0732
0733 static unsigned long __init prom_strtoul(const char *cp, const char **endp)
0734 {
0735 unsigned long result = 0, base = 10, value;
0736
0737 if (*cp == '0') {
0738 base = 8;
0739 cp++;
0740 if (prom_toupper(*cp) == 'X') {
0741 cp++;
0742 base = 16;
0743 }
0744 }
0745
0746 while (prom_isxdigit(*cp) &&
0747 (value = prom_isdigit(*cp) ? *cp - '0' : prom_toupper(*cp) - 'A' + 10) < base) {
0748 result = result * base + value;
0749 cp++;
0750 }
0751
0752 if (endp)
0753 *endp = cp;
0754
0755 return result;
0756 }
0757
0758 static unsigned long __init prom_memparse(const char *ptr, const char **retptr)
0759 {
0760 unsigned long ret = prom_strtoul(ptr, retptr);
0761 int shift = 0;
0762
0763
0764
0765
0766
0767
0768 if ('G' == **retptr || 'g' == **retptr)
0769 shift = 30;
0770
0771 if ('M' == **retptr || 'm' == **retptr)
0772 shift = 20;
0773
0774 if ('K' == **retptr || 'k' == **retptr)
0775 shift = 10;
0776
0777 if (shift) {
0778 ret <<= shift;
0779 (*retptr)++;
0780 }
0781
0782 return ret;
0783 }
0784
0785
0786
0787
0788
0789 static void __init early_cmdline_parse(void)
0790 {
0791 const char *opt;
0792
0793 char *p;
0794 int l = 0;
0795
0796 prom_cmd_line[0] = 0;
0797 p = prom_cmd_line;
0798
0799 if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && (long)prom.chosen > 0)
0800 l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
0801
0802 if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || l <= 0 || p[0] == '\0')
0803 prom_strlcat(prom_cmd_line, " " CONFIG_CMDLINE,
0804 sizeof(prom_cmd_line));
0805
0806 prom_printf("command line: %s\n", prom_cmd_line);
0807
0808 #ifdef CONFIG_PPC64
0809 opt = prom_strstr(prom_cmd_line, "iommu=");
0810 if (opt) {
0811 prom_printf("iommu opt is: %s\n", opt);
0812 opt += 6;
0813 while (*opt && *opt == ' ')
0814 opt++;
0815 if (!prom_strncmp(opt, "off", 3))
0816 prom_iommu_off = 1;
0817 else if (!prom_strncmp(opt, "force", 5))
0818 prom_iommu_force_on = 1;
0819 }
0820 #endif
0821 opt = prom_strstr(prom_cmd_line, "mem=");
0822 if (opt) {
0823 opt += 4;
0824 prom_memory_limit = prom_memparse(opt, (const char **)&opt);
0825 #ifdef CONFIG_PPC64
0826
0827 prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
0828 #endif
0829 }
0830
0831 #ifdef CONFIG_PPC_PSERIES
0832 prom_radix_disable = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
0833 opt = prom_strstr(prom_cmd_line, "disable_radix");
0834 if (opt) {
0835 opt += 13;
0836 if (*opt && *opt == '=') {
0837 bool val;
0838
0839 if (prom_strtobool(++opt, &val))
0840 prom_radix_disable = false;
0841 else
0842 prom_radix_disable = val;
0843 } else
0844 prom_radix_disable = true;
0845 }
0846 if (prom_radix_disable)
0847 prom_debug("Radix disabled from cmdline\n");
0848
0849 opt = prom_strstr(prom_cmd_line, "radix_hcall_invalidate=on");
0850 if (opt) {
0851 prom_radix_gtse_disable = true;
0852 prom_debug("Radix GTSE disabled from cmdline\n");
0853 }
0854
0855 opt = prom_strstr(prom_cmd_line, "xive=off");
0856 if (opt) {
0857 prom_xive_disable = true;
0858 prom_debug("XIVE disabled from cmdline\n");
0859 }
0860 #endif
0861
0862 #ifdef CONFIG_PPC_SVM
0863 opt = prom_strstr(prom_cmd_line, "svm=");
0864 if (opt) {
0865 bool val;
0866
0867 opt += sizeof("svm=") - 1;
0868 if (!prom_strtobool(opt, &val))
0869 prom_svm_enable = val;
0870 }
0871 #endif
0872 }
0873
0874 #ifdef CONFIG_PPC_PSERIES
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884 #define NUM_VECTORS(n) ((n) - 1)
0885
0886
0887
0888
0889
0890 #define VECTOR_LENGTH(n) (1 + (n) - 2)
0891
0892 struct option_vector1 {
0893 u8 byte1;
0894 u8 arch_versions;
0895 u8 arch_versions3;
0896 } __packed;
0897
0898 struct option_vector2 {
0899 u8 byte1;
0900 __be16 reserved;
0901 __be32 real_base;
0902 __be32 real_size;
0903 __be32 virt_base;
0904 __be32 virt_size;
0905 __be32 load_base;
0906 __be32 min_rma;
0907 __be32 min_load;
0908 u8 min_rma_percent;
0909 u8 max_pft_size;
0910 } __packed;
0911
0912 struct option_vector3 {
0913 u8 byte1;
0914 u8 byte2;
0915 } __packed;
0916
0917 struct option_vector4 {
0918 u8 byte1;
0919 u8 min_vp_cap;
0920 } __packed;
0921
0922 struct option_vector5 {
0923 u8 byte1;
0924 u8 byte2;
0925 u8 byte3;
0926 u8 cmo;
0927 u8 associativity;
0928 u8 bin_opts;
0929 u8 micro_checkpoint;
0930 u8 reserved0;
0931 __be32 max_cpus;
0932 __be16 papr_level;
0933 __be16 reserved1;
0934 u8 platform_facilities;
0935 u8 reserved2;
0936 __be16 reserved3;
0937 u8 subprocessors;
0938 u8 byte22;
0939 u8 intarch;
0940 u8 mmu;
0941 u8 hash_ext;
0942 u8 radix_ext;
0943 } __packed;
0944
0945 struct option_vector6 {
0946 u8 reserved;
0947 u8 secondary_pteg;
0948 u8 os_name;
0949 } __packed;
0950
0951 struct option_vector7 {
0952 u8 os_id[256];
0953 } __packed;
0954
0955 struct ibm_arch_vec {
0956 struct { u32 mask, val; } pvrs[14];
0957
0958 u8 num_vectors;
0959
0960 u8 vec1_len;
0961 struct option_vector1 vec1;
0962
0963 u8 vec2_len;
0964 struct option_vector2 vec2;
0965
0966 u8 vec3_len;
0967 struct option_vector3 vec3;
0968
0969 u8 vec4_len;
0970 struct option_vector4 vec4;
0971
0972 u8 vec5_len;
0973 struct option_vector5 vec5;
0974
0975 u8 vec6_len;
0976 struct option_vector6 vec6;
0977
0978 u8 vec7_len;
0979 struct option_vector7 vec7;
0980 } __packed;
0981
0982 static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
0983 .pvrs = {
0984 {
0985 .mask = cpu_to_be32(0xfffe0000),
0986 .val = cpu_to_be32(0x003a0000),
0987 },
0988 {
0989 .mask = cpu_to_be32(0xffff0000),
0990 .val = cpu_to_be32(0x003e0000),
0991 },
0992 {
0993 .mask = cpu_to_be32(0xffff0000),
0994 .val = cpu_to_be32(0x003f0000),
0995 },
0996 {
0997 .mask = cpu_to_be32(0xffff0000),
0998 .val = cpu_to_be32(0x004b0000),
0999 },
1000 {
1001 .mask = cpu_to_be32(0xffff0000),
1002 .val = cpu_to_be32(0x004c0000),
1003 },
1004 {
1005 .mask = cpu_to_be32(0xffff0000),
1006 .val = cpu_to_be32(0x004d0000),
1007 },
1008 {
1009 .mask = cpu_to_be32(0xffff0000),
1010 .val = cpu_to_be32(0x004e0000),
1011 },
1012 {
1013 .mask = cpu_to_be32(0xffff0000),
1014 .val = cpu_to_be32(0x00800000),
1015 },
1016 {
1017 .mask = cpu_to_be32(0xffffffff),
1018 .val = cpu_to_be32(0x0f000006),
1019 },
1020 {
1021 .mask = cpu_to_be32(0xffffffff),
1022 .val = cpu_to_be32(0x0f000005),
1023 },
1024 {
1025 .mask = cpu_to_be32(0xffffffff),
1026 .val = cpu_to_be32(0x0f000004),
1027 },
1028 {
1029 .mask = cpu_to_be32(0xffffffff),
1030 .val = cpu_to_be32(0x0f000003),
1031 },
1032 {
1033 .mask = cpu_to_be32(0xffffffff),
1034 .val = cpu_to_be32(0x0f000002),
1035 },
1036 {
1037 .mask = cpu_to_be32(0xfffffffe),
1038 .val = cpu_to_be32(0x0f000001),
1039 },
1040 },
1041
1042 .num_vectors = NUM_VECTORS(6),
1043
1044 .vec1_len = VECTOR_LENGTH(sizeof(struct option_vector1)),
1045 .vec1 = {
1046 .byte1 = 0,
1047 .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
1048 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
1049 .arch_versions3 = OV1_PPC_3_00 | OV1_PPC_3_1,
1050 },
1051
1052 .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)),
1053
1054 .vec2 = {
1055 .byte1 = OV2_REAL_MODE,
1056 .reserved = 0,
1057 .real_base = cpu_to_be32(0xffffffff),
1058 .real_size = cpu_to_be32(0xffffffff),
1059 .virt_base = cpu_to_be32(0xffffffff),
1060 .virt_size = cpu_to_be32(0xffffffff),
1061 .load_base = cpu_to_be32(0xffffffff),
1062 .min_rma = cpu_to_be32(512),
1063 .min_load = cpu_to_be32(0xffffffff),
1064 .min_rma_percent = 0,
1065 .max_pft_size = 48,
1066 },
1067
1068 .vec3_len = VECTOR_LENGTH(sizeof(struct option_vector3)),
1069
1070 .vec3 = {
1071 .byte1 = 0,
1072 .byte2 = OV3_FP | OV3_VMX | OV3_DFP,
1073 },
1074
1075 .vec4_len = VECTOR_LENGTH(sizeof(struct option_vector4)),
1076
1077 .vec4 = {
1078 .byte1 = 0,
1079 .min_vp_cap = OV4_MIN_ENT_CAP,
1080 },
1081
1082 .vec5_len = VECTOR_LENGTH(sizeof(struct option_vector5)),
1083
1084 .vec5 = {
1085 .byte1 = 0,
1086 .byte2 = OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
1087 OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
1088 #ifdef CONFIG_PCI_MSI
1089
1090 OV5_FEAT(OV5_MSI),
1091 #else
1092 0,
1093 #endif
1094 .byte3 = 0,
1095 .cmo =
1096 #ifdef CONFIG_PPC_SMLPAR
1097 OV5_FEAT(OV5_CMO) | OV5_FEAT(OV5_XCMO),
1098 #else
1099 0,
1100 #endif
1101 .associativity = OV5_FEAT(OV5_FORM1_AFFINITY) | OV5_FEAT(OV5_PRRN) |
1102 OV5_FEAT(OV5_FORM2_AFFINITY),
1103 .bin_opts = OV5_FEAT(OV5_RESIZE_HPT) | OV5_FEAT(OV5_HP_EVT),
1104 .micro_checkpoint = 0,
1105 .reserved0 = 0,
1106 .max_cpus = cpu_to_be32(NR_CPUS),
1107 .papr_level = 0,
1108 .reserved1 = 0,
1109 .platform_facilities = OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | OV5_FEAT(OV5_PFO_HW_842),
1110 .reserved2 = 0,
1111 .reserved3 = 0,
1112 .subprocessors = 1,
1113 .byte22 = OV5_FEAT(OV5_DRMEM_V2) | OV5_FEAT(OV5_DRC_INFO),
1114 .intarch = 0,
1115 .mmu = 0,
1116 .hash_ext = 0,
1117 .radix_ext = 0,
1118 },
1119
1120
1121 .vec6_len = VECTOR_LENGTH(sizeof(struct option_vector6)),
1122 .vec6 = {
1123 .reserved = 0,
1124 .secondary_pteg = 0,
1125 .os_name = OV6_LINUX,
1126 },
1127
1128
1129 .vec7_len = VECTOR_LENGTH(sizeof(struct option_vector7)),
1130 };
1131
1132 static struct ibm_arch_vec __prombss ibm_architecture_vec ____cacheline_aligned;
1133
1134
1135 #ifdef __BIG_ENDIAN__
1136 static const struct fake_elf {
1137 Elf32_Ehdr elfhdr;
1138 Elf32_Phdr phdr[2];
1139 struct chrpnote {
1140 u32 namesz;
1141 u32 descsz;
1142 u32 type;
1143 char name[8];
1144 struct chrpdesc {
1145 u32 real_mode;
1146 u32 real_base;
1147 u32 real_size;
1148 u32 virt_base;
1149 u32 virt_size;
1150 u32 load_base;
1151 } chrpdesc;
1152 } chrpnote;
1153 struct rpanote {
1154 u32 namesz;
1155 u32 descsz;
1156 u32 type;
1157 char name[24];
1158 struct rpadesc {
1159 u32 lpar_affinity;
1160 u32 min_rmo_size;
1161 u32 min_rmo_percent;
1162 u32 max_pft_size;
1163 u32 splpar;
1164 u32 min_load;
1165 u32 new_mem_def;
1166 u32 ignore_me;
1167 } rpadesc;
1168 } rpanote;
1169 } fake_elf __initconst = {
1170 .elfhdr = {
1171 .e_ident = { 0x7f, 'E', 'L', 'F',
1172 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
1173 .e_type = ET_EXEC,
1174 .e_machine = EM_PPC,
1175 .e_version = EV_CURRENT,
1176 .e_phoff = offsetof(struct fake_elf, phdr),
1177 .e_phentsize = sizeof(Elf32_Phdr),
1178 .e_phnum = 2
1179 },
1180 .phdr = {
1181 [0] = {
1182 .p_type = PT_NOTE,
1183 .p_offset = offsetof(struct fake_elf, chrpnote),
1184 .p_filesz = sizeof(struct chrpnote)
1185 }, [1] = {
1186 .p_type = PT_NOTE,
1187 .p_offset = offsetof(struct fake_elf, rpanote),
1188 .p_filesz = sizeof(struct rpanote)
1189 }
1190 },
1191 .chrpnote = {
1192 .namesz = sizeof("PowerPC"),
1193 .descsz = sizeof(struct chrpdesc),
1194 .type = 0x1275,
1195 .name = "PowerPC",
1196 .chrpdesc = {
1197 .real_mode = ~0U,
1198 .real_base = ~0U,
1199 .real_size = ~0U,
1200 .virt_base = ~0U,
1201 .virt_size = ~0U,
1202 .load_base = ~0U
1203 },
1204 },
1205 .rpanote = {
1206 .namesz = sizeof("IBM,RPA-Client-Config"),
1207 .descsz = sizeof(struct rpadesc),
1208 .type = 0x12759999,
1209 .name = "IBM,RPA-Client-Config",
1210 .rpadesc = {
1211 .lpar_affinity = 0,
1212 .min_rmo_size = 64,
1213 .min_rmo_percent = 0,
1214 .max_pft_size = 48,
1215 .splpar = 1,
1216 .min_load = ~0U,
1217 .new_mem_def = 0
1218 }
1219 }
1220 };
1221 #endif
1222
1223 static int __init prom_count_smt_threads(void)
1224 {
1225 phandle node;
1226 char type[64];
1227 unsigned int plen;
1228
1229
1230 for (node = 0; prom_next_node(&node); ) {
1231 type[0] = 0;
1232 prom_getprop(node, "device_type", type, sizeof(type));
1233
1234 if (prom_strcmp(type, "cpu"))
1235 continue;
1236
1237
1238
1239
1240
1241 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
1242 if (plen == PROM_ERROR)
1243 break;
1244 plen >>= 2;
1245 prom_debug("Found %lu smt threads per core\n", (unsigned long)plen);
1246
1247
1248 if (plen < 1 || plen > 64) {
1249 prom_printf("Threads per core %lu out of bounds, assuming 1\n",
1250 (unsigned long)plen);
1251 return 1;
1252 }
1253 return plen;
1254 }
1255 prom_debug("No threads found, assuming 1 per core\n");
1256
1257 return 1;
1258
1259 }
1260
1261 static void __init prom_parse_mmu_model(u8 val,
1262 struct platform_support *support)
1263 {
1264 switch (val) {
1265 case OV5_FEAT(OV5_MMU_DYNAMIC):
1266 case OV5_FEAT(OV5_MMU_EITHER):
1267 prom_debug("MMU - either supported\n");
1268 support->radix_mmu = !prom_radix_disable;
1269 support->hash_mmu = true;
1270 break;
1271 case OV5_FEAT(OV5_MMU_RADIX):
1272 prom_debug("MMU - radix only\n");
1273 if (prom_radix_disable) {
1274
1275
1276
1277
1278 prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
1279 }
1280 support->radix_mmu = true;
1281 break;
1282 case OV5_FEAT(OV5_MMU_HASH):
1283 prom_debug("MMU - hash only\n");
1284 support->hash_mmu = true;
1285 break;
1286 default:
1287 prom_debug("Unknown mmu support option: 0x%x\n", val);
1288 break;
1289 }
1290 }
1291
1292 static void __init prom_parse_xive_model(u8 val,
1293 struct platform_support *support)
1294 {
1295 switch (val) {
1296 case OV5_FEAT(OV5_XIVE_EITHER):
1297 prom_debug("XIVE - either mode supported\n");
1298 support->xive = !prom_xive_disable;
1299 break;
1300 case OV5_FEAT(OV5_XIVE_EXPLOIT):
1301 prom_debug("XIVE - exploitation mode supported\n");
1302 if (prom_xive_disable) {
1303
1304
1305
1306
1307 prom_printf("WARNING: Ignoring cmdline option xive=off\n");
1308 }
1309 support->xive = true;
1310 break;
1311 case OV5_FEAT(OV5_XIVE_LEGACY):
1312 prom_debug("XIVE - legacy mode supported\n");
1313 break;
1314 default:
1315 prom_debug("Unknown xive support option: 0x%x\n", val);
1316 break;
1317 }
1318 }
1319
1320 static void __init prom_parse_platform_support(u8 index, u8 val,
1321 struct platform_support *support)
1322 {
1323 switch (index) {
1324 case OV5_INDX(OV5_MMU_SUPPORT):
1325 prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
1326 break;
1327 case OV5_INDX(OV5_RADIX_GTSE):
1328 if (val & OV5_FEAT(OV5_RADIX_GTSE))
1329 support->radix_gtse = !prom_radix_gtse_disable;
1330 break;
1331 case OV5_INDX(OV5_XIVE_SUPPORT):
1332 prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT),
1333 support);
1334 break;
1335 }
1336 }
1337
1338 static void __init prom_check_platform_support(void)
1339 {
1340 struct platform_support supported = {
1341 .hash_mmu = false,
1342 .radix_mmu = false,
1343 .radix_gtse = false,
1344 .xive = false
1345 };
1346 int prop_len = prom_getproplen(prom.chosen,
1347 "ibm,arch-vec-5-platform-support");
1348
1349
1350
1351
1352
1353
1354
1355 memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
1356 sizeof(ibm_architecture_vec));
1357
1358 prom_strscpy_pad(ibm_architecture_vec.vec7.os_id, linux_banner, 256);
1359
1360 if (prop_len > 1) {
1361 int i;
1362 u8 vec[8];
1363 prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
1364 prop_len);
1365 if (prop_len > sizeof(vec))
1366 prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n",
1367 prop_len);
1368 prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", &vec, sizeof(vec));
1369 for (i = 0; i < prop_len; i += 2) {
1370 prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2, vec[i], vec[i + 1]);
1371 prom_parse_platform_support(vec[i], vec[i + 1], &supported);
1372 }
1373 }
1374
1375 if (supported.radix_mmu && IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
1376
1377 prom_debug("Asking for radix\n");
1378 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1379 if (supported.radix_gtse)
1380 ibm_architecture_vec.vec5.radix_ext =
1381 OV5_FEAT(OV5_RADIX_GTSE);
1382 else
1383 prom_debug("Radix GTSE isn't supported\n");
1384 } else if (supported.hash_mmu) {
1385
1386 prom_debug("Asking for hash\n");
1387 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
1388 } else {
1389
1390 prom_debug("Assuming legacy hash support\n");
1391 }
1392
1393 if (supported.xive) {
1394 prom_debug("Asking for XIVE\n");
1395 ibm_architecture_vec.vec5.intarch = OV5_FEAT(OV5_XIVE_EXPLOIT);
1396 }
1397 }
1398
1399 static void __init prom_send_capabilities(void)
1400 {
1401 ihandle root;
1402 prom_arg_t ret;
1403 u32 cores;
1404
1405
1406 prom_check_platform_support();
1407
1408 root = call_prom("open", 1, 1, ADDR("/"));
1409 if (root != 0) {
1410
1411
1412
1413
1414
1415
1416
1417 cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
1418 prom_printf("Max number of cores passed to firmware: %u (NR_CPUS = %d)\n",
1419 cores, NR_CPUS);
1420
1421 ibm_architecture_vec.vec5.max_cpus = cpu_to_be32(cores);
1422
1423
1424 prom_printf("Calling ibm,client-architecture-support...");
1425 if (call_prom_ret("call-method", 3, 2, &ret,
1426 ADDR("ibm,client-architecture-support"),
1427 root,
1428 ADDR(&ibm_architecture_vec)) == 0) {
1429
1430 if (ret)
1431 prom_printf("\nWARNING: ibm,client-architecture"
1432 "-support call FAILED!\n");
1433 call_prom("close", 1, 0, root);
1434 prom_printf(" done\n");
1435 return;
1436 }
1437 call_prom("close", 1, 0, root);
1438 prom_printf(" not implemented\n");
1439 }
1440
1441 #ifdef __BIG_ENDIAN__
1442 {
1443 ihandle elfloader;
1444
1445
1446 elfloader = call_prom("open", 1, 1,
1447 ADDR("/packages/elf-loader"));
1448 if (elfloader == 0) {
1449 prom_printf("couldn't open /packages/elf-loader\n");
1450 return;
1451 }
1452 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
1453 elfloader, ADDR(&fake_elf));
1454 call_prom("close", 1, 0, elfloader);
1455 }
1456 #endif
1457 }
1458 #endif
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493 static unsigned long __init alloc_up(unsigned long size, unsigned long align)
1494 {
1495 unsigned long base = alloc_bottom;
1496 unsigned long addr = 0;
1497
1498 if (align)
1499 base = ALIGN(base, align);
1500 prom_debug("%s(%lx, %lx)\n", __func__, size, align);
1501 if (ram_top == 0)
1502 prom_panic("alloc_up() called with mem not initialized\n");
1503
1504 if (align)
1505 base = ALIGN(alloc_bottom, align);
1506 else
1507 base = alloc_bottom;
1508
1509 for(; (base + size) <= alloc_top;
1510 base = ALIGN(base + 0x100000, align)) {
1511 prom_debug(" trying: 0x%lx\n\r", base);
1512 addr = (unsigned long)prom_claim(base, size, 0);
1513 if (addr != PROM_ERROR && addr != 0)
1514 break;
1515 addr = 0;
1516 if (align == 0)
1517 break;
1518 }
1519 if (addr == 0)
1520 return 0;
1521 alloc_bottom = addr + size;
1522
1523 prom_debug(" -> %lx\n", addr);
1524 prom_debug(" alloc_bottom : %lx\n", alloc_bottom);
1525 prom_debug(" alloc_top : %lx\n", alloc_top);
1526 prom_debug(" alloc_top_hi : %lx\n", alloc_top_high);
1527 prom_debug(" rmo_top : %lx\n", rmo_top);
1528 prom_debug(" ram_top : %lx\n", ram_top);
1529
1530 return addr;
1531 }
1532
1533
1534
1535
1536
1537
1538 static unsigned long __init alloc_down(unsigned long size, unsigned long align,
1539 int highmem)
1540 {
1541 unsigned long base, addr = 0;
1542
1543 prom_debug("%s(%lx, %lx, %s)\n", __func__, size, align,
1544 highmem ? "(high)" : "(low)");
1545 if (ram_top == 0)
1546 prom_panic("alloc_down() called with mem not initialized\n");
1547
1548 if (highmem) {
1549
1550 addr = ALIGN_DOWN(alloc_top_high - size, align);
1551 if (addr <= alloc_bottom)
1552 return 0;
1553
1554
1555
1556
1557 if (addr < rmo_top) {
1558
1559 if (alloc_top == rmo_top)
1560 alloc_top = rmo_top = addr;
1561 else
1562 return 0;
1563 }
1564 alloc_top_high = addr;
1565 goto bail;
1566 }
1567
1568 base = ALIGN_DOWN(alloc_top - size, align);
1569 for (; base > alloc_bottom;
1570 base = ALIGN_DOWN(base - 0x100000, align)) {
1571 prom_debug(" trying: 0x%lx\n\r", base);
1572 addr = (unsigned long)prom_claim(base, size, 0);
1573 if (addr != PROM_ERROR && addr != 0)
1574 break;
1575 addr = 0;
1576 }
1577 if (addr == 0)
1578 return 0;
1579 alloc_top = addr;
1580
1581 bail:
1582 prom_debug(" -> %lx\n", addr);
1583 prom_debug(" alloc_bottom : %lx\n", alloc_bottom);
1584 prom_debug(" alloc_top : %lx\n", alloc_top);
1585 prom_debug(" alloc_top_hi : %lx\n", alloc_top_high);
1586 prom_debug(" rmo_top : %lx\n", rmo_top);
1587 prom_debug(" ram_top : %lx\n", ram_top);
1588
1589 return addr;
1590 }
1591
1592
1593
1594
1595 static unsigned long __init prom_next_cell(int s, cell_t **cellp)
1596 {
1597 cell_t *p = *cellp;
1598 unsigned long r = 0;
1599
1600
1601 while (s > sizeof(unsigned long) / 4) {
1602 p++;
1603 s--;
1604 }
1605 r = be32_to_cpu(*p++);
1606 #ifdef CONFIG_PPC64
1607 if (s > 1) {
1608 r <<= 32;
1609 r |= be32_to_cpu(*(p++));
1610 }
1611 #endif
1612 *cellp = p;
1613 return r;
1614 }
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624 static void __init reserve_mem(u64 base, u64 size)
1625 {
1626 u64 top = base + size;
1627 unsigned long cnt = mem_reserve_cnt;
1628
1629 if (size == 0)
1630 return;
1631
1632
1633
1634
1635
1636 base = ALIGN_DOWN(base, PAGE_SIZE);
1637 top = ALIGN(top, PAGE_SIZE);
1638 size = top - base;
1639
1640 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1641 prom_panic("Memory reserve map exhausted !\n");
1642 mem_reserve_map[cnt].base = cpu_to_be64(base);
1643 mem_reserve_map[cnt].size = cpu_to_be64(size);
1644 mem_reserve_cnt = cnt + 1;
1645 }
1646
1647
1648
1649
1650
1651 static void __init prom_init_mem(void)
1652 {
1653 phandle node;
1654 char type[64];
1655 unsigned int plen;
1656 cell_t *p, *endp;
1657 __be32 val;
1658 u32 rac, rsc;
1659
1660
1661
1662
1663
1664
1665 val = cpu_to_be32(2);
1666 prom_getprop(prom.root, "#address-cells", &val, sizeof(val));
1667 rac = be32_to_cpu(val);
1668 val = cpu_to_be32(1);
1669 prom_getprop(prom.root, "#size-cells", &val, sizeof(rsc));
1670 rsc = be32_to_cpu(val);
1671 prom_debug("root_addr_cells: %x\n", rac);
1672 prom_debug("root_size_cells: %x\n", rsc);
1673
1674 prom_debug("scanning memory:\n");
1675
1676 for (node = 0; prom_next_node(&node); ) {
1677 type[0] = 0;
1678 prom_getprop(node, "device_type", type, sizeof(type));
1679
1680 if (type[0] == 0) {
1681
1682
1683
1684
1685 prom_getprop(node, "name", type, sizeof(type));
1686 }
1687 if (prom_strcmp(type, "memory"))
1688 continue;
1689
1690 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
1691 if (plen > sizeof(regbuf)) {
1692 prom_printf("memory node too large for buffer !\n");
1693 plen = sizeof(regbuf);
1694 }
1695 p = regbuf;
1696 endp = p + (plen / sizeof(cell_t));
1697
1698 #ifdef DEBUG_PROM
1699 memset(prom_scratch, 0, sizeof(prom_scratch));
1700 call_prom("package-to-path", 3, 1, node, prom_scratch,
1701 sizeof(prom_scratch) - 1);
1702 prom_debug(" node %s :\n", prom_scratch);
1703 #endif
1704
1705 while ((endp - p) >= (rac + rsc)) {
1706 unsigned long base, size;
1707
1708 base = prom_next_cell(rac, &p);
1709 size = prom_next_cell(rsc, &p);
1710
1711 if (size == 0)
1712 continue;
1713 prom_debug(" %lx %lx\n", base, size);
1714 if (base == 0 && (of_platform & PLATFORM_LPAR))
1715 rmo_top = size;
1716 if ((base + size) > ram_top)
1717 ram_top = base + size;
1718 }
1719 }
1720
1721 alloc_bottom = PAGE_ALIGN((unsigned long)&_end + 0x4000);
1722
1723
1724
1725
1726
1727
1728
1729 alloc_top_high = ram_top;
1730
1731 if (prom_memory_limit) {
1732 if (prom_memory_limit <= alloc_bottom) {
1733 prom_printf("Ignoring mem=%lx <= alloc_bottom.\n",
1734 prom_memory_limit);
1735 prom_memory_limit = 0;
1736 } else if (prom_memory_limit >= ram_top) {
1737 prom_printf("Ignoring mem=%lx >= ram_top.\n",
1738 prom_memory_limit);
1739 prom_memory_limit = 0;
1740 } else {
1741 ram_top = prom_memory_limit;
1742 rmo_top = min(rmo_top, prom_memory_limit);
1743 }
1744 }
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 if (!rmo_top)
1755 rmo_top = ram_top;
1756 rmo_top = min(0x30000000ul, rmo_top);
1757 alloc_top = rmo_top;
1758 alloc_top_high = ram_top;
1759
1760
1761
1762
1763
1764 if (prom_initrd_start &&
1765 prom_initrd_start < rmo_top &&
1766 prom_initrd_end > alloc_bottom)
1767 alloc_bottom = PAGE_ALIGN(prom_initrd_end);
1768
1769 prom_printf("memory layout at init:\n");
1770 prom_printf(" memory_limit : %lx (16 MB aligned)\n",
1771 prom_memory_limit);
1772 prom_printf(" alloc_bottom : %lx\n", alloc_bottom);
1773 prom_printf(" alloc_top : %lx\n", alloc_top);
1774 prom_printf(" alloc_top_hi : %lx\n", alloc_top_high);
1775 prom_printf(" rmo_top : %lx\n", rmo_top);
1776 prom_printf(" ram_top : %lx\n", ram_top);
1777 }
1778
1779 static void __init prom_close_stdin(void)
1780 {
1781 __be32 val;
1782 ihandle stdin;
1783
1784 if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) {
1785 stdin = be32_to_cpu(val);
1786 call_prom("close", 1, 0, stdin);
1787 }
1788 }
1789
1790 #ifdef CONFIG_PPC_SVM
1791 static int __init prom_rtas_hcall(uint64_t args)
1792 {
1793 register uint64_t arg1 asm("r3") = H_RTAS;
1794 register uint64_t arg2 asm("r4") = args;
1795
1796 asm volatile("sc 1\n" : "=r" (arg1) :
1797 "r" (arg1),
1798 "r" (arg2) :);
1799 srr_regs_clobbered();
1800
1801 return arg1;
1802 }
1803
1804 static struct rtas_args __prombss os_term_args;
1805
1806 static void __init prom_rtas_os_term(char *str)
1807 {
1808 phandle rtas_node;
1809 __be32 val;
1810 u32 token;
1811
1812 prom_debug("%s: start...\n", __func__);
1813 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1814 prom_debug("rtas_node: %x\n", rtas_node);
1815 if (!PHANDLE_VALID(rtas_node))
1816 return;
1817
1818 val = 0;
1819 prom_getprop(rtas_node, "ibm,os-term", &val, sizeof(val));
1820 token = be32_to_cpu(val);
1821 prom_debug("ibm,os-term: %x\n", token);
1822 if (token == 0)
1823 prom_panic("Could not get token for ibm,os-term\n");
1824 os_term_args.token = cpu_to_be32(token);
1825 os_term_args.nargs = cpu_to_be32(1);
1826 os_term_args.nret = cpu_to_be32(1);
1827 os_term_args.args[0] = cpu_to_be32(__pa(str));
1828 prom_rtas_hcall((uint64_t)&os_term_args);
1829 }
1830 #endif
1831
1832
1833
1834
1835 static void __init prom_instantiate_rtas(void)
1836 {
1837 phandle rtas_node;
1838 ihandle rtas_inst;
1839 u32 base, entry = 0;
1840 __be32 val;
1841 u32 size = 0;
1842
1843 prom_debug("prom_instantiate_rtas: start...\n");
1844
1845 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1846 prom_debug("rtas_node: %x\n", rtas_node);
1847 if (!PHANDLE_VALID(rtas_node))
1848 return;
1849
1850 val = 0;
1851 prom_getprop(rtas_node, "rtas-size", &val, sizeof(size));
1852 size = be32_to_cpu(val);
1853 if (size == 0)
1854 return;
1855
1856 base = alloc_down(size, PAGE_SIZE, 0);
1857 if (base == 0)
1858 prom_panic("Could not allocate memory for RTAS\n");
1859
1860 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1861 if (!IHANDLE_VALID(rtas_inst)) {
1862 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
1863 return;
1864 }
1865
1866 prom_printf("instantiating rtas at 0x%x...", base);
1867
1868 if (call_prom_ret("call-method", 3, 2, &entry,
1869 ADDR("instantiate-rtas"),
1870 rtas_inst, base) != 0
1871 || entry == 0) {
1872 prom_printf(" failed\n");
1873 return;
1874 }
1875 prom_printf(" done\n");
1876
1877 reserve_mem(base, size);
1878
1879 val = cpu_to_be32(base);
1880 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1881 &val, sizeof(val));
1882 val = cpu_to_be32(entry);
1883 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1884 &val, sizeof(val));
1885
1886
1887 if (prom_getprop(rtas_node, "query-cpu-stopped-state",
1888 &val, sizeof(val)) != PROM_ERROR)
1889 rtas_has_query_cpu_stopped = true;
1890
1891 prom_debug("rtas base = 0x%x\n", base);
1892 prom_debug("rtas entry = 0x%x\n", entry);
1893 prom_debug("rtas size = 0x%x\n", size);
1894
1895 prom_debug("prom_instantiate_rtas: end...\n");
1896 }
1897
1898 #ifdef CONFIG_PPC64
1899
1900
1901
1902 static void __init prom_instantiate_sml(void)
1903 {
1904 phandle ibmvtpm_node;
1905 ihandle ibmvtpm_inst;
1906 u32 entry = 0, size = 0, succ = 0;
1907 u64 base;
1908 __be32 val;
1909
1910 prom_debug("prom_instantiate_sml: start...\n");
1911
1912 ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/vdevice/vtpm"));
1913 prom_debug("ibmvtpm_node: %x\n", ibmvtpm_node);
1914 if (!PHANDLE_VALID(ibmvtpm_node))
1915 return;
1916
1917 ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/vdevice/vtpm"));
1918 if (!IHANDLE_VALID(ibmvtpm_inst)) {
1919 prom_printf("opening vtpm package failed (%x)\n", ibmvtpm_inst);
1920 return;
1921 }
1922
1923 if (prom_getprop(ibmvtpm_node, "ibm,sml-efi-reformat-supported",
1924 &val, sizeof(val)) != PROM_ERROR) {
1925 if (call_prom_ret("call-method", 2, 2, &succ,
1926 ADDR("reformat-sml-to-efi-alignment"),
1927 ibmvtpm_inst) != 0 || succ == 0) {
1928 prom_printf("Reformat SML to EFI alignment failed\n");
1929 return;
1930 }
1931
1932 if (call_prom_ret("call-method", 2, 2, &size,
1933 ADDR("sml-get-allocated-size"),
1934 ibmvtpm_inst) != 0 || size == 0) {
1935 prom_printf("SML get allocated size failed\n");
1936 return;
1937 }
1938 } else {
1939 if (call_prom_ret("call-method", 2, 2, &size,
1940 ADDR("sml-get-handover-size"),
1941 ibmvtpm_inst) != 0 || size == 0) {
1942 prom_printf("SML get handover size failed\n");
1943 return;
1944 }
1945 }
1946
1947 base = alloc_down(size, PAGE_SIZE, 0);
1948 if (base == 0)
1949 prom_panic("Could not allocate memory for sml\n");
1950
1951 prom_printf("instantiating sml at 0x%llx...", base);
1952
1953 memset((void *)base, 0, size);
1954
1955 if (call_prom_ret("call-method", 4, 2, &entry,
1956 ADDR("sml-handover"),
1957 ibmvtpm_inst, size, base) != 0 || entry == 0) {
1958 prom_printf("SML handover failed\n");
1959 return;
1960 }
1961 prom_printf(" done\n");
1962
1963 reserve_mem(base, size);
1964
1965 prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
1966 &base, sizeof(base));
1967 prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
1968 &size, sizeof(size));
1969
1970 prom_debug("sml base = 0x%llx\n", base);
1971 prom_debug("sml size = 0x%x\n", size);
1972
1973 prom_debug("prom_instantiate_sml: end...\n");
1974 }
1975
1976
1977
1978
1979 #ifdef __BIG_ENDIAN__
1980 static void __init prom_initialize_tce_table(void)
1981 {
1982 phandle node;
1983 ihandle phb_node;
1984 char compatible[64], type[64], model[64];
1985 char *path = prom_scratch;
1986 u64 base, align;
1987 u32 minalign, minsize;
1988 u64 tce_entry, *tce_entryp;
1989 u64 local_alloc_top, local_alloc_bottom;
1990 u64 i;
1991
1992 if (prom_iommu_off)
1993 return;
1994
1995 prom_debug("starting prom_initialize_tce_table\n");
1996
1997
1998 local_alloc_top = alloc_top_high;
1999 local_alloc_bottom = local_alloc_top;
2000
2001
2002 for (node = 0; prom_next_node(&node); ) {
2003 compatible[0] = 0;
2004 type[0] = 0;
2005 model[0] = 0;
2006 prom_getprop(node, "compatible",
2007 compatible, sizeof(compatible));
2008 prom_getprop(node, "device_type", type, sizeof(type));
2009 prom_getprop(node, "model", model, sizeof(model));
2010
2011 if ((type[0] == 0) || (prom_strstr(type, "pci") == NULL))
2012 continue;
2013
2014
2015 if (compatible[0] != 0) {
2016 if ((prom_strstr(compatible, "python") == NULL) &&
2017 (prom_strstr(compatible, "Speedwagon") == NULL) &&
2018 (prom_strstr(compatible, "Winnipeg") == NULL))
2019 continue;
2020 } else if (model[0] != 0) {
2021 if ((prom_strstr(model, "ython") == NULL) &&
2022 (prom_strstr(model, "peedwagon") == NULL) &&
2023 (prom_strstr(model, "innipeg") == NULL))
2024 continue;
2025 }
2026
2027 if (prom_getprop(node, "tce-table-minalign", &minalign,
2028 sizeof(minalign)) == PROM_ERROR)
2029 minalign = 0;
2030 if (prom_getprop(node, "tce-table-minsize", &minsize,
2031 sizeof(minsize)) == PROM_ERROR)
2032 minsize = 4UL << 20;
2033
2034
2035
2036
2037
2038
2039
2040 minsize = 4UL << 20;
2041
2042
2043 align = max(minalign, minsize);
2044 base = alloc_down(minsize, align, 1);
2045 if (base == 0)
2046 prom_panic("ERROR, cannot find space for TCE table.\n");
2047 if (base < local_alloc_bottom)
2048 local_alloc_bottom = base;
2049
2050
2051 memset(path, 0, sizeof(prom_scratch));
2052
2053 if (call_prom("package-to-path", 3, 1, node,
2054 path, sizeof(prom_scratch) - 1) == PROM_ERROR) {
2055 prom_printf("package-to-path failed\n");
2056 }
2057
2058
2059 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
2060 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
2061
2062 prom_debug("TCE table: %s\n", path);
2063 prom_debug("\tnode = 0x%x\n", node);
2064 prom_debug("\tbase = 0x%llx\n", base);
2065 prom_debug("\tsize = 0x%x\n", minsize);
2066
2067
2068
2069
2070 tce_entryp = (u64 *)base;
2071 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
2072 tce_entry = (i << PAGE_SHIFT);
2073 tce_entry |= 0x3;
2074 *tce_entryp = tce_entry;
2075 }
2076
2077 prom_printf("opening PHB %s", path);
2078 phb_node = call_prom("open", 1, 1, path);
2079 if (phb_node == 0)
2080 prom_printf("... failed\n");
2081 else
2082 prom_printf("... done\n");
2083
2084 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
2085 phb_node, -1, minsize,
2086 (u32) base, (u32) (base >> 32));
2087 call_prom("close", 1, 0, phb_node);
2088 }
2089
2090 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
2091
2092
2093
2094 prom_tce_alloc_start = local_alloc_bottom;
2095 prom_tce_alloc_end = local_alloc_top;
2096
2097
2098 prom_debug("ending prom_initialize_tce_table\n");
2099 }
2100 #endif
2101 #endif
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125 #define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
2126
2127 static void __init prom_hold_cpus(void)
2128 {
2129 unsigned long i;
2130 phandle node;
2131 char type[64];
2132 unsigned long *spinloop
2133 = (void *) LOW_ADDR(__secondary_hold_spinloop);
2134 unsigned long *acknowledge
2135 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
2136 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
2137
2138
2139
2140
2141
2142
2143 if ((of_platform == PLATFORM_PSERIES ||
2144 of_platform == PLATFORM_PSERIES_LPAR) &&
2145 rtas_has_query_cpu_stopped) {
2146 prom_printf("prom_hold_cpus: skipped\n");
2147 return;
2148 }
2149
2150 prom_debug("prom_hold_cpus: start...\n");
2151 prom_debug(" 1) spinloop = 0x%lx\n", (unsigned long)spinloop);
2152 prom_debug(" 1) *spinloop = 0x%lx\n", *spinloop);
2153 prom_debug(" 1) acknowledge = 0x%lx\n",
2154 (unsigned long)acknowledge);
2155 prom_debug(" 1) *acknowledge = 0x%lx\n", *acknowledge);
2156 prom_debug(" 1) secondary_hold = 0x%lx\n", secondary_hold);
2157
2158
2159
2160
2161
2162
2163 *spinloop = 0;
2164
2165
2166 for (node = 0; prom_next_node(&node); ) {
2167 unsigned int cpu_no;
2168 __be32 reg;
2169
2170 type[0] = 0;
2171 prom_getprop(node, "device_type", type, sizeof(type));
2172 if (prom_strcmp(type, "cpu") != 0)
2173 continue;
2174
2175
2176 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
2177 if (prom_strcmp(type, "okay") != 0)
2178 continue;
2179
2180 reg = cpu_to_be32(-1);
2181 prom_getprop(node, "reg", ®, sizeof(reg));
2182 cpu_no = be32_to_cpu(reg);
2183
2184 prom_debug("cpu hw idx = %u\n", cpu_no);
2185
2186
2187
2188
2189
2190 *acknowledge = (unsigned long)-1;
2191
2192 if (cpu_no != prom.cpu) {
2193
2194 prom_printf("starting cpu hw idx %u... ", cpu_no);
2195 call_prom("start-cpu", 3, 0, node,
2196 secondary_hold, cpu_no);
2197
2198 for (i = 0; (i < 100000000) &&
2199 (*acknowledge == ((unsigned long)-1)); i++ )
2200 mb();
2201
2202 if (*acknowledge == cpu_no)
2203 prom_printf("done\n");
2204 else
2205 prom_printf("failed: %lx\n", *acknowledge);
2206 }
2207 #ifdef CONFIG_SMP
2208 else
2209 prom_printf("boot cpu hw idx %u\n", cpu_no);
2210 #endif
2211 }
2212
2213 prom_debug("prom_hold_cpus: end...\n");
2214 }
2215
2216
2217 static void __init prom_init_client_services(unsigned long pp)
2218 {
2219
2220 prom_entry = pp;
2221
2222
2223 prom.chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
2224 if (!PHANDLE_VALID(prom.chosen))
2225 prom_panic("cannot find chosen");
2226
2227
2228 prom.root = call_prom("finddevice", 1, 1, ADDR("/"));
2229 if (!PHANDLE_VALID(prom.root))
2230 prom_panic("cannot find device tree root");
2231
2232 prom.mmumap = 0;
2233 }
2234
2235 #ifdef CONFIG_PPC32
2236
2237
2238
2239
2240
2241 static void __init prom_find_mmu(void)
2242 {
2243 phandle oprom;
2244 char version[64];
2245
2246 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
2247 if (!PHANDLE_VALID(oprom))
2248 return;
2249 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
2250 return;
2251 version[sizeof(version) - 1] = 0;
2252
2253 if (prom_strcmp(version, "Open Firmware, 1.0.5") == 0)
2254 of_workarounds = OF_WA_CLAIM;
2255 else if (prom_strncmp(version, "FirmWorks,3.", 12) == 0) {
2256 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
2257 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
2258 } else
2259 return;
2260 prom.memory = call_prom("open", 1, 1, ADDR("/memory"));
2261 prom_getprop(prom.chosen, "mmu", &prom.mmumap,
2262 sizeof(prom.mmumap));
2263 prom.mmumap = be32_to_cpu(prom.mmumap);
2264 if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap))
2265 of_workarounds &= ~OF_WA_CLAIM;
2266 }
2267 #else
2268 #define prom_find_mmu()
2269 #endif
2270
2271 static void __init prom_init_stdout(void)
2272 {
2273 char *path = of_stdout_device;
2274 char type[16];
2275 phandle stdout_node;
2276 __be32 val;
2277
2278 if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0)
2279 prom_panic("cannot find stdout");
2280
2281 prom.stdout = be32_to_cpu(val);
2282
2283
2284 memset(path, 0, 256);
2285 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
2286 prom_printf("OF stdout device is: %s\n", of_stdout_device);
2287 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
2288 path, prom_strlen(path) + 1);
2289
2290
2291 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
2292 if (stdout_node != PROM_ERROR) {
2293 val = cpu_to_be32(stdout_node);
2294
2295
2296 memset(type, 0, sizeof(type));
2297 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2298 if (prom_strcmp(type, "display") == 0)
2299 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
2300 }
2301 }
2302
2303 static int __init prom_find_machine_type(void)
2304 {
2305 static char compat[256] __prombss;
2306 int len, i = 0;
2307 #ifdef CONFIG_PPC64
2308 phandle rtas;
2309 int x;
2310 #endif
2311
2312
2313 len = prom_getprop(prom.root, "compatible",
2314 compat, sizeof(compat)-1);
2315 if (len > 0) {
2316 compat[len] = 0;
2317 while (i < len) {
2318 char *p = &compat[i];
2319 int sl = prom_strlen(p);
2320 if (sl == 0)
2321 break;
2322 if (prom_strstr(p, "Power Macintosh") ||
2323 prom_strstr(p, "MacRISC"))
2324 return PLATFORM_POWERMAC;
2325 #ifdef CONFIG_PPC64
2326
2327
2328
2329
2330 if (prom_strstr(p, "IBM,CBEA") ||
2331 prom_strstr(p, "IBM,CPBW-1.0"))
2332 return PLATFORM_GENERIC;
2333 #endif
2334 i += sl + 1;
2335 }
2336 }
2337 #ifdef CONFIG_PPC64
2338
2339
2340
2341
2342
2343
2344 len = prom_getprop(prom.root, "device_type",
2345 compat, sizeof(compat)-1);
2346 if (len <= 0)
2347 return PLATFORM_GENERIC;
2348 if (prom_strcmp(compat, "chrp"))
2349 return PLATFORM_GENERIC;
2350
2351
2352 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
2353 if (!PHANDLE_VALID(rtas))
2354 return PLATFORM_GENERIC;
2355 x = prom_getproplen(rtas, "ibm,hypertas-functions");
2356 if (x != PROM_ERROR) {
2357 prom_debug("Hypertas detected, assuming LPAR !\n");
2358 return PLATFORM_PSERIES_LPAR;
2359 }
2360 return PLATFORM_PSERIES;
2361 #else
2362 return PLATFORM_GENERIC;
2363 #endif
2364 }
2365
2366 static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
2367 {
2368 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
2369 }
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379 static void __init prom_check_displays(void)
2380 {
2381 char type[16], *path;
2382 phandle node;
2383 ihandle ih;
2384 int i;
2385
2386 static const unsigned char default_colors[] __initconst = {
2387 0x00, 0x00, 0x00,
2388 0x00, 0x00, 0xaa,
2389 0x00, 0xaa, 0x00,
2390 0x00, 0xaa, 0xaa,
2391 0xaa, 0x00, 0x00,
2392 0xaa, 0x00, 0xaa,
2393 0xaa, 0xaa, 0x00,
2394 0xaa, 0xaa, 0xaa,
2395 0x55, 0x55, 0x55,
2396 0x55, 0x55, 0xff,
2397 0x55, 0xff, 0x55,
2398 0x55, 0xff, 0xff,
2399 0xff, 0x55, 0x55,
2400 0xff, 0x55, 0xff,
2401 0xff, 0xff, 0x55,
2402 0xff, 0xff, 0xff
2403 };
2404 const unsigned char *clut;
2405
2406 prom_debug("Looking for displays\n");
2407 for (node = 0; prom_next_node(&node); ) {
2408 memset(type, 0, sizeof(type));
2409 prom_getprop(node, "device_type", type, sizeof(type));
2410 if (prom_strcmp(type, "display") != 0)
2411 continue;
2412
2413
2414 path = prom_scratch;
2415 memset(path, 0, sizeof(prom_scratch));
2416
2417
2418
2419
2420
2421 if (call_prom("package-to-path", 3, 1, node, path,
2422 sizeof(prom_scratch) - 10) == PROM_ERROR)
2423 continue;
2424 prom_printf("found display : %s, opening... ", path);
2425
2426 ih = call_prom("open", 1, 1, path);
2427 if (ih == 0) {
2428 prom_printf("failed\n");
2429 continue;
2430 }
2431
2432
2433 prom_printf("done\n");
2434 prom_setprop(node, path, "linux,opened", NULL, 0);
2435
2436
2437
2438 clut = default_colors;
2439 for (i = 0; i < 16; i++, clut += 3)
2440 if (prom_set_color(ih, i, clut[0], clut[1],
2441 clut[2]) != 0)
2442 break;
2443
2444 #ifdef CONFIG_LOGO_LINUX_CLUT224
2445 clut = PTRRELOC(logo_linux_clut224.clut);
2446 for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3)
2447 if (prom_set_color(ih, i + 32, clut[0], clut[1],
2448 clut[2]) != 0)
2449 break;
2450 #endif
2451
2452 #ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
2453 if (prom_getprop(node, "linux,boot-display", NULL, 0) !=
2454 PROM_ERROR) {
2455 u32 width, height, pitch, addr;
2456
2457 prom_printf("Setting btext !\n");
2458
2459 if (prom_getprop(node, "width", &width, 4) == PROM_ERROR)
2460 return;
2461
2462 if (prom_getprop(node, "height", &height, 4) == PROM_ERROR)
2463 return;
2464
2465 if (prom_getprop(node, "linebytes", &pitch, 4) == PROM_ERROR)
2466 return;
2467
2468 if (prom_getprop(node, "address", &addr, 4) == PROM_ERROR)
2469 return;
2470
2471 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
2472 width, height, pitch, addr);
2473 btext_setup_display(width, height, 8, pitch, addr);
2474 btext_prepare_BAT();
2475 }
2476 #endif
2477 }
2478 }
2479
2480
2481
2482 static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
2483 unsigned long needed, unsigned long align)
2484 {
2485 void *ret;
2486
2487 *mem_start = ALIGN(*mem_start, align);
2488 while ((*mem_start + needed) > *mem_end) {
2489 unsigned long room, chunk;
2490
2491 prom_debug("Chunk exhausted, claiming more at %lx...\n",
2492 alloc_bottom);
2493 room = alloc_top - alloc_bottom;
2494 if (room > DEVTREE_CHUNK_SIZE)
2495 room = DEVTREE_CHUNK_SIZE;
2496 if (room < PAGE_SIZE)
2497 prom_panic("No memory for flatten_device_tree "
2498 "(no room)\n");
2499 chunk = alloc_up(room, 0);
2500 if (chunk == 0)
2501 prom_panic("No memory for flatten_device_tree "
2502 "(claim failed)\n");
2503 *mem_end = chunk + room;
2504 }
2505
2506 ret = (void *)*mem_start;
2507 *mem_start += needed;
2508
2509 return ret;
2510 }
2511
2512 #define dt_push_token(token, mem_start, mem_end) do { \
2513 void *room = make_room(mem_start, mem_end, 4, 4); \
2514 *(__be32 *)room = cpu_to_be32(token); \
2515 } while(0)
2516
2517 static unsigned long __init dt_find_string(char *str)
2518 {
2519 char *s, *os;
2520
2521 s = os = (char *)dt_string_start;
2522 s += 4;
2523 while (s < (char *)dt_string_end) {
2524 if (prom_strcmp(s, str) == 0)
2525 return s - os;
2526 s += prom_strlen(s) + 1;
2527 }
2528 return 0;
2529 }
2530
2531
2532
2533
2534
2535 #define MAX_PROPERTY_NAME 64
2536
2537 static void __init scan_dt_build_strings(phandle node,
2538 unsigned long *mem_start,
2539 unsigned long *mem_end)
2540 {
2541 char *prev_name, *namep, *sstart;
2542 unsigned long soff;
2543 phandle child;
2544
2545 sstart = (char *)dt_string_start;
2546
2547
2548 prev_name = "";
2549 for (;;) {
2550
2551 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
2552 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
2553
2554 *mem_start = (unsigned long)namep;
2555 break;
2556 }
2557
2558
2559 if (prom_strcmp(namep, "name") == 0) {
2560 *mem_start = (unsigned long)namep;
2561 prev_name = "name";
2562 continue;
2563 }
2564
2565 soff = dt_find_string(namep);
2566 if (soff != 0) {
2567 *mem_start = (unsigned long)namep;
2568 namep = sstart + soff;
2569 } else {
2570
2571 *mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
2572 dt_string_end = *mem_start;
2573 }
2574 prev_name = namep;
2575 }
2576
2577
2578 child = call_prom("child", 1, 1, node);
2579 while (child != 0) {
2580 scan_dt_build_strings(child, mem_start, mem_end);
2581 child = call_prom("peer", 1, 1, child);
2582 }
2583 }
2584
2585 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2586 unsigned long *mem_end)
2587 {
2588 phandle child;
2589 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
2590 unsigned long soff;
2591 unsigned char *valp;
2592 static char pname[MAX_PROPERTY_NAME] __prombss;
2593 int l, room, has_phandle = 0;
2594
2595 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
2596
2597
2598 namep = (char *)*mem_start;
2599 room = *mem_end - *mem_start;
2600 if (room > 255)
2601 room = 255;
2602 l = call_prom("package-to-path", 3, 1, node, namep, room);
2603 if (l >= 0) {
2604
2605 if (l >= room) {
2606 if (l >= *mem_end - *mem_start)
2607 namep = make_room(mem_start, mem_end, l+1, 1);
2608 call_prom("package-to-path", 3, 1, node, namep, l);
2609 }
2610 namep[l] = '\0';
2611
2612
2613
2614
2615
2616 for (lp = p = namep, ep = namep + l; p < ep; p++) {
2617 if (*p == '/')
2618 lp = namep;
2619 else if (*p != 0)
2620 *lp++ = *p;
2621 }
2622 *lp = 0;
2623 *mem_start = ALIGN((unsigned long)lp + 1, 4);
2624 }
2625
2626
2627 path = prom_scratch;
2628 memset(path, 0, sizeof(prom_scratch));
2629 call_prom("package-to-path", 3, 1, node, path, sizeof(prom_scratch) - 1);
2630
2631
2632 prev_name = "";
2633 sstart = (char *)dt_string_start;
2634 for (;;) {
2635 if (call_prom("nextprop", 3, 1, node, prev_name,
2636 pname) != 1)
2637 break;
2638
2639
2640 if (prom_strcmp(pname, "name") == 0) {
2641 prev_name = "name";
2642 continue;
2643 }
2644
2645
2646 soff = dt_find_string(pname);
2647 if (soff == 0) {
2648 prom_printf("WARNING: Can't find string index for"
2649 " <%s>, node %s\n", pname, path);
2650 break;
2651 }
2652 prev_name = sstart + soff;
2653
2654
2655 l = call_prom("getproplen", 2, 1, node, pname);
2656
2657
2658 if (l == PROM_ERROR)
2659 continue;
2660
2661
2662 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2663 dt_push_token(l, mem_start, mem_end);
2664 dt_push_token(soff, mem_start, mem_end);
2665
2666
2667 valp = make_room(mem_start, mem_end, l, 4);
2668 call_prom("getprop", 4, 1, node, pname, valp, l);
2669 *mem_start = ALIGN(*mem_start, 4);
2670
2671 if (!prom_strcmp(pname, "phandle"))
2672 has_phandle = 1;
2673 }
2674
2675
2676 if (!has_phandle) {
2677 soff = dt_find_string("phandle");
2678 if (soff == 0)
2679 prom_printf("WARNING: Can't find string index for <phandle> node %s\n", path);
2680 else {
2681 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2682 dt_push_token(4, mem_start, mem_end);
2683 dt_push_token(soff, mem_start, mem_end);
2684 valp = make_room(mem_start, mem_end, 4, 4);
2685 *(__be32 *)valp = cpu_to_be32(node);
2686 }
2687 }
2688
2689
2690 child = call_prom("child", 1, 1, node);
2691 while (child != 0) {
2692 scan_dt_build_struct(child, mem_start, mem_end);
2693 child = call_prom("peer", 1, 1, child);
2694 }
2695
2696 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
2697 }
2698
2699 static void __init flatten_device_tree(void)
2700 {
2701 phandle root;
2702 unsigned long mem_start, mem_end, room;
2703 struct boot_param_header *hdr;
2704 char *namep;
2705 u64 *rsvmap;
2706
2707
2708
2709
2710
2711 room = alloc_top - alloc_bottom - 0x4000;
2712 if (room > DEVTREE_CHUNK_SIZE)
2713 room = DEVTREE_CHUNK_SIZE;
2714 prom_debug("starting device tree allocs at %lx\n", alloc_bottom);
2715
2716
2717 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
2718 if (mem_start == 0)
2719 prom_panic("Can't allocate initial device-tree chunk\n");
2720 mem_end = mem_start + room;
2721
2722
2723 root = call_prom("peer", 1, 1, (phandle)0);
2724 if (root == (phandle)0)
2725 prom_panic ("couldn't get device tree root\n");
2726
2727
2728 mem_start = ALIGN(mem_start, 4);
2729 hdr = make_room(&mem_start, &mem_end,
2730 sizeof(struct boot_param_header), 4);
2731 dt_header_start = (unsigned long)hdr;
2732 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
2733
2734
2735 mem_start = PAGE_ALIGN(mem_start);
2736 dt_string_start = mem_start;
2737 mem_start += 4;
2738
2739
2740 namep = make_room(&mem_start, &mem_end, 16, 1);
2741 prom_strscpy_pad(namep, "phandle", sizeof("phandle"));
2742 mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
2743
2744
2745 prom_printf("Building dt strings...\n");
2746 scan_dt_build_strings(root, &mem_start, &mem_end);
2747 dt_string_end = mem_start;
2748
2749
2750 mem_start = PAGE_ALIGN(mem_start);
2751 dt_struct_start = mem_start;
2752 prom_printf("Building dt structure...\n");
2753 scan_dt_build_struct(root, &mem_start, &mem_end);
2754 dt_push_token(OF_DT_END, &mem_start, &mem_end);
2755 dt_struct_end = PAGE_ALIGN(mem_start);
2756
2757
2758 hdr->boot_cpuid_phys = cpu_to_be32(prom.cpu);
2759 hdr->magic = cpu_to_be32(OF_DT_HEADER);
2760 hdr->totalsize = cpu_to_be32(dt_struct_end - dt_header_start);
2761 hdr->off_dt_struct = cpu_to_be32(dt_struct_start - dt_header_start);
2762 hdr->off_dt_strings = cpu_to_be32(dt_string_start - dt_header_start);
2763 hdr->dt_strings_size = cpu_to_be32(dt_string_end - dt_string_start);
2764 hdr->off_mem_rsvmap = cpu_to_be32(((unsigned long)rsvmap) - dt_header_start);
2765 hdr->version = cpu_to_be32(OF_DT_VERSION);
2766
2767 hdr->last_comp_version = cpu_to_be32(0x10);
2768
2769
2770 memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map));
2771
2772 #ifdef DEBUG_PROM
2773 {
2774 int i;
2775 prom_printf("reserved memory map:\n");
2776 for (i = 0; i < mem_reserve_cnt; i++)
2777 prom_printf(" %llx - %llx\n",
2778 be64_to_cpu(mem_reserve_map[i].base),
2779 be64_to_cpu(mem_reserve_map[i].size));
2780 }
2781 #endif
2782
2783
2784
2785 mem_reserve_cnt = MEM_RESERVE_MAP_SIZE;
2786
2787 prom_printf("Device tree strings 0x%lx -> 0x%lx\n",
2788 dt_string_start, dt_string_end);
2789 prom_printf("Device tree struct 0x%lx -> 0x%lx\n",
2790 dt_struct_start, dt_struct_end);
2791 }
2792
2793 #ifdef CONFIG_PPC_MAPLE
2794
2795
2796 static void __init fixup_device_tree_maple(void)
2797 {
2798 phandle isa;
2799 u32 rloc = 0x01002000;
2800 u32 isa_ranges[6];
2801 char *name;
2802
2803 name = "/ht@0/isa@4";
2804 isa = call_prom("finddevice", 1, 1, ADDR(name));
2805 if (!PHANDLE_VALID(isa)) {
2806 name = "/ht@0/isa@6";
2807 isa = call_prom("finddevice", 1, 1, ADDR(name));
2808 rloc = 0x01003000;
2809 }
2810 if (!PHANDLE_VALID(isa))
2811 return;
2812
2813 if (prom_getproplen(isa, "ranges") != 12)
2814 return;
2815 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2816 == PROM_ERROR)
2817 return;
2818
2819 if (isa_ranges[0] != 0x1 ||
2820 isa_ranges[1] != 0xf4000000 ||
2821 isa_ranges[2] != 0x00010000)
2822 return;
2823
2824 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
2825
2826 isa_ranges[0] = 0x1;
2827 isa_ranges[1] = 0x0;
2828 isa_ranges[2] = rloc;
2829 isa_ranges[3] = 0x0;
2830 isa_ranges[4] = 0x0;
2831 isa_ranges[5] = 0x00010000;
2832 prom_setprop(isa, name, "ranges",
2833 isa_ranges, sizeof(isa_ranges));
2834 }
2835
2836 #define CPC925_MC_START 0xf8000000
2837 #define CPC925_MC_LENGTH 0x1000000
2838
2839 static void __init fixup_device_tree_maple_memory_controller(void)
2840 {
2841 phandle mc;
2842 u32 mc_reg[4];
2843 char *name = "/hostbridge@f8000000";
2844 u32 ac, sc;
2845
2846 mc = call_prom("finddevice", 1, 1, ADDR(name));
2847 if (!PHANDLE_VALID(mc))
2848 return;
2849
2850 if (prom_getproplen(mc, "reg") != 8)
2851 return;
2852
2853 prom_getprop(prom.root, "#address-cells", &ac, sizeof(ac));
2854 prom_getprop(prom.root, "#size-cells", &sc, sizeof(sc));
2855 if ((ac != 2) || (sc != 2))
2856 return;
2857
2858 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2859 return;
2860
2861 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2862 return;
2863
2864 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2865
2866 mc_reg[0] = 0x0;
2867 mc_reg[1] = CPC925_MC_START;
2868 mc_reg[2] = 0x0;
2869 mc_reg[3] = CPC925_MC_LENGTH;
2870 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2871 }
2872 #else
2873 #define fixup_device_tree_maple()
2874 #define fixup_device_tree_maple_memory_controller()
2875 #endif
2876
2877 #ifdef CONFIG_PPC_CHRP
2878
2879
2880
2881
2882
2883 static void __init fixup_device_tree_chrp(void)
2884 {
2885 phandle ph;
2886 u32 prop[6];
2887 u32 rloc = 0x01006000;
2888 char *name;
2889 int rc;
2890
2891 name = "/pci@80000000/isa@c";
2892 ph = call_prom("finddevice", 1, 1, ADDR(name));
2893 if (!PHANDLE_VALID(ph)) {
2894 name = "/pci@ff500000/isa@6";
2895 ph = call_prom("finddevice", 1, 1, ADDR(name));
2896 rloc = 0x01003000;
2897 }
2898 if (PHANDLE_VALID(ph)) {
2899 rc = prom_getproplen(ph, "ranges");
2900 if (rc == 0 || rc == PROM_ERROR) {
2901 prom_printf("Fixing up missing ISA range on Pegasos...\n");
2902
2903 prop[0] = 0x1;
2904 prop[1] = 0x0;
2905 prop[2] = rloc;
2906 prop[3] = 0x0;
2907 prop[4] = 0x0;
2908 prop[5] = 0x00010000;
2909 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2910 }
2911 }
2912
2913 name = "/pci@80000000/ide@C,1";
2914 ph = call_prom("finddevice", 1, 1, ADDR(name));
2915 if (PHANDLE_VALID(ph)) {
2916 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2917 prop[0] = 14;
2918 prop[1] = 0x0;
2919 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2920 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2921 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2922 if (rc == sizeof(u32)) {
2923 prop[0] &= ~0x5;
2924 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2925 }
2926 }
2927 }
2928 #else
2929 #define fixup_device_tree_chrp()
2930 #endif
2931
2932 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2933 static void __init fixup_device_tree_pmac(void)
2934 {
2935 phandle u3, i2c, mpic;
2936 u32 u3_rev;
2937 u32 interrupts[2];
2938 u32 parent;
2939
2940
2941 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2942 if (!PHANDLE_VALID(u3))
2943 return;
2944 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2945 if (!PHANDLE_VALID(i2c))
2946 return;
2947 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2948 if (!PHANDLE_VALID(mpic))
2949 return;
2950
2951
2952 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2953 == PROM_ERROR)
2954 return;
2955 if (u3_rev < 0x35 || u3_rev > 0x39)
2956 return;
2957
2958 if (prom_getproplen(i2c, "interrupts") > 0)
2959 return;
2960
2961 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2962
2963
2964 interrupts[0] = 0;
2965 interrupts[1] = 1;
2966 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2967 &interrupts, sizeof(interrupts));
2968 parent = (u32)mpic;
2969 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2970 &parent, sizeof(parent));
2971 }
2972 #else
2973 #define fixup_device_tree_pmac()
2974 #endif
2975
2976 #ifdef CONFIG_PPC_EFIKA
2977
2978
2979
2980
2981
2982
2983 static void __init fixup_device_tree_efika_add_phy(void)
2984 {
2985 u32 node;
2986 char prop[64];
2987 int rv;
2988
2989
2990 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
2991 if (!PHANDLE_VALID(node))
2992 return;
2993
2994
2995 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2996 if (rv <= 0)
2997 return;
2998
2999
3000
3001
3002
3003
3004
3005 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
3006 if (!PHANDLE_VALID(node)) {
3007 prom_printf("Adding Ethernet MDIO node\n");
3008 call_prom("interpret", 1, 1,
3009 " s\" /builtin\" find-device"
3010 " new-device"
3011 " 1 encode-int s\" #address-cells\" property"
3012 " 0 encode-int s\" #size-cells\" property"
3013 " s\" mdio\" device-name"
3014 " s\" fsl,mpc5200b-mdio\" encode-string"
3015 " s\" compatible\" property"
3016 " 0xf0003000 0x400 reg"
3017 " 0x2 encode-int"
3018 " 0x5 encode-int encode+"
3019 " 0x3 encode-int encode+"
3020 " s\" interrupts\" property"
3021 " finish-device");
3022 }
3023
3024
3025
3026 node = call_prom("finddevice", 1, 1,
3027 ADDR("/builtin/mdio/ethernet-phy"));
3028 if (!PHANDLE_VALID(node)) {
3029 prom_printf("Adding Ethernet PHY node\n");
3030 call_prom("interpret", 1, 1,
3031 " s\" /builtin/mdio\" find-device"
3032 " new-device"
3033 " s\" ethernet-phy\" device-name"
3034 " 0x10 encode-int s\" reg\" property"
3035 " my-self"
3036 " ihandle>phandle"
3037 " finish-device"
3038 " s\" /builtin/ethernet\" find-device"
3039 " encode-int"
3040 " s\" phy-handle\" property"
3041 " device-end");
3042 }
3043 }
3044
3045 static void __init fixup_device_tree_efika(void)
3046 {
3047 int sound_irq[3] = { 2, 2, 0 };
3048 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
3049 3,4,0, 3,5,0, 3,6,0, 3,7,0,
3050 3,8,0, 3,9,0, 3,10,0, 3,11,0,
3051 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
3052 u32 node;
3053 char prop[64];
3054 int rv, len;
3055
3056
3057 node = call_prom("finddevice", 1, 1, ADDR("/"));
3058 if (!PHANDLE_VALID(node))
3059 return;
3060
3061 rv = prom_getprop(node, "model", prop, sizeof(prop));
3062 if (rv == PROM_ERROR)
3063 return;
3064 if (prom_strcmp(prop, "EFIKA5K2"))
3065 return;
3066
3067 prom_printf("Applying EFIKA device tree fixups\n");
3068
3069
3070 node = call_prom("finddevice", 1, 1, ADDR("/"));
3071 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
3072 if (rv != PROM_ERROR && (prom_strcmp(prop, "chrp") == 0))
3073 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
3074
3075
3076
3077 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
3078 if (rv != PROM_ERROR && (prom_strstr(prop, "CHRP")))
3079 prom_setprop(node, "/", "CODEGEN,description",
3080 "Efika 5200B PowerPC System",
3081 sizeof("Efika 5200B PowerPC System"));
3082
3083
3084 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
3085 if (PHANDLE_VALID(node)) {
3086 len = prom_getproplen(node, "interrupts");
3087 if (len == 12) {
3088 prom_printf("Fixing bestcomm interrupts property\n");
3089 prom_setprop(node, "/builtin/bestcom", "interrupts",
3090 bcomm_irq, sizeof(bcomm_irq));
3091 }
3092 }
3093
3094
3095 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
3096 if (PHANDLE_VALID(node)) {
3097 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
3098 if (rv == PROM_ERROR) {
3099 prom_printf("Adding sound interrupts property\n");
3100 prom_setprop(node, "/builtin/sound", "interrupts",
3101 sound_irq, sizeof(sound_irq));
3102 }
3103 }
3104
3105
3106 fixup_device_tree_efika_add_phy();
3107 }
3108 #else
3109 #define fixup_device_tree_efika()
3110 #endif
3111
3112 #ifdef CONFIG_PPC_PASEMI_NEMO
3113
3114
3115
3116
3117
3118
3119 static void __init fixup_device_tree_pasemi(void)
3120 {
3121 u32 interrupts[2], parent, rval, val = 0;
3122 char *name, *pci_name;
3123 phandle iob, node;
3124
3125
3126 name = "/pxp@0,e0000000";
3127 iob = call_prom("finddevice", 1, 1, ADDR(name));
3128 if (!PHANDLE_VALID(iob))
3129 return;
3130
3131
3132 if (prom_getproplen(iob, "interrupt-controller") !=PROM_ERROR)
3133 return;
3134
3135 prom_printf("adding interrupt-controller property for SB600...\n");
3136
3137 prom_setprop(iob, name, "interrupt-controller", &val, 0);
3138
3139 pci_name = "/pxp@0,e0000000/pci@11";
3140 node = call_prom("finddevice", 1, 1, ADDR(pci_name));
3141 parent = ADDR(iob);
3142
3143 for( ; prom_next_node(&node); ) {
3144
3145 if (!PHANDLE_VALID(node))
3146 continue;
3147
3148 rval = prom_getproplen(node, "interrupts");
3149 if (rval == 0 || rval == PROM_ERROR)
3150 continue;
3151
3152 prom_getprop(node, "interrupts", &interrupts, sizeof(interrupts));
3153 if ((interrupts[0] < 212) || (interrupts[0] > 222))
3154 continue;
3155
3156
3157 if ((interrupts[0] >= 212) && (interrupts[0] <= 215))
3158 interrupts[0] -= 203;
3159 if ((interrupts[0] >= 216) && (interrupts[0] <= 220))
3160 interrupts[0] -= 213;
3161 if (interrupts[0] == 221)
3162 interrupts[0] = 14;
3163 if (interrupts[0] == 222)
3164 interrupts[0] = 8;
3165
3166 prom_setprop(node, pci_name, "interrupts", interrupts,
3167 sizeof(interrupts));
3168 prom_setprop(node, pci_name, "interrupt-parent", &parent,
3169 sizeof(parent));
3170 }
3171
3172
3173
3174
3175
3176
3177 name = "/pxp@0,e0000000/io-bridge@0";
3178 iob = call_prom("finddevice", 1, 1, ADDR(name));
3179 if (!PHANDLE_VALID(iob))
3180 return;
3181
3182
3183
3184 prom_printf("Changing device_type of SB600 node...\n");
3185
3186 prom_setprop(iob, name, "device_type", "isa", sizeof("isa"));
3187 }
3188 #else
3189 static inline void fixup_device_tree_pasemi(void) { }
3190 #endif
3191
3192 static void __init fixup_device_tree(void)
3193 {
3194 fixup_device_tree_maple();
3195 fixup_device_tree_maple_memory_controller();
3196 fixup_device_tree_chrp();
3197 fixup_device_tree_pmac();
3198 fixup_device_tree_efika();
3199 fixup_device_tree_pasemi();
3200 }
3201
3202 static void __init prom_find_boot_cpu(void)
3203 {
3204 __be32 rval;
3205 ihandle prom_cpu;
3206 phandle cpu_pkg;
3207
3208 rval = 0;
3209 if (prom_getprop(prom.chosen, "cpu", &rval, sizeof(rval)) <= 0)
3210 return;
3211 prom_cpu = be32_to_cpu(rval);
3212
3213 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
3214
3215 if (!PHANDLE_VALID(cpu_pkg))
3216 return;
3217
3218 prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval));
3219 prom.cpu = be32_to_cpu(rval);
3220
3221 prom_debug("Booting CPU hw index = %d\n", prom.cpu);
3222 }
3223
3224 static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
3225 {
3226 #ifdef CONFIG_BLK_DEV_INITRD
3227 if (r3 && r4 && r4 != 0xdeadbeef) {
3228 __be64 val;
3229
3230 prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3;
3231 prom_initrd_end = prom_initrd_start + r4;
3232
3233 val = cpu_to_be64(prom_initrd_start);
3234 prom_setprop(prom.chosen, "/chosen", "linux,initrd-start",
3235 &val, sizeof(val));
3236 val = cpu_to_be64(prom_initrd_end);
3237 prom_setprop(prom.chosen, "/chosen", "linux,initrd-end",
3238 &val, sizeof(val));
3239
3240 reserve_mem(prom_initrd_start,
3241 prom_initrd_end - prom_initrd_start);
3242
3243 prom_debug("initrd_start=0x%lx\n", prom_initrd_start);
3244 prom_debug("initrd_end=0x%lx\n", prom_initrd_end);
3245 }
3246 #endif
3247 }
3248
3249 #ifdef CONFIG_PPC_SVM
3250
3251
3252
3253 static int __init enter_secure_mode(unsigned long kbase, unsigned long fdt)
3254 {
3255 register unsigned long r3 asm("r3") = UV_ESM;
3256 register unsigned long r4 asm("r4") = kbase;
3257 register unsigned long r5 asm("r5") = fdt;
3258
3259 asm volatile("sc 2" : "+r"(r3) : "r"(r4), "r"(r5));
3260
3261 return r3;
3262 }
3263
3264
3265
3266
3267 static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3268 {
3269 int ret;
3270
3271 if (!prom_svm_enable)
3272 return;
3273
3274
3275 prom_printf("Switching to secure mode.\n");
3276
3277
3278
3279
3280
3281
3282 relocate(KERNELBASE);
3283
3284 ret = enter_secure_mode(kbase, fdt);
3285
3286
3287 relocate(kbase);
3288
3289 if (ret != U_SUCCESS) {
3290 prom_printf("Returned %d from switching to secure mode.\n", ret);
3291 prom_rtas_os_term("Switch to secure mode failed.\n");
3292 }
3293 }
3294 #else
3295 static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3296 {
3297 }
3298 #endif
3299
3300
3301
3302
3303
3304
3305 unsigned long __init prom_init(unsigned long r3, unsigned long r4,
3306 unsigned long pp,
3307 unsigned long r6, unsigned long r7,
3308 unsigned long kbase)
3309 {
3310 unsigned long hdr;
3311
3312 #ifdef CONFIG_PPC32
3313 unsigned long offset = reloc_offset();
3314 reloc_got2(offset);
3315 #endif
3316
3317
3318
3319
3320 memset(&__bss_start, 0, __bss_stop - __bss_start);
3321
3322
3323
3324
3325
3326 prom_init_client_services(pp);
3327
3328
3329
3330
3331
3332 prom_find_mmu();
3333
3334
3335
3336
3337 prom_init_stdout();
3338
3339 prom_printf("Preparing to boot %s", linux_banner);
3340
3341
3342
3343
3344
3345 of_platform = prom_find_machine_type();
3346 prom_printf("Detected machine type: %x\n", of_platform);
3347
3348 #ifndef CONFIG_NONSTATIC_KERNEL
3349
3350 if (PHYSICAL_START > 0)
3351 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
3352 #endif
3353
3354
3355
3356
3357 prom_check_initrd(r3, r4);
3358
3359
3360
3361
3362 early_cmdline_parse();
3363
3364 #ifdef CONFIG_PPC_PSERIES
3365
3366
3367
3368 if (of_platform == PLATFORM_PSERIES ||
3369 of_platform == PLATFORM_PSERIES_LPAR)
3370 prom_send_capabilities();
3371 #endif
3372
3373
3374
3375
3376 if (of_platform != PLATFORM_POWERMAC)
3377 copy_and_flush(0, kbase, 0x100, 0);
3378
3379
3380
3381
3382 prom_init_mem();
3383
3384
3385
3386
3387 prom_find_boot_cpu();
3388
3389
3390
3391
3392 prom_check_displays();
3393
3394 #if defined(CONFIG_PPC64) && defined(__BIG_ENDIAN__)
3395
3396
3397
3398
3399
3400 if (of_platform == PLATFORM_PSERIES)
3401 prom_initialize_tce_table();
3402 #endif
3403
3404
3405
3406
3407
3408 if (of_platform != PLATFORM_POWERMAC)
3409 prom_instantiate_rtas();
3410
3411 #ifdef CONFIG_PPC64
3412
3413 prom_instantiate_sml();
3414 #endif
3415
3416
3417
3418
3419
3420
3421
3422
3423 if (of_platform != PLATFORM_POWERMAC)
3424 prom_hold_cpus();
3425
3426
3427
3428
3429 if (prom_memory_limit) {
3430 __be64 val = cpu_to_be64(prom_memory_limit);
3431 prom_setprop(prom.chosen, "/chosen", "linux,memory-limit",
3432 &val, sizeof(val));
3433 }
3434 #ifdef CONFIG_PPC64
3435 if (prom_iommu_off)
3436 prom_setprop(prom.chosen, "/chosen", "linux,iommu-off",
3437 NULL, 0);
3438
3439 if (prom_iommu_force_on)
3440 prom_setprop(prom.chosen, "/chosen", "linux,iommu-force-on",
3441 NULL, 0);
3442
3443 if (prom_tce_alloc_start) {
3444 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-start",
3445 &prom_tce_alloc_start,
3446 sizeof(prom_tce_alloc_start));
3447 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-end",
3448 &prom_tce_alloc_end,
3449 sizeof(prom_tce_alloc_end));
3450 }
3451 #endif
3452
3453
3454
3455
3456 fixup_device_tree();
3457
3458
3459
3460
3461 prom_printf("copying OF device tree...\n");
3462 flatten_device_tree();
3463
3464
3465
3466
3467
3468
3469 if (of_platform != PLATFORM_POWERMAC)
3470 prom_close_stdin();
3471
3472
3473
3474
3475
3476 prom_printf("Quiescing Open Firmware ...\n");
3477 call_prom("quiesce", 0, 0);
3478
3479
3480
3481
3482
3483
3484 hdr = dt_header_start;
3485
3486 prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
3487 prom_debug("->dt_header_start=0x%lx\n", hdr);
3488
3489 #ifdef CONFIG_PPC32
3490 reloc_got2(-offset);
3491 #endif
3492
3493
3494 setup_secure_guest(kbase, hdr);
3495
3496 __start(hdr, kbase, 0, 0, 0, 0, 0);
3497
3498 return 0;
3499 }