blob: 1c1b44ec7642a531e116fa0d04b6269dd38e93b5 [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
18#include <stdarg.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100019#include <linux/kernel.h>
20#include <linux/string.h>
21#include <linux/init.h>
22#include <linux/threads.h>
23#include <linux/spinlock.h>
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/proc_fs.h>
27#include <linux/stringify.h>
28#include <linux/delay.h>
29#include <linux/initrd.h>
30#include <linux/bitops.h>
31#include <asm/prom.h>
32#include <asm/rtas.h>
33#include <asm/page.h>
34#include <asm/processor.h>
35#include <asm/irq.h>
36#include <asm/io.h>
37#include <asm/smp.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100038#include <asm/mmu.h>
39#include <asm/pgtable.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100040#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100041#include <asm/btext.h>
42#include <asm/sections.h>
43#include <asm/machdep.h>
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +000044#include <asm/opal.h>
Daniel Axtens0545d542016-09-06 15:32:43 +100045#include <asm/asm-prototypes.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100046
Paul Mackerras9b6b5632005-10-06 12:06:20 +100047#include <linux/linux_logo.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100048
49/*
Paul Mackerras9b6b5632005-10-06 12:06:20 +100050 * Eventually bump that one up
51 */
52#define DEVTREE_CHUNK_SIZE 0x100000
53
54/*
55 * This is the size of the local memory reserve map that gets copied
56 * into the boot params passed to the kernel. That size is totally
57 * flexible as the kernel just reads the list until it encounters an
58 * entry with size 0, so it can be changed without breaking binary
59 * compatibility
60 */
61#define MEM_RESERVE_MAP_SIZE 8
62
63/*
64 * prom_init() is called very early on, before the kernel text
65 * and data have been mapped to KERNELBASE. At this point the code
66 * is running at whatever address it has been loaded at.
67 * On ppc32 we compile with -mrelocatable, which means that references
68 * to extern and static variables get relocated automatically.
Anton Blanchard5ac47f72012-11-26 17:39:03 +000069 * ppc64 objects are always relocatable, we just need to relocate the
70 * TOC.
Paul Mackerras9b6b5632005-10-06 12:06:20 +100071 *
72 * Because OF may have mapped I/O devices into the area starting at
73 * KERNELBASE, particularly on CHRP machines, we can't safely call
74 * OF once the kernel has been mapped to KERNELBASE. Therefore all
75 * OF calls must be done within prom_init().
76 *
77 * ADDR is used in calls to call_prom. The 4th and following
78 * arguments to call_prom should be 32-bit values.
79 * On ppc64, 64 bit values are truncated to 32 bits (and
80 * fortunately don't get interpreted as two arguments).
81 */
Anton Blanchard5ac47f72012-11-26 17:39:03 +000082#define ADDR(x) (u32)(unsigned long)(x)
83
Paul Mackerras9b6b5632005-10-06 12:06:20 +100084#ifdef CONFIG_PPC64
Paul Mackerrasa23414b2005-11-10 12:00:55 +110085#define OF_WORKAROUNDS 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +100086#else
Paul Mackerrasa23414b2005-11-10 12:00:55 +110087#define OF_WORKAROUNDS of_workarounds
88int of_workarounds;
Paul Mackerras9b6b5632005-10-06 12:06:20 +100089#endif
90
Paul Mackerrasa23414b2005-11-10 12:00:55 +110091#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
92#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
93
Paul Mackerras9b6b5632005-10-06 12:06:20 +100094#define PROM_BUG() do { \
95 prom_printf("kernel BUG at %s line 0x%x!\n", \
Anton Blanchard5827d412012-11-26 17:40:03 +000096 __FILE__, __LINE__); \
Paul Mackerras9b6b5632005-10-06 12:06:20 +100097 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
98} while (0)
99
100#ifdef DEBUG_PROM
101#define prom_debug(x...) prom_printf(x)
102#else
103#define prom_debug(x...)
104#endif
105
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000106
107typedef u32 prom_arg_t;
108
109struct prom_args {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000110 __be32 service;
111 __be32 nargs;
112 __be32 nret;
113 __be32 args[10];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000114};
115
116struct prom_t {
117 ihandle root;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100118 phandle chosen;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000119 int cpu;
120 ihandle stdout;
Paul Mackerrasa575b802005-10-23 17:23:21 +1000121 ihandle mmumap;
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100122 ihandle memory;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000123};
124
125struct mem_map_entry {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000126 __be64 base;
127 __be64 size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000128};
129
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000130typedef __be32 cell_t;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000131
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +0000132extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
133 unsigned long r6, unsigned long r7, unsigned long r8,
134 unsigned long r9);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000135
136#ifdef CONFIG_PPC64
Paul Mackerrasc49888202005-10-26 21:52:53 +1000137extern int enter_prom(struct prom_args *args, unsigned long entry);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000138#else
Paul Mackerrasc49888202005-10-26 21:52:53 +1000139static inline int enter_prom(struct prom_args *args, unsigned long entry)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000140{
Paul Mackerrasc49888202005-10-26 21:52:53 +1000141 return ((int (*)(struct prom_args *))entry)(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000142}
143#endif
144
145extern void copy_and_flush(unsigned long dest, unsigned long src,
146 unsigned long size, unsigned long offset);
147
148/* prom structure */
149static struct prom_t __initdata prom;
150
151static unsigned long prom_entry __initdata;
152
153#define PROM_SCRATCH_SIZE 256
154
155static char __initdata of_stdout_device[256];
156static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
157
158static unsigned long __initdata dt_header_start;
159static unsigned long __initdata dt_struct_start, dt_struct_end;
160static unsigned long __initdata dt_string_start, dt_string_end;
161
162static unsigned long __initdata prom_initrd_start, prom_initrd_end;
163
164#ifdef CONFIG_PPC64
Jeremy Kerr165785e2006-11-11 17:25:18 +1100165static int __initdata prom_iommu_force_on;
166static int __initdata prom_iommu_off;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000167static unsigned long __initdata prom_tce_alloc_start;
168static unsigned long __initdata prom_tce_alloc_end;
169#endif
170
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100171static bool __initdata prom_radix_disable;
172
173struct platform_support {
174 bool hash_mmu;
175 bool radix_mmu;
176 bool radix_gtse;
177};
178
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100179/* Platforms codes are now obsolete in the kernel. Now only used within this
180 * file and ultimately gone too. Feel free to change them if you need, they
181 * are not shared with anything outside of this file anymore
182 */
183#define PLATFORM_PSERIES 0x0100
184#define PLATFORM_PSERIES_LPAR 0x0101
185#define PLATFORM_LPAR 0x0001
186#define PLATFORM_POWERMAC 0x0400
187#define PLATFORM_GENERIC 0x0500
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000188#define PLATFORM_OPAL 0x0600
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100189
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000190static int __initdata of_platform;
191
192static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
193
Benjamin Krillcf687872009-07-27 22:02:39 +0000194static unsigned long __initdata prom_memory_limit;
195
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000196static unsigned long __initdata alloc_top;
197static unsigned long __initdata alloc_top_high;
198static unsigned long __initdata alloc_bottom;
199static unsigned long __initdata rmo_top;
200static unsigned long __initdata ram_top;
201
202static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
203static int __initdata mem_reserve_cnt;
204
205static cell_t __initdata regbuf[1024];
206
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +1000207static bool rtas_has_query_cpu_stopped;
208
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000209
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000210/*
211 * Error results ... some OF calls will return "-1" on error, some
212 * will return 0, some will return either. To simplify, here are
213 * macros to use with any ihandle or phandle return value to check if
214 * it is valid
215 */
216
217#define PROM_ERROR (-1u)
218#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
219#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
220
221
222/* This is the one and *ONLY* place where we actually call open
223 * firmware.
224 */
225
226static int __init call_prom(const char *service, int nargs, int nret, ...)
227{
228 int i;
229 struct prom_args args;
230 va_list list;
231
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000232 args.service = cpu_to_be32(ADDR(service));
233 args.nargs = cpu_to_be32(nargs);
234 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000235
236 va_start(list, nret);
237 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000238 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000239 va_end(list);
240
241 for (i = 0; i < nret; i++)
242 args.args[nargs+i] = 0;
243
Anton Blanchard5827d412012-11-26 17:40:03 +0000244 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000245 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000246
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000247 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000248}
249
250static int __init call_prom_ret(const char *service, int nargs, int nret,
251 prom_arg_t *rets, ...)
252{
253 int i;
254 struct prom_args args;
255 va_list list;
256
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000257 args.service = cpu_to_be32(ADDR(service));
258 args.nargs = cpu_to_be32(nargs);
259 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000260
261 va_start(list, rets);
262 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000263 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000264 va_end(list);
265
266 for (i = 0; i < nret; i++)
Olaf Heringed1189b72005-11-29 14:04:05 +0100267 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000268
Anton Blanchard5827d412012-11-26 17:40:03 +0000269 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000270 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000271
272 if (rets != NULL)
273 for (i = 1; i < nret; ++i)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000274 rets[i-1] = be32_to_cpu(args.args[nargs+i]);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000275
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000276 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000277}
278
279
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000280static void __init prom_print(const char *msg)
281{
282 const char *p, *q;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000283
Anton Blanchard5827d412012-11-26 17:40:03 +0000284 if (prom.stdout == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000285 return;
286
287 for (p = msg; *p != 0; p = q) {
288 for (q = p; *q != 0 && *q != '\n'; ++q)
289 ;
290 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000291 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000292 if (*q == 0)
293 break;
294 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000295 call_prom("write", 3, 1, prom.stdout, ADDR("\r\n"), 2);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000296 }
297}
298
299
300static void __init prom_print_hex(unsigned long val)
301{
302 int i, nibbles = sizeof(val)*2;
303 char buf[sizeof(val)*2+1];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000304
305 for (i = nibbles-1; i >= 0; i--) {
306 buf[i] = (val & 0xf) + '0';
307 if (buf[i] > '9')
308 buf[i] += ('a'-'0'-10);
309 val >>= 4;
310 }
311 buf[nibbles] = '\0';
Anton Blanchard5827d412012-11-26 17:40:03 +0000312 call_prom("write", 3, 1, prom.stdout, buf, nibbles);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000313}
314
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000315/* max number of decimal digits in an unsigned long */
316#define UL_DIGITS 21
317static void __init prom_print_dec(unsigned long val)
318{
319 int i, size;
320 char buf[UL_DIGITS+1];
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000321
322 for (i = UL_DIGITS-1; i >= 0; i--) {
323 buf[i] = (val % 10) + '0';
324 val = val/10;
325 if (val == 0)
326 break;
327 }
328 /* shift stuff down */
329 size = UL_DIGITS - i;
Anton Blanchard5827d412012-11-26 17:40:03 +0000330 call_prom("write", 3, 1, prom.stdout, buf+i, size);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000331}
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000332
333static void __init prom_printf(const char *format, ...)
334{
335 const char *p, *q, *s;
336 va_list args;
337 unsigned long v;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000338 long vs;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000339
340 va_start(args, format);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000341 for (p = format; *p != 0; p = q) {
342 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
343 ;
344 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000345 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000346 if (*q == 0)
347 break;
348 if (*q == '\n') {
349 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000350 call_prom("write", 3, 1, prom.stdout,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000351 ADDR("\r\n"), 2);
352 continue;
353 }
354 ++q;
355 if (*q == 0)
356 break;
357 switch (*q) {
358 case 's':
359 ++q;
360 s = va_arg(args, const char *);
361 prom_print(s);
362 break;
363 case 'x':
364 ++q;
365 v = va_arg(args, unsigned long);
366 prom_print_hex(v);
367 break;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000368 case 'd':
369 ++q;
370 vs = va_arg(args, int);
371 if (vs < 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +0000372 prom_print("-");
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000373 vs = -vs;
374 }
375 prom_print_dec(vs);
376 break;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000377 case 'l':
378 ++q;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000379 if (*q == 0)
380 break;
381 else if (*q == 'x') {
382 ++q;
383 v = va_arg(args, unsigned long);
384 prom_print_hex(v);
385 } else if (*q == 'u') { /* '%lu' */
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000386 ++q;
387 v = va_arg(args, unsigned long);
388 prom_print_dec(v);
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000389 } else if (*q == 'd') { /* %ld */
390 ++q;
391 vs = va_arg(args, long);
392 if (vs < 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +0000393 prom_print("-");
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000394 vs = -vs;
395 }
396 prom_print_dec(vs);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000397 }
398 break;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000399 }
400 }
Daniel Axtens1b855e12015-12-17 19:41:00 +1100401 va_end(args);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000402}
403
404
Paul Mackerrasa575b802005-10-23 17:23:21 +1000405static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
406 unsigned long align)
407{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000408
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100409 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
410 /*
411 * Old OF requires we claim physical and virtual separately
412 * and then map explicitly (assuming virtual mode)
413 */
414 int ret;
415 prom_arg_t result;
416
417 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000418 ADDR("claim"), prom.memory,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100419 align, size, virt);
420 if (ret != 0 || result == -1)
421 return -1;
422 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000423 ADDR("claim"), prom.mmumap,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100424 align, size, virt);
425 if (ret != 0) {
426 call_prom("call-method", 4, 1, ADDR("release"),
Anton Blanchard5827d412012-11-26 17:40:03 +0000427 prom.memory, size, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100428 return -1;
429 }
430 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000431 call_prom("call-method", 6, 1,
Anton Blanchard5827d412012-11-26 17:40:03 +0000432 ADDR("map"), prom.mmumap, 0x12, size, virt, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100433 return virt;
434 }
435 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
436 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000437}
438
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000439static void __init __attribute__((noreturn)) prom_panic(const char *reason)
440{
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000441 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100442 /* Do not call exit because it clears the screen on pmac
443 * it also causes some sort of double-fault on early pmacs */
Anton Blanchard5827d412012-11-26 17:40:03 +0000444 if (of_platform == PLATFORM_POWERMAC)
Olaf Heringadd60ef2006-03-23 22:03:57 +0100445 asm("trap\n");
446
Stephen Rothwell1d9a4732012-03-21 18:23:27 +0000447 /* ToDo: should put up an SRC here on pSeries */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000448 call_prom("exit", 0, 0);
449
450 for (;;) /* should never get here */
451 ;
452}
453
454
455static int __init prom_next_node(phandle *nodep)
456{
457 phandle node;
458
459 if ((node = *nodep) != 0
460 && (*nodep = call_prom("child", 1, 1, node)) != 0)
461 return 1;
462 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
463 return 1;
464 for (;;) {
465 if ((node = call_prom("parent", 1, 1, node)) == 0)
466 return 0;
467 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
468 return 1;
469 }
470}
471
Tobias Klauser60d862e2016-11-17 17:20:24 +0100472static inline int prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000473 void *value, size_t valuelen)
474{
475 return call_prom("getprop", 4, 1, node, ADDR(pname),
476 (u32)(unsigned long) value, (u32) valuelen);
477}
478
Tobias Klauser60d862e2016-11-17 17:20:24 +0100479static inline int prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000480{
481 return call_prom("getproplen", 2, 1, node, ADDR(pname));
482}
483
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100484static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000485{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100486 char *p = *str;
487
488 while (*q)
489 *p++ = *q++;
490 *p++ = ' ';
491 *str = p;
492}
493
494static char *tohex(unsigned int x)
495{
496 static char digits[] = "0123456789abcdef";
497 static char result[9];
498 int i;
499
500 result[8] = 0;
501 i = 8;
502 do {
503 --i;
504 result[i] = digits[x & 0xf];
505 x >>= 4;
506 } while (x != 0 && i > 0);
507 return &result[i];
508}
509
510static int __init prom_setprop(phandle node, const char *nodename,
511 const char *pname, void *value, size_t valuelen)
512{
513 char cmd[256], *p;
514
515 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
516 return call_prom("setprop", 4, 1, node, ADDR(pname),
517 (u32)(unsigned long) value, (u32) valuelen);
518
519 /* gah... setprop doesn't work on longtrail, have to use interpret */
520 p = cmd;
521 add_string(&p, "dev");
522 add_string(&p, nodename);
523 add_string(&p, tohex((u32)(unsigned long) value));
524 add_string(&p, tohex(valuelen));
525 add_string(&p, tohex(ADDR(pname)));
Anton Blanchard5827d412012-11-26 17:40:03 +0000526 add_string(&p, tohex(strlen(pname)));
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100527 add_string(&p, "property");
528 *p = 0;
529 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000530}
531
Anton Blanchard5827d412012-11-26 17:40:03 +0000532/* We can't use the standard versions because of relocation headaches. */
Benjamin Krillcf687872009-07-27 22:02:39 +0000533#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
534 || ('a' <= (c) && (c) <= 'f') \
535 || ('A' <= (c) && (c) <= 'F'))
536
537#define isdigit(c) ('0' <= (c) && (c) <= '9')
538#define islower(c) ('a' <= (c) && (c) <= 'z')
539#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
540
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000541static unsigned long prom_strtoul(const char *cp, const char **endp)
Benjamin Krillcf687872009-07-27 22:02:39 +0000542{
543 unsigned long result = 0, base = 10, value;
544
545 if (*cp == '0') {
546 base = 8;
547 cp++;
548 if (toupper(*cp) == 'X') {
549 cp++;
550 base = 16;
551 }
552 }
553
554 while (isxdigit(*cp) &&
555 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
556 result = result * base + value;
557 cp++;
558 }
559
560 if (endp)
561 *endp = cp;
562
563 return result;
564}
565
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000566static unsigned long prom_memparse(const char *ptr, const char **retptr)
Benjamin Krillcf687872009-07-27 22:02:39 +0000567{
568 unsigned long ret = prom_strtoul(ptr, retptr);
569 int shift = 0;
570
571 /*
572 * We can't use a switch here because GCC *may* generate a
573 * jump table which won't work, because we're not running at
574 * the address we're linked at.
575 */
576 if ('G' == **retptr || 'g' == **retptr)
577 shift = 30;
578
579 if ('M' == **retptr || 'm' == **retptr)
580 shift = 20;
581
582 if ('K' == **retptr || 'k' == **retptr)
583 shift = 10;
584
585 if (shift) {
586 ret <<= shift;
587 (*retptr)++;
588 }
589
590 return ret;
591}
592
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000593/*
594 * Early parsing of the command line passed to the kernel, used for
595 * "mem=x" and the options that affect the iommu
596 */
597static void __init early_cmdline_parse(void)
598{
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100599 const char *opt;
Benjamin Krillcf687872009-07-27 22:02:39 +0000600
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100601 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000602 int l = 0;
603
Anton Blanchard5827d412012-11-26 17:40:03 +0000604 prom_cmd_line[0] = 0;
605 p = prom_cmd_line;
606 if ((long)prom.chosen > 0)
607 l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000608#ifdef CONFIG_CMDLINE
Amos Waterland0e4aa9c2006-06-12 23:45:02 -0400609 if (l <= 0 || p[0] == '\0') /* dbl check */
Anton Blanchard5827d412012-11-26 17:40:03 +0000610 strlcpy(prom_cmd_line,
611 CONFIG_CMDLINE, sizeof(prom_cmd_line));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000612#endif /* CONFIG_CMDLINE */
Anton Blanchard5827d412012-11-26 17:40:03 +0000613 prom_printf("command line: %s\n", prom_cmd_line);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000614
615#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +0000616 opt = strstr(prom_cmd_line, "iommu=");
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000617 if (opt) {
618 prom_printf("iommu opt is: %s\n", opt);
619 opt += 6;
620 while (*opt && *opt == ' ')
621 opt++;
Anton Blanchard5827d412012-11-26 17:40:03 +0000622 if (!strncmp(opt, "off", 3))
623 prom_iommu_off = 1;
624 else if (!strncmp(opt, "force", 5))
625 prom_iommu_force_on = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000626 }
627#endif
Anton Blanchard5827d412012-11-26 17:40:03 +0000628 opt = strstr(prom_cmd_line, "mem=");
Benjamin Krillcf687872009-07-27 22:02:39 +0000629 if (opt) {
630 opt += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +0000631 prom_memory_limit = prom_memparse(opt, (const char **)&opt);
Benjamin Krillcf687872009-07-27 22:02:39 +0000632#ifdef CONFIG_PPC64
633 /* Align to 16 MB == size of ppc64 large page */
Anton Blanchard5827d412012-11-26 17:40:03 +0000634 prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
Benjamin Krillcf687872009-07-27 22:02:39 +0000635#endif
636 }
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100637
638 opt = strstr(prom_cmd_line, "disable_radix");
639 if (opt) {
640 prom_debug("Radix disabled from cmdline\n");
641 prom_radix_disable = true;
642 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000643}
644
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000645#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000646/*
Nathan Fontenot530b5e12013-04-24 05:53:10 +0000647 * The architecture vector has an array of PVR mask/value pairs,
648 * followed by # option vectors - 1, followed by the option vectors.
649 *
650 * See prom.h for the definition of the bits specified in the
651 * architecture vector.
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000652 */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000653
Michael Ellermane8a4fd02014-08-29 17:01:43 +1000654/* Firmware expects the value to be n - 1, where n is the # of vectors */
655#define NUM_VECTORS(n) ((n) - 1)
656
657/*
658 * Firmware expects 1 + n - 2, where n is the length of the option vector in
659 * bytes. The 1 accounts for the length byte itself, the - 2 .. ?
660 */
661#define VECTOR_LENGTH(n) (1 + (n) - 2)
662
Michael Ellermand03d1d62016-11-18 23:15:41 +1100663struct option_vector1 {
664 u8 byte1;
665 u8 arch_versions;
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100666 u8 arch_versions3;
Michael Ellermand03d1d62016-11-18 23:15:41 +1100667} __packed;
668
669struct option_vector2 {
670 u8 byte1;
671 __be16 reserved;
672 __be32 real_base;
673 __be32 real_size;
674 __be32 virt_base;
675 __be32 virt_size;
676 __be32 load_base;
677 __be32 min_rma;
678 __be32 min_load;
679 u8 min_rma_percent;
680 u8 max_pft_size;
681} __packed;
682
683struct option_vector3 {
684 u8 byte1;
685 u8 byte2;
686} __packed;
687
688struct option_vector4 {
689 u8 byte1;
690 u8 min_vp_cap;
691} __packed;
692
693struct option_vector5 {
694 u8 byte1;
695 u8 byte2;
696 u8 byte3;
697 u8 cmo;
698 u8 associativity;
699 u8 bin_opts;
700 u8 micro_checkpoint;
701 u8 reserved0;
702 __be32 max_cpus;
703 __be16 papr_level;
704 __be16 reserved1;
705 u8 platform_facilities;
706 u8 reserved2;
707 __be16 reserved3;
708 u8 subprocessors;
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100709 u8 byte22;
710 u8 intarch;
711 u8 mmu;
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100712 u8 hash_ext;
713 u8 radix_ext;
Michael Ellermand03d1d62016-11-18 23:15:41 +1100714} __packed;
715
716struct option_vector6 {
717 u8 reserved;
718 u8 secondary_pteg;
719 u8 os_name;
720} __packed;
721
Michael Ellerman76ffb572016-11-18 23:15:42 +1100722struct ibm_arch_vec {
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100723 struct { u32 mask, val; } pvrs[12];
Michael Ellerman76ffb572016-11-18 23:15:42 +1100724
725 u8 num_vectors;
726
727 u8 vec1_len;
728 struct option_vector1 vec1;
729
730 u8 vec2_len;
731 struct option_vector2 vec2;
732
733 u8 vec3_len;
734 struct option_vector3 vec3;
735
736 u8 vec4_len;
737 struct option_vector4 vec4;
738
739 u8 vec5_len;
740 struct option_vector5 vec5;
741
742 u8 vec6_len;
743 struct option_vector6 vec6;
744} __packed;
745
746struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
747 .pvrs = {
748 {
749 .mask = cpu_to_be32(0xfffe0000), /* POWER5/POWER5+ */
750 .val = cpu_to_be32(0x003a0000),
751 },
752 {
753 .mask = cpu_to_be32(0xffff0000), /* POWER6 */
754 .val = cpu_to_be32(0x003e0000),
755 },
756 {
757 .mask = cpu_to_be32(0xffff0000), /* POWER7 */
758 .val = cpu_to_be32(0x003f0000),
759 },
760 {
761 .mask = cpu_to_be32(0xffff0000), /* POWER8E */
762 .val = cpu_to_be32(0x004b0000),
763 },
764 {
765 .mask = cpu_to_be32(0xffff0000), /* POWER8NVL */
766 .val = cpu_to_be32(0x004c0000),
767 },
768 {
769 .mask = cpu_to_be32(0xffff0000), /* POWER8 */
770 .val = cpu_to_be32(0x004d0000),
771 },
772 {
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100773 .mask = cpu_to_be32(0xffff0000), /* POWER9 */
774 .val = cpu_to_be32(0x004e0000),
775 },
776 {
777 .mask = cpu_to_be32(0xffffffff), /* all 3.00-compliant */
778 .val = cpu_to_be32(0x0f000005),
779 },
780 {
Michael Ellerman76ffb572016-11-18 23:15:42 +1100781 .mask = cpu_to_be32(0xffffffff), /* all 2.07-compliant */
782 .val = cpu_to_be32(0x0f000004),
783 },
784 {
785 .mask = cpu_to_be32(0xffffffff), /* all 2.06-compliant */
786 .val = cpu_to_be32(0x0f000003),
787 },
788 {
789 .mask = cpu_to_be32(0xffffffff), /* all 2.05-compliant */
790 .val = cpu_to_be32(0x0f000002),
791 },
792 {
793 .mask = cpu_to_be32(0xfffffffe), /* all 2.04-compliant and earlier */
794 .val = cpu_to_be32(0x0f000001),
795 },
796 },
797
798 .num_vectors = NUM_VECTORS(6),
799
800 .vec1_len = VECTOR_LENGTH(sizeof(struct option_vector1)),
801 .vec1 = {
802 .byte1 = 0,
803 .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
804 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100805 .arch_versions3 = OV1_PPC_3_00,
Michael Ellerman76ffb572016-11-18 23:15:42 +1100806 },
807
808 .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)),
809 /* option vector 2: Open Firmware options supported */
810 .vec2 = {
811 .byte1 = OV2_REAL_MODE,
812 .reserved = 0,
813 .real_base = cpu_to_be32(0xffffffff),
814 .real_size = cpu_to_be32(0xffffffff),
815 .virt_base = cpu_to_be32(0xffffffff),
816 .virt_size = cpu_to_be32(0xffffffff),
817 .load_base = cpu_to_be32(0xffffffff),
818 .min_rma = cpu_to_be32(256), /* 256MB min RMA */
819 .min_load = cpu_to_be32(0xffffffff), /* full client load */
820 .min_rma_percent = 0, /* min RMA percentage of total RAM */
821 .max_pft_size = 48, /* max log_2(hash table size) */
822 },
823
824 .vec3_len = VECTOR_LENGTH(sizeof(struct option_vector3)),
825 /* option vector 3: processor options supported */
826 .vec3 = {
827 .byte1 = 0, /* don't ignore, don't halt */
828 .byte2 = OV3_FP | OV3_VMX | OV3_DFP,
829 },
830
831 .vec4_len = VECTOR_LENGTH(sizeof(struct option_vector4)),
832 /* option vector 4: IBM PAPR implementation */
833 .vec4 = {
834 .byte1 = 0, /* don't halt */
835 .min_vp_cap = OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
836 },
837
838 .vec5_len = VECTOR_LENGTH(sizeof(struct option_vector5)),
839 /* option vector 5: PAPR/OF options */
840 .vec5 = {
841 .byte1 = 0, /* don't ignore, don't halt */
842 .byte2 = OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
843 OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
844#ifdef CONFIG_PCI_MSI
845 /* PCIe/MSI support. Without MSI full PCIe is not supported */
846 OV5_FEAT(OV5_MSI),
847#else
848 0,
849#endif
850 .byte3 = 0,
851 .cmo =
852#ifdef CONFIG_PPC_SMLPAR
853 OV5_FEAT(OV5_CMO) | OV5_FEAT(OV5_XCMO),
854#else
855 0,
856#endif
857 .associativity = OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN),
Michael Roth3dbbaf22017-02-20 19:12:18 -0600858 .bin_opts = OV5_FEAT(OV5_RESIZE_HPT) | OV5_FEAT(OV5_HP_EVT),
Michael Ellerman76ffb572016-11-18 23:15:42 +1100859 .micro_checkpoint = 0,
860 .reserved0 = 0,
861 .max_cpus = cpu_to_be32(NR_CPUS), /* number of cores supported */
862 .papr_level = 0,
863 .reserved1 = 0,
864 .platform_facilities = OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | OV5_FEAT(OV5_PFO_HW_842),
865 .reserved2 = 0,
866 .reserved3 = 0,
867 .subprocessors = 1,
Paul Mackerrascc3d2942017-01-30 21:21:36 +1100868 .intarch = 0,
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +1100869 .mmu = 0,
870 .hash_ext = 0,
871 .radix_ext = 0,
Michael Ellerman76ffb572016-11-18 23:15:42 +1100872 },
873
874 /* option vector 6: IBM PAPR hints */
875 .vec6_len = VECTOR_LENGTH(sizeof(struct option_vector6)),
876 .vec6 = {
877 .reserved = 0,
878 .secondary_pteg = 0,
879 .os_name = OV6_LINUX,
880 },
881};
882
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000883/* Old method - ELF header with PT_NOTE sections only works on BE */
884#ifdef __BIG_ENDIAN__
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000885static struct fake_elf {
886 Elf32_Ehdr elfhdr;
887 Elf32_Phdr phdr[2];
888 struct chrpnote {
889 u32 namesz;
890 u32 descsz;
891 u32 type;
892 char name[8]; /* "PowerPC" */
893 struct chrpdesc {
894 u32 real_mode;
895 u32 real_base;
896 u32 real_size;
897 u32 virt_base;
898 u32 virt_size;
899 u32 load_base;
900 } chrpdesc;
901 } chrpnote;
902 struct rpanote {
903 u32 namesz;
904 u32 descsz;
905 u32 type;
906 char name[24]; /* "IBM,RPA-Client-Config" */
907 struct rpadesc {
908 u32 lpar_affinity;
909 u32 min_rmo_size;
910 u32 min_rmo_percent;
911 u32 max_pft_size;
912 u32 splpar;
913 u32 min_load;
914 u32 new_mem_def;
915 u32 ignore_me;
916 } rpadesc;
917 } rpanote;
Paul Mackerras5663a122008-10-31 22:27:17 +1100918} fake_elf = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000919 .elfhdr = {
920 .e_ident = { 0x7f, 'E', 'L', 'F',
921 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
922 .e_type = ET_EXEC, /* yeah right */
923 .e_machine = EM_PPC,
924 .e_version = EV_CURRENT,
925 .e_phoff = offsetof(struct fake_elf, phdr),
926 .e_phentsize = sizeof(Elf32_Phdr),
927 .e_phnum = 2
928 },
929 .phdr = {
930 [0] = {
931 .p_type = PT_NOTE,
932 .p_offset = offsetof(struct fake_elf, chrpnote),
933 .p_filesz = sizeof(struct chrpnote)
934 }, [1] = {
935 .p_type = PT_NOTE,
936 .p_offset = offsetof(struct fake_elf, rpanote),
937 .p_filesz = sizeof(struct rpanote)
938 }
939 },
940 .chrpnote = {
941 .namesz = sizeof("PowerPC"),
942 .descsz = sizeof(struct chrpdesc),
943 .type = 0x1275,
944 .name = "PowerPC",
945 .chrpdesc = {
946 .real_mode = ~0U, /* ~0 means "don't care" */
947 .real_base = ~0U,
948 .real_size = ~0U,
949 .virt_base = ~0U,
950 .virt_size = ~0U,
951 .load_base = ~0U
952 },
953 },
954 .rpanote = {
955 .namesz = sizeof("IBM,RPA-Client-Config"),
956 .descsz = sizeof(struct rpadesc),
957 .type = 0x12759999,
958 .name = "IBM,RPA-Client-Config",
959 .rpadesc = {
Paul Mackerras5663a122008-10-31 22:27:17 +1100960 .lpar_affinity = 0,
961 .min_rmo_size = 64, /* in megabytes */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000962 .min_rmo_percent = 0,
Paul Mackerras5663a122008-10-31 22:27:17 +1100963 .max_pft_size = 48, /* 2^48 bytes max PFT size */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000964 .splpar = 1,
965 .min_load = ~0U,
Paul Mackerras5663a122008-10-31 22:27:17 +1100966 .new_mem_def = 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000967 }
968 }
969};
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000970#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000971
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100972static int __init prom_count_smt_threads(void)
973{
974 phandle node;
975 char type[64];
976 unsigned int plen;
977
978 /* Pick up th first CPU node we can find */
979 for (node = 0; prom_next_node(&node); ) {
980 type[0] = 0;
981 prom_getprop(node, "device_type", type, sizeof(type));
982
Anton Blanchard5827d412012-11-26 17:40:03 +0000983 if (strcmp(type, "cpu"))
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100984 continue;
985 /*
986 * There is an entry for each smt thread, each entry being
987 * 4 bytes long. All cpus should have the same number of
988 * smt threads, so return after finding the first.
989 */
990 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
991 if (plen == PROM_ERROR)
992 break;
993 plen >>= 2;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000994 prom_debug("Found %lu smt threads per core\n", (unsigned long)plen);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100995
996 /* Sanity check */
997 if (plen < 1 || plen > 64) {
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000998 prom_printf("Threads per core %lu out of bounds, assuming 1\n",
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100999 (unsigned long)plen);
1000 return 1;
1001 }
1002 return plen;
1003 }
1004 prom_debug("No threads found, assuming 1 per core\n");
1005
1006 return 1;
1007
1008}
1009
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001010static void __init prom_parse_mmu_model(u8 val,
1011 struct platform_support *support)
1012{
1013 switch (val) {
1014 case OV5_FEAT(OV5_MMU_DYNAMIC):
1015 case OV5_FEAT(OV5_MMU_EITHER): /* Either Available */
1016 prom_debug("MMU - either supported\n");
1017 support->radix_mmu = !prom_radix_disable;
1018 support->hash_mmu = true;
1019 break;
1020 case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
1021 prom_debug("MMU - radix only\n");
1022 if (prom_radix_disable) {
1023 /*
1024 * If we __have__ to do radix, we're better off ignoring
1025 * the command line rather than not booting.
1026 */
1027 prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
1028 }
1029 support->radix_mmu = true;
1030 break;
1031 case OV5_FEAT(OV5_MMU_HASH):
1032 prom_debug("MMU - hash only\n");
1033 support->hash_mmu = true;
1034 break;
1035 default:
1036 prom_debug("Unknown mmu support option: 0x%x\n", val);
1037 break;
1038 }
1039}
1040
1041static void __init prom_parse_platform_support(u8 index, u8 val,
1042 struct platform_support *support)
1043{
1044 switch (index) {
1045 case OV5_INDX(OV5_MMU_SUPPORT): /* MMU Model */
1046 prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
1047 break;
1048 case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
1049 if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
1050 prom_debug("Radix - GTSE supported\n");
1051 support->radix_gtse = true;
1052 }
1053 break;
1054 }
1055}
1056
1057static void __init prom_check_platform_support(void)
1058{
1059 struct platform_support supported = {
1060 .hash_mmu = false,
1061 .radix_mmu = false,
1062 .radix_gtse = false
1063 };
1064 int prop_len = prom_getproplen(prom.chosen,
1065 "ibm,arch-vec-5-platform-support");
1066 if (prop_len > 1) {
1067 int i;
1068 u8 vec[prop_len];
1069 prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
1070 prop_len);
1071 prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
1072 &vec, sizeof(vec));
1073 for (i = 0; i < prop_len; i += 2) {
1074 prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
1075 , vec[i]
1076 , vec[i + 1]);
1077 prom_parse_platform_support(vec[i], vec[i + 1],
1078 &supported);
1079 }
1080 }
1081
1082 if (supported.radix_mmu && supported.radix_gtse) {
1083 /* Radix preferred - but we require GTSE for now */
1084 prom_debug("Asking for radix with GTSE\n");
1085 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1086 ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
1087 } else if (supported.hash_mmu) {
1088 /* Default to hash mmu (if we can) */
1089 prom_debug("Asking for hash\n");
1090 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
1091 } else {
1092 /* We're probably on a legacy hypervisor */
1093 prom_debug("Assuming legacy hash support\n");
1094 }
1095}
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001096
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001097static void __init prom_send_capabilities(void)
1098{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001099 ihandle root;
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001100 prom_arg_t ret;
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +02001101 u32 cores;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001102
Suraj Jitindar Singh014d02c2017-02-28 17:03:48 +11001103 /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
1104 prom_check_platform_support();
1105
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001106 root = call_prom("open", 1, 1, ADDR("/"));
1107 if (root != 0) {
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001108 /* We need to tell the FW about the number of cores we support.
1109 *
1110 * To do that, we count the number of threads on the first core
1111 * (we assume this is the same for all cores) and use it to
1112 * divide NR_CPUS.
1113 */
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +02001114
Michael Ellerman76ffb572016-11-18 23:15:42 +11001115 cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
1116 prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
1117 cores, NR_CPUS);
1118
1119 ibm_architecture_vec.vec5.max_cpus = cpu_to_be32(cores);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +11001120
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001121 /* try calling the ibm,client-architecture-support method */
Anton Blanchard049d0492009-09-21 20:47:39 +00001122 prom_printf("Calling ibm,client-architecture-support...");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001123 if (call_prom_ret("call-method", 3, 2, &ret,
1124 ADDR("ibm,client-architecture-support"),
Benjamin Herrenschmidt33b74972006-06-07 12:01:32 +10001125 root,
Michael Ellerman76ffb572016-11-18 23:15:42 +11001126 ADDR(&ibm_architecture_vec)) == 0) {
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001127 /* the call exists... */
1128 if (ret)
Anton Blanchard4da727a2009-03-31 20:06:14 +00001129 prom_printf("\nWARNING: ibm,client-architecture"
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001130 "-support call FAILED!\n");
1131 call_prom("close", 1, 0, root);
Anton Blanchard4da727a2009-03-31 20:06:14 +00001132 prom_printf(" done\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001133 return;
1134 }
1135 call_prom("close", 1, 0, root);
Anton Blanchard049d0492009-09-21 20:47:39 +00001136 prom_printf(" not implemented\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +10001137 }
1138
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001139#ifdef __BIG_ENDIAN__
1140 {
1141 ihandle elfloader;
1142
1143 /* no ibm,client-architecture-support call, try the old way */
1144 elfloader = call_prom("open", 1, 1,
1145 ADDR("/packages/elf-loader"));
1146 if (elfloader == 0) {
1147 prom_printf("couldn't open /packages/elf-loader\n");
1148 return;
1149 }
1150 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
1151 elfloader, ADDR(&fake_elf));
1152 call_prom("close", 1, 0, elfloader);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001153 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001154#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001155}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001156#endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001157
1158/*
1159 * Memory allocation strategy... our layout is normally:
1160 *
1161 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
1162 * rare cases, initrd might end up being before the kernel though.
1163 * We assume this won't override the final kernel at 0, we have no
1164 * provision to handle that in this version, but it should hopefully
1165 * never happen.
1166 *
1167 * alloc_top is set to the top of RMO, eventually shrink down if the
1168 * TCEs overlap
1169 *
1170 * alloc_bottom is set to the top of kernel/initrd
1171 *
1172 * from there, allocations are done this way : rtas is allocated
1173 * topmost, and the device-tree is allocated from the bottom. We try
1174 * to grow the device-tree allocation as we progress. If we can't,
1175 * then we fail, we don't currently have a facility to restart
1176 * elsewhere, but that shouldn't be necessary.
1177 *
1178 * Note that calls to reserve_mem have to be done explicitly, memory
1179 * allocated with either alloc_up or alloc_down isn't automatically
1180 * reserved.
1181 */
1182
1183
1184/*
1185 * Allocates memory in the RMO upward from the kernel/initrd
1186 *
1187 * When align is 0, this is a special case, it means to allocate in place
1188 * at the current location of alloc_bottom or fail (that is basically
1189 * extending the previous allocation). Used for the device-tree flattening
1190 */
1191static unsigned long __init alloc_up(unsigned long size, unsigned long align)
1192{
Anton Blanchard5827d412012-11-26 17:40:03 +00001193 unsigned long base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001194 unsigned long addr = 0;
1195
Paul Mackerrasc49888202005-10-26 21:52:53 +10001196 if (align)
1197 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001198 prom_debug("alloc_up(%x, %x)\n", size, align);
Anton Blanchard5827d412012-11-26 17:40:03 +00001199 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001200 prom_panic("alloc_up() called with mem not initialized\n");
1201
1202 if (align)
Anton Blanchard5827d412012-11-26 17:40:03 +00001203 base = _ALIGN_UP(alloc_bottom, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001204 else
Anton Blanchard5827d412012-11-26 17:40:03 +00001205 base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001206
Anton Blanchard5827d412012-11-26 17:40:03 +00001207 for(; (base + size) <= alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001208 base = _ALIGN_UP(base + 0x100000, align)) {
1209 prom_debug(" trying: 0x%x\n\r", base);
1210 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001211 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001212 break;
1213 addr = 0;
1214 if (align == 0)
1215 break;
1216 }
1217 if (addr == 0)
1218 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +00001219 alloc_bottom = addr + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001220
1221 prom_debug(" -> %x\n", addr);
Anton Blanchard5827d412012-11-26 17:40:03 +00001222 prom_debug(" alloc_bottom : %x\n", alloc_bottom);
1223 prom_debug(" alloc_top : %x\n", alloc_top);
1224 prom_debug(" alloc_top_hi : %x\n", alloc_top_high);
1225 prom_debug(" rmo_top : %x\n", rmo_top);
1226 prom_debug(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001227
1228 return addr;
1229}
1230
1231/*
1232 * Allocates memory downward, either from top of RMO, or if highmem
1233 * is set, from the top of RAM. Note that this one doesn't handle
1234 * failures. It does claim memory if highmem is not set.
1235 */
1236static unsigned long __init alloc_down(unsigned long size, unsigned long align,
1237 int highmem)
1238{
1239 unsigned long base, addr = 0;
1240
1241 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
Anton Blanchard5827d412012-11-26 17:40:03 +00001242 highmem ? "(high)" : "(low)");
1243 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001244 prom_panic("alloc_down() called with mem not initialized\n");
1245
1246 if (highmem) {
1247 /* Carve out storage for the TCE table. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001248 addr = _ALIGN_DOWN(alloc_top_high - size, align);
1249 if (addr <= alloc_bottom)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001250 return 0;
1251 /* Will we bump into the RMO ? If yes, check out that we
1252 * didn't overlap existing allocations there, if we did,
1253 * we are dead, we must be the first in town !
1254 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001255 if (addr < rmo_top) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001256 /* Good, we are first */
Anton Blanchard5827d412012-11-26 17:40:03 +00001257 if (alloc_top == rmo_top)
1258 alloc_top = rmo_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001259 else
1260 return 0;
1261 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001262 alloc_top_high = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001263 goto bail;
1264 }
1265
Anton Blanchard5827d412012-11-26 17:40:03 +00001266 base = _ALIGN_DOWN(alloc_top - size, align);
1267 for (; base > alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001268 base = _ALIGN_DOWN(base - 0x100000, align)) {
1269 prom_debug(" trying: 0x%x\n\r", base);
1270 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001271 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001272 break;
1273 addr = 0;
1274 }
1275 if (addr == 0)
1276 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +00001277 alloc_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001278
1279 bail:
1280 prom_debug(" -> %x\n", addr);
Anton Blanchard5827d412012-11-26 17:40:03 +00001281 prom_debug(" alloc_bottom : %x\n", alloc_bottom);
1282 prom_debug(" alloc_top : %x\n", alloc_top);
1283 prom_debug(" alloc_top_hi : %x\n", alloc_top_high);
1284 prom_debug(" rmo_top : %x\n", rmo_top);
1285 prom_debug(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001286
1287 return addr;
1288}
1289
1290/*
1291 * Parse a "reg" cell
1292 */
1293static unsigned long __init prom_next_cell(int s, cell_t **cellp)
1294{
1295 cell_t *p = *cellp;
1296 unsigned long r = 0;
1297
1298 /* Ignore more than 2 cells */
1299 while (s > sizeof(unsigned long) / 4) {
1300 p++;
1301 s--;
1302 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001303 r = be32_to_cpu(*p++);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001304#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +10001305 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001306 r <<= 32;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001307 r |= be32_to_cpu(*(p++));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001308 }
1309#endif
1310 *cellp = p;
1311 return r;
1312}
1313
1314/*
1315 * Very dumb function for adding to the memory reserve list, but
1316 * we don't need anything smarter at this point
1317 *
1318 * XXX Eventually check for collisions. They should NEVER happen.
1319 * If problems seem to show up, it would be a good start to track
1320 * them down.
1321 */
Michael Ellerman0108d3f2007-05-07 15:58:28 +10001322static void __init reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001323{
Kumar Galacbbcf342006-01-11 17:57:13 -06001324 u64 top = base + size;
Anton Blanchard5827d412012-11-26 17:40:03 +00001325 unsigned long cnt = mem_reserve_cnt;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001326
1327 if (size == 0)
1328 return;
1329
1330 /* We need to always keep one empty entry so that we
1331 * have our terminator with "size" set to 0 since we are
1332 * dumb and just copy this entire array to the boot params
1333 */
1334 base = _ALIGN_DOWN(base, PAGE_SIZE);
1335 top = _ALIGN_UP(top, PAGE_SIZE);
1336 size = top - base;
1337
1338 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1339 prom_panic("Memory reserve map exhausted !\n");
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001340 mem_reserve_map[cnt].base = cpu_to_be64(base);
1341 mem_reserve_map[cnt].size = cpu_to_be64(size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001342 mem_reserve_cnt = cnt + 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001343}
1344
1345/*
Adrian Bunkb3c2ffd2006-06-30 18:20:44 +02001346 * Initialize memory allocation mechanism, parse "memory" nodes and
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001347 * obtain that way the top of memory and RMO to setup out local allocator
1348 */
1349static void __init prom_init_mem(void)
1350{
1351 phandle node;
1352 char *path, type[64];
1353 unsigned int plen;
1354 cell_t *p, *endp;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001355 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001356 u32 rac, rsc;
1357
1358 /*
1359 * We iterate the memory nodes to find
1360 * 1) top of RMO (first node)
1361 * 2) top of memory
1362 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001363 val = cpu_to_be32(2);
1364 prom_getprop(prom.root, "#address-cells", &val, sizeof(val));
1365 rac = be32_to_cpu(val);
1366 val = cpu_to_be32(1);
1367 prom_getprop(prom.root, "#size-cells", &val, sizeof(rsc));
1368 rsc = be32_to_cpu(val);
1369 prom_debug("root_addr_cells: %x\n", rac);
1370 prom_debug("root_size_cells: %x\n", rsc);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001371
1372 prom_debug("scanning memory:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00001373 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001374
1375 for (node = 0; prom_next_node(&node); ) {
1376 type[0] = 0;
1377 prom_getprop(node, "device_type", type, sizeof(type));
1378
Paul Mackerrasc49888202005-10-26 21:52:53 +10001379 if (type[0] == 0) {
1380 /*
1381 * CHRP Longtrail machines have no device_type
1382 * on the memory node, so check the name instead...
1383 */
1384 prom_getprop(node, "name", type, sizeof(type));
1385 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001386 if (strcmp(type, "memory"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001387 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001388
Anton Blanchard5827d412012-11-26 17:40:03 +00001389 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001390 if (plen > sizeof(regbuf)) {
1391 prom_printf("memory node too large for buffer !\n");
1392 plen = sizeof(regbuf);
1393 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001394 p = regbuf;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001395 endp = p + (plen / sizeof(cell_t));
1396
1397#ifdef DEBUG_PROM
1398 memset(path, 0, PROM_SCRATCH_SIZE);
1399 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1400 prom_debug(" node %s :\n", path);
1401#endif /* DEBUG_PROM */
1402
1403 while ((endp - p) >= (rac + rsc)) {
1404 unsigned long base, size;
1405
1406 base = prom_next_cell(rac, &p);
1407 size = prom_next_cell(rsc, &p);
1408
1409 if (size == 0)
1410 continue;
1411 prom_debug(" %x %x\n", base, size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001412 if (base == 0 && (of_platform & PLATFORM_LPAR))
1413 rmo_top = size;
1414 if ((base + size) > ram_top)
1415 ram_top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001416 }
1417 }
1418
Anton Blanchard5827d412012-11-26 17:40:03 +00001419 alloc_bottom = PAGE_ALIGN((unsigned long)&_end + 0x4000);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001420
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001421 /*
Benjamin Krillcf687872009-07-27 22:02:39 +00001422 * If prom_memory_limit is set we reduce the upper limits *except* for
1423 * alloc_top_high. This must be the real top of RAM so we can put
1424 * TCE's up there.
1425 */
1426
Anton Blanchard5827d412012-11-26 17:40:03 +00001427 alloc_top_high = ram_top;
Benjamin Krillcf687872009-07-27 22:02:39 +00001428
Anton Blanchard5827d412012-11-26 17:40:03 +00001429 if (prom_memory_limit) {
1430 if (prom_memory_limit <= alloc_bottom) {
Benjamin Krillcf687872009-07-27 22:02:39 +00001431 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00001432 prom_memory_limit);
1433 prom_memory_limit = 0;
1434 } else if (prom_memory_limit >= ram_top) {
Benjamin Krillcf687872009-07-27 22:02:39 +00001435 prom_printf("Ignoring mem=%x >= ram_top.\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00001436 prom_memory_limit);
1437 prom_memory_limit = 0;
Benjamin Krillcf687872009-07-27 22:02:39 +00001438 } else {
Anton Blanchard5827d412012-11-26 17:40:03 +00001439 ram_top = prom_memory_limit;
1440 rmo_top = min(rmo_top, prom_memory_limit);
Benjamin Krillcf687872009-07-27 22:02:39 +00001441 }
1442 }
1443
1444 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001445 * Setup our top alloc point, that is top of RMO or top of
1446 * segment 0 when running non-LPAR.
1447 * Some RS64 machines have buggy firmware where claims up at
1448 * 1GB fail. Cap at 768MB as a workaround.
1449 * Since 768MB is plenty of room, and we need to cap to something
1450 * reasonable on 32-bit, cap at 768MB on all machines.
1451 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001452 if (!rmo_top)
1453 rmo_top = ram_top;
1454 rmo_top = min(0x30000000ul, rmo_top);
1455 alloc_top = rmo_top;
1456 alloc_top_high = ram_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001457
Paul Mackerras64968f62011-12-13 17:54:13 +00001458 /*
1459 * Check if we have an initrd after the kernel but still inside
1460 * the RMO. If we do move our bottom point to after it.
1461 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001462 if (prom_initrd_start &&
1463 prom_initrd_start < rmo_top &&
1464 prom_initrd_end > alloc_bottom)
1465 alloc_bottom = PAGE_ALIGN(prom_initrd_end);
Paul Mackerras64968f62011-12-13 17:54:13 +00001466
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001467 prom_printf("memory layout at init:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00001468 prom_printf(" memory_limit : %x (16 MB aligned)\n", prom_memory_limit);
1469 prom_printf(" alloc_bottom : %x\n", alloc_bottom);
1470 prom_printf(" alloc_top : %x\n", alloc_top);
1471 prom_printf(" alloc_top_hi : %x\n", alloc_top_high);
1472 prom_printf(" rmo_top : %x\n", rmo_top);
1473 prom_printf(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001474}
1475
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001476static void __init prom_close_stdin(void)
1477{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001478 __be32 val;
1479 ihandle stdin;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001480
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001481 if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) {
1482 stdin = be32_to_cpu(val);
1483 call_prom("close", 1, 0, stdin);
1484 }
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001485}
1486
1487#ifdef CONFIG_PPC_POWERNV
1488
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001489#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1490static u64 __initdata prom_opal_base;
1491static u64 __initdata prom_opal_entry;
1492#endif
1493
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001494/*
1495 * Allocate room for and instantiate OPAL
1496 */
1497static void __init prom_instantiate_opal(void)
1498{
1499 phandle opal_node;
1500 ihandle opal_inst;
1501 u64 base, entry;
1502 u64 size = 0, align = 0x10000;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001503 __be64 val64;
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001504 u32 rets[2];
1505
1506 prom_debug("prom_instantiate_opal: start...\n");
1507
1508 opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
1509 prom_debug("opal_node: %x\n", opal_node);
1510 if (!PHANDLE_VALID(opal_node))
1511 return;
1512
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001513 val64 = 0;
1514 prom_getprop(opal_node, "opal-runtime-size", &val64, sizeof(val64));
1515 size = be64_to_cpu(val64);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001516 if (size == 0)
1517 return;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001518 val64 = 0;
1519 prom_getprop(opal_node, "opal-runtime-alignment", &val64,sizeof(val64));
1520 align = be64_to_cpu(val64);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001521
1522 base = alloc_down(size, align, 0);
1523 if (base == 0) {
1524 prom_printf("OPAL allocation failed !\n");
1525 return;
1526 }
1527
1528 opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
1529 if (!IHANDLE_VALID(opal_inst)) {
1530 prom_printf("opening opal package failed (%x)\n", opal_inst);
1531 return;
1532 }
1533
1534 prom_printf("instantiating opal at 0x%x...", base);
1535
1536 if (call_prom_ret("call-method", 4, 3, rets,
1537 ADDR("load-opal-runtime"),
1538 opal_inst,
1539 base >> 32, base & 0xffffffff) != 0
1540 || (rets[0] == 0 && rets[1] == 0)) {
1541 prom_printf(" failed\n");
1542 return;
1543 }
1544 entry = (((u64)rets[0]) << 32) | rets[1];
1545
1546 prom_printf(" done\n");
1547
1548 reserve_mem(base, size);
1549
1550 prom_debug("opal base = 0x%x\n", base);
1551 prom_debug("opal align = 0x%x\n", align);
1552 prom_debug("opal entry = 0x%x\n", entry);
1553 prom_debug("opal size = 0x%x\n", (long)size);
1554
1555 prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
1556 &base, sizeof(base));
1557 prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
1558 &entry, sizeof(entry));
1559
1560#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
Anton Blanchard5827d412012-11-26 17:40:03 +00001561 prom_opal_base = base;
1562 prom_opal_entry = entry;
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001563#endif
1564 prom_debug("prom_instantiate_opal: end...\n");
1565}
1566
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001567#endif /* CONFIG_PPC_POWERNV */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001568
1569/*
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);
1630 prom_debug("rtas size = 0x%x\n", (long)size);
1631
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
1688 prom_printf("instantiating sml at 0x%x...", base);
1689
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
1707 prom_debug("sml base = 0x%x\n", base);
1708 prom_debug("sml size = 0x%x\n", (long)size);
1709
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.
1776 *
1777 * On POWER4, firmware sets the TCE region by assuming
1778 * each TCE table is 8MB. Using this memory for anything
1779 * else will impact performance, so we always allocate 8MB.
1780 * Anton
1781 */
Michael Ellermand3dbeef2012-08-19 21:44:01 +00001782 if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001783 minsize = 8UL << 20;
1784 else
1785 minsize = 4UL << 20;
1786
1787 /* Align to the greater of the align or size */
1788 align = max(minalign, minsize);
1789 base = alloc_down(minsize, align, 1);
1790 if (base == 0)
1791 prom_panic("ERROR, cannot find space for TCE table.\n");
1792 if (base < local_alloc_bottom)
1793 local_alloc_bottom = base;
1794
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001795 /* It seems OF doesn't null-terminate the path :-( */
Li Zefanaca71ef2007-11-05 13:21:56 +11001796 memset(path, 0, PROM_SCRATCH_SIZE);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001797 /* Call OF to setup the TCE hardware */
1798 if (call_prom("package-to-path", 3, 1, node,
1799 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1800 prom_printf("package-to-path failed\n");
1801 }
1802
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001803 /* Save away the TCE table attributes for later use. */
1804 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1805 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1806
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001807 prom_debug("TCE table: %s\n", path);
1808 prom_debug("\tnode = 0x%x\n", node);
1809 prom_debug("\tbase = 0x%x\n", base);
1810 prom_debug("\tsize = 0x%x\n", minsize);
1811
1812 /* Initialize the table to have a one-to-one mapping
1813 * over the allocated size.
1814 */
Ingo Molnar2b931fb2009-01-06 13:56:52 +00001815 tce_entryp = (u64 *)base;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001816 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1817 tce_entry = (i << PAGE_SHIFT);
1818 tce_entry |= 0x3;
1819 *tce_entryp = tce_entry;
1820 }
1821
1822 prom_printf("opening PHB %s", path);
1823 phb_node = call_prom("open", 1, 1, path);
1824 if (phb_node == 0)
1825 prom_printf("... failed\n");
1826 else
1827 prom_printf("... done\n");
1828
1829 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1830 phb_node, -1, minsize,
1831 (u32) base, (u32) (base >> 32));
1832 call_prom("close", 1, 0, phb_node);
1833 }
1834
1835 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1836
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001837 /* These are only really needed if there is a memory limit in
1838 * effect, but we don't know so export them always. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001839 prom_tce_alloc_start = local_alloc_bottom;
1840 prom_tce_alloc_end = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001841
1842 /* Flag the first invalid entry */
1843 prom_debug("ending prom_initialize_tce_table\n");
1844}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001845#endif /* __BIG_ENDIAN__ */
1846#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001847
1848/*
1849 * With CHRP SMP we need to use the OF to start the other processors.
1850 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1851 * so we have to put the processors into a holding pattern controlled
1852 * by the kernel (not OF) before we destroy the OF.
1853 *
1854 * This uses a chunk of low memory, puts some holding pattern
1855 * code there and sends the other processors off to there until
1856 * smp_boot_cpus tells them to do something. The holding pattern
1857 * checks that address until its cpu # is there, when it is that
1858 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1859 * of setting those values.
1860 *
1861 * We also use physical address 0x4 here to tell when a cpu
1862 * is in its holding pattern code.
1863 *
1864 * -- Cort
1865 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001866/*
1867 * We want to reference the copy of __secondary_hold_* in the
1868 * 0 - 0x100 address range
1869 */
1870#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1871
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001872static void __init prom_hold_cpus(void)
1873{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001874 unsigned long i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001875 phandle node;
1876 char type[64];
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001877 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001878 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001879 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001880 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001881 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001882
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10001883 /*
1884 * On pseries, if RTAS supports "query-cpu-stopped-state",
1885 * we skip this stage, the CPUs will be started by the
1886 * kernel using RTAS.
1887 */
1888 if ((of_platform == PLATFORM_PSERIES ||
1889 of_platform == PLATFORM_PSERIES_LPAR) &&
1890 rtas_has_query_cpu_stopped) {
1891 prom_printf("prom_hold_cpus: skipped\n");
1892 return;
1893 }
1894
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001895 prom_debug("prom_hold_cpus: start...\n");
1896 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1897 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1898 prom_debug(" 1) acknowledge = 0x%x\n",
1899 (unsigned long)acknowledge);
1900 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1901 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1902
1903 /* Set the common spinloop variable, so all of the secondary cpus
1904 * will block when they are awakened from their OF spinloop.
1905 * This must occur for both SMP and non SMP kernels, since OF will
1906 * be trashed when we move the kernel.
1907 */
1908 *spinloop = 0;
1909
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001910 /* look for cpus */
1911 for (node = 0; prom_next_node(&node); ) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001912 unsigned int cpu_no;
1913 __be32 reg;
1914
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001915 type[0] = 0;
1916 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00001917 if (strcmp(type, "cpu") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001918 continue;
1919
1920 /* Skip non-configured cpus. */
1921 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
Anton Blanchard5827d412012-11-26 17:40:03 +00001922 if (strcmp(type, "okay") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001923 continue;
1924
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001925 reg = cpu_to_be32(-1); /* make sparse happy */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001926 prom_getprop(node, "reg", &reg, sizeof(reg));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001927 cpu_no = be32_to_cpu(reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001928
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001929 prom_debug("cpu hw idx = %lu\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001930
1931 /* Init the acknowledge var which will be reset by
1932 * the secondary cpu when it awakens from its OF
1933 * spinloop.
1934 */
1935 *acknowledge = (unsigned long)-1;
1936
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001937 if (cpu_no != prom.cpu) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001938 /* Primary Thread of non-boot cpu or any thread */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001939 prom_printf("starting cpu hw idx %lu... ", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001940 call_prom("start-cpu", 3, 0, node,
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001941 secondary_hold, cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001942
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001943 for (i = 0; (i < 100000000) &&
1944 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001945 mb();
1946
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001947 if (*acknowledge == cpu_no)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001948 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001949 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001950 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001951 }
1952#ifdef CONFIG_SMP
1953 else
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001954 prom_printf("boot cpu hw idx %lu\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001955#endif /* CONFIG_SMP */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001956 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001957
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001958 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001959}
1960
1961
1962static void __init prom_init_client_services(unsigned long pp)
1963{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001964 /* Get a handle to the prom entry point before anything else */
Anton Blanchard5827d412012-11-26 17:40:03 +00001965 prom_entry = pp;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001966
1967 /* get a handle for the stdout device */
Anton Blanchard5827d412012-11-26 17:40:03 +00001968 prom.chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1969 if (!PHANDLE_VALID(prom.chosen))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001970 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1971
1972 /* get device tree root */
Anton Blanchard5827d412012-11-26 17:40:03 +00001973 prom.root = call_prom("finddevice", 1, 1, ADDR("/"));
1974 if (!PHANDLE_VALID(prom.root))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001975 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001976
Anton Blanchard5827d412012-11-26 17:40:03 +00001977 prom.mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001978}
1979
Paul Mackerrasa575b802005-10-23 17:23:21 +10001980#ifdef CONFIG_PPC32
1981/*
1982 * For really old powermacs, we need to map things we claim.
1983 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001984 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001985 */
1986static void __init prom_find_mmu(void)
1987{
Paul Mackerrasa575b802005-10-23 17:23:21 +10001988 phandle oprom;
1989 char version[64];
1990
1991 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1992 if (!PHANDLE_VALID(oprom))
1993 return;
1994 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1995 return;
1996 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001997 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001998 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1999 of_workarounds = OF_WA_CLAIM;
2000 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
2001 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
2002 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
2003 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10002004 return;
Anton Blanchard5827d412012-11-26 17:40:03 +00002005 prom.memory = call_prom("open", 1, 1, ADDR("/memory"));
2006 prom_getprop(prom.chosen, "mmu", &prom.mmumap,
2007 sizeof(prom.mmumap));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002008 prom.mmumap = be32_to_cpu(prom.mmumap);
Anton Blanchard5827d412012-11-26 17:40:03 +00002009 if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002010 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002011}
2012#else
2013#define prom_find_mmu()
2014#endif
2015
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002016static void __init prom_init_stdout(void)
2017{
Anton Blanchard5827d412012-11-26 17:40:03 +00002018 char *path = of_stdout_device;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002019 char type[16];
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002020 phandle stdout_node;
2021 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002022
Anton Blanchard5827d412012-11-26 17:40:03 +00002023 if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002024 prom_panic("cannot find stdout");
2025
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002026 prom.stdout = be32_to_cpu(val);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002027
2028 /* Get the full OF pathname of the stdout device */
2029 memset(path, 0, 256);
Anton Blanchard5827d412012-11-26 17:40:03 +00002030 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
Anton Blanchard5827d412012-11-26 17:40:03 +00002031 prom_printf("OF stdout device is: %s\n", of_stdout_device);
2032 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002033 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002034
Benjamin Herrenschmidt10348f52014-01-13 09:49:17 +11002035 /* instance-to-package fails on PA-Semi */
2036 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
2037 if (stdout_node != PROM_ERROR) {
2038 val = cpu_to_be32(stdout_node);
2039 prom_setprop(prom.chosen, "/chosen", "linux,stdout-package",
2040 &val, sizeof(val));
2041
2042 /* If it's a display, note it */
2043 memset(type, 0, sizeof(type));
2044 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2045 if (strcmp(type, "display") == 0)
2046 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
2047 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002048}
2049
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002050static int __init prom_find_machine_type(void)
2051{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002052 char compat[256];
2053 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002054#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002055 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002056 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002057#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002058
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002059 /* Look for a PowerMac or a Cell */
Anton Blanchard5827d412012-11-26 17:40:03 +00002060 len = prom_getprop(prom.root, "compatible",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002061 compat, sizeof(compat)-1);
2062 if (len > 0) {
2063 compat[len] = 0;
2064 while (i < len) {
2065 char *p = &compat[i];
2066 int sl = strlen(p);
2067 if (sl == 0)
2068 break;
Anton Blanchard5827d412012-11-26 17:40:03 +00002069 if (strstr(p, "Power Macintosh") ||
2070 strstr(p, "MacRISC"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002071 return PLATFORM_POWERMAC;
Arnd Bergmann133dda12006-06-07 12:04:18 +10002072#ifdef CONFIG_PPC64
2073 /* We must make sure we don't detect the IBM Cell
2074 * blades as pSeries due to some firmware issues,
2075 * so we do it here.
2076 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002077 if (strstr(p, "IBM,CBEA") ||
2078 strstr(p, "IBM,CPBW-1.0"))
Arnd Bergmann133dda12006-06-07 12:04:18 +10002079 return PLATFORM_GENERIC;
2080#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002081 i += sl + 1;
2082 }
2083 }
2084#ifdef CONFIG_PPC64
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002085 /* Try to detect OPAL */
2086 if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
2087 return PLATFORM_OPAL;
2088
2089 /* Try to figure out if it's an IBM pSeries or any other
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002090 * PAPR compliant platform. We assume it is if :
2091 * - /device_type is "chrp" (please, do NOT use that for future
2092 * non-IBM designs !
2093 * - it has /rtas
2094 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002095 len = prom_getprop(prom.root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002096 compat, sizeof(compat)-1);
2097 if (len <= 0)
2098 return PLATFORM_GENERIC;
Anton Blanchard5827d412012-11-26 17:40:03 +00002099 if (strcmp(compat, "chrp"))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002100 return PLATFORM_GENERIC;
2101
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002102 /* Default to pSeries. We need to know if we are running LPAR */
2103 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002104 if (!PHANDLE_VALID(rtas))
2105 return PLATFORM_GENERIC;
2106 x = prom_getproplen(rtas, "ibm,hypertas-functions");
2107 if (x != PROM_ERROR) {
Anton Blanchard4da727a2009-03-31 20:06:14 +00002108 prom_debug("Hypertas detected, assuming LPAR !\n");
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002109 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002110 }
2111 return PLATFORM_PSERIES;
2112#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002113 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002114#endif
2115}
2116
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002117static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
2118{
2119 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
2120}
2121
2122/*
2123 * If we have a display that we don't know how to drive,
2124 * we will want to try to execute OF's open method for it
2125 * later. However, OF will probably fall over if we do that
2126 * we've taken over the MMU.
2127 * So we check whether we will need to open the display,
2128 * and if so, open it now.
2129 */
2130static void __init prom_check_displays(void)
2131{
2132 char type[16], *path;
2133 phandle node;
2134 ihandle ih;
2135 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002136
2137 static unsigned char default_colors[] = {
2138 0x00, 0x00, 0x00,
2139 0x00, 0x00, 0xaa,
2140 0x00, 0xaa, 0x00,
2141 0x00, 0xaa, 0xaa,
2142 0xaa, 0x00, 0x00,
2143 0xaa, 0x00, 0xaa,
2144 0xaa, 0xaa, 0x00,
2145 0xaa, 0xaa, 0xaa,
2146 0x55, 0x55, 0x55,
2147 0x55, 0x55, 0xff,
2148 0x55, 0xff, 0x55,
2149 0x55, 0xff, 0xff,
2150 0xff, 0x55, 0x55,
2151 0xff, 0x55, 0xff,
2152 0xff, 0xff, 0x55,
2153 0xff, 0xff, 0xff
2154 };
2155 const unsigned char *clut;
2156
Anton Blanchard4da727a2009-03-31 20:06:14 +00002157 prom_debug("Looking for displays\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002158 for (node = 0; prom_next_node(&node); ) {
2159 memset(type, 0, sizeof(type));
2160 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00002161 if (strcmp(type, "display") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002162 continue;
2163
2164 /* It seems OF doesn't null-terminate the path :-( */
Anton Blanchard5827d412012-11-26 17:40:03 +00002165 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002166 memset(path, 0, PROM_SCRATCH_SIZE);
2167
2168 /*
2169 * leave some room at the end of the path for appending extra
2170 * arguments
2171 */
2172 if (call_prom("package-to-path", 3, 1, node, path,
2173 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2174 continue;
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002175 prom_printf("found display : %s, opening... ", path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002176
2177 ih = call_prom("open", 1, 1, path);
2178 if (ih == 0) {
2179 prom_printf("failed\n");
2180 continue;
2181 }
2182
2183 /* Success */
2184 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002185 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002186
2187 /* Setup a usable color table when the appropriate
2188 * method is available. Should update this to set-colors */
Anton Blanchard5827d412012-11-26 17:40:03 +00002189 clut = default_colors;
Benjamin Herrenschmidt3f536382011-12-14 13:55:11 +00002190 for (i = 0; i < 16; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002191 if (prom_set_color(ih, i, clut[0], clut[1],
2192 clut[2]) != 0)
2193 break;
2194
2195#ifdef CONFIG_LOGO_LINUX_CLUT224
Anton Blanchard5827d412012-11-26 17:40:03 +00002196 clut = PTRRELOC(logo_linux_clut224.clut);
2197 for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002198 if (prom_set_color(ih, i + 32, clut[0], clut[1],
2199 clut[2]) != 0)
2200 break;
2201#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Benjamin Herrenschmidt7191b612013-07-25 12:12:32 +10002202
2203#ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
2204 if (prom_getprop(node, "linux,boot-display", NULL, 0) !=
2205 PROM_ERROR) {
2206 u32 width, height, pitch, addr;
2207
2208 prom_printf("Setting btext !\n");
2209 prom_getprop(node, "width", &width, 4);
2210 prom_getprop(node, "height", &height, 4);
2211 prom_getprop(node, "linebytes", &pitch, 4);
2212 prom_getprop(node, "address", &addr, 4);
2213 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
2214 width, height, pitch, addr);
2215 btext_setup_display(width, height, 8, pitch, addr);
2216 }
2217#endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002218 }
2219}
2220
2221
2222/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
2223static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
2224 unsigned long needed, unsigned long align)
2225{
2226 void *ret;
2227
2228 *mem_start = _ALIGN(*mem_start, align);
2229 while ((*mem_start + needed) > *mem_end) {
2230 unsigned long room, chunk;
2231
2232 prom_debug("Chunk exhausted, claiming more at %x...\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002233 alloc_bottom);
2234 room = alloc_top - alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002235 if (room > DEVTREE_CHUNK_SIZE)
2236 room = DEVTREE_CHUNK_SIZE;
2237 if (room < PAGE_SIZE)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002238 prom_panic("No memory for flatten_device_tree "
2239 "(no room)\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002240 chunk = alloc_up(room, 0);
2241 if (chunk == 0)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002242 prom_panic("No memory for flatten_device_tree "
2243 "(claim failed)\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002244 *mem_end = chunk + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002245 }
2246
2247 ret = (void *)*mem_start;
2248 *mem_start += needed;
2249
2250 return ret;
2251}
2252
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002253#define dt_push_token(token, mem_start, mem_end) do { \
2254 void *room = make_room(mem_start, mem_end, 4, 4); \
2255 *(__be32 *)room = cpu_to_be32(token); \
2256 } while(0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002257
2258static unsigned long __init dt_find_string(char *str)
2259{
2260 char *s, *os;
2261
Anton Blanchard5827d412012-11-26 17:40:03 +00002262 s = os = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002263 s += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +00002264 while (s < (char *)dt_string_end) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002265 if (strcmp(s, str) == 0)
2266 return s - os;
2267 s += strlen(s) + 1;
2268 }
2269 return 0;
2270}
2271
2272/*
2273 * The Open Firmware 1275 specification states properties must be 31 bytes or
2274 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
2275 */
2276#define MAX_PROPERTY_NAME 64
2277
2278static void __init scan_dt_build_strings(phandle node,
2279 unsigned long *mem_start,
2280 unsigned long *mem_end)
2281{
2282 char *prev_name, *namep, *sstart;
2283 unsigned long soff;
2284 phandle child;
2285
Anton Blanchard5827d412012-11-26 17:40:03 +00002286 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002287
2288 /* get and store all property names */
Anton Blanchard5827d412012-11-26 17:40:03 +00002289 prev_name = "";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002290 for (;;) {
2291 /* 64 is max len of name including nul. */
2292 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
2293 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
2294 /* No more nodes: unwind alloc */
2295 *mem_start = (unsigned long)namep;
2296 break;
2297 }
2298
2299 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002300 if (strcmp(namep, "name") == 0) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002301 *mem_start = (unsigned long)namep;
Anton Blanchard5827d412012-11-26 17:40:03 +00002302 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002303 continue;
2304 }
2305 /* get/create string entry */
2306 soff = dt_find_string(namep);
2307 if (soff != 0) {
2308 *mem_start = (unsigned long)namep;
2309 namep = sstart + soff;
2310 } else {
2311 /* Trim off some if we can */
2312 *mem_start = (unsigned long)namep + strlen(namep) + 1;
Anton Blanchard5827d412012-11-26 17:40:03 +00002313 dt_string_end = *mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002314 }
2315 prev_name = namep;
2316 }
2317
2318 /* do all our children */
2319 child = call_prom("child", 1, 1, node);
2320 while (child != 0) {
2321 scan_dt_build_strings(child, mem_start, mem_end);
2322 child = call_prom("peer", 1, 1, child);
2323 }
2324}
2325
2326static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2327 unsigned long *mem_end)
2328{
2329 phandle child;
2330 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
2331 unsigned long soff;
2332 unsigned char *valp;
2333 static char pname[MAX_PROPERTY_NAME];
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002334 int l, room, has_phandle = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002335
2336 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
2337
2338 /* get the node's full name */
2339 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10002340 room = *mem_end - *mem_start;
2341 if (room > 255)
2342 room = 255;
2343 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002344 if (l >= 0) {
2345 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10002346 if (l >= room) {
2347 if (l >= *mem_end - *mem_start)
2348 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002349 call_prom("package-to-path", 3, 1, node, namep, l);
2350 }
2351 namep[l] = '\0';
2352
2353 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10002354 * middle of the path in some properties, and extract
2355 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002356 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002357 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002358 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10002359 lp = namep;
2360 else if (*p != 0)
2361 *lp++ = *p;
2362 }
2363 *lp = 0;
2364 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002365 }
2366
2367 /* get it again for debugging */
Anton Blanchard5827d412012-11-26 17:40:03 +00002368 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002369 memset(path, 0, PROM_SCRATCH_SIZE);
2370 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2371
2372 /* get and store all properties */
Anton Blanchard5827d412012-11-26 17:40:03 +00002373 prev_name = "";
2374 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002375 for (;;) {
2376 if (call_prom("nextprop", 3, 1, node, prev_name,
Anton Blanchard5827d412012-11-26 17:40:03 +00002377 pname) != 1)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002378 break;
2379
2380 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002381 if (strcmp(pname, "name") == 0) {
2382 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002383 continue;
2384 }
2385
2386 /* find string offset */
Anton Blanchard5827d412012-11-26 17:40:03 +00002387 soff = dt_find_string(pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002388 if (soff == 0) {
2389 prom_printf("WARNING: Can't find string index for"
Anton Blanchard5827d412012-11-26 17:40:03 +00002390 " <%s>, node %s\n", pname, path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002391 break;
2392 }
2393 prev_name = sstart + soff;
2394
2395 /* get length */
Anton Blanchard5827d412012-11-26 17:40:03 +00002396 l = call_prom("getproplen", 2, 1, node, pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002397
2398 /* sanity checks */
2399 if (l == PROM_ERROR)
2400 continue;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002401
2402 /* push property head */
2403 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2404 dt_push_token(l, mem_start, mem_end);
2405 dt_push_token(soff, mem_start, mem_end);
2406
2407 /* push property content */
2408 valp = make_room(mem_start, mem_end, l, 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002409 call_prom("getprop", 4, 1, node, pname, valp, l);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002410 *mem_start = _ALIGN(*mem_start, 4);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002411
Anton Blanchard5827d412012-11-26 17:40:03 +00002412 if (!strcmp(pname, "phandle"))
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002413 has_phandle = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002414 }
2415
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002416 /* Add a "linux,phandle" property if no "phandle" property already
2417 * existed (can happen with OPAL)
2418 */
2419 if (!has_phandle) {
Anton Blanchard5827d412012-11-26 17:40:03 +00002420 soff = dt_find_string("linux,phandle");
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002421 if (soff == 0)
2422 prom_printf("WARNING: Can't find string index for"
2423 " <linux-phandle> node %s\n", path);
2424 else {
2425 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2426 dt_push_token(4, mem_start, mem_end);
2427 dt_push_token(soff, mem_start, mem_end);
2428 valp = make_room(mem_start, mem_end, 4, 4);
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002429 *(__be32 *)valp = cpu_to_be32(node);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002430 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002431 }
2432
2433 /* do all our children */
2434 child = call_prom("child", 1, 1, node);
2435 while (child != 0) {
2436 scan_dt_build_struct(child, mem_start, mem_end);
2437 child = call_prom("peer", 1, 1, child);
2438 }
2439
2440 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
2441}
2442
2443static void __init flatten_device_tree(void)
2444{
2445 phandle root;
2446 unsigned long mem_start, mem_end, room;
2447 struct boot_param_header *hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002448 char *namep;
2449 u64 *rsvmap;
2450
2451 /*
2452 * Check how much room we have between alloc top & bottom (+/- a
Anton Blanchardfbafd722011-07-25 20:47:51 +00002453 * few pages), crop to 1MB, as this is our "chunk" size
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002454 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002455 room = alloc_top - alloc_bottom - 0x4000;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002456 if (room > DEVTREE_CHUNK_SIZE)
2457 room = DEVTREE_CHUNK_SIZE;
Anton Blanchard5827d412012-11-26 17:40:03 +00002458 prom_debug("starting device tree allocs at %x\n", alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002459
2460 /* Now try to claim that */
2461 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
2462 if (mem_start == 0)
2463 prom_panic("Can't allocate initial device-tree chunk\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002464 mem_end = mem_start + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002465
2466 /* Get root of tree */
2467 root = call_prom("peer", 1, 1, (phandle)0);
2468 if (root == (phandle)0)
2469 prom_panic ("couldn't get device tree root\n");
2470
2471 /* Build header and make room for mem rsv map */
2472 mem_start = _ALIGN(mem_start, 4);
2473 hdr = make_room(&mem_start, &mem_end,
2474 sizeof(struct boot_param_header), 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002475 dt_header_start = (unsigned long)hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002476 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
2477
2478 /* Start of strings */
2479 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002480 dt_string_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002481 mem_start += 4; /* hole */
2482
2483 /* Add "linux,phandle" in there, we'll need it */
2484 namep = make_room(&mem_start, &mem_end, 16, 1);
Anton Blanchard5827d412012-11-26 17:40:03 +00002485 strcpy(namep, "linux,phandle");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002486 mem_start = (unsigned long)namep + strlen(namep) + 1;
2487
2488 /* Build string array */
2489 prom_printf("Building dt strings...\n");
2490 scan_dt_build_strings(root, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002491 dt_string_end = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002492
2493 /* Build structure */
2494 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002495 dt_struct_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002496 prom_printf("Building dt structure...\n");
2497 scan_dt_build_struct(root, &mem_start, &mem_end);
2498 dt_push_token(OF_DT_END, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002499 dt_struct_end = PAGE_ALIGN(mem_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002500
2501 /* Finish header */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002502 hdr->boot_cpuid_phys = cpu_to_be32(prom.cpu);
2503 hdr->magic = cpu_to_be32(OF_DT_HEADER);
2504 hdr->totalsize = cpu_to_be32(dt_struct_end - dt_header_start);
2505 hdr->off_dt_struct = cpu_to_be32(dt_struct_start - dt_header_start);
2506 hdr->off_dt_strings = cpu_to_be32(dt_string_start - dt_header_start);
2507 hdr->dt_strings_size = cpu_to_be32(dt_string_end - dt_string_start);
2508 hdr->off_mem_rsvmap = cpu_to_be32(((unsigned long)rsvmap) - dt_header_start);
2509 hdr->version = cpu_to_be32(OF_DT_VERSION);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002510 /* Version 16 is not backward compatible */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002511 hdr->last_comp_version = cpu_to_be32(0x10);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002512
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002513 /* Copy the reserve map in */
Anton Blanchard5827d412012-11-26 17:40:03 +00002514 memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002515
2516#ifdef DEBUG_PROM
2517 {
2518 int i;
2519 prom_printf("reserved memory map:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00002520 for (i = 0; i < mem_reserve_cnt; i++)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002521 prom_printf(" %x - %x\n",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002522 be64_to_cpu(mem_reserve_map[i].base),
2523 be64_to_cpu(mem_reserve_map[i].size));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002524 }
2525#endif
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002526 /* Bump mem_reserve_cnt to cause further reservations to fail
2527 * since it's too late.
2528 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002529 mem_reserve_cnt = MEM_RESERVE_MAP_SIZE;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002530
2531 prom_printf("Device tree strings 0x%x -> 0x%x\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002532 dt_string_start, dt_string_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002533 prom_printf("Device tree struct 0x%x -> 0x%x\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002534 dt_struct_start, dt_struct_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002535}
2536
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002537#ifdef CONFIG_PPC_MAPLE
2538/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2539 * The values are bad, and it doesn't even have the right number of cells. */
2540static void __init fixup_device_tree_maple(void)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002541{
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002542 phandle isa;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002543 u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002544 u32 isa_ranges[6];
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002545 char *name;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002546
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002547 name = "/ht@0/isa@4";
2548 isa = call_prom("finddevice", 1, 1, ADDR(name));
2549 if (!PHANDLE_VALID(isa)) {
2550 name = "/ht@0/isa@6";
2551 isa = call_prom("finddevice", 1, 1, ADDR(name));
2552 rloc = 0x01003000; /* IO space; PCI device = 6 */
2553 }
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002554 if (!PHANDLE_VALID(isa))
2555 return;
2556
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002557 if (prom_getproplen(isa, "ranges") != 12)
2558 return;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002559 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2560 == PROM_ERROR)
2561 return;
2562
2563 if (isa_ranges[0] != 0x1 ||
2564 isa_ranges[1] != 0xf4000000 ||
2565 isa_ranges[2] != 0x00010000)
2566 return;
2567
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002568 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002569
2570 isa_ranges[0] = 0x1;
2571 isa_ranges[1] = 0x0;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002572 isa_ranges[2] = rloc;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002573 isa_ranges[3] = 0x0;
2574 isa_ranges[4] = 0x0;
2575 isa_ranges[5] = 0x00010000;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002576 prom_setprop(isa, name, "ranges",
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002577 isa_ranges, sizeof(isa_ranges));
2578}
Harry Ciao8f101a052009-06-17 16:28:00 -07002579
2580#define CPC925_MC_START 0xf8000000
2581#define CPC925_MC_LENGTH 0x1000000
2582/* The values for memory-controller don't have right number of cells */
2583static void __init fixup_device_tree_maple_memory_controller(void)
2584{
2585 phandle mc;
2586 u32 mc_reg[4];
2587 char *name = "/hostbridge@f8000000";
Harry Ciao8f101a052009-06-17 16:28:00 -07002588 u32 ac, sc;
2589
2590 mc = call_prom("finddevice", 1, 1, ADDR(name));
2591 if (!PHANDLE_VALID(mc))
2592 return;
2593
2594 if (prom_getproplen(mc, "reg") != 8)
2595 return;
2596
Anton Blanchard5827d412012-11-26 17:40:03 +00002597 prom_getprop(prom.root, "#address-cells", &ac, sizeof(ac));
2598 prom_getprop(prom.root, "#size-cells", &sc, sizeof(sc));
Harry Ciao8f101a052009-06-17 16:28:00 -07002599 if ((ac != 2) || (sc != 2))
2600 return;
2601
2602 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2603 return;
2604
2605 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2606 return;
2607
2608 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2609
2610 mc_reg[0] = 0x0;
2611 mc_reg[1] = CPC925_MC_START;
2612 mc_reg[2] = 0x0;
2613 mc_reg[3] = CPC925_MC_LENGTH;
2614 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2615}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002616#else
2617#define fixup_device_tree_maple()
Harry Ciao8f101a052009-06-17 16:28:00 -07002618#define fixup_device_tree_maple_memory_controller()
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002619#endif
2620
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002621#ifdef CONFIG_PPC_CHRP
Olaf Heringe4805922007-04-04 18:20:04 +02002622/*
2623 * Pegasos and BriQ lacks the "ranges" property in the isa node
2624 * Pegasos needs decimal IRQ 14/15, not hexadecimal
Olaf Hering556ecf9b2007-08-18 04:27:17 +10002625 * Pegasos has the IDE configured in legacy mode, but advertised as native
Olaf Heringe4805922007-04-04 18:20:04 +02002626 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002627static void __init fixup_device_tree_chrp(void)
2628{
Olaf Heringe4805922007-04-04 18:20:04 +02002629 phandle ph;
2630 u32 prop[6];
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002631 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002632 char *name;
2633 int rc;
2634
2635 name = "/pci@80000000/isa@c";
Olaf Heringe4805922007-04-04 18:20:04 +02002636 ph = call_prom("finddevice", 1, 1, ADDR(name));
2637 if (!PHANDLE_VALID(ph)) {
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002638 name = "/pci@ff500000/isa@6";
Olaf Heringe4805922007-04-04 18:20:04 +02002639 ph = call_prom("finddevice", 1, 1, ADDR(name));
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002640 rloc = 0x01003000; /* IO space; PCI device = 6 */
2641 }
Olaf Heringe4805922007-04-04 18:20:04 +02002642 if (PHANDLE_VALID(ph)) {
2643 rc = prom_getproplen(ph, "ranges");
2644 if (rc == 0 || rc == PROM_ERROR) {
2645 prom_printf("Fixing up missing ISA range on Pegasos...\n");
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002646
Olaf Heringe4805922007-04-04 18:20:04 +02002647 prop[0] = 0x1;
2648 prop[1] = 0x0;
2649 prop[2] = rloc;
2650 prop[3] = 0x0;
2651 prop[4] = 0x0;
2652 prop[5] = 0x00010000;
2653 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2654 }
2655 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002656
Olaf Heringe4805922007-04-04 18:20:04 +02002657 name = "/pci@80000000/ide@C,1";
2658 ph = call_prom("finddevice", 1, 1, ADDR(name));
2659 if (PHANDLE_VALID(ph)) {
2660 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2661 prop[0] = 14;
2662 prop[1] = 0x0;
Olaf Hering556ecf9b2007-08-18 04:27:17 +10002663 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2664 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2665 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2666 if (rc == sizeof(u32)) {
2667 prop[0] &= ~0x5;
2668 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2669 }
Olaf Heringe4805922007-04-04 18:20:04 +02002670 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002671}
2672#else
2673#define fixup_device_tree_chrp()
2674#endif
2675
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002676#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002677static void __init fixup_device_tree_pmac(void)
2678{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002679 phandle u3, i2c, mpic;
2680 u32 u3_rev;
2681 u32 interrupts[2];
2682 u32 parent;
2683
2684 /* Some G5s have a missing interrupt definition, fix it up here */
2685 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2686 if (!PHANDLE_VALID(u3))
2687 return;
2688 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2689 if (!PHANDLE_VALID(i2c))
2690 return;
2691 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2692 if (!PHANDLE_VALID(mpic))
2693 return;
2694
2695 /* check if proper rev of u3 */
2696 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2697 == PROM_ERROR)
2698 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002699 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002700 return;
2701 /* does it need fixup ? */
2702 if (prom_getproplen(i2c, "interrupts") > 0)
2703 return;
2704
2705 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2706
2707 /* interrupt on this revision of u3 is number 0 and level */
2708 interrupts[0] = 0;
2709 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002710 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2711 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002712 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002713 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2714 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002715}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002716#else
2717#define fixup_device_tree_pmac()
2718#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002719
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002720#ifdef CONFIG_PPC_EFIKA
Grant Likely94d2dde2008-01-24 22:25:32 -07002721/*
2722 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2723 * to talk to the phy. If the phy-handle property is missing, then this
2724 * function is called to add the appropriate nodes and link it to the
2725 * ethernet node.
2726 */
2727static void __init fixup_device_tree_efika_add_phy(void)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002728{
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002729 u32 node;
2730 char prop[64];
Grant Likely94d2dde2008-01-24 22:25:32 -07002731 int rv;
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002732
Grant Likely94d2dde2008-01-24 22:25:32 -07002733 /* Check if /builtin/ethernet exists - bail if it doesn't */
2734 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002735 if (!PHANDLE_VALID(node))
2736 return;
2737
Grant Likely94d2dde2008-01-24 22:25:32 -07002738 /* Check if the phy-handle property exists - bail if it does */
2739 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2740 if (!rv)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002741 return;
2742
Grant Likely94d2dde2008-01-24 22:25:32 -07002743 /*
2744 * At this point the ethernet device doesn't have a phy described.
2745 * Now we need to add the missing phy node and linkage
2746 */
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002747
Grant Likely94d2dde2008-01-24 22:25:32 -07002748 /* Check for an MDIO bus node - if missing then create one */
Olaf Hering6f4347c2008-01-10 01:06:08 +11002749 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2750 if (!PHANDLE_VALID(node)) {
2751 prom_printf("Adding Ethernet MDIO node\n");
2752 call_prom("interpret", 1, 1,
2753 " s\" /builtin\" find-device"
2754 " new-device"
2755 " 1 encode-int s\" #address-cells\" property"
2756 " 0 encode-int s\" #size-cells\" property"
Grant Likely94d2dde2008-01-24 22:25:32 -07002757 " s\" mdio\" device-name"
2758 " s\" fsl,mpc5200b-mdio\" encode-string"
Olaf Hering6f4347c2008-01-10 01:06:08 +11002759 " s\" compatible\" property"
2760 " 0xf0003000 0x400 reg"
2761 " 0x2 encode-int"
2762 " 0x5 encode-int encode+"
2763 " 0x3 encode-int encode+"
2764 " s\" interrupts\" property"
2765 " finish-device");
2766 };
2767
Grant Likely94d2dde2008-01-24 22:25:32 -07002768 /* Check for a PHY device node - if missing then create one and
2769 * give it's phandle to the ethernet node */
2770 node = call_prom("finddevice", 1, 1,
2771 ADDR("/builtin/mdio/ethernet-phy"));
Olaf Hering6f4347c2008-01-10 01:06:08 +11002772 if (!PHANDLE_VALID(node)) {
2773 prom_printf("Adding Ethernet PHY node\n");
2774 call_prom("interpret", 1, 1,
2775 " s\" /builtin/mdio\" find-device"
2776 " new-device"
2777 " s\" ethernet-phy\" device-name"
2778 " 0x10 encode-int s\" reg\" property"
2779 " my-self"
2780 " ihandle>phandle"
2781 " finish-device"
2782 " s\" /builtin/ethernet\" find-device"
2783 " encode-int"
2784 " s\" phy-handle\" property"
2785 " device-end");
2786 }
Grant Likely94d2dde2008-01-24 22:25:32 -07002787}
Olaf Hering6f4347c2008-01-10 01:06:08 +11002788
Grant Likely94d2dde2008-01-24 22:25:32 -07002789static void __init fixup_device_tree_efika(void)
2790{
2791 int sound_irq[3] = { 2, 2, 0 };
2792 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2793 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2794 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2795 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2796 u32 node;
2797 char prop[64];
2798 int rv, len;
2799
2800 /* Check if we're really running on a EFIKA */
2801 node = call_prom("finddevice", 1, 1, ADDR("/"));
2802 if (!PHANDLE_VALID(node))
2803 return;
2804
2805 rv = prom_getprop(node, "model", prop, sizeof(prop));
2806 if (rv == PROM_ERROR)
2807 return;
2808 if (strcmp(prop, "EFIKA5K2"))
2809 return;
2810
2811 prom_printf("Applying EFIKA device tree fixups\n");
2812
2813 /* Claiming to be 'chrp' is death */
2814 node = call_prom("finddevice", 1, 1, ADDR("/"));
2815 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2816 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2817 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2818
David Woodhouse7f4392c2008-04-14 02:52:38 +10002819 /* CODEGEN,description is exposed in /proc/cpuinfo so
2820 fix that too */
2821 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2822 if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2823 prom_setprop(node, "/", "CODEGEN,description",
2824 "Efika 5200B PowerPC System",
2825 sizeof("Efika 5200B PowerPC System"));
2826
Grant Likely94d2dde2008-01-24 22:25:32 -07002827 /* Fixup bestcomm interrupts property */
2828 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2829 if (PHANDLE_VALID(node)) {
2830 len = prom_getproplen(node, "interrupts");
2831 if (len == 12) {
2832 prom_printf("Fixing bestcomm interrupts property\n");
2833 prom_setprop(node, "/builtin/bestcom", "interrupts",
2834 bcomm_irq, sizeof(bcomm_irq));
2835 }
2836 }
2837
2838 /* Fixup sound interrupts property */
2839 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2840 if (PHANDLE_VALID(node)) {
2841 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2842 if (rv == PROM_ERROR) {
2843 prom_printf("Adding sound interrupts property\n");
2844 prom_setprop(node, "/builtin/sound", "interrupts",
2845 sound_irq, sizeof(sound_irq));
2846 }
2847 }
2848
2849 /* Make sure ethernet phy-handle property exists */
2850 fixup_device_tree_efika_add_phy();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002851}
2852#else
2853#define fixup_device_tree_efika()
2854#endif
2855
Darren Stevens50246782016-08-31 13:24:40 +01002856#ifdef CONFIG_PPC_PASEMI_NEMO
2857/*
2858 * CFE supplied on Nemo is broken in several ways, biggest
2859 * problem is that it reassigns ISA interrupts to unused mpic ints.
2860 * Add an interrupt-controller property for the io-bridge to use
2861 * and correct the ints so we can attach them to an irq_domain
2862 */
2863static void __init fixup_device_tree_pasemi(void)
2864{
2865 u32 interrupts[2], parent, rval, val = 0;
2866 char *name, *pci_name;
2867 phandle iob, node;
2868
2869 /* Find the root pci node */
2870 name = "/pxp@0,e0000000";
2871 iob = call_prom("finddevice", 1, 1, ADDR(name));
2872 if (!PHANDLE_VALID(iob))
2873 return;
2874
2875 /* check if interrupt-controller node set yet */
2876 if (prom_getproplen(iob, "interrupt-controller") !=PROM_ERROR)
2877 return;
2878
2879 prom_printf("adding interrupt-controller property for SB600...\n");
2880
2881 prom_setprop(iob, name, "interrupt-controller", &val, 0);
2882
2883 pci_name = "/pxp@0,e0000000/pci@11";
2884 node = call_prom("finddevice", 1, 1, ADDR(pci_name));
2885 parent = ADDR(iob);
2886
2887 for( ; prom_next_node(&node); ) {
2888 /* scan each node for one with an interrupt */
2889 if (!PHANDLE_VALID(node))
2890 continue;
2891
2892 rval = prom_getproplen(node, "interrupts");
2893 if (rval == 0 || rval == PROM_ERROR)
2894 continue;
2895
2896 prom_getprop(node, "interrupts", &interrupts, sizeof(interrupts));
2897 if ((interrupts[0] < 212) || (interrupts[0] > 222))
2898 continue;
2899
2900 /* found a node, update both interrupts and interrupt-parent */
2901 if ((interrupts[0] >= 212) && (interrupts[0] <= 215))
2902 interrupts[0] -= 203;
2903 if ((interrupts[0] >= 216) && (interrupts[0] <= 220))
2904 interrupts[0] -= 213;
2905 if (interrupts[0] == 221)
2906 interrupts[0] = 14;
2907 if (interrupts[0] == 222)
2908 interrupts[0] = 8;
2909
2910 prom_setprop(node, pci_name, "interrupts", interrupts,
2911 sizeof(interrupts));
2912 prom_setprop(node, pci_name, "interrupt-parent", &parent,
2913 sizeof(parent));
2914 }
Darren Stevens687e16b2016-08-31 13:24:45 +01002915
2916 /*
2917 * The io-bridge has device_type set to 'io-bridge' change it to 'isa'
2918 * so that generic isa-bridge code can add the SB600 and its on-board
2919 * peripherals.
2920 */
2921 name = "/pxp@0,e0000000/io-bridge@0";
2922 iob = call_prom("finddevice", 1, 1, ADDR(name));
2923 if (!PHANDLE_VALID(iob))
2924 return;
2925
2926 /* device_type is already set, just change it. */
2927
2928 prom_printf("Changing device_type of SB600 node...\n");
2929
2930 prom_setprop(iob, name, "device_type", "isa", sizeof("isa"));
Darren Stevens50246782016-08-31 13:24:40 +01002931}
2932#else /* !CONFIG_PPC_PASEMI_NEMO */
2933static inline void fixup_device_tree_pasemi(void) { }
2934#endif
2935
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002936static void __init fixup_device_tree(void)
2937{
2938 fixup_device_tree_maple();
Harry Ciao8f101a052009-06-17 16:28:00 -07002939 fixup_device_tree_maple_memory_controller();
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002940 fixup_device_tree_chrp();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002941 fixup_device_tree_pmac();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002942 fixup_device_tree_efika();
Darren Stevens50246782016-08-31 13:24:40 +01002943 fixup_device_tree_pasemi();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002944}
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002945
2946static void __init prom_find_boot_cpu(void)
2947{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002948 __be32 rval;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002949 ihandle prom_cpu;
2950 phandle cpu_pkg;
2951
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002952 rval = 0;
2953 if (prom_getprop(prom.chosen, "cpu", &rval, sizeof(rval)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002954 return;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002955 prom_cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002956
2957 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2958
Darren Stevensaf2b7fa2017-01-23 19:42:54 +00002959 if (!PHANDLE_VALID(cpu_pkg))
2960 return;
2961
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002962 prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval));
2963 prom.cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002964
Anton Blanchard5827d412012-11-26 17:40:03 +00002965 prom_debug("Booting CPU hw index = %lu\n", prom.cpu);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002966}
2967
2968static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2969{
2970#ifdef CONFIG_BLK_DEV_INITRD
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002971 if (r3 && r4 && r4 != 0xdeadbeef) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002972 __be64 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002973
Anton Blanchard5827d412012-11-26 17:40:03 +00002974 prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3;
2975 prom_initrd_end = prom_initrd_start + r4;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002976
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002977 val = cpu_to_be64(prom_initrd_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002978 prom_setprop(prom.chosen, "/chosen", "linux,initrd-start",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002979 &val, sizeof(val));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002980 val = cpu_to_be64(prom_initrd_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002981 prom_setprop(prom.chosen, "/chosen", "linux,initrd-end",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002982 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002983
Anton Blanchard5827d412012-11-26 17:40:03 +00002984 reserve_mem(prom_initrd_start,
2985 prom_initrd_end - prom_initrd_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002986
Anton Blanchard5827d412012-11-26 17:40:03 +00002987 prom_debug("initrd_start=0x%x\n", prom_initrd_start);
2988 prom_debug("initrd_end=0x%x\n", prom_initrd_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002989 }
2990#endif /* CONFIG_BLK_DEV_INITRD */
2991}
2992
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002993#ifdef CONFIG_PPC64
2994#ifdef CONFIG_RELOCATABLE
2995static void reloc_toc(void)
2996{
2997}
2998
2999static void unreloc_toc(void)
3000{
3001}
3002#else
Anton Blanchard16744002013-03-12 01:51:51 +00003003static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003004{
3005 unsigned long i;
Anton Blanchard16744002013-03-12 01:51:51 +00003006 unsigned long *toc_entry;
3007
3008 /* Get the start of the TOC by using r2 directly. */
3009 asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003010
3011 for (i = 0; i < nr_entries; i++) {
3012 *toc_entry = *toc_entry + offset;
3013 toc_entry++;
3014 }
3015}
3016
3017static void reloc_toc(void)
3018{
3019 unsigned long offset = reloc_offset();
3020 unsigned long nr_entries =
3021 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
3022
Anton Blanchard16744002013-03-12 01:51:51 +00003023 __reloc_toc(offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003024
3025 mb();
3026}
3027
3028static void unreloc_toc(void)
3029{
3030 unsigned long offset = reloc_offset();
3031 unsigned long nr_entries =
3032 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
3033
3034 mb();
3035
Anton Blanchard16744002013-03-12 01:51:51 +00003036 __reloc_toc(-offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003037}
3038#endif
3039#endif
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003040
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003041/*
3042 * We enter here early on, when the Open Firmware prom is still
3043 * handling exceptions and the MMU hash table for us.
3044 */
3045
3046unsigned long __init prom_init(unsigned long r3, unsigned long r4,
3047 unsigned long pp,
Paul Mackerras549e8152008-08-30 11:43:47 +10003048 unsigned long r6, unsigned long r7,
3049 unsigned long kbase)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003050{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003051 unsigned long hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003052
3053#ifdef CONFIG_PPC32
Paul Mackerras549e8152008-08-30 11:43:47 +10003054 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003055 reloc_got2(offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003056#else
3057 reloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003058#endif
3059
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003060 /*
3061 * First zero the BSS
3062 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003063 memset(&__bss_start, 0, __bss_stop - __bss_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003064
3065 /*
3066 * Init interface to Open Firmware, get some node references,
3067 * like /chosen
3068 */
3069 prom_init_client_services(pp);
3070
3071 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003072 * See if this OF is old enough that we need to do explicit maps
3073 * and other workarounds
3074 */
3075 prom_find_mmu();
3076
3077 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003078 * Init prom stdout device
3079 */
3080 prom_init_stdout();
3081
Anton Blanchard5827d412012-11-26 17:40:03 +00003082 prom_printf("Preparing to boot %s", linux_banner);
Michael Ellermane7943fb2009-03-04 19:02:01 +00003083
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003084 /*
3085 * Get default machine type. At this point, we do not differentiate
3086 * between pSeries SMP and pSeries LPAR
3087 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003088 of_platform = prom_find_machine_type();
3089 prom_printf("Detected machine type: %x\n", of_platform);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003090
Suzuki Poulose0f890c82011-12-14 22:57:15 +00003091#ifndef CONFIG_NONSTATIC_KERNEL
Olaf Heringadd60ef2006-03-23 22:03:57 +01003092 /* Bail if this is a kdump kernel. */
3093 if (PHYSICAL_START > 0)
3094 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
Paul Mackerras549e8152008-08-30 11:43:47 +10003095#endif
Olaf Heringadd60ef2006-03-23 22:03:57 +01003096
3097 /*
3098 * Check for an initrd
3099 */
3100 prom_check_initrd(r3, r4);
3101
Suraj Jitindar Singh12cc9fd2017-02-28 17:03:47 +11003102 /*
3103 * Do early parsing of command line
3104 */
3105 early_cmdline_parse();
3106
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003107#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003108 /*
3109 * On pSeries, inform the firmware about our capabilities
3110 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003111 if (of_platform == PLATFORM_PSERIES ||
3112 of_platform == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003113 prom_send_capabilities();
3114#endif
3115
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003116 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05003117 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003118 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003119 if (of_platform != PLATFORM_POWERMAC)
Paul Mackerras549e8152008-08-30 11:43:47 +10003120 copy_and_flush(0, kbase, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003121
3122 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003123 * Initialize memory management within prom_init
3124 */
3125 prom_init_mem();
3126
3127 /*
3128 * Determine which cpu is actually running right _now_
3129 */
3130 prom_find_boot_cpu();
3131
3132 /*
3133 * Initialize display devices
3134 */
3135 prom_check_displays();
3136
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003137#if defined(CONFIG_PPC64) && defined(__BIG_ENDIAN__)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003138 /*
3139 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
3140 * that uses the allocator, we need to make sure we get the top of memory
3141 * available for us here...
3142 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003143 if (of_platform == PLATFORM_PSERIES)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003144 prom_initialize_tce_table();
3145#endif
3146
3147 /*
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003148 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
3149 * have a usable RTAS implementation.
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003150 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003151 if (of_platform != PLATFORM_POWERMAC &&
3152 of_platform != PLATFORM_OPAL)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003153 prom_instantiate_rtas();
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003154
3155#ifdef CONFIG_PPC_POWERNV
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003156 if (of_platform == PLATFORM_OPAL)
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003157 prom_instantiate_opal();
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003158#endif /* CONFIG_PPC_POWERNV */
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003159
Ashley Lai4a727422012-08-14 18:34:57 -05003160#ifdef CONFIG_PPC64
3161 /* instantiate sml */
3162 prom_instantiate_sml();
3163#endif
3164
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003165 /*
3166 * On non-powermacs, put all CPUs in spin-loops.
3167 *
3168 * PowerMacs use a different mechanism to spin CPUs
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10003169 *
3170 * (This must be done after instanciating RTAS)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003171 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003172 if (of_platform != PLATFORM_POWERMAC &&
3173 of_platform != PLATFORM_OPAL)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003174 prom_hold_cpus();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003175
3176 /*
3177 * Fill in some infos for use by the kernel later on
3178 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003179 if (prom_memory_limit) {
3180 __be64 val = cpu_to_be64(prom_memory_limit);
Anton Blanchard5827d412012-11-26 17:40:03 +00003181 prom_setprop(prom.chosen, "/chosen", "linux,memory-limit",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003182 &val, sizeof(val));
3183 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003184#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +00003185 if (prom_iommu_off)
3186 prom_setprop(prom.chosen, "/chosen", "linux,iommu-off",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003187 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003188
Anton Blanchard5827d412012-11-26 17:40:03 +00003189 if (prom_iommu_force_on)
3190 prom_setprop(prom.chosen, "/chosen", "linux,iommu-force-on",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003191 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003192
Anton Blanchard5827d412012-11-26 17:40:03 +00003193 if (prom_tce_alloc_start) {
3194 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-start",
3195 &prom_tce_alloc_start,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003196 sizeof(prom_tce_alloc_start));
Anton Blanchard5827d412012-11-26 17:40:03 +00003197 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-end",
3198 &prom_tce_alloc_end,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003199 sizeof(prom_tce_alloc_end));
3200 }
3201#endif
3202
3203 /*
3204 * Fixup any known bugs in the device-tree
3205 */
3206 fixup_device_tree();
3207
3208 /*
3209 * Now finally create the flattened device-tree
3210 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00003211 prom_printf("copying OF device tree...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003212 flatten_device_tree();
3213
Paul Mackerras3825ac02005-11-08 22:48:08 +11003214 /*
3215 * in case stdin is USB and still active on IBM machines...
3216 * Unfortunately quiesce crashes on some powermacs if we have
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003217 * closed stdin already (in particular the powerbook 101). It
3218 * appears that the OPAL version of OFW doesn't like it either.
Paul Mackerras3825ac02005-11-08 22:48:08 +11003219 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003220 if (of_platform != PLATFORM_POWERMAC &&
3221 of_platform != PLATFORM_OPAL)
Paul Mackerras3825ac02005-11-08 22:48:08 +11003222 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003223
3224 /*
3225 * Call OF "quiesce" method to shut down pending DMA's from
3226 * devices etc...
3227 */
Michael Ellerman7e862d72015-03-30 17:38:09 +11003228 prom_printf("Quiescing Open Firmware ...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003229 call_prom("quiesce", 0, 0);
3230
3231 /*
3232 * And finally, call the kernel passing it the flattened device
3233 * tree and NULL as r5, thus triggering the new entry point which
3234 * is common to us and kexec
3235 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003236 hdr = dt_header_start;
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003237
3238 /* Don't print anything after quiesce under OPAL, it crashes OFW */
Anton Blanchard5827d412012-11-26 17:40:03 +00003239 if (of_platform != PLATFORM_OPAL) {
Benjamin Herrenschmidt7d70c632016-08-10 17:29:29 +10003240 prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003241 prom_debug("->dt_header_start=0x%x\n", hdr);
3242 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003243
3244#ifdef CONFIG_PPC32
3245 reloc_got2(-offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003246#else
3247 unreloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003248#endif
3249
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003250#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
3251 /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
3252 __start(hdr, kbase, 0, 0, 0,
Anton Blanchard5827d412012-11-26 17:40:03 +00003253 prom_opal_base, prom_opal_entry);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003254#else
3255 __start(hdr, kbase, 0, 0, 0, 0, 0);
3256#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003257
3258 return 0;
3259}