blob: 84f763e0fe1d8ed5a1d46272b0397231fa0db370 [file] [log] [blame]
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001/*
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
Daniel Axtens054f3672017-07-12 14:36:04 -070018/* we cannot use FORTIFY as it brings in new symbols */
19#define __NO_FORTIFY
20
Paul Mackerras9b6b5632005-10-06 12:06:20 +100021#include <stdarg.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100022#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/threads.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28#include <linux/pci.h>
29#include <linux/proc_fs.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100030#include <linux/delay.h>
31#include <linux/initrd.h>
32#include <linux/bitops.h>
33#include <asm/prom.h>
34#include <asm/rtas.h>
35#include <asm/page.h>
36#include <asm/processor.h>
37#include <asm/irq.h>
38#include <asm/io.h>
39#include <asm/smp.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100040#include <asm/mmu.h>
41#include <asm/pgtable.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100042#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100043#include <asm/btext.h>
44#include <asm/sections.h>
45#include <asm/machdep.h>
Daniel Axtens0545d542016-09-06 15:32:43 +100046#include <asm/asm-prototypes.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100047
Paul Mackerras9b6b5632005-10-06 12:06:20 +100048#include <linux/linux_logo.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100049
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +110050/* All of prom_init bss lives here */
51#define __prombss __initdata
52
Paul Mackerras9b6b5632005-10-06 12:06:20 +100053/*
Paul Mackerras9b6b5632005-10-06 12:06:20 +100054 * Eventually bump that one up
55 */
56#define DEVTREE_CHUNK_SIZE 0x100000
57
58/*
59 * This is the size of the local memory reserve map that gets copied
60 * into the boot params passed to the kernel. That size is totally
61 * flexible as the kernel just reads the list until it encounters an
62 * entry with size 0, so it can be changed without breaking binary
63 * compatibility
64 */
65#define MEM_RESERVE_MAP_SIZE 8
66
67/*
68 * prom_init() is called very early on, before the kernel text
69 * and data have been mapped to KERNELBASE. At this point the code
70 * is running at whatever address it has been loaded at.
71 * On ppc32 we compile with -mrelocatable, which means that references
72 * to extern and static variables get relocated automatically.
Anton Blanchard5ac47f72012-11-26 17:39:03 +000073 * ppc64 objects are always relocatable, we just need to relocate the
74 * TOC.
Paul Mackerras9b6b5632005-10-06 12:06:20 +100075 *
76 * Because OF may have mapped I/O devices into the area starting at
77 * KERNELBASE, particularly on CHRP machines, we can't safely call
78 * OF once the kernel has been mapped to KERNELBASE. Therefore all
79 * OF calls must be done within prom_init().
80 *
81 * ADDR is used in calls to call_prom. The 4th and following
82 * arguments to call_prom should be 32-bit values.
83 * On ppc64, 64 bit values are truncated to 32 bits (and
84 * fortunately don't get interpreted as two arguments).
85 */
Anton Blanchard5ac47f72012-11-26 17:39:03 +000086#define ADDR(x) (u32)(unsigned long)(x)
87
Paul Mackerras9b6b5632005-10-06 12:06:20 +100088#ifdef CONFIG_PPC64
Paul Mackerrasa23414b2005-11-10 12:00:55 +110089#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100090#else
Paul Mackerrasa23414b2005-11-10 12:00:55 +110091#define OF_WORKAROUNDS of_workarounds
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +110092static int of_workarounds __prombss;
Paul Mackerras9b6b5632005-10-06 12:06:20 +100093#endif
94
Paul Mackerrasa23414b2005-11-10 12:00:55 +110095#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
96#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
97
Paul Mackerras9b6b5632005-10-06 12:06:20 +100098#define PROM_BUG() do { \
99 prom_printf("kernel BUG at %s line 0x%x!\n", \
Anton Blanchard5827d412012-11-26 17:40:03 +0000100 __FILE__, __LINE__); \
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000101 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
102} while (0)
103
104#ifdef DEBUG_PROM
105#define prom_debug(x...) prom_printf(x)
106#else
Mathieu Malaterre85aa4b92018-04-23 21:36:38 +0200107#define prom_debug(x...) do { } while (0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000108#endif
109
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000110
111typedef u32 prom_arg_t;
112
113struct prom_args {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000114 __be32 service;
115 __be32 nargs;
116 __be32 nret;
117 __be32 args[10];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000118};
119
120struct prom_t {
121 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100122 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000123 int cpu;
124 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000125 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100126 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000127};
128
129struct mem_map_entry {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000130 __be64 base;
131 __be64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000132};
133
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000134typedef __be32 cell_t;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000135
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +0000136extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
137 unsigned long r6, unsigned long r7, unsigned long r8,
138 unsigned long r9);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000139
140#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000141extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000142#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000143static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000144{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000145 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000146}
147#endif
148
149extern void copy_and_flush(unsigned long dest, unsigned long src,
150 unsigned long size, unsigned long offset);
151
152/* prom structure */
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100153static struct prom_t __prombss prom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000154
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100155static unsigned long __prombss prom_entry;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000156
157#define PROM_SCRATCH_SIZE 256
158
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100159static char __prombss of_stdout_device[256];
160static char __prombss prom_scratch[PROM_SCRATCH_SIZE];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000161
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100162static unsigned long __prombss dt_header_start;
163static unsigned long __prombss dt_struct_start, dt_struct_end;
164static unsigned long __prombss dt_string_start, dt_string_end;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000165
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100166static unsigned long __prombss prom_initrd_start, prom_initrd_end;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000167
168#ifdef CONFIG_PPC64
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100169static int __prombss prom_iommu_force_on;
170static int __prombss prom_iommu_off;
171static unsigned long __prombss prom_tce_alloc_start;
172static unsigned long __prombss prom_tce_alloc_end;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000173#endif
174
Aneesh Kumar K.V7a22d632018-03-30 17:39:02 +0530175static bool prom_radix_disable __initdata = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100176
177struct platform_support {
178 bool hash_mmu;
179 bool radix_mmu;
180 bool radix_gtse;
Cédric Le Goaterac5e5a52017-08-30 21:46:16 +0200181 bool xive;
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100182};
183
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100184/* Platforms codes are now obsolete in the kernel. Now only used within this
185 * file and ultimately gone too. Feel free to change them if you need, they
186 * are not shared with anything outside of this file anymore
187 */
188#define PLATFORM_PSERIES 0x0100
189#define PLATFORM_PSERIES_LPAR 0x0101
190#define PLATFORM_LPAR 0x0001
191#define PLATFORM_POWERMAC 0x0400
192#define PLATFORM_GENERIC 0x0500
193
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100194static int __prombss of_platform;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000195
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100196static char __prombss prom_cmd_line[COMMAND_LINE_SIZE];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000197
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100198static unsigned long __prombss prom_memory_limit;
Benjamin Krillcf687872009-07-27 22:02:39 +0000199
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100200static unsigned long __prombss alloc_top;
201static unsigned long __prombss alloc_top_high;
202static unsigned long __prombss alloc_bottom;
203static unsigned long __prombss rmo_top;
204static unsigned long __prombss ram_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000205
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100206static struct mem_map_entry __prombss mem_reserve_map[MEM_RESERVE_MAP_SIZE];
207static int __prombss mem_reserve_cnt;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000208
Benjamin Herrenschmidte63334e2018-10-15 13:49:52 +1100209static cell_t __prombss regbuf[1024];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000210
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +1000211static bool rtas_has_query_cpu_stopped;
212
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000213
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000214/*
215 * Error results ... some OF calls will return "-1" on error, some
216 * will return 0, some will return either. To simplify, here are
217 * macros to use with any ihandle or phandle return value to check if
218 * it is valid
219 */
220
221#define PROM_ERROR (-1u)
222#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
223#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
224
225
226/* This is the one and *ONLY* place where we actually call open
227 * firmware.
228 */
229
230static int __init call_prom(const char *service, int nargs, int nret, ...)
231{
232 int i;
233 struct prom_args args;
234 va_list list;
235
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000236 args.service = cpu_to_be32(ADDR(service));
237 args.nargs = cpu_to_be32(nargs);
238 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000239
240 va_start(list, nret);
241 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000242 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000243 va_end(list);
244
245 for (i = 0; i < nret; i++)
246 args.args[nargs+i] = 0;
247
Anton Blanchard5827d412012-11-26 17:40:03 +0000248 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000249 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000250
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000251 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000252}
253
254static int __init call_prom_ret(const char *service, int nargs, int nret,
255 prom_arg_t *rets, ...)
256{
257 int i;
258 struct prom_args args;
259 va_list list;
260
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000261 args.service = cpu_to_be32(ADDR(service));
262 args.nargs = cpu_to_be32(nargs);
263 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000264
265 va_start(list, rets);
266 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000267 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000268 va_end(list);
269
270 for (i = 0; i < nret; i++)
Olaf Heringed1189b72005-11-29 14:04:05 +0100271 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000272
Anton Blanchard5827d412012-11-26 17:40:03 +0000273 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000274 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000275
276 if (rets != NULL)
277 for (i = 1; i < nret; ++i)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000278 rets[i-1] = be32_to_cpu(args.args[nargs+i]);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000279
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000280 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000281}
282
283
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000284static void __init prom_print(const char *msg)
285{
286 const char *p, *q;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000287
Anton Blanchard5827d412012-11-26 17:40:03 +0000288 if (prom.stdout == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000289 return;
290
291 for (p = msg; *p != 0; p = q) {
292 for (q = p; *q != 0 && *q != '\n'; ++q)
293 ;
294 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000295 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000296 if (*q == 0)
297 break;
298 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000299 call_prom("write", 3, 1, prom.stdout, ADDR("\r\n"), 2);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000300 }
301}
302
303
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200304/*
305 * Both prom_print_hex & prom_print_dec takes an unsigned long as input so that
306 * we do not need __udivdi3 or __umoddi3 on 32bits.
307 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000308static void __init prom_print_hex(unsigned long val)
309{
310 int i, nibbles = sizeof(val)*2;
311 char buf[sizeof(val)*2+1];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000312
313 for (i = nibbles-1; i >= 0; i--) {
314 buf[i] = (val & 0xf) + '0';
315 if (buf[i] > '9')
316 buf[i] += ('a'-'0'-10);
317 val >>= 4;
318 }
319 buf[nibbles] = '\0';
Anton Blanchard5827d412012-11-26 17:40:03 +0000320 call_prom("write", 3, 1, prom.stdout, buf, nibbles);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000321}
322
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000323/* max number of decimal digits in an unsigned long */
324#define UL_DIGITS 21
325static void __init prom_print_dec(unsigned long val)
326{
327 int i, size;
328 char buf[UL_DIGITS+1];
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000329
330 for (i = UL_DIGITS-1; i >= 0; i--) {
331 buf[i] = (val % 10) + '0';
332 val = val/10;
333 if (val == 0)
334 break;
335 }
336 /* shift stuff down */
337 size = UL_DIGITS - i;
Anton Blanchard5827d412012-11-26 17:40:03 +0000338 call_prom("write", 3, 1, prom.stdout, buf+i, size);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000339}
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000340
Mathieu Malaterreeae5f702018-04-06 22:12:19 +0200341__printf(1, 2)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000342static void __init prom_printf(const char *format, ...)
343{
344 const char *p, *q, *s;
345 va_list args;
346 unsigned long v;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000347 long vs;
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200348 int n = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000349
350 va_start(args, format);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000351 for (p = format; *p != 0; p = q) {
352 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
353 ;
354 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000355 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000356 if (*q == 0)
357 break;
358 if (*q == '\n') {
359 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000360 call_prom("write", 3, 1, prom.stdout,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000361 ADDR("\r\n"), 2);
362 continue;
363 }
364 ++q;
365 if (*q == 0)
366 break;
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200367 while (*q == 'l') {
368 ++q;
369 ++n;
370 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000371 switch (*q) {
372 case 's':
373 ++q;
374 s = va_arg(args, const char *);
375 prom_print(s);
376 break;
377 case 'x':
378 ++q;
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200379 switch (n) {
380 case 0:
381 v = va_arg(args, unsigned int);
382 break;
383 case 1:
384 v = va_arg(args, unsigned long);
385 break;
386 case 2:
387 default:
388 v = va_arg(args, unsigned long long);
389 break;
390 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000391 prom_print_hex(v);
392 break;
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200393 case 'u':
394 ++q;
395 switch (n) {
396 case 0:
397 v = va_arg(args, unsigned int);
398 break;
399 case 1:
400 v = va_arg(args, unsigned long);
401 break;
402 case 2:
403 default:
404 v = va_arg(args, unsigned long long);
405 break;
406 }
407 prom_print_dec(v);
408 break;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000409 case 'd':
410 ++q;
Mathieu Malaterre8af1da42018-05-29 21:20:01 +0200411 switch (n) {
412 case 0:
413 vs = va_arg(args, int);
414 break;
415 case 1:
416 vs = va_arg(args, long);
417 break;
418 case 2:
419 default:
420 vs = va_arg(args, long long);
421 break;
422 }
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000423 if (vs < 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +0000424 prom_print("-");
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000425 vs = -vs;
426 }
427 prom_print_dec(vs);
428 break;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000429 }
430 }
Daniel Axtens1b855e12015-12-17 19:41:00 +1100431 va_end(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000432}
433
434
Paul Mackerrasa575b802005-10-23 17:23:21 +1000435static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
436 unsigned long align)
437{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000438
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100439 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
440 /*
441 * Old OF requires we claim physical and virtual separately
442 * and then map explicitly (assuming virtual mode)
443 */
444 int ret;
445 prom_arg_t result;
446
447 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000448 ADDR("claim"), prom.memory,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100449 align, size, virt);
450 if (ret != 0 || result == -1)
451 return -1;
452 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000453 ADDR("claim"), prom.mmumap,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100454 align, size, virt);
455 if (ret != 0) {
456 call_prom("call-method", 4, 1, ADDR("release"),
Anton Blanchard5827d412012-11-26 17:40:03 +0000457 prom.memory, size, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100458 return -1;
459 }
460 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000461 call_prom("call-method", 6, 1,
Anton Blanchard5827d412012-11-26 17:40:03 +0000462 ADDR("map"), prom.mmumap, 0x12, size, virt, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100463 return virt;
464 }
465 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
466 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000467}
468
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000469static void __init __attribute__((noreturn)) prom_panic(const char *reason)
470{
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000471 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100472 /* Do not call exit because it clears the screen on pmac
473 * it also causes some sort of double-fault on early pmacs */
Anton Blanchard5827d412012-11-26 17:40:03 +0000474 if (of_platform == PLATFORM_POWERMAC)
Olaf Heringadd60ef2006-03-23 22:03:57 +0100475 asm("trap\n");
476
Stephen Rothwell1d9a4732012-03-21 18:23:27 +0000477 /* ToDo: should put up an SRC here on pSeries */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000478 call_prom("exit", 0, 0);
479
480 for (;;) /* should never get here */
481 ;
482}
483
484
485static int __init prom_next_node(phandle *nodep)
486{
487 phandle node;
488
489 if ((node = *nodep) != 0
490 && (*nodep = call_prom("child", 1, 1, node)) != 0)
491 return 1;
492 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
493 return 1;
494 for (;;) {
495 if ((node = call_prom("parent", 1, 1, node)) == 0)
496 return 0;
497 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
498 return 1;
499 }
500}
501
Tobias Klauser60d862e2016-11-17 17:20:24 +0100502static inline int prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000503 void *value, size_t valuelen)
504{
505 return call_prom("getprop", 4, 1, node, ADDR(pname),
506 (u32)(unsigned long) value, (u32) valuelen);
507}
508
Tobias Klauser60d862e2016-11-17 17:20:24 +0100509static inline int prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000510{
511 return call_prom("getproplen", 2, 1, node, ADDR(pname));
512}
513
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100514static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000515{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100516 char *p = *str;
517
518 while (*q)
519 *p++ = *q++;
520 *p++ = ' ';
521 *str = p;
522}
523
524static char *tohex(unsigned int x)
525{
526 static char digits[] = "0123456789abcdef";
527 static char result[9];
528 int i;
529
530 result[8] = 0;
531 i = 8;
532 do {
533 --i;
534 result[i] = digits[x & 0xf];
535 x >>= 4;
536 } while (x != 0 && i > 0);
537 return &result[i];
538}
539
540static int __init prom_setprop(phandle node, const char *nodename,
541 const char *pname, void *value, size_t valuelen)
542{
543 char cmd[256], *p;
544
545 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
546 return call_prom("setprop", 4, 1, node, ADDR(pname),
547 (u32)(unsigned long) value, (u32) valuelen);
548
549 /* gah... setprop doesn't work on longtrail, have to use interpret */
550 p = cmd;
551 add_string(&p, "dev");
552 add_string(&p, nodename);
553 add_string(&p, tohex((u32)(unsigned long) value));
554 add_string(&p, tohex(valuelen));
555 add_string(&p, tohex(ADDR(pname)));
Anton Blanchard5827d412012-11-26 17:40:03 +0000556 add_string(&p, tohex(strlen(pname)));
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100557 add_string(&p, "property");
558 *p = 0;
559 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000560}
561
Anton Blanchard5827d412012-11-26 17:40:03 +0000562/* We can't use the standard versions because of relocation headaches. */
Benjamin Krillcf687872009-07-27 22:02:39 +0000563#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
564 || ('a' <= (c) && (c) <= 'f') \
565 || ('A' <= (c) && (c) <= 'F'))
566
567#define isdigit(c) ('0' <= (c) && (c) <= '9')
568#define islower(c) ('a' <= (c) && (c) <= 'z')
569#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
570
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000571static unsigned long prom_strtoul(const char *cp, const char **endp)
Benjamin Krillcf687872009-07-27 22:02:39 +0000572{
573 unsigned long result = 0, base = 10, value;
574
575 if (*cp == '0') {
576 base = 8;
577 cp++;
578 if (toupper(*cp) == 'X') {
579 cp++;
580 base = 16;
581 }
582 }
583
584 while (isxdigit(*cp) &&
585 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
586 result = result * base + value;
587 cp++;
588 }
589
590 if (endp)
591 *endp = cp;
592
593 return result;
594}
595
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000596static unsigned long prom_memparse(const char *ptr, const char **retptr)
Benjamin Krillcf687872009-07-27 22:02:39 +0000597{
598 unsigned long ret = prom_strtoul(ptr, retptr);
599 int shift = 0;
600
601 /*
602 * We can't use a switch here because GCC *may* generate a
603 * jump table which won't work, because we're not running at
604 * the address we're linked at.
605 */
606 if ('G' == **retptr || 'g' == **retptr)
607 shift = 30;
608
609 if ('M' == **retptr || 'm' == **retptr)
610 shift = 20;
611
612 if ('K' == **retptr || 'k' == **retptr)
613 shift = 10;
614
615 if (shift) {
616 ret <<= shift;
617 (*retptr)++;
618 }
619
620 return ret;
621}
622
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000623/*
624 * Early parsing of the command line passed to the kernel, used for
625 * "mem=x" and the options that affect the iommu
626 */
627static void __init early_cmdline_parse(void)
628{
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100629 const char *opt;
Benjamin Krillcf687872009-07-27 22:02:39 +0000630
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100631 char *p;
Mathieu Malaterreeab00a22018-04-04 22:08:35 +0200632 int l __maybe_unused = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000633
Anton Blanchard5827d412012-11-26 17:40:03 +0000634 prom_cmd_line[0] = 0;
635 p = prom_cmd_line;
636 if ((long)prom.chosen > 0)
637 l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000638#ifdef CONFIG_CMDLINE
Amos Waterland0e4aa9c2006-06-12 23:45:02 -0400639 if (l <= 0 || p[0] == '\0') /* dbl check */
Anton Blanchard5827d412012-11-26 17:40:03 +0000640 strlcpy(prom_cmd_line,
641 CONFIG_CMDLINE, sizeof(prom_cmd_line));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000642#endif /* CONFIG_CMDLINE */
Anton Blanchard5827d412012-11-26 17:40:03 +0000643 prom_printf("command line: %s\n", prom_cmd_line);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000644
645#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +0000646 opt = strstr(prom_cmd_line, "iommu=");
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000647 if (opt) {
648 prom_printf("iommu opt is: %s\n", opt);
649 opt += 6;
650 while (*opt && *opt == ' ')
651 opt++;
Anton Blanchard5827d412012-11-26 17:40:03 +0000652 if (!strncmp(opt, "off", 3))
653 prom_iommu_off = 1;
654 else if (!strncmp(opt, "force", 5))
655 prom_iommu_force_on = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000656 }
657#endif
Anton Blanchard5827d412012-11-26 17:40:03 +0000658 opt = strstr(prom_cmd_line, "mem=");
Benjamin Krillcf687872009-07-27 22:02:39 +0000659 if (opt) {
660 opt += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +0000661 prom_memory_limit = prom_memparse(opt, (const char **)&opt);
Benjamin Krillcf687872009-07-27 22:02:39 +0000662#ifdef CONFIG_PPC64
663 /* Align to 16 MB == size of ppc64 large page */
Anton Blanchard5827d412012-11-26 17:40:03 +0000664 prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
Benjamin Krillcf687872009-07-27 22:02:39 +0000665#endif
666 }
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100667
668 opt = strstr(prom_cmd_line, "disable_radix");
669 if (opt) {
Aneesh Kumar K.V7a22d632018-03-30 17:39:02 +0530670 opt += 13;
671 if (*opt && *opt == '=') {
672 bool val;
673
674 if (kstrtobool(++opt, &val))
675 prom_radix_disable = false;
676 else
677 prom_radix_disable = val;
678 } else
679 prom_radix_disable = true;
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100680 }
Aneesh Kumar K.V7a22d632018-03-30 17:39:02 +0530681 if (prom_radix_disable)
682 prom_debug("Radix disabled from cmdline\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000683}
684
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +1100685#ifdef CONFIG_PPC_PSERIES
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000686/*
Nathan Fontenot530b5e12013-04-24 05:53:10 +0000687 * The architecture vector has an array of PVR mask/value pairs,
688 * followed by # option vectors - 1, followed by the option vectors.
689 *
690 * See prom.h for the definition of the bits specified in the
691 * architecture vector.
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000692 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000693
Michael Ellermane8a4fd02014-08-29 17:01:43 +1000694/* Firmware expects the value to be n - 1, where n is the # of vectors */
695#define NUM_VECTORS(n) ((n) - 1)
696
697/*
698 * Firmware expects 1 + n - 2, where n is the length of the option vector in
699 * bytes. The 1 accounts for the length byte itself, the - 2 .. ?
700 */
701#define VECTOR_LENGTH(n) (1 + (n) - 2)
702
Michael Ellermand03d1d62016-11-18 23:15:41 +1100703struct option_vector1 {
704 u8 byte1;
705 u8 arch_versions;
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100706 u8 arch_versions3;
Michael Ellermand03d1d62016-11-18 23:15:41 +1100707} __packed;
708
709struct option_vector2 {
710 u8 byte1;
711 __be16 reserved;
712 __be32 real_base;
713 __be32 real_size;
714 __be32 virt_base;
715 __be32 virt_size;
716 __be32 load_base;
717 __be32 min_rma;
718 __be32 min_load;
719 u8 min_rma_percent;
720 u8 max_pft_size;
721} __packed;
722
723struct option_vector3 {
724 u8 byte1;
725 u8 byte2;
726} __packed;
727
728struct option_vector4 {
729 u8 byte1;
730 u8 min_vp_cap;
731} __packed;
732
733struct option_vector5 {
734 u8 byte1;
735 u8 byte2;
736 u8 byte3;
737 u8 cmo;
738 u8 associativity;
739 u8 bin_opts;
740 u8 micro_checkpoint;
741 u8 reserved0;
742 __be32 max_cpus;
743 __be16 papr_level;
744 __be16 reserved1;
745 u8 platform_facilities;
746 u8 reserved2;
747 __be16 reserved3;
748 u8 subprocessors;
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100749 u8 byte22;
750 u8 intarch;
751 u8 mmu;
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100752 u8 hash_ext;
753 u8 radix_ext;
Michael Ellermand03d1d62016-11-18 23:15:41 +1100754} __packed;
755
756struct option_vector6 {
757 u8 reserved;
758 u8 secondary_pteg;
759 u8 os_name;
760} __packed;
761
Michael Ellerman76ffb572016-11-18 23:15:42 +1100762struct ibm_arch_vec {
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100763 struct { u32 mask, val; } pvrs[12];
Michael Ellerman76ffb572016-11-18 23:15:42 +1100764
765 u8 num_vectors;
766
767 u8 vec1_len;
768 struct option_vector1 vec1;
769
770 u8 vec2_len;
771 struct option_vector2 vec2;
772
773 u8 vec3_len;
774 struct option_vector3 vec3;
775
776 u8 vec4_len;
777 struct option_vector4 vec4;
778
779 u8 vec5_len;
780 struct option_vector5 vec5;
781
782 u8 vec6_len;
783 struct option_vector6 vec6;
784} __packed;
785
786struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
787 .pvrs = {
788 {
789 .mask = cpu_to_be32(0xfffe0000), /* POWER5/POWER5+ */
790 .val = cpu_to_be32(0x003a0000),
791 },
792 {
793 .mask = cpu_to_be32(0xffff0000), /* POWER6 */
794 .val = cpu_to_be32(0x003e0000),
795 },
796 {
797 .mask = cpu_to_be32(0xffff0000), /* POWER7 */
798 .val = cpu_to_be32(0x003f0000),
799 },
800 {
801 .mask = cpu_to_be32(0xffff0000), /* POWER8E */
802 .val = cpu_to_be32(0x004b0000),
803 },
804 {
805 .mask = cpu_to_be32(0xffff0000), /* POWER8NVL */
806 .val = cpu_to_be32(0x004c0000),
807 },
808 {
809 .mask = cpu_to_be32(0xffff0000), /* POWER8 */
810 .val = cpu_to_be32(0x004d0000),
811 },
812 {
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100813 .mask = cpu_to_be32(0xffff0000), /* POWER9 */
814 .val = cpu_to_be32(0x004e0000),
815 },
816 {
817 .mask = cpu_to_be32(0xffffffff), /* all 3.00-compliant */
818 .val = cpu_to_be32(0x0f000005),
819 },
820 {
Michael Ellerman76ffb572016-11-18 23:15:42 +1100821 .mask = cpu_to_be32(0xffffffff), /* all 2.07-compliant */
822 .val = cpu_to_be32(0x0f000004),
823 },
824 {
825 .mask = cpu_to_be32(0xffffffff), /* all 2.06-compliant */
826 .val = cpu_to_be32(0x0f000003),
827 },
828 {
829 .mask = cpu_to_be32(0xffffffff), /* all 2.05-compliant */
830 .val = cpu_to_be32(0x0f000002),
831 },
832 {
833 .mask = cpu_to_be32(0xfffffffe), /* all 2.04-compliant and earlier */
834 .val = cpu_to_be32(0x0f000001),
835 },
836 },
837
838 .num_vectors = NUM_VECTORS(6),
839
840 .vec1_len = VECTOR_LENGTH(sizeof(struct option_vector1)),
841 .vec1 = {
842 .byte1 = 0,
843 .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
844 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100845 .arch_versions3 = OV1_PPC_3_00,
Michael Ellerman76ffb572016-11-18 23:15:42 +1100846 },
847
848 .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)),
849 /* option vector 2: Open Firmware options supported */
850 .vec2 = {
851 .byte1 = OV2_REAL_MODE,
852 .reserved = 0,
853 .real_base = cpu_to_be32(0xffffffff),
854 .real_size = cpu_to_be32(0xffffffff),
855 .virt_base = cpu_to_be32(0xffffffff),
856 .virt_size = cpu_to_be32(0xffffffff),
857 .load_base = cpu_to_be32(0xffffffff),
Sukadev Bhattiprolu687da8f2017-03-27 19:43:14 -0400858 .min_rma = cpu_to_be32(512), /* 512MB min RMA */
Michael Ellerman76ffb572016-11-18 23:15:42 +1100859 .min_load = cpu_to_be32(0xffffffff), /* full client load */
860 .min_rma_percent = 0, /* min RMA percentage of total RAM */
861 .max_pft_size = 48, /* max log_2(hash table size) */
862 },
863
864 .vec3_len = VECTOR_LENGTH(sizeof(struct option_vector3)),
865 /* option vector 3: processor options supported */
866 .vec3 = {
867 .byte1 = 0, /* don't ignore, don't halt */
868 .byte2 = OV3_FP | OV3_VMX | OV3_DFP,
869 },
870
871 .vec4_len = VECTOR_LENGTH(sizeof(struct option_vector4)),
872 /* option vector 4: IBM PAPR implementation */
873 .vec4 = {
874 .byte1 = 0, /* don't halt */
875 .min_vp_cap = OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
876 },
877
878 .vec5_len = VECTOR_LENGTH(sizeof(struct option_vector5)),
879 /* option vector 5: PAPR/OF options */
880 .vec5 = {
881 .byte1 = 0, /* don't ignore, don't halt */
882 .byte2 = OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
883 OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
884#ifdef CONFIG_PCI_MSI
885 /* PCIe/MSI support. Without MSI full PCIe is not supported */
886 OV5_FEAT(OV5_MSI),
887#else
888 0,
889#endif
890 .byte3 = 0,
891 .cmo =
892#ifdef CONFIG_PPC_SMLPAR
893 OV5_FEAT(OV5_CMO) | OV5_FEAT(OV5_XCMO),
894#else
895 0,
896#endif
897 .associativity = OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN),
Michael Roth3dbbaf22017-02-20 19:12:18 -0600898 .bin_opts = OV5_FEAT(OV5_RESIZE_HPT) | OV5_FEAT(OV5_HP_EVT),
Michael Ellerman76ffb572016-11-18 23:15:42 +1100899 .micro_checkpoint = 0,
900 .reserved0 = 0,
901 .max_cpus = cpu_to_be32(NR_CPUS), /* number of cores supported */
902 .papr_level = 0,
903 .reserved1 = 0,
904 .platform_facilities = OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | OV5_FEAT(OV5_PFO_HW_842),
905 .reserved2 = 0,
906 .reserved3 = 0,
907 .subprocessors = 1,
Nathan Fontenot0c38ed62017-12-01 10:48:03 -0600908 .byte22 = OV5_FEAT(OV5_DRMEM_V2),
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100909 .intarch = 0,
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100910 .mmu = 0,
911 .hash_ext = 0,
912 .radix_ext = 0,
Michael Ellerman76ffb572016-11-18 23:15:42 +1100913 },
914
915 /* option vector 6: IBM PAPR hints */
916 .vec6_len = VECTOR_LENGTH(sizeof(struct option_vector6)),
917 .vec6 = {
918 .reserved = 0,
919 .secondary_pteg = 0,
920 .os_name = OV6_LINUX,
921 },
922};
923
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000924/* Old method - ELF header with PT_NOTE sections only works on BE */
925#ifdef __BIG_ENDIAN__
Benjamin Herrenschmidt30c69ca2018-05-31 14:33:40 +1000926static const struct fake_elf {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000927 Elf32_Ehdr elfhdr;
928 Elf32_Phdr phdr[2];
929 struct chrpnote {
930 u32 namesz;
931 u32 descsz;
932 u32 type;
933 char name[8]; /* "PowerPC" */
934 struct chrpdesc {
935 u32 real_mode;
936 u32 real_base;
937 u32 real_size;
938 u32 virt_base;
939 u32 virt_size;
940 u32 load_base;
941 } chrpdesc;
942 } chrpnote;
943 struct rpanote {
944 u32 namesz;
945 u32 descsz;
946 u32 type;
947 char name[24]; /* "IBM,RPA-Client-Config" */
948 struct rpadesc {
949 u32 lpar_affinity;
950 u32 min_rmo_size;
951 u32 min_rmo_percent;
952 u32 max_pft_size;
953 u32 splpar;
954 u32 min_load;
955 u32 new_mem_def;
956 u32 ignore_me;
957 } rpadesc;
958 } rpanote;
Paul Mackerras5663a122008-10-31 22:27:17 +1100959} fake_elf = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000960 .elfhdr = {
961 .e_ident = { 0x7f, 'E', 'L', 'F',
962 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
963 .e_type = ET_EXEC, /* yeah right */
964 .e_machine = EM_PPC,
965 .e_version = EV_CURRENT,
966 .e_phoff = offsetof(struct fake_elf, phdr),
967 .e_phentsize = sizeof(Elf32_Phdr),
968 .e_phnum = 2
969 },
970 .phdr = {
971 [0] = {
972 .p_type = PT_NOTE,
973 .p_offset = offsetof(struct fake_elf, chrpnote),
974 .p_filesz = sizeof(struct chrpnote)
975 }, [1] = {
976 .p_type = PT_NOTE,
977 .p_offset = offsetof(struct fake_elf, rpanote),
978 .p_filesz = sizeof(struct rpanote)
979 }
980 },
981 .chrpnote = {
982 .namesz = sizeof("PowerPC"),
983 .descsz = sizeof(struct chrpdesc),
984 .type = 0x1275,
985 .name = "PowerPC",
986 .chrpdesc = {
987 .real_mode = ~0U, /* ~0 means "don't care" */
988 .real_base = ~0U,
989 .real_size = ~0U,
990 .virt_base = ~0U,
991 .virt_size = ~0U,
992 .load_base = ~0U
993 },
994 },
995 .rpanote = {
996 .namesz = sizeof("IBM,RPA-Client-Config"),
997 .descsz = sizeof(struct rpadesc),
998 .type = 0x12759999,
999 .name = "IBM,RPA-Client-Config",
1000 .rpadesc = {
Paul Mackerras5663a122008-10-31 22:27:17 +11001001 .lpar_affinity = 0,
1002 .min_rmo_size = 64, /* in megabytes */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001003 .min_rmo_percent = 0,
Paul Mackerras5663a122008-10-31 22:27:17 +11001004 .max_pft_size = 48, /* 2^48 bytes max PFT size */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001005 .splpar = 1,
1006 .min_load = ~0U,
Paul Mackerras5663a122008-10-31 22:27:17 +11001007 .new_mem_def = 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001008 }
1009 }
1010};
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001011#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001012
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001013static int __init prom_count_smt_threads(void)
1014{
1015 phandle node;
1016 char type[64];
1017 unsigned int plen;
1018
1019 /* Pick up th first CPU node we can find */
1020 for (node = 0; prom_next_node(&node); ) {
1021 type[0] = 0;
1022 prom_getprop(node, "device_type", type, sizeof(type));
1023
Anton Blanchard5827d412012-11-26 17:40:03 +00001024 if (strcmp(type, "cpu"))
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001025 continue;
1026 /*
1027 * There is an entry for each smt thread, each entry being
1028 * 4 bytes long. All cpus should have the same number of
1029 * smt threads, so return after finding the first.
1030 */
1031 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
1032 if (plen == PROM_ERROR)
1033 break;
1034 plen >>= 2;
Michael Neuling2c48a7d2010-07-27 18:26:21 +00001035 prom_debug("Found %lu smt threads per core\n", (unsigned long)plen);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001036
1037 /* Sanity check */
1038 if (plen < 1 || plen > 64) {
Michael Neuling2c48a7d2010-07-27 18:26:21 +00001039 prom_printf("Threads per core %lu out of bounds, assuming 1\n",
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001040 (unsigned long)plen);
1041 return 1;
1042 }
1043 return plen;
1044 }
1045 prom_debug("No threads found, assuming 1 per core\n");
1046
1047 return 1;
1048
1049}
1050
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001051static void __init prom_parse_mmu_model(u8 val,
1052 struct platform_support *support)
1053{
1054 switch (val) {
1055 case OV5_FEAT(OV5_MMU_DYNAMIC):
1056 case OV5_FEAT(OV5_MMU_EITHER): /* Either Available */
1057 prom_debug("MMU - either supported\n");
1058 support->radix_mmu = !prom_radix_disable;
1059 support->hash_mmu = true;
1060 break;
1061 case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
1062 prom_debug("MMU - radix only\n");
1063 if (prom_radix_disable) {
1064 /*
1065 * If we __have__ to do radix, we're better off ignoring
1066 * the command line rather than not booting.
1067 */
1068 prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
1069 }
1070 support->radix_mmu = true;
1071 break;
1072 case OV5_FEAT(OV5_MMU_HASH):
1073 prom_debug("MMU - hash only\n");
1074 support->hash_mmu = true;
1075 break;
1076 default:
1077 prom_debug("Unknown mmu support option: 0x%x\n", val);
1078 break;
1079 }
1080}
1081
Cédric Le Goaterac5e5a52017-08-30 21:46:16 +02001082static void __init prom_parse_xive_model(u8 val,
1083 struct platform_support *support)
1084{
1085 switch (val) {
1086 case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */
1087 prom_debug("XIVE - either mode supported\n");
1088 support->xive = true;
1089 break;
1090 case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */
1091 prom_debug("XIVE - exploitation mode supported\n");
1092 support->xive = true;
1093 break;
1094 case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
1095 prom_debug("XIVE - legacy mode supported\n");
1096 break;
1097 default:
1098 prom_debug("Unknown xive support option: 0x%x\n", val);
1099 break;
1100 }
1101}
1102
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001103static void __init prom_parse_platform_support(u8 index, u8 val,
1104 struct platform_support *support)
1105{
1106 switch (index) {
1107 case OV5_INDX(OV5_MMU_SUPPORT): /* MMU Model */
1108 prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
1109 break;
1110 case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
1111 if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
1112 prom_debug("Radix - GTSE supported\n");
1113 support->radix_gtse = true;
1114 }
1115 break;
Cédric Le Goaterac5e5a52017-08-30 21:46:16 +02001116 case OV5_INDX(OV5_XIVE_SUPPORT): /* Interrupt mode */
1117 prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT),
1118 support);
1119 break;
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001120 }
1121}
1122
1123static void __init prom_check_platform_support(void)
1124{
1125 struct platform_support supported = {
1126 .hash_mmu = false,
1127 .radix_mmu = false,
Cédric Le Goaterac5e5a52017-08-30 21:46:16 +02001128 .radix_gtse = false,
1129 .xive = false
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001130 };
1131 int prop_len = prom_getproplen(prom.chosen,
1132 "ibm,arch-vec-5-platform-support");
1133 if (prop_len > 1) {
1134 int i;
Suraj Jitindar Singhab912392018-09-05 12:09:50 +10001135 u8 vec[8];
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001136 prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
1137 prop_len);
Suraj Jitindar Singhab912392018-09-05 12:09:50 +10001138 if (prop_len > sizeof(vec))
1139 prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n",
1140 prop_len);
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001141 prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
1142 &vec, sizeof(vec));
Suraj Jitindar Singhab912392018-09-05 12:09:50 +10001143 for (i = 0; i < sizeof(vec); i += 2) {
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001144 prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
1145 , vec[i]
1146 , vec[i + 1]);
1147 prom_parse_platform_support(vec[i], vec[i + 1],
1148 &supported);
1149 }
1150 }
1151
Alexey Kardashevskiy79b46862018-01-09 16:45:20 +11001152 if (supported.radix_mmu && supported.radix_gtse &&
1153 IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001154 /* Radix preferred - but we require GTSE for now */
1155 prom_debug("Asking for radix with GTSE\n");
1156 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1157 ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
1158 } else if (supported.hash_mmu) {
1159 /* Default to hash mmu (if we can) */
1160 prom_debug("Asking for hash\n");
1161 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
1162 } else {
1163 /* We're probably on a legacy hypervisor */
1164 prom_debug("Assuming legacy hash support\n");
1165 }
Cédric Le Goaterac5e5a52017-08-30 21:46:16 +02001166
1167 if (supported.xive) {
1168 prom_debug("Asking for XIVE\n");
1169 ibm_architecture_vec.vec5.intarch = OV5_FEAT(OV5_XIVE_EXPLOIT);
1170 }
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001171}
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001172
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001173static void __init prom_send_capabilities(void)
1174{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001175 ihandle root;
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001176 prom_arg_t ret;
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +02001177 u32 cores;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001178
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001179 /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
1180 prom_check_platform_support();
1181
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001182 root = call_prom("open", 1, 1, ADDR("/"));
1183 if (root != 0) {
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001184 /* We need to tell the FW about the number of cores we support.
1185 *
1186 * To do that, we count the number of threads on the first core
1187 * (we assume this is the same for all cores) and use it to
1188 * divide NR_CPUS.
1189 */
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +02001190
Michael Ellerman76ffb572016-11-18 23:15:42 +11001191 cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001192 prom_printf("Max number of cores passed to firmware: %u (NR_CPUS = %d)\n",
Michael Ellerman76ffb572016-11-18 23:15:42 +11001193 cores, NR_CPUS);
1194
1195 ibm_architecture_vec.vec5.max_cpus = cpu_to_be32(cores);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001196
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001197 /* try calling the ibm,client-architecture-support method */
Anton Blanchard049d0492009-09-21 20:47:39 +00001198 prom_printf("Calling ibm,client-architecture-support...");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001199 if (call_prom_ret("call-method", 3, 2, &ret,
1200 ADDR("ibm,client-architecture-support"),
Benjamin Herrenschmidt33b74972006-06-07 12:01:32 +10001201 root,
Michael Ellerman76ffb572016-11-18 23:15:42 +11001202 ADDR(&ibm_architecture_vec)) == 0) {
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001203 /* the call exists... */
1204 if (ret)
Anton Blanchard4da727a2009-03-31 20:06:14 +00001205 prom_printf("\nWARNING: ibm,client-architecture"
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001206 "-support call FAILED!\n");
1207 call_prom("close", 1, 0, root);
Anton Blanchard4da727a2009-03-31 20:06:14 +00001208 prom_printf(" done\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001209 return;
1210 }
1211 call_prom("close", 1, 0, root);
Anton Blanchard049d0492009-09-21 20:47:39 +00001212 prom_printf(" not implemented\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001213 }
1214
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001215#ifdef __BIG_ENDIAN__
1216 {
1217 ihandle elfloader;
1218
1219 /* no ibm,client-architecture-support call, try the old way */
1220 elfloader = call_prom("open", 1, 1,
1221 ADDR("/packages/elf-loader"));
1222 if (elfloader == 0) {
1223 prom_printf("couldn't open /packages/elf-loader\n");
1224 return;
1225 }
1226 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
1227 elfloader, ADDR(&fake_elf));
1228 call_prom("close", 1, 0, elfloader);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001229 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001230#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001231}
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11001232#endif /* CONFIG_PPC_PSERIES */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001233
1234/*
1235 * Memory allocation strategy... our layout is normally:
1236 *
1237 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
1238 * rare cases, initrd might end up being before the kernel though.
1239 * We assume this won't override the final kernel at 0, we have no
1240 * provision to handle that in this version, but it should hopefully
1241 * never happen.
1242 *
1243 * alloc_top is set to the top of RMO, eventually shrink down if the
1244 * TCEs overlap
1245 *
1246 * alloc_bottom is set to the top of kernel/initrd
1247 *
1248 * from there, allocations are done this way : rtas is allocated
1249 * topmost, and the device-tree is allocated from the bottom. We try
1250 * to grow the device-tree allocation as we progress. If we can't,
1251 * then we fail, we don't currently have a facility to restart
1252 * elsewhere, but that shouldn't be necessary.
1253 *
1254 * Note that calls to reserve_mem have to be done explicitly, memory
1255 * allocated with either alloc_up or alloc_down isn't automatically
1256 * reserved.
1257 */
1258
1259
1260/*
1261 * Allocates memory in the RMO upward from the kernel/initrd
1262 *
1263 * When align is 0, this is a special case, it means to allocate in place
1264 * at the current location of alloc_bottom or fail (that is basically
1265 * extending the previous allocation). Used for the device-tree flattening
1266 */
1267static unsigned long __init alloc_up(unsigned long size, unsigned long align)
1268{
Anton Blanchard5827d412012-11-26 17:40:03 +00001269 unsigned long base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001270 unsigned long addr = 0;
1271
Paul Mackerrasc49888202005-10-26 21:52:53 +10001272 if (align)
1273 base = _ALIGN_UP(base, align);
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001274 prom_debug("%s(%lx, %lx)\n", __func__, size, align);
Anton Blanchard5827d412012-11-26 17:40:03 +00001275 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001276 prom_panic("alloc_up() called with mem not initialized\n");
1277
1278 if (align)
Anton Blanchard5827d412012-11-26 17:40:03 +00001279 base = _ALIGN_UP(alloc_bottom, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001280 else
Anton Blanchard5827d412012-11-26 17:40:03 +00001281 base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001282
Anton Blanchard5827d412012-11-26 17:40:03 +00001283 for(; (base + size) <= alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001284 base = _ALIGN_UP(base + 0x100000, align)) {
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001285 prom_debug(" trying: 0x%lx\n\r", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001286 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001287 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001288 break;
1289 addr = 0;
1290 if (align == 0)
1291 break;
1292 }
1293 if (addr == 0)
1294 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +00001295 alloc_bottom = addr + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001296
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001297 prom_debug(" -> %lx\n", addr);
1298 prom_debug(" alloc_bottom : %lx\n", alloc_bottom);
1299 prom_debug(" alloc_top : %lx\n", alloc_top);
1300 prom_debug(" alloc_top_hi : %lx\n", alloc_top_high);
1301 prom_debug(" rmo_top : %lx\n", rmo_top);
1302 prom_debug(" ram_top : %lx\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001303
1304 return addr;
1305}
1306
1307/*
1308 * Allocates memory downward, either from top of RMO, or if highmem
1309 * is set, from the top of RAM. Note that this one doesn't handle
1310 * failures. It does claim memory if highmem is not set.
1311 */
1312static unsigned long __init alloc_down(unsigned long size, unsigned long align,
1313 int highmem)
1314{
1315 unsigned long base, addr = 0;
1316
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001317 prom_debug("%s(%lx, %lx, %s)\n", __func__, size, align,
Anton Blanchard5827d412012-11-26 17:40:03 +00001318 highmem ? "(high)" : "(low)");
1319 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001320 prom_panic("alloc_down() called with mem not initialized\n");
1321
1322 if (highmem) {
1323 /* Carve out storage for the TCE table. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001324 addr = _ALIGN_DOWN(alloc_top_high - size, align);
1325 if (addr <= alloc_bottom)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001326 return 0;
1327 /* Will we bump into the RMO ? If yes, check out that we
1328 * didn't overlap existing allocations there, if we did,
1329 * we are dead, we must be the first in town !
1330 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001331 if (addr < rmo_top) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001332 /* Good, we are first */
Anton Blanchard5827d412012-11-26 17:40:03 +00001333 if (alloc_top == rmo_top)
1334 alloc_top = rmo_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001335 else
1336 return 0;
1337 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001338 alloc_top_high = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001339 goto bail;
1340 }
1341
Anton Blanchard5827d412012-11-26 17:40:03 +00001342 base = _ALIGN_DOWN(alloc_top - size, align);
1343 for (; base > alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001344 base = _ALIGN_DOWN(base - 0x100000, align)) {
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001345 prom_debug(" trying: 0x%lx\n\r", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001346 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001347 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001348 break;
1349 addr = 0;
1350 }
1351 if (addr == 0)
1352 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +00001353 alloc_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001354
1355 bail:
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001356 prom_debug(" -> %lx\n", addr);
1357 prom_debug(" alloc_bottom : %lx\n", alloc_bottom);
1358 prom_debug(" alloc_top : %lx\n", alloc_top);
1359 prom_debug(" alloc_top_hi : %lx\n", alloc_top_high);
1360 prom_debug(" rmo_top : %lx\n", rmo_top);
1361 prom_debug(" ram_top : %lx\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001362
1363 return addr;
1364}
1365
1366/*
1367 * Parse a "reg" cell
1368 */
1369static unsigned long __init prom_next_cell(int s, cell_t **cellp)
1370{
1371 cell_t *p = *cellp;
1372 unsigned long r = 0;
1373
1374 /* Ignore more than 2 cells */
1375 while (s > sizeof(unsigned long) / 4) {
1376 p++;
1377 s--;
1378 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001379 r = be32_to_cpu(*p++);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001380#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +10001381 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001382 r <<= 32;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001383 r |= be32_to_cpu(*(p++));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001384 }
1385#endif
1386 *cellp = p;
1387 return r;
1388}
1389
1390/*
1391 * Very dumb function for adding to the memory reserve list, but
1392 * we don't need anything smarter at this point
1393 *
1394 * XXX Eventually check for collisions. They should NEVER happen.
1395 * If problems seem to show up, it would be a good start to track
1396 * them down.
1397 */
Michael Ellerman0108d3f2007-05-07 15:58:28 +10001398static void __init reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001399{
Kumar Galacbbcf342006-01-11 17:57:13 -06001400 u64 top = base + size;
Anton Blanchard5827d412012-11-26 17:40:03 +00001401 unsigned long cnt = mem_reserve_cnt;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001402
1403 if (size == 0)
1404 return;
1405
1406 /* We need to always keep one empty entry so that we
1407 * have our terminator with "size" set to 0 since we are
1408 * dumb and just copy this entire array to the boot params
1409 */
1410 base = _ALIGN_DOWN(base, PAGE_SIZE);
1411 top = _ALIGN_UP(top, PAGE_SIZE);
1412 size = top - base;
1413
1414 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1415 prom_panic("Memory reserve map exhausted !\n");
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001416 mem_reserve_map[cnt].base = cpu_to_be64(base);
1417 mem_reserve_map[cnt].size = cpu_to_be64(size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001418 mem_reserve_cnt = cnt + 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001419}
1420
1421/*
Adrian Bunkb3c2ffd2006-06-30 18:20:44 +02001422 * Initialize memory allocation mechanism, parse "memory" nodes and
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001423 * obtain that way the top of memory and RMO to setup out local allocator
1424 */
1425static void __init prom_init_mem(void)
1426{
1427 phandle node;
Mathieu Malaterreeab00a22018-04-04 22:08:35 +02001428#ifdef DEBUG_PROM
1429 char *path;
1430#endif
1431 char type[64];
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001432 unsigned int plen;
1433 cell_t *p, *endp;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001434 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001435 u32 rac, rsc;
1436
1437 /*
1438 * We iterate the memory nodes to find
1439 * 1) top of RMO (first node)
1440 * 2) top of memory
1441 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001442 val = cpu_to_be32(2);
1443 prom_getprop(prom.root, "#address-cells", &val, sizeof(val));
1444 rac = be32_to_cpu(val);
1445 val = cpu_to_be32(1);
1446 prom_getprop(prom.root, "#size-cells", &val, sizeof(rsc));
1447 rsc = be32_to_cpu(val);
1448 prom_debug("root_addr_cells: %x\n", rac);
1449 prom_debug("root_size_cells: %x\n", rsc);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001450
1451 prom_debug("scanning memory:\n");
Mathieu Malaterreeab00a22018-04-04 22:08:35 +02001452#ifdef DEBUG_PROM
Anton Blanchard5827d412012-11-26 17:40:03 +00001453 path = prom_scratch;
Mathieu Malaterreeab00a22018-04-04 22:08:35 +02001454#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001455
1456 for (node = 0; prom_next_node(&node); ) {
1457 type[0] = 0;
1458 prom_getprop(node, "device_type", type, sizeof(type));
1459
Paul Mackerrasc49888202005-10-26 21:52:53 +10001460 if (type[0] == 0) {
1461 /*
1462 * CHRP Longtrail machines have no device_type
1463 * on the memory node, so check the name instead...
1464 */
1465 prom_getprop(node, "name", type, sizeof(type));
1466 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001467 if (strcmp(type, "memory"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001468 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001469
Anton Blanchard5827d412012-11-26 17:40:03 +00001470 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001471 if (plen > sizeof(regbuf)) {
1472 prom_printf("memory node too large for buffer !\n");
1473 plen = sizeof(regbuf);
1474 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001475 p = regbuf;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001476 endp = p + (plen / sizeof(cell_t));
1477
1478#ifdef DEBUG_PROM
1479 memset(path, 0, PROM_SCRATCH_SIZE);
1480 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1481 prom_debug(" node %s :\n", path);
1482#endif /* DEBUG_PROM */
1483
1484 while ((endp - p) >= (rac + rsc)) {
1485 unsigned long base, size;
1486
1487 base = prom_next_cell(rac, &p);
1488 size = prom_next_cell(rsc, &p);
1489
1490 if (size == 0)
1491 continue;
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001492 prom_debug(" %lx %lx\n", base, size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001493 if (base == 0 && (of_platform & PLATFORM_LPAR))
1494 rmo_top = size;
1495 if ((base + size) > ram_top)
1496 ram_top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001497 }
1498 }
1499
Anton Blanchard5827d412012-11-26 17:40:03 +00001500 alloc_bottom = PAGE_ALIGN((unsigned long)&_end + 0x4000);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001501
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001502 /*
Benjamin Krillcf687872009-07-27 22:02:39 +00001503 * If prom_memory_limit is set we reduce the upper limits *except* for
1504 * alloc_top_high. This must be the real top of RAM so we can put
1505 * TCE's up there.
1506 */
1507
Anton Blanchard5827d412012-11-26 17:40:03 +00001508 alloc_top_high = ram_top;
Benjamin Krillcf687872009-07-27 22:02:39 +00001509
Anton Blanchard5827d412012-11-26 17:40:03 +00001510 if (prom_memory_limit) {
1511 if (prom_memory_limit <= alloc_bottom) {
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001512 prom_printf("Ignoring mem=%lx <= alloc_bottom.\n",
1513 prom_memory_limit);
Anton Blanchard5827d412012-11-26 17:40:03 +00001514 prom_memory_limit = 0;
1515 } else if (prom_memory_limit >= ram_top) {
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001516 prom_printf("Ignoring mem=%lx >= ram_top.\n",
1517 prom_memory_limit);
Anton Blanchard5827d412012-11-26 17:40:03 +00001518 prom_memory_limit = 0;
Benjamin Krillcf687872009-07-27 22:02:39 +00001519 } else {
Anton Blanchard5827d412012-11-26 17:40:03 +00001520 ram_top = prom_memory_limit;
1521 rmo_top = min(rmo_top, prom_memory_limit);
Benjamin Krillcf687872009-07-27 22:02:39 +00001522 }
1523 }
1524
1525 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001526 * Setup our top alloc point, that is top of RMO or top of
1527 * segment 0 when running non-LPAR.
1528 * Some RS64 machines have buggy firmware where claims up at
1529 * 1GB fail. Cap at 768MB as a workaround.
1530 * Since 768MB is plenty of room, and we need to cap to something
1531 * reasonable on 32-bit, cap at 768MB on all machines.
1532 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001533 if (!rmo_top)
1534 rmo_top = ram_top;
1535 rmo_top = min(0x30000000ul, rmo_top);
1536 alloc_top = rmo_top;
1537 alloc_top_high = ram_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001538
Paul Mackerras64968f62011-12-13 17:54:13 +00001539 /*
1540 * Check if we have an initrd after the kernel but still inside
1541 * the RMO. If we do move our bottom point to after it.
1542 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001543 if (prom_initrd_start &&
1544 prom_initrd_start < rmo_top &&
1545 prom_initrd_end > alloc_bottom)
1546 alloc_bottom = PAGE_ALIGN(prom_initrd_end);
Paul Mackerras64968f62011-12-13 17:54:13 +00001547
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001548 prom_printf("memory layout at init:\n");
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001549 prom_printf(" memory_limit : %lx (16 MB aligned)\n",
1550 prom_memory_limit);
1551 prom_printf(" alloc_bottom : %lx\n", alloc_bottom);
1552 prom_printf(" alloc_top : %lx\n", alloc_top);
1553 prom_printf(" alloc_top_hi : %lx\n", alloc_top_high);
1554 prom_printf(" rmo_top : %lx\n", rmo_top);
1555 prom_printf(" ram_top : %lx\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001556}
1557
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001558static void __init prom_close_stdin(void)
1559{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001560 __be32 val;
1561 ihandle stdin;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001562
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001563 if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) {
1564 stdin = be32_to_cpu(val);
1565 call_prom("close", 1, 0, stdin);
1566 }
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001567}
1568
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001569/*
1570 * Allocate room for and instantiate RTAS
1571 */
1572static void __init prom_instantiate_rtas(void)
1573{
1574 phandle rtas_node;
1575 ihandle rtas_inst;
1576 u32 base, entry = 0;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001577 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001578 u32 size = 0;
1579
1580 prom_debug("prom_instantiate_rtas: start...\n");
1581
1582 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1583 prom_debug("rtas_node: %x\n", rtas_node);
1584 if (!PHANDLE_VALID(rtas_node))
1585 return;
1586
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001587 val = 0;
1588 prom_getprop(rtas_node, "rtas-size", &val, sizeof(size));
1589 size = be32_to_cpu(val);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001590 if (size == 0)
1591 return;
1592
1593 base = alloc_down(size, PAGE_SIZE, 0);
Anton Blanchard6d1e2c62011-11-14 12:55:47 +00001594 if (base == 0)
1595 prom_panic("Could not allocate memory for RTAS\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001596
1597 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1598 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001599 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001600 return;
1601 }
1602
Anton Blanchard1f8737a2009-03-31 20:06:15 +00001603 prom_printf("instantiating rtas at 0x%x...", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001604
1605 if (call_prom_ret("call-method", 3, 2, &entry,
1606 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001607 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001608 || entry == 0) {
1609 prom_printf(" failed\n");
1610 return;
1611 }
1612 prom_printf(" done\n");
1613
1614 reserve_mem(base, size);
1615
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001616 val = cpu_to_be32(base);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001617 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001618 &val, sizeof(val));
1619 val = cpu_to_be32(entry);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001620 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001621 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001622
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10001623 /* Check if it supports "query-cpu-stopped-state" */
1624 if (prom_getprop(rtas_node, "query-cpu-stopped-state",
1625 &val, sizeof(val)) != PROM_ERROR)
1626 rtas_has_query_cpu_stopped = true;
1627
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001628 prom_debug("rtas base = 0x%x\n", base);
1629 prom_debug("rtas entry = 0x%x\n", entry);
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001630 prom_debug("rtas size = 0x%x\n", size);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001631
1632 prom_debug("prom_instantiate_rtas: end...\n");
1633}
1634
1635#ifdef CONFIG_PPC64
1636/*
Ashley Lai4a727422012-08-14 18:34:57 -05001637 * Allocate room for and instantiate Stored Measurement Log (SML)
1638 */
1639static void __init prom_instantiate_sml(void)
1640{
1641 phandle ibmvtpm_node;
1642 ihandle ibmvtpm_inst;
Hon Ching \(Vicky\) Lob4ed0462015-10-07 20:11:53 -04001643 u32 entry = 0, size = 0, succ = 0;
Ashley Lai4a727422012-08-14 18:34:57 -05001644 u64 base;
Hon Ching \(Vicky\) Lob4ed0462015-10-07 20:11:53 -04001645 __be32 val;
Ashley Lai4a727422012-08-14 18:34:57 -05001646
1647 prom_debug("prom_instantiate_sml: start...\n");
1648
Hon Ching \(Vicky\) Lo2f82e982015-10-07 20:11:52 -04001649 ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/vdevice/vtpm"));
Ashley Lai4a727422012-08-14 18:34:57 -05001650 prom_debug("ibmvtpm_node: %x\n", ibmvtpm_node);
1651 if (!PHANDLE_VALID(ibmvtpm_node))
1652 return;
1653
Hon Ching \(Vicky\) Lo2f82e982015-10-07 20:11:52 -04001654 ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/vdevice/vtpm"));
Ashley Lai4a727422012-08-14 18:34:57 -05001655 if (!IHANDLE_VALID(ibmvtpm_inst)) {
1656 prom_printf("opening vtpm package failed (%x)\n", ibmvtpm_inst);
1657 return;
1658 }
1659
Hon Ching \(Vicky\) Lob4ed0462015-10-07 20:11:53 -04001660 if (prom_getprop(ibmvtpm_node, "ibm,sml-efi-reformat-supported",
1661 &val, sizeof(val)) != PROM_ERROR) {
1662 if (call_prom_ret("call-method", 2, 2, &succ,
1663 ADDR("reformat-sml-to-efi-alignment"),
1664 ibmvtpm_inst) != 0 || succ == 0) {
1665 prom_printf("Reformat SML to EFI alignment failed\n");
1666 return;
1667 }
Hon Ching \(Vicky\) Lob4ed0462015-10-07 20:11:53 -04001668
Hon Ching \(Vicky\) Lo9e5d4af2015-10-07 20:11:54 -04001669 if (call_prom_ret("call-method", 2, 2, &size,
1670 ADDR("sml-get-allocated-size"),
1671 ibmvtpm_inst) != 0 || size == 0) {
1672 prom_printf("SML get allocated size failed\n");
1673 return;
1674 }
1675 } else {
1676 if (call_prom_ret("call-method", 2, 2, &size,
1677 ADDR("sml-get-handover-size"),
1678 ibmvtpm_inst) != 0 || size == 0) {
1679 prom_printf("SML get handover size failed\n");
1680 return;
1681 }
Ashley Lai4a727422012-08-14 18:34:57 -05001682 }
1683
1684 base = alloc_down(size, PAGE_SIZE, 0);
1685 if (base == 0)
1686 prom_panic("Could not allocate memory for sml\n");
1687
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001688 prom_printf("instantiating sml at 0x%llx...", base);
Ashley Lai4a727422012-08-14 18:34:57 -05001689
Hon Ching \(Vicky\) Lo9e5d4af2015-10-07 20:11:54 -04001690 memset((void *)base, 0, size);
1691
Ashley Lai4a727422012-08-14 18:34:57 -05001692 if (call_prom_ret("call-method", 4, 2, &entry,
1693 ADDR("sml-handover"),
1694 ibmvtpm_inst, size, base) != 0 || entry == 0) {
1695 prom_printf("SML handover failed\n");
1696 return;
1697 }
1698 prom_printf(" done\n");
1699
1700 reserve_mem(base, size);
1701
Hon Ching \(Vicky\) Lo2f82e982015-10-07 20:11:52 -04001702 prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
Ashley Lai4a727422012-08-14 18:34:57 -05001703 &base, sizeof(base));
Hon Ching \(Vicky\) Lo2f82e982015-10-07 20:11:52 -04001704 prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
Ashley Lai4a727422012-08-14 18:34:57 -05001705 &size, sizeof(size));
1706
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001707 prom_debug("sml base = 0x%llx\n", base);
1708 prom_debug("sml size = 0x%x\n", size);
Ashley Lai4a727422012-08-14 18:34:57 -05001709
1710 prom_debug("prom_instantiate_sml: end...\n");
1711}
1712
1713/*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001714 * Allocate room for and initialize TCE tables
1715 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001716#ifdef __BIG_ENDIAN__
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001717static void __init prom_initialize_tce_table(void)
1718{
1719 phandle node;
1720 ihandle phb_node;
1721 char compatible[64], type[64], model[64];
Anton Blanchard5827d412012-11-26 17:40:03 +00001722 char *path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001723 u64 base, align;
1724 u32 minalign, minsize;
1725 u64 tce_entry, *tce_entryp;
1726 u64 local_alloc_top, local_alloc_bottom;
1727 u64 i;
1728
Anton Blanchard5827d412012-11-26 17:40:03 +00001729 if (prom_iommu_off)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001730 return;
1731
1732 prom_debug("starting prom_initialize_tce_table\n");
1733
1734 /* Cache current top of allocs so we reserve a single block */
Anton Blanchard5827d412012-11-26 17:40:03 +00001735 local_alloc_top = alloc_top_high;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001736 local_alloc_bottom = local_alloc_top;
1737
1738 /* Search all nodes looking for PHBs. */
1739 for (node = 0; prom_next_node(&node); ) {
1740 compatible[0] = 0;
1741 type[0] = 0;
1742 model[0] = 0;
1743 prom_getprop(node, "compatible",
1744 compatible, sizeof(compatible));
1745 prom_getprop(node, "device_type", type, sizeof(type));
1746 prom_getprop(node, "model", model, sizeof(model));
1747
Anton Blanchard5827d412012-11-26 17:40:03 +00001748 if ((type[0] == 0) || (strstr(type, "pci") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001749 continue;
1750
Linas Vepstase788ff12007-09-07 03:45:21 +10001751 /* Keep the old logic intact to avoid regression. */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001752 if (compatible[0] != 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +00001753 if ((strstr(compatible, "python") == NULL) &&
1754 (strstr(compatible, "Speedwagon") == NULL) &&
1755 (strstr(compatible, "Winnipeg") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001756 continue;
1757 } else if (model[0] != 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +00001758 if ((strstr(model, "ython") == NULL) &&
1759 (strstr(model, "peedwagon") == NULL) &&
1760 (strstr(model, "innipeg") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001761 continue;
1762 }
1763
1764 if (prom_getprop(node, "tce-table-minalign", &minalign,
1765 sizeof(minalign)) == PROM_ERROR)
1766 minalign = 0;
1767 if (prom_getprop(node, "tce-table-minsize", &minsize,
1768 sizeof(minsize)) == PROM_ERROR)
1769 minsize = 4UL << 20;
1770
1771 /*
1772 * Even though we read what OF wants, we just set the table
1773 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1774 * By doing this, we avoid the pitfalls of trying to DMA to
1775 * MMIO space and the DMA alias hole.
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001776 */
Nicholas Piggin471d7ff2018-02-21 05:08:29 +10001777 minsize = 4UL << 20;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001778
1779 /* Align to the greater of the align or size */
1780 align = max(minalign, minsize);
1781 base = alloc_down(minsize, align, 1);
1782 if (base == 0)
1783 prom_panic("ERROR, cannot find space for TCE table.\n");
1784 if (base < local_alloc_bottom)
1785 local_alloc_bottom = base;
1786
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001787 /* It seems OF doesn't null-terminate the path :-( */
Li Zefanaca71ef2007-11-05 13:21:56 +11001788 memset(path, 0, PROM_SCRATCH_SIZE);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001789 /* Call OF to setup the TCE hardware */
1790 if (call_prom("package-to-path", 3, 1, node,
1791 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1792 prom_printf("package-to-path failed\n");
1793 }
1794
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001795 /* Save away the TCE table attributes for later use. */
1796 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1797 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1798
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001799 prom_debug("TCE table: %s\n", path);
1800 prom_debug("\tnode = 0x%x\n", node);
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001801 prom_debug("\tbase = 0x%llx\n", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001802 prom_debug("\tsize = 0x%x\n", minsize);
1803
1804 /* Initialize the table to have a one-to-one mapping
1805 * over the allocated size.
1806 */
Ingo Molnar2b931fb2009-01-06 13:56:52 +00001807 tce_entryp = (u64 *)base;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001808 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1809 tce_entry = (i << PAGE_SHIFT);
1810 tce_entry |= 0x3;
1811 *tce_entryp = tce_entry;
1812 }
1813
1814 prom_printf("opening PHB %s", path);
1815 phb_node = call_prom("open", 1, 1, path);
1816 if (phb_node == 0)
1817 prom_printf("... failed\n");
1818 else
1819 prom_printf("... done\n");
1820
1821 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1822 phb_node, -1, minsize,
1823 (u32) base, (u32) (base >> 32));
1824 call_prom("close", 1, 0, phb_node);
1825 }
1826
1827 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1828
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001829 /* These are only really needed if there is a memory limit in
1830 * effect, but we don't know so export them always. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001831 prom_tce_alloc_start = local_alloc_bottom;
1832 prom_tce_alloc_end = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001833
1834 /* Flag the first invalid entry */
1835 prom_debug("ending prom_initialize_tce_table\n");
1836}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001837#endif /* __BIG_ENDIAN__ */
1838#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001839
1840/*
1841 * With CHRP SMP we need to use the OF to start the other processors.
1842 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1843 * so we have to put the processors into a holding pattern controlled
1844 * by the kernel (not OF) before we destroy the OF.
1845 *
1846 * This uses a chunk of low memory, puts some holding pattern
1847 * code there and sends the other processors off to there until
1848 * smp_boot_cpus tells them to do something. The holding pattern
1849 * checks that address until its cpu # is there, when it is that
1850 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1851 * of setting those values.
1852 *
1853 * We also use physical address 0x4 here to tell when a cpu
1854 * is in its holding pattern code.
1855 *
1856 * -- Cort
1857 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001858/*
1859 * We want to reference the copy of __secondary_hold_* in the
1860 * 0 - 0x100 address range
1861 */
1862#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1863
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001864static void __init prom_hold_cpus(void)
1865{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001866 unsigned long i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001867 phandle node;
1868 char type[64];
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001869 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001870 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001871 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001872 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001873 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001874
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10001875 /*
1876 * On pseries, if RTAS supports "query-cpu-stopped-state",
1877 * we skip this stage, the CPUs will be started by the
1878 * kernel using RTAS.
1879 */
1880 if ((of_platform == PLATFORM_PSERIES ||
1881 of_platform == PLATFORM_PSERIES_LPAR) &&
1882 rtas_has_query_cpu_stopped) {
1883 prom_printf("prom_hold_cpus: skipped\n");
1884 return;
1885 }
1886
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001887 prom_debug("prom_hold_cpus: start...\n");
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001888 prom_debug(" 1) spinloop = 0x%lx\n", (unsigned long)spinloop);
1889 prom_debug(" 1) *spinloop = 0x%lx\n", *spinloop);
1890 prom_debug(" 1) acknowledge = 0x%lx\n",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001891 (unsigned long)acknowledge);
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001892 prom_debug(" 1) *acknowledge = 0x%lx\n", *acknowledge);
1893 prom_debug(" 1) secondary_hold = 0x%lx\n", secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001894
1895 /* Set the common spinloop variable, so all of the secondary cpus
1896 * will block when they are awakened from their OF spinloop.
1897 * This must occur for both SMP and non SMP kernels, since OF will
1898 * be trashed when we move the kernel.
1899 */
1900 *spinloop = 0;
1901
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001902 /* look for cpus */
1903 for (node = 0; prom_next_node(&node); ) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001904 unsigned int cpu_no;
1905 __be32 reg;
1906
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001907 type[0] = 0;
1908 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00001909 if (strcmp(type, "cpu") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001910 continue;
1911
1912 /* Skip non-configured cpus. */
1913 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
Anton Blanchard5827d412012-11-26 17:40:03 +00001914 if (strcmp(type, "okay") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001915 continue;
1916
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001917 reg = cpu_to_be32(-1); /* make sparse happy */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001918 prom_getprop(node, "reg", &reg, sizeof(reg));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001919 cpu_no = be32_to_cpu(reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001920
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001921 prom_debug("cpu hw idx = %u\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001922
1923 /* Init the acknowledge var which will be reset by
1924 * the secondary cpu when it awakens from its OF
1925 * spinloop.
1926 */
1927 *acknowledge = (unsigned long)-1;
1928
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001929 if (cpu_no != prom.cpu) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001930 /* Primary Thread of non-boot cpu or any thread */
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001931 prom_printf("starting cpu hw idx %u... ", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001932 call_prom("start-cpu", 3, 0, node,
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001933 secondary_hold, cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001934
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001935 for (i = 0; (i < 100000000) &&
1936 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001937 mb();
1938
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001939 if (*acknowledge == cpu_no)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001940 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001941 else
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001942 prom_printf("failed: %lx\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001943 }
1944#ifdef CONFIG_SMP
1945 else
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02001946 prom_printf("boot cpu hw idx %u\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001947#endif /* CONFIG_SMP */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001948 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001949
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001950 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001951}
1952
1953
1954static void __init prom_init_client_services(unsigned long pp)
1955{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001956 /* Get a handle to the prom entry point before anything else */
Anton Blanchard5827d412012-11-26 17:40:03 +00001957 prom_entry = pp;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001958
1959 /* get a handle for the stdout device */
Anton Blanchard5827d412012-11-26 17:40:03 +00001960 prom.chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1961 if (!PHANDLE_VALID(prom.chosen))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001962 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1963
1964 /* get device tree root */
Anton Blanchard5827d412012-11-26 17:40:03 +00001965 prom.root = call_prom("finddevice", 1, 1, ADDR("/"));
1966 if (!PHANDLE_VALID(prom.root))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001967 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001968
Anton Blanchard5827d412012-11-26 17:40:03 +00001969 prom.mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001970}
1971
Paul Mackerrasa575b802005-10-23 17:23:21 +10001972#ifdef CONFIG_PPC32
1973/*
1974 * For really old powermacs, we need to map things we claim.
1975 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001976 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001977 */
1978static void __init prom_find_mmu(void)
1979{
Paul Mackerrasa575b802005-10-23 17:23:21 +10001980 phandle oprom;
1981 char version[64];
1982
1983 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1984 if (!PHANDLE_VALID(oprom))
1985 return;
1986 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1987 return;
1988 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001989 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001990 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1991 of_workarounds = OF_WA_CLAIM;
1992 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1993 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1994 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1995 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001996 return;
Anton Blanchard5827d412012-11-26 17:40:03 +00001997 prom.memory = call_prom("open", 1, 1, ADDR("/memory"));
1998 prom_getprop(prom.chosen, "mmu", &prom.mmumap,
1999 sizeof(prom.mmumap));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002000 prom.mmumap = be32_to_cpu(prom.mmumap);
Anton Blanchard5827d412012-11-26 17:40:03 +00002001 if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002002 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002003}
2004#else
2005#define prom_find_mmu()
2006#endif
2007
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002008static void __init prom_init_stdout(void)
2009{
Anton Blanchard5827d412012-11-26 17:40:03 +00002010 char *path = of_stdout_device;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002011 char type[16];
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002012 phandle stdout_node;
2013 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002014
Anton Blanchard5827d412012-11-26 17:40:03 +00002015 if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002016 prom_panic("cannot find stdout");
2017
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002018 prom.stdout = be32_to_cpu(val);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002019
2020 /* Get the full OF pathname of the stdout device */
2021 memset(path, 0, 256);
Anton Blanchard5827d412012-11-26 17:40:03 +00002022 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
Anton Blanchard5827d412012-11-26 17:40:03 +00002023 prom_printf("OF stdout device is: %s\n", of_stdout_device);
2024 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002025 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002026
Benjamin Herrenschmidt10348f52014-01-13 09:49:17 +11002027 /* instance-to-package fails on PA-Semi */
2028 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
2029 if (stdout_node != PROM_ERROR) {
2030 val = cpu_to_be32(stdout_node);
Benjamin Herrenschmidt10348f52014-01-13 09:49:17 +11002031
2032 /* If it's a display, note it */
2033 memset(type, 0, sizeof(type));
2034 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2035 if (strcmp(type, "display") == 0)
2036 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
2037 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002038}
2039
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002040static int __init prom_find_machine_type(void)
2041{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002042 char compat[256];
2043 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002044#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002045 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002046 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002047#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002048
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002049 /* Look for a PowerMac or a Cell */
Anton Blanchard5827d412012-11-26 17:40:03 +00002050 len = prom_getprop(prom.root, "compatible",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002051 compat, sizeof(compat)-1);
2052 if (len > 0) {
2053 compat[len] = 0;
2054 while (i < len) {
2055 char *p = &compat[i];
2056 int sl = strlen(p);
2057 if (sl == 0)
2058 break;
Anton Blanchard5827d412012-11-26 17:40:03 +00002059 if (strstr(p, "Power Macintosh") ||
2060 strstr(p, "MacRISC"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002061 return PLATFORM_POWERMAC;
Arnd Bergmann133dda12006-06-07 12:04:18 +10002062#ifdef CONFIG_PPC64
2063 /* We must make sure we don't detect the IBM Cell
2064 * blades as pSeries due to some firmware issues,
2065 * so we do it here.
2066 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002067 if (strstr(p, "IBM,CBEA") ||
2068 strstr(p, "IBM,CPBW-1.0"))
Arnd Bergmann133dda12006-06-07 12:04:18 +10002069 return PLATFORM_GENERIC;
2070#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002071 i += sl + 1;
2072 }
2073 }
2074#ifdef CONFIG_PPC64
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002075 /* Try to figure out if it's an IBM pSeries or any other
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002076 * PAPR compliant platform. We assume it is if :
2077 * - /device_type is "chrp" (please, do NOT use that for future
2078 * non-IBM designs !
2079 * - it has /rtas
2080 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002081 len = prom_getprop(prom.root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002082 compat, sizeof(compat)-1);
2083 if (len <= 0)
2084 return PLATFORM_GENERIC;
Anton Blanchard5827d412012-11-26 17:40:03 +00002085 if (strcmp(compat, "chrp"))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002086 return PLATFORM_GENERIC;
2087
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002088 /* Default to pSeries. We need to know if we are running LPAR */
2089 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002090 if (!PHANDLE_VALID(rtas))
2091 return PLATFORM_GENERIC;
2092 x = prom_getproplen(rtas, "ibm,hypertas-functions");
2093 if (x != PROM_ERROR) {
Anton Blanchard4da727a2009-03-31 20:06:14 +00002094 prom_debug("Hypertas detected, assuming LPAR !\n");
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002095 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002096 }
2097 return PLATFORM_PSERIES;
2098#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002099 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002100#endif
2101}
2102
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002103static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
2104{
2105 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
2106}
2107
2108/*
2109 * If we have a display that we don't know how to drive,
2110 * we will want to try to execute OF's open method for it
2111 * later. However, OF will probably fall over if we do that
2112 * we've taken over the MMU.
2113 * So we check whether we will need to open the display,
2114 * and if so, open it now.
2115 */
2116static void __init prom_check_displays(void)
2117{
2118 char type[16], *path;
2119 phandle node;
2120 ihandle ih;
2121 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002122
Benjamin Herrenschmidt7f995d32018-05-31 14:33:41 +10002123 static const unsigned char default_colors[] = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002124 0x00, 0x00, 0x00,
2125 0x00, 0x00, 0xaa,
2126 0x00, 0xaa, 0x00,
2127 0x00, 0xaa, 0xaa,
2128 0xaa, 0x00, 0x00,
2129 0xaa, 0x00, 0xaa,
2130 0xaa, 0xaa, 0x00,
2131 0xaa, 0xaa, 0xaa,
2132 0x55, 0x55, 0x55,
2133 0x55, 0x55, 0xff,
2134 0x55, 0xff, 0x55,
2135 0x55, 0xff, 0xff,
2136 0xff, 0x55, 0x55,
2137 0xff, 0x55, 0xff,
2138 0xff, 0xff, 0x55,
2139 0xff, 0xff, 0xff
2140 };
2141 const unsigned char *clut;
2142
Anton Blanchard4da727a2009-03-31 20:06:14 +00002143 prom_debug("Looking for displays\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002144 for (node = 0; prom_next_node(&node); ) {
2145 memset(type, 0, sizeof(type));
2146 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00002147 if (strcmp(type, "display") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002148 continue;
2149
2150 /* It seems OF doesn't null-terminate the path :-( */
Anton Blanchard5827d412012-11-26 17:40:03 +00002151 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002152 memset(path, 0, PROM_SCRATCH_SIZE);
2153
2154 /*
2155 * leave some room at the end of the path for appending extra
2156 * arguments
2157 */
2158 if (call_prom("package-to-path", 3, 1, node, path,
2159 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2160 continue;
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002161 prom_printf("found display : %s, opening... ", path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002162
2163 ih = call_prom("open", 1, 1, path);
2164 if (ih == 0) {
2165 prom_printf("failed\n");
2166 continue;
2167 }
2168
2169 /* Success */
2170 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002171 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002172
2173 /* Setup a usable color table when the appropriate
2174 * method is available. Should update this to set-colors */
Anton Blanchard5827d412012-11-26 17:40:03 +00002175 clut = default_colors;
Benjamin Herrenschmidt3f536382011-12-14 13:55:11 +00002176 for (i = 0; i < 16; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002177 if (prom_set_color(ih, i, clut[0], clut[1],
2178 clut[2]) != 0)
2179 break;
2180
2181#ifdef CONFIG_LOGO_LINUX_CLUT224
Anton Blanchard5827d412012-11-26 17:40:03 +00002182 clut = PTRRELOC(logo_linux_clut224.clut);
2183 for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002184 if (prom_set_color(ih, i + 32, clut[0], clut[1],
2185 clut[2]) != 0)
2186 break;
2187#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Benjamin Herrenschmidt7191b612013-07-25 12:12:32 +10002188
2189#ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
2190 if (prom_getprop(node, "linux,boot-display", NULL, 0) !=
2191 PROM_ERROR) {
2192 u32 width, height, pitch, addr;
2193
2194 prom_printf("Setting btext !\n");
2195 prom_getprop(node, "width", &width, 4);
2196 prom_getprop(node, "height", &height, 4);
2197 prom_getprop(node, "linebytes", &pitch, 4);
2198 prom_getprop(node, "address", &addr, 4);
2199 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
2200 width, height, pitch, addr);
2201 btext_setup_display(width, height, 8, pitch, addr);
2202 }
2203#endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002204 }
2205}
2206
2207
2208/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
2209static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
2210 unsigned long needed, unsigned long align)
2211{
2212 void *ret;
2213
2214 *mem_start = _ALIGN(*mem_start, align);
2215 while ((*mem_start + needed) > *mem_end) {
2216 unsigned long room, chunk;
2217
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002218 prom_debug("Chunk exhausted, claiming more at %lx...\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002219 alloc_bottom);
2220 room = alloc_top - alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002221 if (room > DEVTREE_CHUNK_SIZE)
2222 room = DEVTREE_CHUNK_SIZE;
2223 if (room < PAGE_SIZE)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002224 prom_panic("No memory for flatten_device_tree "
2225 "(no room)\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002226 chunk = alloc_up(room, 0);
2227 if (chunk == 0)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002228 prom_panic("No memory for flatten_device_tree "
2229 "(claim failed)\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002230 *mem_end = chunk + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002231 }
2232
2233 ret = (void *)*mem_start;
2234 *mem_start += needed;
2235
2236 return ret;
2237}
2238
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002239#define dt_push_token(token, mem_start, mem_end) do { \
2240 void *room = make_room(mem_start, mem_end, 4, 4); \
2241 *(__be32 *)room = cpu_to_be32(token); \
2242 } while(0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002243
2244static unsigned long __init dt_find_string(char *str)
2245{
2246 char *s, *os;
2247
Anton Blanchard5827d412012-11-26 17:40:03 +00002248 s = os = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002249 s += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +00002250 while (s < (char *)dt_string_end) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002251 if (strcmp(s, str) == 0)
2252 return s - os;
2253 s += strlen(s) + 1;
2254 }
2255 return 0;
2256}
2257
2258/*
2259 * The Open Firmware 1275 specification states properties must be 31 bytes or
2260 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
2261 */
2262#define MAX_PROPERTY_NAME 64
2263
2264static void __init scan_dt_build_strings(phandle node,
2265 unsigned long *mem_start,
2266 unsigned long *mem_end)
2267{
2268 char *prev_name, *namep, *sstart;
2269 unsigned long soff;
2270 phandle child;
2271
Anton Blanchard5827d412012-11-26 17:40:03 +00002272 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002273
2274 /* get and store all property names */
Anton Blanchard5827d412012-11-26 17:40:03 +00002275 prev_name = "";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002276 for (;;) {
2277 /* 64 is max len of name including nul. */
2278 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
2279 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
2280 /* No more nodes: unwind alloc */
2281 *mem_start = (unsigned long)namep;
2282 break;
2283 }
2284
2285 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002286 if (strcmp(namep, "name") == 0) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002287 *mem_start = (unsigned long)namep;
Anton Blanchard5827d412012-11-26 17:40:03 +00002288 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002289 continue;
2290 }
2291 /* get/create string entry */
2292 soff = dt_find_string(namep);
2293 if (soff != 0) {
2294 *mem_start = (unsigned long)namep;
2295 namep = sstart + soff;
2296 } else {
2297 /* Trim off some if we can */
2298 *mem_start = (unsigned long)namep + strlen(namep) + 1;
Anton Blanchard5827d412012-11-26 17:40:03 +00002299 dt_string_end = *mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002300 }
2301 prev_name = namep;
2302 }
2303
2304 /* do all our children */
2305 child = call_prom("child", 1, 1, node);
2306 while (child != 0) {
2307 scan_dt_build_strings(child, mem_start, mem_end);
2308 child = call_prom("peer", 1, 1, child);
2309 }
2310}
2311
2312static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2313 unsigned long *mem_end)
2314{
2315 phandle child;
2316 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
2317 unsigned long soff;
2318 unsigned char *valp;
2319 static char pname[MAX_PROPERTY_NAME];
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002320 int l, room, has_phandle = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002321
2322 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
2323
2324 /* get the node's full name */
2325 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10002326 room = *mem_end - *mem_start;
2327 if (room > 255)
2328 room = 255;
2329 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002330 if (l >= 0) {
2331 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10002332 if (l >= room) {
2333 if (l >= *mem_end - *mem_start)
2334 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002335 call_prom("package-to-path", 3, 1, node, namep, l);
2336 }
2337 namep[l] = '\0';
2338
2339 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10002340 * middle of the path in some properties, and extract
2341 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002342 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002343 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002344 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10002345 lp = namep;
2346 else if (*p != 0)
2347 *lp++ = *p;
2348 }
2349 *lp = 0;
2350 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002351 }
2352
2353 /* get it again for debugging */
Anton Blanchard5827d412012-11-26 17:40:03 +00002354 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002355 memset(path, 0, PROM_SCRATCH_SIZE);
2356 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2357
2358 /* get and store all properties */
Anton Blanchard5827d412012-11-26 17:40:03 +00002359 prev_name = "";
2360 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002361 for (;;) {
2362 if (call_prom("nextprop", 3, 1, node, prev_name,
Anton Blanchard5827d412012-11-26 17:40:03 +00002363 pname) != 1)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002364 break;
2365
2366 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002367 if (strcmp(pname, "name") == 0) {
2368 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002369 continue;
2370 }
2371
2372 /* find string offset */
Anton Blanchard5827d412012-11-26 17:40:03 +00002373 soff = dt_find_string(pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002374 if (soff == 0) {
2375 prom_printf("WARNING: Can't find string index for"
Anton Blanchard5827d412012-11-26 17:40:03 +00002376 " <%s>, node %s\n", pname, path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002377 break;
2378 }
2379 prev_name = sstart + soff;
2380
2381 /* get length */
Anton Blanchard5827d412012-11-26 17:40:03 +00002382 l = call_prom("getproplen", 2, 1, node, pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002383
2384 /* sanity checks */
2385 if (l == PROM_ERROR)
2386 continue;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002387
2388 /* push property head */
2389 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2390 dt_push_token(l, mem_start, mem_end);
2391 dt_push_token(soff, mem_start, mem_end);
2392
2393 /* push property content */
2394 valp = make_room(mem_start, mem_end, l, 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002395 call_prom("getprop", 4, 1, node, pname, valp, l);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002396 *mem_start = _ALIGN(*mem_start, 4);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002397
Anton Blanchard5827d412012-11-26 17:40:03 +00002398 if (!strcmp(pname, "phandle"))
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002399 has_phandle = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002400 }
2401
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002402 /* Add a "linux,phandle" property if no "phandle" property already
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11002403 * existed.
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002404 */
2405 if (!has_phandle) {
Anton Blanchard5827d412012-11-26 17:40:03 +00002406 soff = dt_find_string("linux,phandle");
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002407 if (soff == 0)
2408 prom_printf("WARNING: Can't find string index for"
2409 " <linux-phandle> node %s\n", path);
2410 else {
2411 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2412 dt_push_token(4, mem_start, mem_end);
2413 dt_push_token(soff, mem_start, mem_end);
2414 valp = make_room(mem_start, mem_end, 4, 4);
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002415 *(__be32 *)valp = cpu_to_be32(node);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002416 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002417 }
2418
2419 /* do all our children */
2420 child = call_prom("child", 1, 1, node);
2421 while (child != 0) {
2422 scan_dt_build_struct(child, mem_start, mem_end);
2423 child = call_prom("peer", 1, 1, child);
2424 }
2425
2426 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
2427}
2428
2429static void __init flatten_device_tree(void)
2430{
2431 phandle root;
2432 unsigned long mem_start, mem_end, room;
2433 struct boot_param_header *hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002434 char *namep;
2435 u64 *rsvmap;
2436
2437 /*
2438 * Check how much room we have between alloc top & bottom (+/- a
Anton Blanchardfbafd722011-07-25 20:47:51 +00002439 * few pages), crop to 1MB, as this is our "chunk" size
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002440 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002441 room = alloc_top - alloc_bottom - 0x4000;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002442 if (room > DEVTREE_CHUNK_SIZE)
2443 room = DEVTREE_CHUNK_SIZE;
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002444 prom_debug("starting device tree allocs at %lx\n", alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002445
2446 /* Now try to claim that */
2447 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
2448 if (mem_start == 0)
2449 prom_panic("Can't allocate initial device-tree chunk\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002450 mem_end = mem_start + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002451
2452 /* Get root of tree */
2453 root = call_prom("peer", 1, 1, (phandle)0);
2454 if (root == (phandle)0)
2455 prom_panic ("couldn't get device tree root\n");
2456
2457 /* Build header and make room for mem rsv map */
2458 mem_start = _ALIGN(mem_start, 4);
2459 hdr = make_room(&mem_start, &mem_end,
2460 sizeof(struct boot_param_header), 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002461 dt_header_start = (unsigned long)hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002462 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
2463
2464 /* Start of strings */
2465 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002466 dt_string_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002467 mem_start += 4; /* hole */
2468
2469 /* Add "linux,phandle" in there, we'll need it */
2470 namep = make_room(&mem_start, &mem_end, 16, 1);
Anton Blanchard5827d412012-11-26 17:40:03 +00002471 strcpy(namep, "linux,phandle");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002472 mem_start = (unsigned long)namep + strlen(namep) + 1;
2473
2474 /* Build string array */
2475 prom_printf("Building dt strings...\n");
2476 scan_dt_build_strings(root, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002477 dt_string_end = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002478
2479 /* Build structure */
2480 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002481 dt_struct_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002482 prom_printf("Building dt structure...\n");
2483 scan_dt_build_struct(root, &mem_start, &mem_end);
2484 dt_push_token(OF_DT_END, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002485 dt_struct_end = PAGE_ALIGN(mem_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002486
2487 /* Finish header */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002488 hdr->boot_cpuid_phys = cpu_to_be32(prom.cpu);
2489 hdr->magic = cpu_to_be32(OF_DT_HEADER);
2490 hdr->totalsize = cpu_to_be32(dt_struct_end - dt_header_start);
2491 hdr->off_dt_struct = cpu_to_be32(dt_struct_start - dt_header_start);
2492 hdr->off_dt_strings = cpu_to_be32(dt_string_start - dt_header_start);
2493 hdr->dt_strings_size = cpu_to_be32(dt_string_end - dt_string_start);
2494 hdr->off_mem_rsvmap = cpu_to_be32(((unsigned long)rsvmap) - dt_header_start);
2495 hdr->version = cpu_to_be32(OF_DT_VERSION);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002496 /* Version 16 is not backward compatible */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002497 hdr->last_comp_version = cpu_to_be32(0x10);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002498
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002499 /* Copy the reserve map in */
Anton Blanchard5827d412012-11-26 17:40:03 +00002500 memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002501
2502#ifdef DEBUG_PROM
2503 {
2504 int i;
2505 prom_printf("reserved memory map:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00002506 for (i = 0; i < mem_reserve_cnt; i++)
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002507 prom_printf(" %llx - %llx\n",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002508 be64_to_cpu(mem_reserve_map[i].base),
2509 be64_to_cpu(mem_reserve_map[i].size));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002510 }
2511#endif
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002512 /* Bump mem_reserve_cnt to cause further reservations to fail
2513 * since it's too late.
2514 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002515 mem_reserve_cnt = MEM_RESERVE_MAP_SIZE;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002516
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002517 prom_printf("Device tree strings 0x%lx -> 0x%lx\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002518 dt_string_start, dt_string_end);
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002519 prom_printf("Device tree struct 0x%lx -> 0x%lx\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002520 dt_struct_start, dt_struct_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002521}
2522
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002523#ifdef CONFIG_PPC_MAPLE
2524/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2525 * The values are bad, and it doesn't even have the right number of cells. */
2526static void __init fixup_device_tree_maple(void)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002527{
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002528 phandle isa;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002529 u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002530 u32 isa_ranges[6];
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002531 char *name;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002532
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002533 name = "/ht@0/isa@4";
2534 isa = call_prom("finddevice", 1, 1, ADDR(name));
2535 if (!PHANDLE_VALID(isa)) {
2536 name = "/ht@0/isa@6";
2537 isa = call_prom("finddevice", 1, 1, ADDR(name));
2538 rloc = 0x01003000; /* IO space; PCI device = 6 */
2539 }
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002540 if (!PHANDLE_VALID(isa))
2541 return;
2542
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002543 if (prom_getproplen(isa, "ranges") != 12)
2544 return;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002545 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2546 == PROM_ERROR)
2547 return;
2548
2549 if (isa_ranges[0] != 0x1 ||
2550 isa_ranges[1] != 0xf4000000 ||
2551 isa_ranges[2] != 0x00010000)
2552 return;
2553
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002554 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002555
2556 isa_ranges[0] = 0x1;
2557 isa_ranges[1] = 0x0;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002558 isa_ranges[2] = rloc;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002559 isa_ranges[3] = 0x0;
2560 isa_ranges[4] = 0x0;
2561 isa_ranges[5] = 0x00010000;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002562 prom_setprop(isa, name, "ranges",
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002563 isa_ranges, sizeof(isa_ranges));
2564}
Harry Ciao8f101a052009-06-17 16:28:00 -07002565
2566#define CPC925_MC_START 0xf8000000
2567#define CPC925_MC_LENGTH 0x1000000
2568/* The values for memory-controller don't have right number of cells */
2569static void __init fixup_device_tree_maple_memory_controller(void)
2570{
2571 phandle mc;
2572 u32 mc_reg[4];
2573 char *name = "/hostbridge@f8000000";
Harry Ciao8f101a052009-06-17 16:28:00 -07002574 u32 ac, sc;
2575
2576 mc = call_prom("finddevice", 1, 1, ADDR(name));
2577 if (!PHANDLE_VALID(mc))
2578 return;
2579
2580 if (prom_getproplen(mc, "reg") != 8)
2581 return;
2582
Anton Blanchard5827d412012-11-26 17:40:03 +00002583 prom_getprop(prom.root, "#address-cells", &ac, sizeof(ac));
2584 prom_getprop(prom.root, "#size-cells", &sc, sizeof(sc));
Harry Ciao8f101a052009-06-17 16:28:00 -07002585 if ((ac != 2) || (sc != 2))
2586 return;
2587
2588 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2589 return;
2590
2591 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2592 return;
2593
2594 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2595
2596 mc_reg[0] = 0x0;
2597 mc_reg[1] = CPC925_MC_START;
2598 mc_reg[2] = 0x0;
2599 mc_reg[3] = CPC925_MC_LENGTH;
2600 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2601}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002602#else
2603#define fixup_device_tree_maple()
Harry Ciao8f101a052009-06-17 16:28:00 -07002604#define fixup_device_tree_maple_memory_controller()
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002605#endif
2606
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002607#ifdef CONFIG_PPC_CHRP
Olaf Heringe4805922007-04-04 18:20:04 +02002608/*
2609 * Pegasos and BriQ lacks the "ranges" property in the isa node
2610 * Pegasos needs decimal IRQ 14/15, not hexadecimal
Olaf Hering556ecf92007-08-18 04:27:17 +10002611 * Pegasos has the IDE configured in legacy mode, but advertised as native
Olaf Heringe4805922007-04-04 18:20:04 +02002612 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002613static void __init fixup_device_tree_chrp(void)
2614{
Olaf Heringe4805922007-04-04 18:20:04 +02002615 phandle ph;
2616 u32 prop[6];
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002617 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002618 char *name;
2619 int rc;
2620
2621 name = "/pci@80000000/isa@c";
Olaf Heringe4805922007-04-04 18:20:04 +02002622 ph = call_prom("finddevice", 1, 1, ADDR(name));
2623 if (!PHANDLE_VALID(ph)) {
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002624 name = "/pci@ff500000/isa@6";
Olaf Heringe4805922007-04-04 18:20:04 +02002625 ph = call_prom("finddevice", 1, 1, ADDR(name));
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002626 rloc = 0x01003000; /* IO space; PCI device = 6 */
2627 }
Olaf Heringe4805922007-04-04 18:20:04 +02002628 if (PHANDLE_VALID(ph)) {
2629 rc = prom_getproplen(ph, "ranges");
2630 if (rc == 0 || rc == PROM_ERROR) {
2631 prom_printf("Fixing up missing ISA range on Pegasos...\n");
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002632
Olaf Heringe4805922007-04-04 18:20:04 +02002633 prop[0] = 0x1;
2634 prop[1] = 0x0;
2635 prop[2] = rloc;
2636 prop[3] = 0x0;
2637 prop[4] = 0x0;
2638 prop[5] = 0x00010000;
2639 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2640 }
2641 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002642
Olaf Heringe4805922007-04-04 18:20:04 +02002643 name = "/pci@80000000/ide@C,1";
2644 ph = call_prom("finddevice", 1, 1, ADDR(name));
2645 if (PHANDLE_VALID(ph)) {
2646 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2647 prop[0] = 14;
2648 prop[1] = 0x0;
Olaf Hering556ecf92007-08-18 04:27:17 +10002649 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2650 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2651 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2652 if (rc == sizeof(u32)) {
2653 prop[0] &= ~0x5;
2654 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2655 }
Olaf Heringe4805922007-04-04 18:20:04 +02002656 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002657}
2658#else
2659#define fixup_device_tree_chrp()
2660#endif
2661
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002662#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002663static void __init fixup_device_tree_pmac(void)
2664{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002665 phandle u3, i2c, mpic;
2666 u32 u3_rev;
2667 u32 interrupts[2];
2668 u32 parent;
2669
2670 /* Some G5s have a missing interrupt definition, fix it up here */
2671 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2672 if (!PHANDLE_VALID(u3))
2673 return;
2674 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2675 if (!PHANDLE_VALID(i2c))
2676 return;
2677 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2678 if (!PHANDLE_VALID(mpic))
2679 return;
2680
2681 /* check if proper rev of u3 */
2682 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2683 == PROM_ERROR)
2684 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002685 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002686 return;
2687 /* does it need fixup ? */
2688 if (prom_getproplen(i2c, "interrupts") > 0)
2689 return;
2690
2691 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2692
2693 /* interrupt on this revision of u3 is number 0 and level */
2694 interrupts[0] = 0;
2695 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002696 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2697 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002698 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002699 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2700 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002701}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002702#else
2703#define fixup_device_tree_pmac()
2704#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002705
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002706#ifdef CONFIG_PPC_EFIKA
Grant Likely94d2dde2008-01-24 22:25:32 -07002707/*
2708 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2709 * to talk to the phy. If the phy-handle property is missing, then this
2710 * function is called to add the appropriate nodes and link it to the
2711 * ethernet node.
2712 */
2713static void __init fixup_device_tree_efika_add_phy(void)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002714{
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002715 u32 node;
2716 char prop[64];
Grant Likely94d2dde2008-01-24 22:25:32 -07002717 int rv;
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002718
Grant Likely94d2dde2008-01-24 22:25:32 -07002719 /* Check if /builtin/ethernet exists - bail if it doesn't */
2720 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002721 if (!PHANDLE_VALID(node))
2722 return;
2723
Grant Likely94d2dde2008-01-24 22:25:32 -07002724 /* Check if the phy-handle property exists - bail if it does */
2725 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2726 if (!rv)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002727 return;
2728
Grant Likely94d2dde2008-01-24 22:25:32 -07002729 /*
2730 * At this point the ethernet device doesn't have a phy described.
2731 * Now we need to add the missing phy node and linkage
2732 */
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002733
Grant Likely94d2dde2008-01-24 22:25:32 -07002734 /* Check for an MDIO bus node - if missing then create one */
Olaf Hering6f4347c2008-01-10 01:06:08 +11002735 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2736 if (!PHANDLE_VALID(node)) {
2737 prom_printf("Adding Ethernet MDIO node\n");
2738 call_prom("interpret", 1, 1,
2739 " s\" /builtin\" find-device"
2740 " new-device"
2741 " 1 encode-int s\" #address-cells\" property"
2742 " 0 encode-int s\" #size-cells\" property"
Grant Likely94d2dde2008-01-24 22:25:32 -07002743 " s\" mdio\" device-name"
2744 " s\" fsl,mpc5200b-mdio\" encode-string"
Olaf Hering6f4347c2008-01-10 01:06:08 +11002745 " s\" compatible\" property"
2746 " 0xf0003000 0x400 reg"
2747 " 0x2 encode-int"
2748 " 0x5 encode-int encode+"
2749 " 0x3 encode-int encode+"
2750 " s\" interrupts\" property"
2751 " finish-device");
2752 };
2753
Grant Likely94d2dde2008-01-24 22:25:32 -07002754 /* Check for a PHY device node - if missing then create one and
2755 * give it's phandle to the ethernet node */
2756 node = call_prom("finddevice", 1, 1,
2757 ADDR("/builtin/mdio/ethernet-phy"));
Olaf Hering6f4347c2008-01-10 01:06:08 +11002758 if (!PHANDLE_VALID(node)) {
2759 prom_printf("Adding Ethernet PHY node\n");
2760 call_prom("interpret", 1, 1,
2761 " s\" /builtin/mdio\" find-device"
2762 " new-device"
2763 " s\" ethernet-phy\" device-name"
2764 " 0x10 encode-int s\" reg\" property"
2765 " my-self"
2766 " ihandle>phandle"
2767 " finish-device"
2768 " s\" /builtin/ethernet\" find-device"
2769 " encode-int"
2770 " s\" phy-handle\" property"
2771 " device-end");
2772 }
Grant Likely94d2dde2008-01-24 22:25:32 -07002773}
Olaf Hering6f4347c2008-01-10 01:06:08 +11002774
Grant Likely94d2dde2008-01-24 22:25:32 -07002775static void __init fixup_device_tree_efika(void)
2776{
2777 int sound_irq[3] = { 2, 2, 0 };
2778 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2779 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2780 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2781 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2782 u32 node;
2783 char prop[64];
2784 int rv, len;
2785
2786 /* Check if we're really running on a EFIKA */
2787 node = call_prom("finddevice", 1, 1, ADDR("/"));
2788 if (!PHANDLE_VALID(node))
2789 return;
2790
2791 rv = prom_getprop(node, "model", prop, sizeof(prop));
2792 if (rv == PROM_ERROR)
2793 return;
2794 if (strcmp(prop, "EFIKA5K2"))
2795 return;
2796
2797 prom_printf("Applying EFIKA device tree fixups\n");
2798
2799 /* Claiming to be 'chrp' is death */
2800 node = call_prom("finddevice", 1, 1, ADDR("/"));
2801 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2802 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2803 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2804
David Woodhouse7f4392c2008-04-14 02:52:38 +10002805 /* CODEGEN,description is exposed in /proc/cpuinfo so
2806 fix that too */
2807 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2808 if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2809 prom_setprop(node, "/", "CODEGEN,description",
2810 "Efika 5200B PowerPC System",
2811 sizeof("Efika 5200B PowerPC System"));
2812
Grant Likely94d2dde2008-01-24 22:25:32 -07002813 /* Fixup bestcomm interrupts property */
2814 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2815 if (PHANDLE_VALID(node)) {
2816 len = prom_getproplen(node, "interrupts");
2817 if (len == 12) {
2818 prom_printf("Fixing bestcomm interrupts property\n");
2819 prom_setprop(node, "/builtin/bestcom", "interrupts",
2820 bcomm_irq, sizeof(bcomm_irq));
2821 }
2822 }
2823
2824 /* Fixup sound interrupts property */
2825 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2826 if (PHANDLE_VALID(node)) {
2827 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2828 if (rv == PROM_ERROR) {
2829 prom_printf("Adding sound interrupts property\n");
2830 prom_setprop(node, "/builtin/sound", "interrupts",
2831 sound_irq, sizeof(sound_irq));
2832 }
2833 }
2834
2835 /* Make sure ethernet phy-handle property exists */
2836 fixup_device_tree_efika_add_phy();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002837}
2838#else
2839#define fixup_device_tree_efika()
2840#endif
2841
Darren Stevens50246782016-08-31 13:24:40 +01002842#ifdef CONFIG_PPC_PASEMI_NEMO
2843/*
2844 * CFE supplied on Nemo is broken in several ways, biggest
2845 * problem is that it reassigns ISA interrupts to unused mpic ints.
2846 * Add an interrupt-controller property for the io-bridge to use
2847 * and correct the ints so we can attach them to an irq_domain
2848 */
2849static void __init fixup_device_tree_pasemi(void)
2850{
2851 u32 interrupts[2], parent, rval, val = 0;
2852 char *name, *pci_name;
2853 phandle iob, node;
2854
2855 /* Find the root pci node */
2856 name = "/pxp@0,e0000000";
2857 iob = call_prom("finddevice", 1, 1, ADDR(name));
2858 if (!PHANDLE_VALID(iob))
2859 return;
2860
2861 /* check if interrupt-controller node set yet */
2862 if (prom_getproplen(iob, "interrupt-controller") !=PROM_ERROR)
2863 return;
2864
2865 prom_printf("adding interrupt-controller property for SB600...\n");
2866
2867 prom_setprop(iob, name, "interrupt-controller", &val, 0);
2868
2869 pci_name = "/pxp@0,e0000000/pci@11";
2870 node = call_prom("finddevice", 1, 1, ADDR(pci_name));
2871 parent = ADDR(iob);
2872
2873 for( ; prom_next_node(&node); ) {
2874 /* scan each node for one with an interrupt */
2875 if (!PHANDLE_VALID(node))
2876 continue;
2877
2878 rval = prom_getproplen(node, "interrupts");
2879 if (rval == 0 || rval == PROM_ERROR)
2880 continue;
2881
2882 prom_getprop(node, "interrupts", &interrupts, sizeof(interrupts));
2883 if ((interrupts[0] < 212) || (interrupts[0] > 222))
2884 continue;
2885
2886 /* found a node, update both interrupts and interrupt-parent */
2887 if ((interrupts[0] >= 212) && (interrupts[0] <= 215))
2888 interrupts[0] -= 203;
2889 if ((interrupts[0] >= 216) && (interrupts[0] <= 220))
2890 interrupts[0] -= 213;
2891 if (interrupts[0] == 221)
2892 interrupts[0] = 14;
2893 if (interrupts[0] == 222)
2894 interrupts[0] = 8;
2895
2896 prom_setprop(node, pci_name, "interrupts", interrupts,
2897 sizeof(interrupts));
2898 prom_setprop(node, pci_name, "interrupt-parent", &parent,
2899 sizeof(parent));
2900 }
Darren Stevens687e16b2016-08-31 13:24:45 +01002901
2902 /*
2903 * The io-bridge has device_type set to 'io-bridge' change it to 'isa'
2904 * so that generic isa-bridge code can add the SB600 and its on-board
2905 * peripherals.
2906 */
2907 name = "/pxp@0,e0000000/io-bridge@0";
2908 iob = call_prom("finddevice", 1, 1, ADDR(name));
2909 if (!PHANDLE_VALID(iob))
2910 return;
2911
2912 /* device_type is already set, just change it. */
2913
2914 prom_printf("Changing device_type of SB600 node...\n");
2915
2916 prom_setprop(iob, name, "device_type", "isa", sizeof("isa"));
Darren Stevens50246782016-08-31 13:24:40 +01002917}
2918#else /* !CONFIG_PPC_PASEMI_NEMO */
2919static inline void fixup_device_tree_pasemi(void) { }
2920#endif
2921
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002922static void __init fixup_device_tree(void)
2923{
2924 fixup_device_tree_maple();
Harry Ciao8f101a052009-06-17 16:28:00 -07002925 fixup_device_tree_maple_memory_controller();
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002926 fixup_device_tree_chrp();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002927 fixup_device_tree_pmac();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002928 fixup_device_tree_efika();
Darren Stevens50246782016-08-31 13:24:40 +01002929 fixup_device_tree_pasemi();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002930}
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002931
2932static void __init prom_find_boot_cpu(void)
2933{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002934 __be32 rval;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002935 ihandle prom_cpu;
2936 phandle cpu_pkg;
2937
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002938 rval = 0;
2939 if (prom_getprop(prom.chosen, "cpu", &rval, sizeof(rval)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002940 return;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002941 prom_cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002942
2943 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2944
Darren Stevensaf2b7fa2017-01-23 19:42:54 +00002945 if (!PHANDLE_VALID(cpu_pkg))
2946 return;
2947
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002948 prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval));
2949 prom.cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002950
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002951 prom_debug("Booting CPU hw index = %d\n", prom.cpu);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002952}
2953
2954static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2955{
2956#ifdef CONFIG_BLK_DEV_INITRD
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002957 if (r3 && r4 && r4 != 0xdeadbeef) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002958 __be64 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002959
Anton Blanchard5827d412012-11-26 17:40:03 +00002960 prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3;
2961 prom_initrd_end = prom_initrd_start + r4;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002962
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002963 val = cpu_to_be64(prom_initrd_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002964 prom_setprop(prom.chosen, "/chosen", "linux,initrd-start",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002965 &val, sizeof(val));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002966 val = cpu_to_be64(prom_initrd_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002967 prom_setprop(prom.chosen, "/chosen", "linux,initrd-end",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002968 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002969
Anton Blanchard5827d412012-11-26 17:40:03 +00002970 reserve_mem(prom_initrd_start,
2971 prom_initrd_end - prom_initrd_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002972
Mathieu Malaterreeae5f702018-04-06 22:12:19 +02002973 prom_debug("initrd_start=0x%lx\n", prom_initrd_start);
2974 prom_debug("initrd_end=0x%lx\n", prom_initrd_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002975 }
2976#endif /* CONFIG_BLK_DEV_INITRD */
2977}
2978
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002979#ifdef CONFIG_PPC64
2980#ifdef CONFIG_RELOCATABLE
2981static void reloc_toc(void)
2982{
2983}
2984
2985static void unreloc_toc(void)
2986{
2987}
2988#else
Anton Blanchard16744002013-03-12 01:51:51 +00002989static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002990{
2991 unsigned long i;
Anton Blanchard16744002013-03-12 01:51:51 +00002992 unsigned long *toc_entry;
2993
2994 /* Get the start of the TOC by using r2 directly. */
2995 asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002996
2997 for (i = 0; i < nr_entries; i++) {
2998 *toc_entry = *toc_entry + offset;
2999 toc_entry++;
3000 }
3001}
3002
3003static void reloc_toc(void)
3004{
3005 unsigned long offset = reloc_offset();
3006 unsigned long nr_entries =
3007 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
3008
Anton Blanchard16744002013-03-12 01:51:51 +00003009 __reloc_toc(offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003010
3011 mb();
3012}
3013
3014static void unreloc_toc(void)
3015{
3016 unsigned long offset = reloc_offset();
3017 unsigned long nr_entries =
3018 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
3019
3020 mb();
3021
Anton Blanchard16744002013-03-12 01:51:51 +00003022 __reloc_toc(-offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003023}
3024#endif
3025#endif
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003026
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003027/*
3028 * We enter here early on, when the Open Firmware prom is still
3029 * handling exceptions and the MMU hash table for us.
3030 */
3031
3032unsigned long __init prom_init(unsigned long r3, unsigned long r4,
3033 unsigned long pp,
Paul Mackerras549e8152008-08-30 11:43:47 +10003034 unsigned long r6, unsigned long r7,
3035 unsigned long kbase)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003036{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003037 unsigned long hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003038
3039#ifdef CONFIG_PPC32
Paul Mackerras549e8152008-08-30 11:43:47 +10003040 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003041 reloc_got2(offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003042#else
3043 reloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003044#endif
3045
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003046 /*
3047 * First zero the BSS
3048 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003049 memset(&__bss_start, 0, __bss_stop - __bss_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003050
3051 /*
3052 * Init interface to Open Firmware, get some node references,
3053 * like /chosen
3054 */
3055 prom_init_client_services(pp);
3056
3057 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003058 * See if this OF is old enough that we need to do explicit maps
3059 * and other workarounds
3060 */
3061 prom_find_mmu();
3062
3063 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003064 * Init prom stdout device
3065 */
3066 prom_init_stdout();
3067
Anton Blanchard5827d412012-11-26 17:40:03 +00003068 prom_printf("Preparing to boot %s", linux_banner);
Michael Ellermane7943fb2009-03-04 19:02:01 +00003069
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003070 /*
3071 * Get default machine type. At this point, we do not differentiate
3072 * between pSeries SMP and pSeries LPAR
3073 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003074 of_platform = prom_find_machine_type();
3075 prom_printf("Detected machine type: %x\n", of_platform);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003076
Suzuki Poulose0f890c82011-12-14 22:57:15 +00003077#ifndef CONFIG_NONSTATIC_KERNEL
Olaf Heringadd60ef2006-03-23 22:03:57 +01003078 /* Bail if this is a kdump kernel. */
3079 if (PHYSICAL_START > 0)
3080 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
Paul Mackerras549e8152008-08-30 11:43:47 +10003081#endif
Olaf Heringadd60ef2006-03-23 22:03:57 +01003082
3083 /*
3084 * Check for an initrd
3085 */
3086 prom_check_initrd(r3, r4);
3087
Suraj Jitindar Singh12cc9fd2017-02-28 17:03:47 +11003088 /*
3089 * Do early parsing of command line
3090 */
3091 early_cmdline_parse();
3092
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003093#ifdef CONFIG_PPC_PSERIES
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003094 /*
3095 * On pSeries, inform the firmware about our capabilities
3096 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003097 if (of_platform == PLATFORM_PSERIES ||
3098 of_platform == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003099 prom_send_capabilities();
3100#endif
3101
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003102 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05003103 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003104 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003105 if (of_platform != PLATFORM_POWERMAC)
Paul Mackerras549e8152008-08-30 11:43:47 +10003106 copy_and_flush(0, kbase, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003107
3108 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003109 * Initialize memory management within prom_init
3110 */
3111 prom_init_mem();
3112
3113 /*
3114 * Determine which cpu is actually running right _now_
3115 */
3116 prom_find_boot_cpu();
3117
3118 /*
3119 * Initialize display devices
3120 */
3121 prom_check_displays();
3122
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003123#if defined(CONFIG_PPC64) && defined(__BIG_ENDIAN__)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003124 /*
3125 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
3126 * that uses the allocator, we need to make sure we get the top of memory
3127 * available for us here...
3128 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003129 if (of_platform == PLATFORM_PSERIES)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003130 prom_initialize_tce_table();
3131#endif
3132
3133 /*
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003134 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
3135 * have a usable RTAS implementation.
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003136 */
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003137 if (of_platform != PLATFORM_POWERMAC)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003138 prom_instantiate_rtas();
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003139
Ashley Lai4a727422012-08-14 18:34:57 -05003140#ifdef CONFIG_PPC64
3141 /* instantiate sml */
3142 prom_instantiate_sml();
3143#endif
3144
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003145 /*
3146 * On non-powermacs, put all CPUs in spin-loops.
3147 *
3148 * PowerMacs use a different mechanism to spin CPUs
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10003149 *
3150 * (This must be done after instanciating RTAS)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003151 */
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003152 if (of_platform != PLATFORM_POWERMAC)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003153 prom_hold_cpus();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003154
3155 /*
3156 * Fill in some infos for use by the kernel later on
3157 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003158 if (prom_memory_limit) {
3159 __be64 val = cpu_to_be64(prom_memory_limit);
Anton Blanchard5827d412012-11-26 17:40:03 +00003160 prom_setprop(prom.chosen, "/chosen", "linux,memory-limit",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003161 &val, sizeof(val));
3162 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003163#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +00003164 if (prom_iommu_off)
3165 prom_setprop(prom.chosen, "/chosen", "linux,iommu-off",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003166 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003167
Anton Blanchard5827d412012-11-26 17:40:03 +00003168 if (prom_iommu_force_on)
3169 prom_setprop(prom.chosen, "/chosen", "linux,iommu-force-on",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003170 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003171
Anton Blanchard5827d412012-11-26 17:40:03 +00003172 if (prom_tce_alloc_start) {
3173 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-start",
3174 &prom_tce_alloc_start,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003175 sizeof(prom_tce_alloc_start));
Anton Blanchard5827d412012-11-26 17:40:03 +00003176 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-end",
3177 &prom_tce_alloc_end,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003178 sizeof(prom_tce_alloc_end));
3179 }
3180#endif
3181
3182 /*
3183 * Fixup any known bugs in the device-tree
3184 */
3185 fixup_device_tree();
3186
3187 /*
3188 * Now finally create the flattened device-tree
3189 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00003190 prom_printf("copying OF device tree...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003191 flatten_device_tree();
3192
Paul Mackerras3825ac02005-11-08 22:48:08 +11003193 /*
3194 * in case stdin is USB and still active on IBM machines...
3195 * Unfortunately quiesce crashes on some powermacs if we have
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003196 * closed stdin already (in particular the powerbook 101).
Paul Mackerras3825ac02005-11-08 22:48:08 +11003197 */
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003198 if (of_platform != PLATFORM_POWERMAC)
Paul Mackerras3825ac02005-11-08 22:48:08 +11003199 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003200
3201 /*
3202 * Call OF "quiesce" method to shut down pending DMA's from
3203 * devices etc...
3204 */
Michael Ellerman7e862d72015-03-30 17:38:09 +11003205 prom_printf("Quiescing Open Firmware ...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003206 call_prom("quiesce", 0, 0);
3207
3208 /*
3209 * And finally, call the kernel passing it the flattened device
3210 * tree and NULL as r5, thus triggering the new entry point which
3211 * is common to us and kexec
3212 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003213 hdr = dt_header_start;
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003214
3215 /* Don't print anything after quiesce under OPAL, it crashes OFW */
Benjamin Herrenschmidt11fdb302018-10-15 13:49:53 +11003216 prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
3217 prom_debug("->dt_header_start=0x%lx\n", hdr);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003218
3219#ifdef CONFIG_PPC32
3220 reloc_got2(-offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003221#else
3222 unreloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003223#endif
3224
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003225 __start(hdr, kbase, 0, 0, 0, 0, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003226
3227 return 0;
3228}