blob: 078145acf7fb867dca6278f776a935ba0b2ecf25 [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>
40#include <asm/pci.h>
41#include <asm/iommu.h>
Paul Mackerras9b6b5632005-10-06 12:06:20 +100042#include <asm/btext.h>
43#include <asm/sections.h>
44#include <asm/machdep.h>
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +000045#include <asm/opal.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
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100171/* Platforms codes are now obsolete in the kernel. Now only used within this
172 * file and ultimately gone too. Feel free to change them if you need, they
173 * are not shared with anything outside of this file anymore
174 */
175#define PLATFORM_PSERIES 0x0100
176#define PLATFORM_PSERIES_LPAR 0x0101
177#define PLATFORM_LPAR 0x0001
178#define PLATFORM_POWERMAC 0x0400
179#define PLATFORM_GENERIC 0x0500
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000180#define PLATFORM_OPAL 0x0600
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +1100181
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000182static int __initdata of_platform;
183
184static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
185
Benjamin Krillcf687872009-07-27 22:02:39 +0000186static unsigned long __initdata prom_memory_limit;
187
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000188static unsigned long __initdata alloc_top;
189static unsigned long __initdata alloc_top_high;
190static unsigned long __initdata alloc_bottom;
191static unsigned long __initdata rmo_top;
192static unsigned long __initdata ram_top;
193
194static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
195static int __initdata mem_reserve_cnt;
196
197static cell_t __initdata regbuf[1024];
198
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +1000199static bool rtas_has_query_cpu_stopped;
200
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000201
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000202/*
203 * Error results ... some OF calls will return "-1" on error, some
204 * will return 0, some will return either. To simplify, here are
205 * macros to use with any ihandle or phandle return value to check if
206 * it is valid
207 */
208
209#define PROM_ERROR (-1u)
210#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
211#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
212
213
214/* This is the one and *ONLY* place where we actually call open
215 * firmware.
216 */
217
218static int __init call_prom(const char *service, int nargs, int nret, ...)
219{
220 int i;
221 struct prom_args args;
222 va_list list;
223
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000224 args.service = cpu_to_be32(ADDR(service));
225 args.nargs = cpu_to_be32(nargs);
226 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000227
228 va_start(list, nret);
229 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000230 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000231 va_end(list);
232
233 for (i = 0; i < nret; i++)
234 args.args[nargs+i] = 0;
235
Anton Blanchard5827d412012-11-26 17:40:03 +0000236 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000237 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000238
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000239 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000240}
241
242static int __init call_prom_ret(const char *service, int nargs, int nret,
243 prom_arg_t *rets, ...)
244{
245 int i;
246 struct prom_args args;
247 va_list list;
248
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000249 args.service = cpu_to_be32(ADDR(service));
250 args.nargs = cpu_to_be32(nargs);
251 args.nret = cpu_to_be32(nret);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000252
253 va_start(list, rets);
254 for (i = 0; i < nargs; i++)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000255 args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000256 va_end(list);
257
258 for (i = 0; i < nret; i++)
Olaf Heringed1189b2005-11-29 14:04:05 +0100259 args.args[nargs+i] = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000260
Anton Blanchard5827d412012-11-26 17:40:03 +0000261 if (enter_prom(&args, prom_entry) < 0)
Paul Mackerrasc49888202005-10-26 21:52:53 +1000262 return PROM_ERROR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000263
264 if (rets != NULL)
265 for (i = 1; i < nret; ++i)
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000266 rets[i-1] = be32_to_cpu(args.args[nargs+i]);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000267
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000268 return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000269}
270
271
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000272static void __init prom_print(const char *msg)
273{
274 const char *p, *q;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000275
Anton Blanchard5827d412012-11-26 17:40:03 +0000276 if (prom.stdout == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000277 return;
278
279 for (p = msg; *p != 0; p = q) {
280 for (q = p; *q != 0 && *q != '\n'; ++q)
281 ;
282 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000283 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000284 if (*q == 0)
285 break;
286 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000287 call_prom("write", 3, 1, prom.stdout, ADDR("\r\n"), 2);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000288 }
289}
290
291
292static void __init prom_print_hex(unsigned long val)
293{
294 int i, nibbles = sizeof(val)*2;
295 char buf[sizeof(val)*2+1];
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000296
297 for (i = nibbles-1; i >= 0; i--) {
298 buf[i] = (val & 0xf) + '0';
299 if (buf[i] > '9')
300 buf[i] += ('a'-'0'-10);
301 val >>= 4;
302 }
303 buf[nibbles] = '\0';
Anton Blanchard5827d412012-11-26 17:40:03 +0000304 call_prom("write", 3, 1, prom.stdout, buf, nibbles);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000305}
306
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000307/* max number of decimal digits in an unsigned long */
308#define UL_DIGITS 21
309static void __init prom_print_dec(unsigned long val)
310{
311 int i, size;
312 char buf[UL_DIGITS+1];
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000313
314 for (i = UL_DIGITS-1; i >= 0; i--) {
315 buf[i] = (val % 10) + '0';
316 val = val/10;
317 if (val == 0)
318 break;
319 }
320 /* shift stuff down */
321 size = UL_DIGITS - i;
Anton Blanchard5827d412012-11-26 17:40:03 +0000322 call_prom("write", 3, 1, prom.stdout, buf+i, size);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000323}
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000324
325static void __init prom_printf(const char *format, ...)
326{
327 const char *p, *q, *s;
328 va_list args;
329 unsigned long v;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000330 long vs;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000331
332 va_start(args, format);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000333 for (p = format; *p != 0; p = q) {
334 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
335 ;
336 if (q > p)
Anton Blanchard5827d412012-11-26 17:40:03 +0000337 call_prom("write", 3, 1, prom.stdout, p, q - p);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000338 if (*q == 0)
339 break;
340 if (*q == '\n') {
341 ++q;
Anton Blanchard5827d412012-11-26 17:40:03 +0000342 call_prom("write", 3, 1, prom.stdout,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000343 ADDR("\r\n"), 2);
344 continue;
345 }
346 ++q;
347 if (*q == 0)
348 break;
349 switch (*q) {
350 case 's':
351 ++q;
352 s = va_arg(args, const char *);
353 prom_print(s);
354 break;
355 case 'x':
356 ++q;
357 v = va_arg(args, unsigned long);
358 prom_print_hex(v);
359 break;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000360 case 'd':
361 ++q;
362 vs = va_arg(args, int);
363 if (vs < 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +0000364 prom_print("-");
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000365 vs = -vs;
366 }
367 prom_print_dec(vs);
368 break;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000369 case 'l':
370 ++q;
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000371 if (*q == 0)
372 break;
373 else if (*q == 'x') {
374 ++q;
375 v = va_arg(args, unsigned long);
376 prom_print_hex(v);
377 } else if (*q == 'u') { /* '%lu' */
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000378 ++q;
379 v = va_arg(args, unsigned long);
380 prom_print_dec(v);
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000381 } else if (*q == 'd') { /* %ld */
382 ++q;
383 vs = va_arg(args, long);
384 if (vs < 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +0000385 prom_print("-");
Benjamin Herrenschmidtaf277142011-04-06 10:51:17 +1000386 vs = -vs;
387 }
388 prom_print_dec(vs);
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000389 }
390 break;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000391 }
392 }
393}
394
395
Paul Mackerrasa575b802005-10-23 17:23:21 +1000396static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
397 unsigned long align)
398{
Paul Mackerrasa575b802005-10-23 17:23:21 +1000399
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100400 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
401 /*
402 * Old OF requires we claim physical and virtual separately
403 * and then map explicitly (assuming virtual mode)
404 */
405 int ret;
406 prom_arg_t result;
407
408 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000409 ADDR("claim"), prom.memory,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100410 align, size, virt);
411 if (ret != 0 || result == -1)
412 return -1;
413 ret = call_prom_ret("call-method", 5, 2, &result,
Anton Blanchard5827d412012-11-26 17:40:03 +0000414 ADDR("claim"), prom.mmumap,
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100415 align, size, virt);
416 if (ret != 0) {
417 call_prom("call-method", 4, 1, ADDR("release"),
Anton Blanchard5827d412012-11-26 17:40:03 +0000418 prom.memory, size, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100419 return -1;
420 }
421 /* the 0x12 is M (coherence) + PP == read/write */
Paul Mackerrasa575b802005-10-23 17:23:21 +1000422 call_prom("call-method", 6, 1,
Anton Blanchard5827d412012-11-26 17:40:03 +0000423 ADDR("map"), prom.mmumap, 0x12, size, virt, virt);
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100424 return virt;
425 }
426 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
427 (prom_arg_t)align);
Paul Mackerrasa575b802005-10-23 17:23:21 +1000428}
429
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000430static void __init __attribute__((noreturn)) prom_panic(const char *reason)
431{
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000432 prom_print(reason);
Olaf Heringadd60ef2006-03-23 22:03:57 +0100433 /* Do not call exit because it clears the screen on pmac
434 * it also causes some sort of double-fault on early pmacs */
Anton Blanchard5827d412012-11-26 17:40:03 +0000435 if (of_platform == PLATFORM_POWERMAC)
Olaf Heringadd60ef2006-03-23 22:03:57 +0100436 asm("trap\n");
437
Stephen Rothwell1d9a4732012-03-21 18:23:27 +0000438 /* ToDo: should put up an SRC here on pSeries */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000439 call_prom("exit", 0, 0);
440
441 for (;;) /* should never get here */
442 ;
443}
444
445
446static int __init prom_next_node(phandle *nodep)
447{
448 phandle node;
449
450 if ((node = *nodep) != 0
451 && (*nodep = call_prom("child", 1, 1, node)) != 0)
452 return 1;
453 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
454 return 1;
455 for (;;) {
456 if ((node = call_prom("parent", 1, 1, node)) == 0)
457 return 0;
458 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
459 return 1;
460 }
461}
462
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100463static int inline prom_getprop(phandle node, const char *pname,
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000464 void *value, size_t valuelen)
465{
466 return call_prom("getprop", 4, 1, node, ADDR(pname),
467 (u32)(unsigned long) value, (u32) valuelen);
468}
469
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +1100470static int inline prom_getproplen(phandle node, const char *pname)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000471{
472 return call_prom("getproplen", 2, 1, node, ADDR(pname));
473}
474
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100475static void add_string(char **str, const char *q)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000476{
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100477 char *p = *str;
478
479 while (*q)
480 *p++ = *q++;
481 *p++ = ' ';
482 *str = p;
483}
484
485static char *tohex(unsigned int x)
486{
487 static char digits[] = "0123456789abcdef";
488 static char result[9];
489 int i;
490
491 result[8] = 0;
492 i = 8;
493 do {
494 --i;
495 result[i] = digits[x & 0xf];
496 x >>= 4;
497 } while (x != 0 && i > 0);
498 return &result[i];
499}
500
501static int __init prom_setprop(phandle node, const char *nodename,
502 const char *pname, void *value, size_t valuelen)
503{
504 char cmd[256], *p;
505
506 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
507 return call_prom("setprop", 4, 1, node, ADDR(pname),
508 (u32)(unsigned long) value, (u32) valuelen);
509
510 /* gah... setprop doesn't work on longtrail, have to use interpret */
511 p = cmd;
512 add_string(&p, "dev");
513 add_string(&p, nodename);
514 add_string(&p, tohex((u32)(unsigned long) value));
515 add_string(&p, tohex(valuelen));
516 add_string(&p, tohex(ADDR(pname)));
Anton Blanchard5827d412012-11-26 17:40:03 +0000517 add_string(&p, tohex(strlen(pname)));
Paul Mackerrasa23414b2005-11-10 12:00:55 +1100518 add_string(&p, "property");
519 *p = 0;
520 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000521}
522
Anton Blanchard5827d412012-11-26 17:40:03 +0000523/* We can't use the standard versions because of relocation headaches. */
Benjamin Krillcf687872009-07-27 22:02:39 +0000524#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
525 || ('a' <= (c) && (c) <= 'f') \
526 || ('A' <= (c) && (c) <= 'F'))
527
528#define isdigit(c) ('0' <= (c) && (c) <= '9')
529#define islower(c) ('a' <= (c) && (c) <= 'z')
530#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
531
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000532static unsigned long prom_strtoul(const char *cp, const char **endp)
Benjamin Krillcf687872009-07-27 22:02:39 +0000533{
534 unsigned long result = 0, base = 10, value;
535
536 if (*cp == '0') {
537 base = 8;
538 cp++;
539 if (toupper(*cp) == 'X') {
540 cp++;
541 base = 16;
542 }
543 }
544
545 while (isxdigit(*cp) &&
546 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
547 result = result * base + value;
548 cp++;
549 }
550
551 if (endp)
552 *endp = cp;
553
554 return result;
555}
556
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000557static unsigned long prom_memparse(const char *ptr, const char **retptr)
Benjamin Krillcf687872009-07-27 22:02:39 +0000558{
559 unsigned long ret = prom_strtoul(ptr, retptr);
560 int shift = 0;
561
562 /*
563 * We can't use a switch here because GCC *may* generate a
564 * jump table which won't work, because we're not running at
565 * the address we're linked at.
566 */
567 if ('G' == **retptr || 'g' == **retptr)
568 shift = 30;
569
570 if ('M' == **retptr || 'm' == **retptr)
571 shift = 20;
572
573 if ('K' == **retptr || 'k' == **retptr)
574 shift = 10;
575
576 if (shift) {
577 ret <<= shift;
578 (*retptr)++;
579 }
580
581 return ret;
582}
583
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000584/*
585 * Early parsing of the command line passed to the kernel, used for
586 * "mem=x" and the options that affect the iommu
587 */
588static void __init early_cmdline_parse(void)
589{
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100590 const char *opt;
Benjamin Krillcf687872009-07-27 22:02:39 +0000591
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100592 char *p;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000593 int l = 0;
594
Anton Blanchard5827d412012-11-26 17:40:03 +0000595 prom_cmd_line[0] = 0;
596 p = prom_cmd_line;
597 if ((long)prom.chosen > 0)
598 l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000599#ifdef CONFIG_CMDLINE
Amos Waterland0e4aa9c2006-06-12 23:45:02 -0400600 if (l <= 0 || p[0] == '\0') /* dbl check */
Anton Blanchard5827d412012-11-26 17:40:03 +0000601 strlcpy(prom_cmd_line,
602 CONFIG_CMDLINE, sizeof(prom_cmd_line));
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000603#endif /* CONFIG_CMDLINE */
Anton Blanchard5827d412012-11-26 17:40:03 +0000604 prom_printf("command line: %s\n", prom_cmd_line);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000605
606#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +0000607 opt = strstr(prom_cmd_line, "iommu=");
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000608 if (opt) {
609 prom_printf("iommu opt is: %s\n", opt);
610 opt += 6;
611 while (*opt && *opt == ' ')
612 opt++;
Anton Blanchard5827d412012-11-26 17:40:03 +0000613 if (!strncmp(opt, "off", 3))
614 prom_iommu_off = 1;
615 else if (!strncmp(opt, "force", 5))
616 prom_iommu_force_on = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000617 }
618#endif
Anton Blanchard5827d412012-11-26 17:40:03 +0000619 opt = strstr(prom_cmd_line, "mem=");
Benjamin Krillcf687872009-07-27 22:02:39 +0000620 if (opt) {
621 opt += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +0000622 prom_memory_limit = prom_memparse(opt, (const char **)&opt);
Benjamin Krillcf687872009-07-27 22:02:39 +0000623#ifdef CONFIG_PPC64
624 /* Align to 16 MB == size of ppc64 large page */
Anton Blanchard5827d412012-11-26 17:40:03 +0000625 prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
Benjamin Krillcf687872009-07-27 22:02:39 +0000626#endif
627 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000628}
629
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +0000630#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000631/*
Nathan Fontenot530b5e12013-04-24 05:53:10 +0000632 * The architecture vector has an array of PVR mask/value pairs,
633 * followed by # option vectors - 1, followed by the option vectors.
634 *
635 * See prom.h for the definition of the bits specified in the
636 * architecture vector.
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000637 *
638 * Because the description vector contains a mix of byte and word
639 * values, we declare it as an unsigned char array, and use this
640 * macro to put word values in.
641 */
642#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
643 ((x) >> 8) & 0xff, (x) & 0xff
644
Nathan Fontenot530b5e12013-04-24 05:53:10 +0000645unsigned char ibm_architecture_vec[] = {
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000646 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
Anton Blanchard03054d52006-04-29 09:51:06 +1000647 W(0xffff0000), W(0x003e0000), /* POWER6 */
Michael Neulinge952e6c2008-06-18 10:47:26 +1000648 W(0xffff0000), W(0x003f0000), /* POWER7 */
Michael Neuling33959f82013-07-18 11:31:51 +1000649 W(0xffff0000), W(0x004b0000), /* POWER8E */
650 W(0xffff0000), W(0x004d0000), /* POWER8 */
Michael Neulingdf77c792012-11-08 20:23:11 +0000651 W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
Joel Schopp0cb99012008-06-19 06:23:23 +1000652 W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
Paul Mackerras0efbc182006-11-29 22:31:47 +1100653 W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000654 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000655 6 - 1, /* 6 option vectors */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000656
657 /* option vector 1: processor architectures supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500658 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000659 0, /* don't ignore, don't halt */
660 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
Michael Neulingdf77c792012-11-08 20:23:11 +0000661 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000662
663 /* option vector 2: Open Firmware options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500664 34 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000665 OV2_REAL_MODE,
666 0, 0,
667 W(0xffffffff), /* real_base */
668 W(0xffffffff), /* real_size */
669 W(0xffffffff), /* virt_base */
670 W(0xffffffff), /* virt_size */
671 W(0xffffffff), /* load_base */
Anton Blanchard33392642011-12-04 13:13:58 +0000672 W(256), /* 256MB min RMA */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000673 W(0xffffffff), /* full client load */
674 0, /* min RMA percentage of total RAM */
675 48, /* max log_2(hash table size) */
676
677 /* option vector 3: processor options supported */
Will Schmidt11e9ed42006-08-25 15:46:59 -0500678 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000679 0, /* don't ignore, don't halt */
Paul Mackerras974a76f2006-11-10 20:38:53 +1100680 OV3_FP | OV3_VMX | OV3_DFP,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000681
682 /* option vector 4: IBM PAPR implementation */
Robert Jennings404e32e2012-05-10 08:55:49 +0000683 3 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000684 0, /* don't halt */
Robert Jennings404e32e2012-05-10 08:55:49 +0000685 OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000686
687 /* option vector 5: PAPR/OF options */
Michael Neulingdf77c792012-11-08 20:23:11 +0000688 19 - 2, /* length */
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000689 0, /* don't ignore, don't halt */
Nathan Fontenotf0ff7eb2013-04-24 05:57:18 +0000690 OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
691 OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
692#ifdef CONFIG_PCI_MSI
693 /* PCIe/MSI support. Without MSI full PCIe is not supported */
694 OV5_FEAT(OV5_MSI),
695#else
Nathan Fontenot8391e422008-07-24 04:36:38 +1000696 0,
Nathan Fontenotf0ff7eb2013-04-24 05:57:18 +0000697#endif
698 0,
699#ifdef CONFIG_PPC_SMLPAR
700 OV5_FEAT(OV5_CMO) | OV5_FEAT(OV5_XCMO),
701#else
702 0,
703#endif
Nathan Fontenot1b1218d2013-04-24 06:06:17 +0000704 OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN),
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000705 0,
706 0,
707 0,
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100708 /* WARNING: The offset of the "number of cores" field below
709 * must match by the macro below. Update the definition if
710 * the structure layout changes.
711 */
Michael Neuling33959f82013-07-18 11:31:51 +1000712#define IBM_ARCH_VEC_NRCORES_OFFSET 125
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100713 W(NR_CPUS), /* number of cores supported */
Kent Yoder828d2b52012-04-12 05:17:51 +0000714 0,
715 0,
716 0,
717 0,
Nathan Fontenotf0ff7eb2013-04-24 05:57:18 +0000718 OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) |
719 OV5_FEAT(OV5_PFO_HW_842),
720 OV5_FEAT(OV5_SUB_PROCESSORS),
jschopp@austin.ibm.com28bb9ee2010-02-01 12:50:48 +0000721 /* option vector 6: IBM PAPR hints */
722 4 - 2, /* length */
723 0,
724 0,
725 OV6_LINUX,
726
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000727};
728
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000729/* Old method - ELF header with PT_NOTE sections only works on BE */
730#ifdef __BIG_ENDIAN__
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000731static struct fake_elf {
732 Elf32_Ehdr elfhdr;
733 Elf32_Phdr phdr[2];
734 struct chrpnote {
735 u32 namesz;
736 u32 descsz;
737 u32 type;
738 char name[8]; /* "PowerPC" */
739 struct chrpdesc {
740 u32 real_mode;
741 u32 real_base;
742 u32 real_size;
743 u32 virt_base;
744 u32 virt_size;
745 u32 load_base;
746 } chrpdesc;
747 } chrpnote;
748 struct rpanote {
749 u32 namesz;
750 u32 descsz;
751 u32 type;
752 char name[24]; /* "IBM,RPA-Client-Config" */
753 struct rpadesc {
754 u32 lpar_affinity;
755 u32 min_rmo_size;
756 u32 min_rmo_percent;
757 u32 max_pft_size;
758 u32 splpar;
759 u32 min_load;
760 u32 new_mem_def;
761 u32 ignore_me;
762 } rpadesc;
763 } rpanote;
Paul Mackerras5663a122008-10-31 22:27:17 +1100764} fake_elf = {
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000765 .elfhdr = {
766 .e_ident = { 0x7f, 'E', 'L', 'F',
767 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
768 .e_type = ET_EXEC, /* yeah right */
769 .e_machine = EM_PPC,
770 .e_version = EV_CURRENT,
771 .e_phoff = offsetof(struct fake_elf, phdr),
772 .e_phentsize = sizeof(Elf32_Phdr),
773 .e_phnum = 2
774 },
775 .phdr = {
776 [0] = {
777 .p_type = PT_NOTE,
778 .p_offset = offsetof(struct fake_elf, chrpnote),
779 .p_filesz = sizeof(struct chrpnote)
780 }, [1] = {
781 .p_type = PT_NOTE,
782 .p_offset = offsetof(struct fake_elf, rpanote),
783 .p_filesz = sizeof(struct rpanote)
784 }
785 },
786 .chrpnote = {
787 .namesz = sizeof("PowerPC"),
788 .descsz = sizeof(struct chrpdesc),
789 .type = 0x1275,
790 .name = "PowerPC",
791 .chrpdesc = {
792 .real_mode = ~0U, /* ~0 means "don't care" */
793 .real_base = ~0U,
794 .real_size = ~0U,
795 .virt_base = ~0U,
796 .virt_size = ~0U,
797 .load_base = ~0U
798 },
799 },
800 .rpanote = {
801 .namesz = sizeof("IBM,RPA-Client-Config"),
802 .descsz = sizeof(struct rpadesc),
803 .type = 0x12759999,
804 .name = "IBM,RPA-Client-Config",
805 .rpadesc = {
Paul Mackerras5663a122008-10-31 22:27:17 +1100806 .lpar_affinity = 0,
807 .min_rmo_size = 64, /* in megabytes */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000808 .min_rmo_percent = 0,
Paul Mackerras5663a122008-10-31 22:27:17 +1100809 .max_pft_size = 48, /* 2^48 bytes max PFT size */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000810 .splpar = 1,
811 .min_load = ~0U,
Paul Mackerras5663a122008-10-31 22:27:17 +1100812 .new_mem_def = 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000813 }
814 }
815};
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000816#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000817
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100818static int __init prom_count_smt_threads(void)
819{
820 phandle node;
821 char type[64];
822 unsigned int plen;
823
824 /* Pick up th first CPU node we can find */
825 for (node = 0; prom_next_node(&node); ) {
826 type[0] = 0;
827 prom_getprop(node, "device_type", type, sizeof(type));
828
Anton Blanchard5827d412012-11-26 17:40:03 +0000829 if (strcmp(type, "cpu"))
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100830 continue;
831 /*
832 * There is an entry for each smt thread, each entry being
833 * 4 bytes long. All cpus should have the same number of
834 * smt threads, so return after finding the first.
835 */
836 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
837 if (plen == PROM_ERROR)
838 break;
839 plen >>= 2;
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000840 prom_debug("Found %lu smt threads per core\n", (unsigned long)plen);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100841
842 /* Sanity check */
843 if (plen < 1 || plen > 64) {
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000844 prom_printf("Threads per core %lu out of bounds, assuming 1\n",
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100845 (unsigned long)plen);
846 return 1;
847 }
848 return plen;
849 }
850 prom_debug("No threads found, assuming 1 per core\n");
851
852 return 1;
853
854}
855
856
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000857static void __init prom_send_capabilities(void)
858{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000859 ihandle root;
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000860 prom_arg_t ret;
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +0200861 u32 cores;
862 unsigned char *ptcores;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000863
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000864 root = call_prom("open", 1, 1, ADDR("/"));
865 if (root != 0) {
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100866 /* We need to tell the FW about the number of cores we support.
867 *
868 * To do that, we count the number of threads on the first core
869 * (we assume this is the same for all cores) and use it to
870 * divide NR_CPUS.
871 */
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +0200872
873 /* The core value may start at an odd address. If such a word
874 * access is made at a cache line boundary, this leads to an
875 * exception which may not be handled at this time.
876 * Forcing a per byte access to avoid exception.
877 */
878 ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
879 cores = 0;
880 cores |= ptcores[0] << 24;
881 cores |= ptcores[1] << 16;
882 cores |= ptcores[2] << 8;
883 cores |= ptcores[3];
884 if (cores != NR_CPUS) {
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100885 prom_printf("WARNING ! "
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000886 "ibm_architecture_vec structure inconsistent: %lu!\n",
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +0200887 cores);
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100888 } else {
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +0200889 cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
Michael Neuling2c48a7d2010-07-27 18:26:21 +0000890 prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
Laurent Dufourdbd0c5d2013-09-17 11:52:48 +0200891 cores, NR_CPUS);
892 ptcores[0] = (cores >> 24) & 0xff;
893 ptcores[1] = (cores >> 16) & 0xff;
894 ptcores[2] = (cores >> 8) & 0xff;
895 ptcores[3] = cores & 0xff;
Benjamin Herrenschmidtefec9592010-02-04 14:33:54 +1100896 }
897
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000898 /* try calling the ibm,client-architecture-support method */
Anton Blanchard049d0492009-09-21 20:47:39 +0000899 prom_printf("Calling ibm,client-architecture-support...");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000900 if (call_prom_ret("call-method", 3, 2, &ret,
901 ADDR("ibm,client-architecture-support"),
Benjamin Herrenschmidt33b74972006-06-07 12:01:32 +1000902 root,
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000903 ADDR(ibm_architecture_vec)) == 0) {
904 /* the call exists... */
905 if (ret)
Anton Blanchard4da727a2009-03-31 20:06:14 +0000906 prom_printf("\nWARNING: ibm,client-architecture"
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000907 "-support call FAILED!\n");
908 call_prom("close", 1, 0, root);
Anton Blanchard4da727a2009-03-31 20:06:14 +0000909 prom_printf(" done\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000910 return;
911 }
912 call_prom("close", 1, 0, root);
Anton Blanchard049d0492009-09-21 20:47:39 +0000913 prom_printf(" not implemented\n");
Paul Mackerrasf709bfa2006-04-28 16:28:35 +1000914 }
915
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000916#ifdef __BIG_ENDIAN__
917 {
918 ihandle elfloader;
919
920 /* no ibm,client-architecture-support call, try the old way */
921 elfloader = call_prom("open", 1, 1,
922 ADDR("/packages/elf-loader"));
923 if (elfloader == 0) {
924 prom_printf("couldn't open /packages/elf-loader\n");
925 return;
926 }
927 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
928 elfloader, ADDR(&fake_elf));
929 call_prom("close", 1, 0, elfloader);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000930 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000931#endif /* __BIG_ENDIAN__ */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000932}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +1000933#endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000934
935/*
936 * Memory allocation strategy... our layout is normally:
937 *
938 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
939 * rare cases, initrd might end up being before the kernel though.
940 * We assume this won't override the final kernel at 0, we have no
941 * provision to handle that in this version, but it should hopefully
942 * never happen.
943 *
944 * alloc_top is set to the top of RMO, eventually shrink down if the
945 * TCEs overlap
946 *
947 * alloc_bottom is set to the top of kernel/initrd
948 *
949 * from there, allocations are done this way : rtas is allocated
950 * topmost, and the device-tree is allocated from the bottom. We try
951 * to grow the device-tree allocation as we progress. If we can't,
952 * then we fail, we don't currently have a facility to restart
953 * elsewhere, but that shouldn't be necessary.
954 *
955 * Note that calls to reserve_mem have to be done explicitly, memory
956 * allocated with either alloc_up or alloc_down isn't automatically
957 * reserved.
958 */
959
960
961/*
962 * Allocates memory in the RMO upward from the kernel/initrd
963 *
964 * When align is 0, this is a special case, it means to allocate in place
965 * at the current location of alloc_bottom or fail (that is basically
966 * extending the previous allocation). Used for the device-tree flattening
967 */
968static unsigned long __init alloc_up(unsigned long size, unsigned long align)
969{
Anton Blanchard5827d412012-11-26 17:40:03 +0000970 unsigned long base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000971 unsigned long addr = 0;
972
Paul Mackerrasc49888202005-10-26 21:52:53 +1000973 if (align)
974 base = _ALIGN_UP(base, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000975 prom_debug("alloc_up(%x, %x)\n", size, align);
Anton Blanchard5827d412012-11-26 17:40:03 +0000976 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000977 prom_panic("alloc_up() called with mem not initialized\n");
978
979 if (align)
Anton Blanchard5827d412012-11-26 17:40:03 +0000980 base = _ALIGN_UP(alloc_bottom, align);
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000981 else
Anton Blanchard5827d412012-11-26 17:40:03 +0000982 base = alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000983
Anton Blanchard5827d412012-11-26 17:40:03 +0000984 for(; (base + size) <= alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000985 base = _ALIGN_UP(base + 0x100000, align)) {
986 prom_debug(" trying: 0x%x\n\r", base);
987 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +1000988 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000989 break;
990 addr = 0;
991 if (align == 0)
992 break;
993 }
994 if (addr == 0)
995 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +0000996 alloc_bottom = addr + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +1000997
998 prom_debug(" -> %x\n", addr);
Anton Blanchard5827d412012-11-26 17:40:03 +0000999 prom_debug(" alloc_bottom : %x\n", alloc_bottom);
1000 prom_debug(" alloc_top : %x\n", alloc_top);
1001 prom_debug(" alloc_top_hi : %x\n", alloc_top_high);
1002 prom_debug(" rmo_top : %x\n", rmo_top);
1003 prom_debug(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001004
1005 return addr;
1006}
1007
1008/*
1009 * Allocates memory downward, either from top of RMO, or if highmem
1010 * is set, from the top of RAM. Note that this one doesn't handle
1011 * failures. It does claim memory if highmem is not set.
1012 */
1013static unsigned long __init alloc_down(unsigned long size, unsigned long align,
1014 int highmem)
1015{
1016 unsigned long base, addr = 0;
1017
1018 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
Anton Blanchard5827d412012-11-26 17:40:03 +00001019 highmem ? "(high)" : "(low)");
1020 if (ram_top == 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001021 prom_panic("alloc_down() called with mem not initialized\n");
1022
1023 if (highmem) {
1024 /* Carve out storage for the TCE table. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001025 addr = _ALIGN_DOWN(alloc_top_high - size, align);
1026 if (addr <= alloc_bottom)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001027 return 0;
1028 /* Will we bump into the RMO ? If yes, check out that we
1029 * didn't overlap existing allocations there, if we did,
1030 * we are dead, we must be the first in town !
1031 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001032 if (addr < rmo_top) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001033 /* Good, we are first */
Anton Blanchard5827d412012-11-26 17:40:03 +00001034 if (alloc_top == rmo_top)
1035 alloc_top = rmo_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001036 else
1037 return 0;
1038 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001039 alloc_top_high = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001040 goto bail;
1041 }
1042
Anton Blanchard5827d412012-11-26 17:40:03 +00001043 base = _ALIGN_DOWN(alloc_top - size, align);
1044 for (; base > alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001045 base = _ALIGN_DOWN(base - 0x100000, align)) {
1046 prom_debug(" trying: 0x%x\n\r", base);
1047 addr = (unsigned long)prom_claim(base, size, 0);
Paul Mackerrasc49888202005-10-26 21:52:53 +10001048 if (addr != PROM_ERROR && addr != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001049 break;
1050 addr = 0;
1051 }
1052 if (addr == 0)
1053 return 0;
Anton Blanchard5827d412012-11-26 17:40:03 +00001054 alloc_top = addr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001055
1056 bail:
1057 prom_debug(" -> %x\n", addr);
Anton Blanchard5827d412012-11-26 17:40:03 +00001058 prom_debug(" alloc_bottom : %x\n", alloc_bottom);
1059 prom_debug(" alloc_top : %x\n", alloc_top);
1060 prom_debug(" alloc_top_hi : %x\n", alloc_top_high);
1061 prom_debug(" rmo_top : %x\n", rmo_top);
1062 prom_debug(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001063
1064 return addr;
1065}
1066
1067/*
1068 * Parse a "reg" cell
1069 */
1070static unsigned long __init prom_next_cell(int s, cell_t **cellp)
1071{
1072 cell_t *p = *cellp;
1073 unsigned long r = 0;
1074
1075 /* Ignore more than 2 cells */
1076 while (s > sizeof(unsigned long) / 4) {
1077 p++;
1078 s--;
1079 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001080 r = be32_to_cpu(*p++);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001081#ifdef CONFIG_PPC64
Paul Mackerras35499c02005-10-22 16:02:39 +10001082 if (s > 1) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001083 r <<= 32;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001084 r |= be32_to_cpu(*(p++));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001085 }
1086#endif
1087 *cellp = p;
1088 return r;
1089}
1090
1091/*
1092 * Very dumb function for adding to the memory reserve list, but
1093 * we don't need anything smarter at this point
1094 *
1095 * XXX Eventually check for collisions. They should NEVER happen.
1096 * If problems seem to show up, it would be a good start to track
1097 * them down.
1098 */
Michael Ellerman0108d3f2007-05-07 15:58:28 +10001099static void __init reserve_mem(u64 base, u64 size)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001100{
Kumar Galacbbcf342006-01-11 17:57:13 -06001101 u64 top = base + size;
Anton Blanchard5827d412012-11-26 17:40:03 +00001102 unsigned long cnt = mem_reserve_cnt;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001103
1104 if (size == 0)
1105 return;
1106
1107 /* We need to always keep one empty entry so that we
1108 * have our terminator with "size" set to 0 since we are
1109 * dumb and just copy this entire array to the boot params
1110 */
1111 base = _ALIGN_DOWN(base, PAGE_SIZE);
1112 top = _ALIGN_UP(top, PAGE_SIZE);
1113 size = top - base;
1114
1115 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1116 prom_panic("Memory reserve map exhausted !\n");
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001117 mem_reserve_map[cnt].base = cpu_to_be64(base);
1118 mem_reserve_map[cnt].size = cpu_to_be64(size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001119 mem_reserve_cnt = cnt + 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001120}
1121
1122/*
Adrian Bunkb3c2ffd2006-06-30 18:20:44 +02001123 * Initialize memory allocation mechanism, parse "memory" nodes and
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001124 * obtain that way the top of memory and RMO to setup out local allocator
1125 */
1126static void __init prom_init_mem(void)
1127{
1128 phandle node;
1129 char *path, type[64];
1130 unsigned int plen;
1131 cell_t *p, *endp;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001132 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001133 u32 rac, rsc;
1134
1135 /*
1136 * We iterate the memory nodes to find
1137 * 1) top of RMO (first node)
1138 * 2) top of memory
1139 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001140 val = cpu_to_be32(2);
1141 prom_getprop(prom.root, "#address-cells", &val, sizeof(val));
1142 rac = be32_to_cpu(val);
1143 val = cpu_to_be32(1);
1144 prom_getprop(prom.root, "#size-cells", &val, sizeof(rsc));
1145 rsc = be32_to_cpu(val);
1146 prom_debug("root_addr_cells: %x\n", rac);
1147 prom_debug("root_size_cells: %x\n", rsc);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001148
1149 prom_debug("scanning memory:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00001150 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001151
1152 for (node = 0; prom_next_node(&node); ) {
1153 type[0] = 0;
1154 prom_getprop(node, "device_type", type, sizeof(type));
1155
Paul Mackerrasc49888202005-10-26 21:52:53 +10001156 if (type[0] == 0) {
1157 /*
1158 * CHRP Longtrail machines have no device_type
1159 * on the memory node, so check the name instead...
1160 */
1161 prom_getprop(node, "name", type, sizeof(type));
1162 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001163 if (strcmp(type, "memory"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001164 continue;
Paul Mackerrasc49888202005-10-26 21:52:53 +10001165
Anton Blanchard5827d412012-11-26 17:40:03 +00001166 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001167 if (plen > sizeof(regbuf)) {
1168 prom_printf("memory node too large for buffer !\n");
1169 plen = sizeof(regbuf);
1170 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001171 p = regbuf;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001172 endp = p + (plen / sizeof(cell_t));
1173
1174#ifdef DEBUG_PROM
1175 memset(path, 0, PROM_SCRATCH_SIZE);
1176 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1177 prom_debug(" node %s :\n", path);
1178#endif /* DEBUG_PROM */
1179
1180 while ((endp - p) >= (rac + rsc)) {
1181 unsigned long base, size;
1182
1183 base = prom_next_cell(rac, &p);
1184 size = prom_next_cell(rsc, &p);
1185
1186 if (size == 0)
1187 continue;
1188 prom_debug(" %x %x\n", base, size);
Anton Blanchard5827d412012-11-26 17:40:03 +00001189 if (base == 0 && (of_platform & PLATFORM_LPAR))
1190 rmo_top = size;
1191 if ((base + size) > ram_top)
1192 ram_top = base + size;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001193 }
1194 }
1195
Anton Blanchard5827d412012-11-26 17:40:03 +00001196 alloc_bottom = PAGE_ALIGN((unsigned long)&_end + 0x4000);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001197
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001198 /*
Benjamin Krillcf687872009-07-27 22:02:39 +00001199 * If prom_memory_limit is set we reduce the upper limits *except* for
1200 * alloc_top_high. This must be the real top of RAM so we can put
1201 * TCE's up there.
1202 */
1203
Anton Blanchard5827d412012-11-26 17:40:03 +00001204 alloc_top_high = ram_top;
Benjamin Krillcf687872009-07-27 22:02:39 +00001205
Anton Blanchard5827d412012-11-26 17:40:03 +00001206 if (prom_memory_limit) {
1207 if (prom_memory_limit <= alloc_bottom) {
Benjamin Krillcf687872009-07-27 22:02:39 +00001208 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00001209 prom_memory_limit);
1210 prom_memory_limit = 0;
1211 } else if (prom_memory_limit >= ram_top) {
Benjamin Krillcf687872009-07-27 22:02:39 +00001212 prom_printf("Ignoring mem=%x >= ram_top.\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00001213 prom_memory_limit);
1214 prom_memory_limit = 0;
Benjamin Krillcf687872009-07-27 22:02:39 +00001215 } else {
Anton Blanchard5827d412012-11-26 17:40:03 +00001216 ram_top = prom_memory_limit;
1217 rmo_top = min(rmo_top, prom_memory_limit);
Benjamin Krillcf687872009-07-27 22:02:39 +00001218 }
1219 }
1220
1221 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001222 * Setup our top alloc point, that is top of RMO or top of
1223 * segment 0 when running non-LPAR.
1224 * Some RS64 machines have buggy firmware where claims up at
1225 * 1GB fail. Cap at 768MB as a workaround.
1226 * Since 768MB is plenty of room, and we need to cap to something
1227 * reasonable on 32-bit, cap at 768MB on all machines.
1228 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001229 if (!rmo_top)
1230 rmo_top = ram_top;
1231 rmo_top = min(0x30000000ul, rmo_top);
1232 alloc_top = rmo_top;
1233 alloc_top_high = ram_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001234
Paul Mackerras64968f62011-12-13 17:54:13 +00001235 /*
1236 * Check if we have an initrd after the kernel but still inside
1237 * the RMO. If we do move our bottom point to after it.
1238 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001239 if (prom_initrd_start &&
1240 prom_initrd_start < rmo_top &&
1241 prom_initrd_end > alloc_bottom)
1242 alloc_bottom = PAGE_ALIGN(prom_initrd_end);
Paul Mackerras64968f62011-12-13 17:54:13 +00001243
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001244 prom_printf("memory layout at init:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00001245 prom_printf(" memory_limit : %x (16 MB aligned)\n", prom_memory_limit);
1246 prom_printf(" alloc_bottom : %x\n", alloc_bottom);
1247 prom_printf(" alloc_top : %x\n", alloc_top);
1248 prom_printf(" alloc_top_hi : %x\n", alloc_top_high);
1249 prom_printf(" rmo_top : %x\n", rmo_top);
1250 prom_printf(" ram_top : %x\n", ram_top);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001251}
1252
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001253static void __init prom_close_stdin(void)
1254{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001255 __be32 val;
1256 ihandle stdin;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001257
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001258 if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) {
1259 stdin = be32_to_cpu(val);
1260 call_prom("close", 1, 0, stdin);
1261 }
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001262}
1263
1264#ifdef CONFIG_PPC_POWERNV
1265
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001266#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1267static u64 __initdata prom_opal_base;
1268static u64 __initdata prom_opal_entry;
1269#endif
1270
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001271#ifdef __BIG_ENDIAN__
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001272/* XXX Don't change this structure without updating opal-takeover.S */
1273static struct opal_secondary_data {
1274 s64 ack; /* 0 */
1275 u64 go; /* 8 */
1276 struct opal_takeover_args args; /* 16 */
1277} opal_secondary_data;
1278
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001279static u64 __initdata prom_opal_align;
1280static u64 __initdata prom_opal_size;
1281static int __initdata prom_rtas_start_cpu;
1282static u64 __initdata prom_rtas_data;
1283static u64 __initdata prom_rtas_entry;
1284
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001285extern char opal_secondary_entry;
1286
Li Zhong2cb387a2012-06-07 17:44:23 +00001287static void __init prom_query_opal(void)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001288{
1289 long rc;
1290
Benjamin Herrenschmidt76800572011-09-28 20:51:46 +00001291 /* We must not query for OPAL presence on a machine that
1292 * supports TNK takeover (970 blades), as this uses the same
1293 * h-call with different arguments and will crash
1294 */
1295 if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
1296 ADDR("/tnk-memory-map")))) {
1297 prom_printf("TNK takeover detected, skipping OPAL check\n");
1298 return;
1299 }
1300
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001301 prom_printf("Querying for OPAL presence... ");
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001302
Anton Blanchard5827d412012-11-26 17:40:03 +00001303 rc = opal_query_takeover(&prom_opal_size,
1304 &prom_opal_align);
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001305 prom_debug("(rc = %ld) ", rc);
1306 if (rc != 0) {
1307 prom_printf("not there.\n");
1308 return;
1309 }
Anton Blanchard5827d412012-11-26 17:40:03 +00001310 of_platform = PLATFORM_OPAL;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001311 prom_printf(" there !\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00001312 prom_debug(" opal_size = 0x%lx\n", prom_opal_size);
1313 prom_debug(" opal_align = 0x%lx\n", prom_opal_align);
1314 if (prom_opal_align < 0x10000)
1315 prom_opal_align = 0x10000;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001316}
1317
Vladimir Murzin620e5052013-09-10 18:42:07 +02001318static int __init prom_rtas_call(int token, int nargs, int nret,
1319 int *outputs, ...)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001320{
1321 struct rtas_args rtas_args;
1322 va_list list;
1323 int i;
1324
1325 rtas_args.token = token;
1326 rtas_args.nargs = nargs;
1327 rtas_args.nret = nret;
1328 rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]);
1329 va_start(list, outputs);
1330 for (i = 0; i < nargs; ++i)
1331 rtas_args.args[i] = va_arg(list, rtas_arg_t);
1332 va_end(list);
1333
1334 for (i = 0; i < nret; ++i)
1335 rtas_args.rets[i] = 0;
1336
Anton Blanchard5827d412012-11-26 17:40:03 +00001337 opal_enter_rtas(&rtas_args, prom_rtas_data,
1338 prom_rtas_entry);
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001339
1340 if (nret > 1 && outputs != NULL)
1341 for (i = 0; i < nret-1; ++i)
1342 outputs[i] = rtas_args.rets[i+1];
1343 return (nret > 0)? rtas_args.rets[0]: 0;
1344}
1345
1346static void __init prom_opal_hold_cpus(void)
1347{
1348 int i, cnt, cpu, rc;
1349 long j;
1350 phandle node;
1351 char type[64];
1352 u32 servers[8];
Anton Blanchard5827d412012-11-26 17:40:03 +00001353 void *entry = (unsigned long *)&opal_secondary_entry;
1354 struct opal_secondary_data *data = &opal_secondary_data;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001355
1356 prom_debug("prom_opal_hold_cpus: start...\n");
1357 prom_debug(" - entry = 0x%x\n", entry);
1358 prom_debug(" - data = 0x%x\n", data);
1359
1360 data->ack = -1;
1361 data->go = 0;
1362
1363 /* look for cpus */
1364 for (node = 0; prom_next_node(&node); ) {
1365 type[0] = 0;
1366 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00001367 if (strcmp(type, "cpu") != 0)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001368 continue;
1369
1370 /* Skip non-configured cpus. */
1371 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
Anton Blanchard5827d412012-11-26 17:40:03 +00001372 if (strcmp(type, "okay") != 0)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001373 continue;
1374
1375 cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
1376 sizeof(servers));
1377 if (cnt == PROM_ERROR)
1378 break;
1379 cnt >>= 2;
1380 for (i = 0; i < cnt; i++) {
1381 cpu = servers[i];
1382 prom_debug("CPU %d ... ", cpu);
Anton Blanchard5827d412012-11-26 17:40:03 +00001383 if (cpu == prom.cpu) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001384 prom_debug("booted !\n");
1385 continue;
1386 }
1387 prom_debug("starting ... ");
1388
1389 /* Init the acknowledge var which will be reset by
1390 * the secondary cpu when it awakens from its OF
1391 * spinloop.
1392 */
1393 data->ack = -1;
Anton Blanchard5827d412012-11-26 17:40:03 +00001394 rc = prom_rtas_call(prom_rtas_start_cpu, 3, 1,
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001395 NULL, cpu, entry, data);
1396 prom_debug("rtas rc=%d ...", rc);
1397
1398 for (j = 0; j < 100000000 && data->ack == -1; j++) {
1399 HMT_low();
1400 mb();
1401 }
1402 HMT_medium();
1403 if (data->ack != -1)
1404 prom_debug("done, PIR=0x%x\n", data->ack);
1405 else
1406 prom_debug("timeout !\n");
1407 }
1408 }
1409 prom_debug("prom_opal_hold_cpus: end...\n");
1410}
1411
Li Zhong2cb387a2012-06-07 17:44:23 +00001412static void __init prom_opal_takeover(void)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001413{
Anton Blanchard5827d412012-11-26 17:40:03 +00001414 struct opal_secondary_data *data = &opal_secondary_data;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001415 struct opal_takeover_args *args = &data->args;
Anton Blanchard5827d412012-11-26 17:40:03 +00001416 u64 align = prom_opal_align;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001417 u64 top_addr, opal_addr;
1418
Anton Blanchard5827d412012-11-26 17:40:03 +00001419 args->k_image = (u64)_stext;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001420 args->k_size = _end - _stext;
1421 args->k_entry = 0;
1422 args->k_entry2 = 0x60;
1423
1424 top_addr = _ALIGN_UP(args->k_size, align);
1425
Anton Blanchard5827d412012-11-26 17:40:03 +00001426 if (prom_initrd_start != 0) {
1427 args->rd_image = prom_initrd_start;
1428 args->rd_size = prom_initrd_end - args->rd_image;
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001429 args->rd_loc = top_addr;
1430 top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
1431 }
1432
1433 /* Pickup an address for the HAL. We want to go really high
1434 * up to avoid problem with future kexecs. On the other hand
1435 * we don't want to be all over the TCEs on P5IOC2 machines
1436 * which are going to be up there too. We assume the machine
1437 * has plenty of memory, and we ask for the HAL for now to
1438 * be just below the 1G point, or above the initrd
1439 */
Anton Blanchard5827d412012-11-26 17:40:03 +00001440 opal_addr = _ALIGN_DOWN(0x40000000 - prom_opal_size, align);
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001441 if (opal_addr < top_addr)
1442 opal_addr = top_addr;
1443 args->hal_addr = opal_addr;
1444
Benjamin Herrenschmidt817c21a2011-09-19 17:44:56 +00001445 /* Copy the command line to the kernel image */
Anton Blanchard5827d412012-11-26 17:40:03 +00001446 strlcpy(boot_command_line, prom_cmd_line,
Benjamin Herrenschmidt817c21a2011-09-19 17:44:56 +00001447 COMMAND_LINE_SIZE);
1448
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001449 prom_debug(" k_image = 0x%lx\n", args->k_image);
1450 prom_debug(" k_size = 0x%lx\n", args->k_size);
1451 prom_debug(" k_entry = 0x%lx\n", args->k_entry);
1452 prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2);
1453 prom_debug(" hal_addr = 0x%lx\n", args->hal_addr);
1454 prom_debug(" rd_image = 0x%lx\n", args->rd_image);
1455 prom_debug(" rd_size = 0x%lx\n", args->rd_size);
1456 prom_debug(" rd_loc = 0x%lx\n", args->rd_loc);
1457 prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
1458 prom_close_stdin();
1459 mb();
1460 data->go = 1;
1461 for (;;)
1462 opal_do_takeover(args);
1463}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001464#endif /* __BIG_ENDIAN__ */
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001465
1466/*
1467 * Allocate room for and instantiate OPAL
1468 */
1469static void __init prom_instantiate_opal(void)
1470{
1471 phandle opal_node;
1472 ihandle opal_inst;
1473 u64 base, entry;
1474 u64 size = 0, align = 0x10000;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001475 __be64 val64;
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001476 u32 rets[2];
1477
1478 prom_debug("prom_instantiate_opal: start...\n");
1479
1480 opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
1481 prom_debug("opal_node: %x\n", opal_node);
1482 if (!PHANDLE_VALID(opal_node))
1483 return;
1484
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001485 val64 = 0;
1486 prom_getprop(opal_node, "opal-runtime-size", &val64, sizeof(val64));
1487 size = be64_to_cpu(val64);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001488 if (size == 0)
1489 return;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001490 val64 = 0;
1491 prom_getprop(opal_node, "opal-runtime-alignment", &val64,sizeof(val64));
1492 align = be64_to_cpu(val64);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001493
1494 base = alloc_down(size, align, 0);
1495 if (base == 0) {
1496 prom_printf("OPAL allocation failed !\n");
1497 return;
1498 }
1499
1500 opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
1501 if (!IHANDLE_VALID(opal_inst)) {
1502 prom_printf("opening opal package failed (%x)\n", opal_inst);
1503 return;
1504 }
1505
1506 prom_printf("instantiating opal at 0x%x...", base);
1507
1508 if (call_prom_ret("call-method", 4, 3, rets,
1509 ADDR("load-opal-runtime"),
1510 opal_inst,
1511 base >> 32, base & 0xffffffff) != 0
1512 || (rets[0] == 0 && rets[1] == 0)) {
1513 prom_printf(" failed\n");
1514 return;
1515 }
1516 entry = (((u64)rets[0]) << 32) | rets[1];
1517
1518 prom_printf(" done\n");
1519
1520 reserve_mem(base, size);
1521
1522 prom_debug("opal base = 0x%x\n", base);
1523 prom_debug("opal align = 0x%x\n", align);
1524 prom_debug("opal entry = 0x%x\n", entry);
1525 prom_debug("opal size = 0x%x\n", (long)size);
1526
1527 prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
1528 &base, sizeof(base));
1529 prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
1530 &entry, sizeof(entry));
1531
1532#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
Anton Blanchard5827d412012-11-26 17:40:03 +00001533 prom_opal_base = base;
1534 prom_opal_entry = entry;
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00001535#endif
1536 prom_debug("prom_instantiate_opal: end...\n");
1537}
1538
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001539#endif /* CONFIG_PPC_POWERNV */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001540
1541/*
1542 * Allocate room for and instantiate RTAS
1543 */
1544static void __init prom_instantiate_rtas(void)
1545{
1546 phandle rtas_node;
1547 ihandle rtas_inst;
1548 u32 base, entry = 0;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001549 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001550 u32 size = 0;
1551
1552 prom_debug("prom_instantiate_rtas: start...\n");
1553
1554 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1555 prom_debug("rtas_node: %x\n", rtas_node);
1556 if (!PHANDLE_VALID(rtas_node))
1557 return;
1558
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001559 val = 0;
1560 prom_getprop(rtas_node, "rtas-size", &val, sizeof(size));
1561 size = be32_to_cpu(val);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001562 if (size == 0)
1563 return;
1564
1565 base = alloc_down(size, PAGE_SIZE, 0);
Anton Blanchard6d1e2c62011-11-14 12:55:47 +00001566 if (base == 0)
1567 prom_panic("Could not allocate memory for RTAS\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001568
1569 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1570 if (!IHANDLE_VALID(rtas_inst)) {
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001571 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001572 return;
1573 }
1574
Anton Blanchard1f8737a2009-03-31 20:06:15 +00001575 prom_printf("instantiating rtas at 0x%x...", base);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001576
1577 if (call_prom_ret("call-method", 3, 2, &entry,
1578 ADDR("instantiate-rtas"),
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001579 rtas_inst, base) != 0
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001580 || entry == 0) {
1581 prom_printf(" failed\n");
1582 return;
1583 }
1584 prom_printf(" done\n");
1585
1586 reserve_mem(base, size);
1587
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001588 val = cpu_to_be32(base);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001589 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001590 &val, sizeof(val));
1591 val = cpu_to_be32(entry);
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001592 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001593 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001594
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10001595 /* Check if it supports "query-cpu-stopped-state" */
1596 if (prom_getprop(rtas_node, "query-cpu-stopped-state",
1597 &val, sizeof(val)) != PROM_ERROR)
1598 rtas_has_query_cpu_stopped = true;
1599
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001600#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001601 /* PowerVN takeover hack */
Anton Blanchard5827d412012-11-26 17:40:03 +00001602 prom_rtas_data = base;
1603 prom_rtas_entry = entry;
1604 prom_getprop(rtas_node, "start-cpu", &prom_rtas_start_cpu, 4);
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001605#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001606 prom_debug("rtas base = 0x%x\n", base);
1607 prom_debug("rtas entry = 0x%x\n", entry);
1608 prom_debug("rtas size = 0x%x\n", (long)size);
1609
1610 prom_debug("prom_instantiate_rtas: end...\n");
1611}
1612
1613#ifdef CONFIG_PPC64
1614/*
Ashley Lai4a727422012-08-14 18:34:57 -05001615 * Allocate room for and instantiate Stored Measurement Log (SML)
1616 */
1617static void __init prom_instantiate_sml(void)
1618{
1619 phandle ibmvtpm_node;
1620 ihandle ibmvtpm_inst;
1621 u32 entry = 0, size = 0;
1622 u64 base;
1623
1624 prom_debug("prom_instantiate_sml: start...\n");
1625
1626 ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/ibm,vtpm"));
1627 prom_debug("ibmvtpm_node: %x\n", ibmvtpm_node);
1628 if (!PHANDLE_VALID(ibmvtpm_node))
1629 return;
1630
1631 ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/ibm,vtpm"));
1632 if (!IHANDLE_VALID(ibmvtpm_inst)) {
1633 prom_printf("opening vtpm package failed (%x)\n", ibmvtpm_inst);
1634 return;
1635 }
1636
1637 if (call_prom_ret("call-method", 2, 2, &size,
1638 ADDR("sml-get-handover-size"),
1639 ibmvtpm_inst) != 0 || size == 0) {
1640 prom_printf("SML get handover size failed\n");
1641 return;
1642 }
1643
1644 base = alloc_down(size, PAGE_SIZE, 0);
1645 if (base == 0)
1646 prom_panic("Could not allocate memory for sml\n");
1647
1648 prom_printf("instantiating sml at 0x%x...", base);
1649
1650 if (call_prom_ret("call-method", 4, 2, &entry,
1651 ADDR("sml-handover"),
1652 ibmvtpm_inst, size, base) != 0 || entry == 0) {
1653 prom_printf("SML handover failed\n");
1654 return;
1655 }
1656 prom_printf(" done\n");
1657
1658 reserve_mem(base, size);
1659
1660 prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-base",
1661 &base, sizeof(base));
1662 prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-size",
1663 &size, sizeof(size));
1664
1665 prom_debug("sml base = 0x%x\n", base);
1666 prom_debug("sml size = 0x%x\n", (long)size);
1667
1668 prom_debug("prom_instantiate_sml: end...\n");
1669}
1670
1671/*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001672 * Allocate room for and initialize TCE tables
1673 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001674#ifdef __BIG_ENDIAN__
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001675static void __init prom_initialize_tce_table(void)
1676{
1677 phandle node;
1678 ihandle phb_node;
1679 char compatible[64], type[64], model[64];
Anton Blanchard5827d412012-11-26 17:40:03 +00001680 char *path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001681 u64 base, align;
1682 u32 minalign, minsize;
1683 u64 tce_entry, *tce_entryp;
1684 u64 local_alloc_top, local_alloc_bottom;
1685 u64 i;
1686
Anton Blanchard5827d412012-11-26 17:40:03 +00001687 if (prom_iommu_off)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001688 return;
1689
1690 prom_debug("starting prom_initialize_tce_table\n");
1691
1692 /* Cache current top of allocs so we reserve a single block */
Anton Blanchard5827d412012-11-26 17:40:03 +00001693 local_alloc_top = alloc_top_high;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001694 local_alloc_bottom = local_alloc_top;
1695
1696 /* Search all nodes looking for PHBs. */
1697 for (node = 0; prom_next_node(&node); ) {
1698 compatible[0] = 0;
1699 type[0] = 0;
1700 model[0] = 0;
1701 prom_getprop(node, "compatible",
1702 compatible, sizeof(compatible));
1703 prom_getprop(node, "device_type", type, sizeof(type));
1704 prom_getprop(node, "model", model, sizeof(model));
1705
Anton Blanchard5827d412012-11-26 17:40:03 +00001706 if ((type[0] == 0) || (strstr(type, "pci") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001707 continue;
1708
Linas Vepstase788ff12007-09-07 03:45:21 +10001709 /* Keep the old logic intact to avoid regression. */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001710 if (compatible[0] != 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +00001711 if ((strstr(compatible, "python") == NULL) &&
1712 (strstr(compatible, "Speedwagon") == NULL) &&
1713 (strstr(compatible, "Winnipeg") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001714 continue;
1715 } else if (model[0] != 0) {
Anton Blanchard5827d412012-11-26 17:40:03 +00001716 if ((strstr(model, "ython") == NULL) &&
1717 (strstr(model, "peedwagon") == NULL) &&
1718 (strstr(model, "innipeg") == NULL))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001719 continue;
1720 }
1721
1722 if (prom_getprop(node, "tce-table-minalign", &minalign,
1723 sizeof(minalign)) == PROM_ERROR)
1724 minalign = 0;
1725 if (prom_getprop(node, "tce-table-minsize", &minsize,
1726 sizeof(minsize)) == PROM_ERROR)
1727 minsize = 4UL << 20;
1728
1729 /*
1730 * Even though we read what OF wants, we just set the table
1731 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1732 * By doing this, we avoid the pitfalls of trying to DMA to
1733 * MMIO space and the DMA alias hole.
1734 *
1735 * On POWER4, firmware sets the TCE region by assuming
1736 * each TCE table is 8MB. Using this memory for anything
1737 * else will impact performance, so we always allocate 8MB.
1738 * Anton
1739 */
Michael Ellermand3dbeef2012-08-19 21:44:01 +00001740 if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001741 minsize = 8UL << 20;
1742 else
1743 minsize = 4UL << 20;
1744
1745 /* Align to the greater of the align or size */
1746 align = max(minalign, minsize);
1747 base = alloc_down(minsize, align, 1);
1748 if (base == 0)
1749 prom_panic("ERROR, cannot find space for TCE table.\n");
1750 if (base < local_alloc_bottom)
1751 local_alloc_bottom = base;
1752
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001753 /* It seems OF doesn't null-terminate the path :-( */
Li Zefanaca71ef2007-11-05 13:21:56 +11001754 memset(path, 0, PROM_SCRATCH_SIZE);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001755 /* Call OF to setup the TCE hardware */
1756 if (call_prom("package-to-path", 3, 1, node,
1757 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1758 prom_printf("package-to-path failed\n");
1759 }
1760
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001761 /* Save away the TCE table attributes for later use. */
1762 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1763 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1764
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001765 prom_debug("TCE table: %s\n", path);
1766 prom_debug("\tnode = 0x%x\n", node);
1767 prom_debug("\tbase = 0x%x\n", base);
1768 prom_debug("\tsize = 0x%x\n", minsize);
1769
1770 /* Initialize the table to have a one-to-one mapping
1771 * over the allocated size.
1772 */
Ingo Molnar2b931fb2009-01-06 13:56:52 +00001773 tce_entryp = (u64 *)base;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001774 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1775 tce_entry = (i << PAGE_SHIFT);
1776 tce_entry |= 0x3;
1777 *tce_entryp = tce_entry;
1778 }
1779
1780 prom_printf("opening PHB %s", path);
1781 phb_node = call_prom("open", 1, 1, path);
1782 if (phb_node == 0)
1783 prom_printf("... failed\n");
1784 else
1785 prom_printf("... done\n");
1786
1787 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1788 phb_node, -1, minsize,
1789 (u32) base, (u32) (base >> 32));
1790 call_prom("close", 1, 0, phb_node);
1791 }
1792
1793 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1794
Michael Ellerman2babf5c2006-05-17 18:00:46 +10001795 /* These are only really needed if there is a memory limit in
1796 * effect, but we don't know so export them always. */
Anton Blanchard5827d412012-11-26 17:40:03 +00001797 prom_tce_alloc_start = local_alloc_bottom;
1798 prom_tce_alloc_end = local_alloc_top;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001799
1800 /* Flag the first invalid entry */
1801 prom_debug("ending prom_initialize_tce_table\n");
1802}
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001803#endif /* __BIG_ENDIAN__ */
1804#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001805
1806/*
1807 * With CHRP SMP we need to use the OF to start the other processors.
1808 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1809 * so we have to put the processors into a holding pattern controlled
1810 * by the kernel (not OF) before we destroy the OF.
1811 *
1812 * This uses a chunk of low memory, puts some holding pattern
1813 * code there and sends the other processors off to there until
1814 * smp_boot_cpus tells them to do something. The holding pattern
1815 * checks that address until its cpu # is there, when it is that
1816 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1817 * of setting those values.
1818 *
1819 * We also use physical address 0x4 here to tell when a cpu
1820 * is in its holding pattern code.
1821 *
1822 * -- Cort
1823 */
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001824/*
1825 * We want to reference the copy of __secondary_hold_* in the
1826 * 0 - 0x100 address range
1827 */
1828#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1829
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001830static void __init prom_hold_cpus(void)
1831{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001832 unsigned long i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001833 phandle node;
1834 char type[64];
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001835 unsigned long *spinloop
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001836 = (void *) LOW_ADDR(__secondary_hold_spinloop);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001837 unsigned long *acknowledge
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001838 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001839 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001840
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10001841 /*
1842 * On pseries, if RTAS supports "query-cpu-stopped-state",
1843 * we skip this stage, the CPUs will be started by the
1844 * kernel using RTAS.
1845 */
1846 if ((of_platform == PLATFORM_PSERIES ||
1847 of_platform == PLATFORM_PSERIES_LPAR) &&
1848 rtas_has_query_cpu_stopped) {
1849 prom_printf("prom_hold_cpus: skipped\n");
1850 return;
1851 }
1852
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001853 prom_debug("prom_hold_cpus: start...\n");
1854 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1855 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1856 prom_debug(" 1) acknowledge = 0x%x\n",
1857 (unsigned long)acknowledge);
1858 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1859 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1860
1861 /* Set the common spinloop variable, so all of the secondary cpus
1862 * will block when they are awakened from their OF spinloop.
1863 * This must occur for both SMP and non SMP kernels, since OF will
1864 * be trashed when we move the kernel.
1865 */
1866 *spinloop = 0;
1867
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001868 /* look for cpus */
1869 for (node = 0; prom_next_node(&node); ) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001870 unsigned int cpu_no;
1871 __be32 reg;
1872
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001873 type[0] = 0;
1874 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00001875 if (strcmp(type, "cpu") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001876 continue;
1877
1878 /* Skip non-configured cpus. */
1879 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
Anton Blanchard5827d412012-11-26 17:40:03 +00001880 if (strcmp(type, "okay") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001881 continue;
1882
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001883 reg = cpu_to_be32(-1); /* make sparse happy */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001884 prom_getprop(node, "reg", &reg, sizeof(reg));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001885 cpu_no = be32_to_cpu(reg);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001886
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001887 prom_debug("cpu hw idx = %lu\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001888
1889 /* Init the acknowledge var which will be reset by
1890 * the secondary cpu when it awakens from its OF
1891 * spinloop.
1892 */
1893 *acknowledge = (unsigned long)-1;
1894
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001895 if (cpu_no != prom.cpu) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00001896 /* Primary Thread of non-boot cpu or any thread */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001897 prom_printf("starting cpu hw idx %lu... ", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001898 call_prom("start-cpu", 3, 0, node,
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001899 secondary_hold, cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001900
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001901 for (i = 0; (i < 100000000) &&
1902 (*acknowledge == ((unsigned long)-1)); i++ )
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001903 mb();
1904
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001905 if (*acknowledge == cpu_no)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001906 prom_printf("done\n");
Paul Mackerrasbbd0abd2005-10-26 21:45:56 +10001907 else
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001908 prom_printf("failed: %x\n", *acknowledge);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001909 }
1910#ifdef CONFIG_SMP
1911 else
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001912 prom_printf("boot cpu hw idx %lu\n", cpu_no);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001913#endif /* CONFIG_SMP */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001914 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001915
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001916 prom_debug("prom_hold_cpus: end...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001917}
1918
1919
1920static void __init prom_init_client_services(unsigned long pp)
1921{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001922 /* Get a handle to the prom entry point before anything else */
Anton Blanchard5827d412012-11-26 17:40:03 +00001923 prom_entry = pp;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001924
1925 /* get a handle for the stdout device */
Anton Blanchard5827d412012-11-26 17:40:03 +00001926 prom.chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1927 if (!PHANDLE_VALID(prom.chosen))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001928 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1929
1930 /* get device tree root */
Anton Blanchard5827d412012-11-26 17:40:03 +00001931 prom.root = call_prom("finddevice", 1, 1, ADDR("/"));
1932 if (!PHANDLE_VALID(prom.root))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001933 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001934
Anton Blanchard5827d412012-11-26 17:40:03 +00001935 prom.mmumap = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001936}
1937
Paul Mackerrasa575b802005-10-23 17:23:21 +10001938#ifdef CONFIG_PPC32
1939/*
1940 * For really old powermacs, we need to map things we claim.
1941 * For that, we need the ihandle of the mmu.
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001942 * Also, on the longtrail, we need to work around other bugs.
Paul Mackerrasa575b802005-10-23 17:23:21 +10001943 */
1944static void __init prom_find_mmu(void)
1945{
Paul Mackerrasa575b802005-10-23 17:23:21 +10001946 phandle oprom;
1947 char version[64];
1948
1949 oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1950 if (!PHANDLE_VALID(oprom))
1951 return;
1952 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1953 return;
1954 version[sizeof(version) - 1] = 0;
Paul Mackerrasa575b802005-10-23 17:23:21 +10001955 /* XXX might need to add other versions here */
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001956 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1957 of_workarounds = OF_WA_CLAIM;
1958 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1959 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1960 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1961 } else
Paul Mackerrasa575b802005-10-23 17:23:21 +10001962 return;
Anton Blanchard5827d412012-11-26 17:40:03 +00001963 prom.memory = call_prom("open", 1, 1, ADDR("/memory"));
1964 prom_getprop(prom.chosen, "mmu", &prom.mmumap,
1965 sizeof(prom.mmumap));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001966 prom.mmumap = be32_to_cpu(prom.mmumap);
Anton Blanchard5827d412012-11-26 17:40:03 +00001967 if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap))
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001968 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
Paul Mackerrasa575b802005-10-23 17:23:21 +10001969}
1970#else
1971#define prom_find_mmu()
1972#endif
1973
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001974static void __init prom_init_stdout(void)
1975{
Anton Blanchard5827d412012-11-26 17:40:03 +00001976 char *path = of_stdout_device;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001977 char type[16];
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001978 phandle stdout_node;
1979 __be32 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001980
Anton Blanchard5827d412012-11-26 17:40:03 +00001981 if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001982 prom_panic("cannot find stdout");
1983
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10001984 prom.stdout = be32_to_cpu(val);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001985
1986 /* Get the full OF pathname of the stdout device */
1987 memset(path, 0, 256);
Anton Blanchard5827d412012-11-26 17:40:03 +00001988 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
Anton Blanchard5827d412012-11-26 17:40:03 +00001989 prom_printf("OF stdout device is: %s\n", of_stdout_device);
1990 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11001991 path, strlen(path) + 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10001992
Benjamin Herrenschmidt10348f52014-01-13 09:49:17 +11001993 /* instance-to-package fails on PA-Semi */
1994 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
1995 if (stdout_node != PROM_ERROR) {
1996 val = cpu_to_be32(stdout_node);
1997 prom_setprop(prom.chosen, "/chosen", "linux,stdout-package",
1998 &val, sizeof(val));
1999
2000 /* If it's a display, note it */
2001 memset(type, 0, sizeof(type));
2002 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2003 if (strcmp(type, "display") == 0)
2004 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
2005 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002006}
2007
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002008static int __init prom_find_machine_type(void)
2009{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002010 char compat[256];
2011 int len, i = 0;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002012#ifdef CONFIG_PPC64
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002013 phandle rtas;
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002014 int x;
Benjamin Herrenschmidt21fe3302005-11-07 16:41:59 +11002015#endif
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002016
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002017 /* Look for a PowerMac or a Cell */
Anton Blanchard5827d412012-11-26 17:40:03 +00002018 len = prom_getprop(prom.root, "compatible",
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002019 compat, sizeof(compat)-1);
2020 if (len > 0) {
2021 compat[len] = 0;
2022 while (i < len) {
2023 char *p = &compat[i];
2024 int sl = strlen(p);
2025 if (sl == 0)
2026 break;
Anton Blanchard5827d412012-11-26 17:40:03 +00002027 if (strstr(p, "Power Macintosh") ||
2028 strstr(p, "MacRISC"))
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002029 return PLATFORM_POWERMAC;
Arnd Bergmann133dda12006-06-07 12:04:18 +10002030#ifdef CONFIG_PPC64
2031 /* We must make sure we don't detect the IBM Cell
2032 * blades as pSeries due to some firmware issues,
2033 * so we do it here.
2034 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002035 if (strstr(p, "IBM,CBEA") ||
2036 strstr(p, "IBM,CPBW-1.0"))
Arnd Bergmann133dda12006-06-07 12:04:18 +10002037 return PLATFORM_GENERIC;
2038#endif /* CONFIG_PPC64 */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002039 i += sl + 1;
2040 }
2041 }
2042#ifdef CONFIG_PPC64
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002043 /* Try to detect OPAL */
2044 if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
2045 return PLATFORM_OPAL;
2046
2047 /* Try to figure out if it's an IBM pSeries or any other
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002048 * PAPR compliant platform. We assume it is if :
2049 * - /device_type is "chrp" (please, do NOT use that for future
2050 * non-IBM designs !
2051 * - it has /rtas
2052 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002053 len = prom_getprop(prom.root, "device_type",
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002054 compat, sizeof(compat)-1);
2055 if (len <= 0)
2056 return PLATFORM_GENERIC;
Anton Blanchard5827d412012-11-26 17:40:03 +00002057 if (strcmp(compat, "chrp"))
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002058 return PLATFORM_GENERIC;
2059
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002060 /* Default to pSeries. We need to know if we are running LPAR */
2061 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002062 if (!PHANDLE_VALID(rtas))
2063 return PLATFORM_GENERIC;
2064 x = prom_getproplen(rtas, "ibm,hypertas-functions");
2065 if (x != PROM_ERROR) {
Anton Blanchard4da727a2009-03-31 20:06:14 +00002066 prom_debug("Hypertas detected, assuming LPAR !\n");
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002067 return PLATFORM_PSERIES_LPAR;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002068 }
2069 return PLATFORM_PSERIES;
2070#else
Benjamin Herrenschmidte8222502006-03-28 23:15:54 +11002071 return PLATFORM_GENERIC;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002072#endif
2073}
2074
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002075static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
2076{
2077 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
2078}
2079
2080/*
2081 * If we have a display that we don't know how to drive,
2082 * we will want to try to execute OF's open method for it
2083 * later. However, OF will probably fall over if we do that
2084 * we've taken over the MMU.
2085 * So we check whether we will need to open the display,
2086 * and if so, open it now.
2087 */
2088static void __init prom_check_displays(void)
2089{
2090 char type[16], *path;
2091 phandle node;
2092 ihandle ih;
2093 int i;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002094
2095 static unsigned char default_colors[] = {
2096 0x00, 0x00, 0x00,
2097 0x00, 0x00, 0xaa,
2098 0x00, 0xaa, 0x00,
2099 0x00, 0xaa, 0xaa,
2100 0xaa, 0x00, 0x00,
2101 0xaa, 0x00, 0xaa,
2102 0xaa, 0xaa, 0x00,
2103 0xaa, 0xaa, 0xaa,
2104 0x55, 0x55, 0x55,
2105 0x55, 0x55, 0xff,
2106 0x55, 0xff, 0x55,
2107 0x55, 0xff, 0xff,
2108 0xff, 0x55, 0x55,
2109 0xff, 0x55, 0xff,
2110 0xff, 0xff, 0x55,
2111 0xff, 0xff, 0xff
2112 };
2113 const unsigned char *clut;
2114
Anton Blanchard4da727a2009-03-31 20:06:14 +00002115 prom_debug("Looking for displays\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002116 for (node = 0; prom_next_node(&node); ) {
2117 memset(type, 0, sizeof(type));
2118 prom_getprop(node, "device_type", type, sizeof(type));
Anton Blanchard5827d412012-11-26 17:40:03 +00002119 if (strcmp(type, "display") != 0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002120 continue;
2121
2122 /* It seems OF doesn't null-terminate the path :-( */
Anton Blanchard5827d412012-11-26 17:40:03 +00002123 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002124 memset(path, 0, PROM_SCRATCH_SIZE);
2125
2126 /*
2127 * leave some room at the end of the path for appending extra
2128 * arguments
2129 */
2130 if (call_prom("package-to-path", 3, 1, node, path,
2131 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2132 continue;
Anton Blanchard1f8737a2009-03-31 20:06:15 +00002133 prom_printf("found display : %s, opening... ", path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002134
2135 ih = call_prom("open", 1, 1, path);
2136 if (ih == 0) {
2137 prom_printf("failed\n");
2138 continue;
2139 }
2140
2141 /* Success */
2142 prom_printf("done\n");
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002143 prom_setprop(node, path, "linux,opened", NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002144
2145 /* Setup a usable color table when the appropriate
2146 * method is available. Should update this to set-colors */
Anton Blanchard5827d412012-11-26 17:40:03 +00002147 clut = default_colors;
Benjamin Herrenschmidt3f536382011-12-14 13:55:11 +00002148 for (i = 0; i < 16; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002149 if (prom_set_color(ih, i, clut[0], clut[1],
2150 clut[2]) != 0)
2151 break;
2152
2153#ifdef CONFIG_LOGO_LINUX_CLUT224
Anton Blanchard5827d412012-11-26 17:40:03 +00002154 clut = PTRRELOC(logo_linux_clut224.clut);
2155 for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002156 if (prom_set_color(ih, i + 32, clut[0], clut[1],
2157 clut[2]) != 0)
2158 break;
2159#endif /* CONFIG_LOGO_LINUX_CLUT224 */
Benjamin Herrenschmidt7191b612013-07-25 12:12:32 +10002160
2161#ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
2162 if (prom_getprop(node, "linux,boot-display", NULL, 0) !=
2163 PROM_ERROR) {
2164 u32 width, height, pitch, addr;
2165
2166 prom_printf("Setting btext !\n");
2167 prom_getprop(node, "width", &width, 4);
2168 prom_getprop(node, "height", &height, 4);
2169 prom_getprop(node, "linebytes", &pitch, 4);
2170 prom_getprop(node, "address", &addr, 4);
2171 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
2172 width, height, pitch, addr);
2173 btext_setup_display(width, height, 8, pitch, addr);
2174 }
2175#endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002176 }
2177}
2178
2179
2180/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
2181static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
2182 unsigned long needed, unsigned long align)
2183{
2184 void *ret;
2185
2186 *mem_start = _ALIGN(*mem_start, align);
2187 while ((*mem_start + needed) > *mem_end) {
2188 unsigned long room, chunk;
2189
2190 prom_debug("Chunk exhausted, claiming more at %x...\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002191 alloc_bottom);
2192 room = alloc_top - alloc_bottom;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002193 if (room > DEVTREE_CHUNK_SIZE)
2194 room = DEVTREE_CHUNK_SIZE;
2195 if (room < PAGE_SIZE)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002196 prom_panic("No memory for flatten_device_tree "
2197 "(no room)\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002198 chunk = alloc_up(room, 0);
2199 if (chunk == 0)
Anton Blanchardfbafd722011-07-25 20:47:51 +00002200 prom_panic("No memory for flatten_device_tree "
2201 "(claim failed)\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002202 *mem_end = chunk + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002203 }
2204
2205 ret = (void *)*mem_start;
2206 *mem_start += needed;
2207
2208 return ret;
2209}
2210
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002211#define dt_push_token(token, mem_start, mem_end) do { \
2212 void *room = make_room(mem_start, mem_end, 4, 4); \
2213 *(__be32 *)room = cpu_to_be32(token); \
2214 } while(0)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002215
2216static unsigned long __init dt_find_string(char *str)
2217{
2218 char *s, *os;
2219
Anton Blanchard5827d412012-11-26 17:40:03 +00002220 s = os = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002221 s += 4;
Anton Blanchard5827d412012-11-26 17:40:03 +00002222 while (s < (char *)dt_string_end) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002223 if (strcmp(s, str) == 0)
2224 return s - os;
2225 s += strlen(s) + 1;
2226 }
2227 return 0;
2228}
2229
2230/*
2231 * The Open Firmware 1275 specification states properties must be 31 bytes or
2232 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
2233 */
2234#define MAX_PROPERTY_NAME 64
2235
2236static void __init scan_dt_build_strings(phandle node,
2237 unsigned long *mem_start,
2238 unsigned long *mem_end)
2239{
2240 char *prev_name, *namep, *sstart;
2241 unsigned long soff;
2242 phandle child;
2243
Anton Blanchard5827d412012-11-26 17:40:03 +00002244 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002245
2246 /* get and store all property names */
Anton Blanchard5827d412012-11-26 17:40:03 +00002247 prev_name = "";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002248 for (;;) {
2249 /* 64 is max len of name including nul. */
2250 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
2251 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
2252 /* No more nodes: unwind alloc */
2253 *mem_start = (unsigned long)namep;
2254 break;
2255 }
2256
2257 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002258 if (strcmp(namep, "name") == 0) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002259 *mem_start = (unsigned long)namep;
Anton Blanchard5827d412012-11-26 17:40:03 +00002260 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002261 continue;
2262 }
2263 /* get/create string entry */
2264 soff = dt_find_string(namep);
2265 if (soff != 0) {
2266 *mem_start = (unsigned long)namep;
2267 namep = sstart + soff;
2268 } else {
2269 /* Trim off some if we can */
2270 *mem_start = (unsigned long)namep + strlen(namep) + 1;
Anton Blanchard5827d412012-11-26 17:40:03 +00002271 dt_string_end = *mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002272 }
2273 prev_name = namep;
2274 }
2275
2276 /* do all our children */
2277 child = call_prom("child", 1, 1, node);
2278 while (child != 0) {
2279 scan_dt_build_strings(child, mem_start, mem_end);
2280 child = call_prom("peer", 1, 1, child);
2281 }
2282}
2283
2284static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2285 unsigned long *mem_end)
2286{
2287 phandle child;
2288 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
2289 unsigned long soff;
2290 unsigned char *valp;
2291 static char pname[MAX_PROPERTY_NAME];
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002292 int l, room, has_phandle = 0;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002293
2294 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
2295
2296 /* get the node's full name */
2297 namep = (char *)*mem_start;
Paul Mackerrasc49888202005-10-26 21:52:53 +10002298 room = *mem_end - *mem_start;
2299 if (room > 255)
2300 room = 255;
2301 l = call_prom("package-to-path", 3, 1, node, namep, room);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002302 if (l >= 0) {
2303 /* Didn't fit? Get more room. */
Paul Mackerrasc49888202005-10-26 21:52:53 +10002304 if (l >= room) {
2305 if (l >= *mem_end - *mem_start)
2306 namep = make_room(mem_start, mem_end, l+1, 1);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002307 call_prom("package-to-path", 3, 1, node, namep, l);
2308 }
2309 namep[l] = '\0';
2310
2311 /* Fixup an Apple bug where they have bogus \0 chars in the
Paul Mackerrasa575b802005-10-23 17:23:21 +10002312 * middle of the path in some properties, and extract
2313 * the unit name (everything after the last '/').
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002314 */
Paul Mackerrasa575b802005-10-23 17:23:21 +10002315 for (lp = p = namep, ep = namep + l; p < ep; p++) {
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002316 if (*p == '/')
Paul Mackerrasa575b802005-10-23 17:23:21 +10002317 lp = namep;
2318 else if (*p != 0)
2319 *lp++ = *p;
2320 }
2321 *lp = 0;
2322 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002323 }
2324
2325 /* get it again for debugging */
Anton Blanchard5827d412012-11-26 17:40:03 +00002326 path = prom_scratch;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002327 memset(path, 0, PROM_SCRATCH_SIZE);
2328 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2329
2330 /* get and store all properties */
Anton Blanchard5827d412012-11-26 17:40:03 +00002331 prev_name = "";
2332 sstart = (char *)dt_string_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002333 for (;;) {
2334 if (call_prom("nextprop", 3, 1, node, prev_name,
Anton Blanchard5827d412012-11-26 17:40:03 +00002335 pname) != 1)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002336 break;
2337
2338 /* skip "name" */
Anton Blanchard5827d412012-11-26 17:40:03 +00002339 if (strcmp(pname, "name") == 0) {
2340 prev_name = "name";
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002341 continue;
2342 }
2343
2344 /* find string offset */
Anton Blanchard5827d412012-11-26 17:40:03 +00002345 soff = dt_find_string(pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002346 if (soff == 0) {
2347 prom_printf("WARNING: Can't find string index for"
Anton Blanchard5827d412012-11-26 17:40:03 +00002348 " <%s>, node %s\n", pname, path);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002349 break;
2350 }
2351 prev_name = sstart + soff;
2352
2353 /* get length */
Anton Blanchard5827d412012-11-26 17:40:03 +00002354 l = call_prom("getproplen", 2, 1, node, pname);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002355
2356 /* sanity checks */
2357 if (l == PROM_ERROR)
2358 continue;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002359
2360 /* push property head */
2361 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2362 dt_push_token(l, mem_start, mem_end);
2363 dt_push_token(soff, mem_start, mem_end);
2364
2365 /* push property content */
2366 valp = make_room(mem_start, mem_end, l, 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002367 call_prom("getprop", 4, 1, node, pname, valp, l);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002368 *mem_start = _ALIGN(*mem_start, 4);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002369
Anton Blanchard5827d412012-11-26 17:40:03 +00002370 if (!strcmp(pname, "phandle"))
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002371 has_phandle = 1;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002372 }
2373
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002374 /* Add a "linux,phandle" property if no "phandle" property already
2375 * existed (can happen with OPAL)
2376 */
2377 if (!has_phandle) {
Anton Blanchard5827d412012-11-26 17:40:03 +00002378 soff = dt_find_string("linux,phandle");
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002379 if (soff == 0)
2380 prom_printf("WARNING: Can't find string index for"
2381 " <linux-phandle> node %s\n", path);
2382 else {
2383 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2384 dt_push_token(4, mem_start, mem_end);
2385 dt_push_token(soff, mem_start, mem_end);
2386 valp = make_room(mem_start, mem_end, 4, 4);
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002387 *(__be32 *)valp = cpu_to_be32(node);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00002388 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002389 }
2390
2391 /* do all our children */
2392 child = call_prom("child", 1, 1, node);
2393 while (child != 0) {
2394 scan_dt_build_struct(child, mem_start, mem_end);
2395 child = call_prom("peer", 1, 1, child);
2396 }
2397
2398 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
2399}
2400
2401static void __init flatten_device_tree(void)
2402{
2403 phandle root;
2404 unsigned long mem_start, mem_end, room;
2405 struct boot_param_header *hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002406 char *namep;
2407 u64 *rsvmap;
2408
2409 /*
2410 * Check how much room we have between alloc top & bottom (+/- a
Anton Blanchardfbafd722011-07-25 20:47:51 +00002411 * few pages), crop to 1MB, as this is our "chunk" size
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002412 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002413 room = alloc_top - alloc_bottom - 0x4000;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002414 if (room > DEVTREE_CHUNK_SIZE)
2415 room = DEVTREE_CHUNK_SIZE;
Anton Blanchard5827d412012-11-26 17:40:03 +00002416 prom_debug("starting device tree allocs at %x\n", alloc_bottom);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002417
2418 /* Now try to claim that */
2419 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
2420 if (mem_start == 0)
2421 prom_panic("Can't allocate initial device-tree chunk\n");
Anton Blanchard966728d2011-07-25 20:47:07 +00002422 mem_end = mem_start + room;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002423
2424 /* Get root of tree */
2425 root = call_prom("peer", 1, 1, (phandle)0);
2426 if (root == (phandle)0)
2427 prom_panic ("couldn't get device tree root\n");
2428
2429 /* Build header and make room for mem rsv map */
2430 mem_start = _ALIGN(mem_start, 4);
2431 hdr = make_room(&mem_start, &mem_end,
2432 sizeof(struct boot_param_header), 4);
Anton Blanchard5827d412012-11-26 17:40:03 +00002433 dt_header_start = (unsigned long)hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002434 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
2435
2436 /* Start of strings */
2437 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002438 dt_string_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002439 mem_start += 4; /* hole */
2440
2441 /* Add "linux,phandle" in there, we'll need it */
2442 namep = make_room(&mem_start, &mem_end, 16, 1);
Anton Blanchard5827d412012-11-26 17:40:03 +00002443 strcpy(namep, "linux,phandle");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002444 mem_start = (unsigned long)namep + strlen(namep) + 1;
2445
2446 /* Build string array */
2447 prom_printf("Building dt strings...\n");
2448 scan_dt_build_strings(root, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002449 dt_string_end = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002450
2451 /* Build structure */
2452 mem_start = PAGE_ALIGN(mem_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002453 dt_struct_start = mem_start;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002454 prom_printf("Building dt structure...\n");
2455 scan_dt_build_struct(root, &mem_start, &mem_end);
2456 dt_push_token(OF_DT_END, &mem_start, &mem_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002457 dt_struct_end = PAGE_ALIGN(mem_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002458
2459 /* Finish header */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002460 hdr->boot_cpuid_phys = cpu_to_be32(prom.cpu);
2461 hdr->magic = cpu_to_be32(OF_DT_HEADER);
2462 hdr->totalsize = cpu_to_be32(dt_struct_end - dt_header_start);
2463 hdr->off_dt_struct = cpu_to_be32(dt_struct_start - dt_header_start);
2464 hdr->off_dt_strings = cpu_to_be32(dt_string_start - dt_header_start);
2465 hdr->dt_strings_size = cpu_to_be32(dt_string_end - dt_string_start);
2466 hdr->off_mem_rsvmap = cpu_to_be32(((unsigned long)rsvmap) - dt_header_start);
2467 hdr->version = cpu_to_be32(OF_DT_VERSION);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002468 /* Version 16 is not backward compatible */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002469 hdr->last_comp_version = cpu_to_be32(0x10);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002470
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002471 /* Copy the reserve map in */
Anton Blanchard5827d412012-11-26 17:40:03 +00002472 memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002473
2474#ifdef DEBUG_PROM
2475 {
2476 int i;
2477 prom_printf("reserved memory map:\n");
Anton Blanchard5827d412012-11-26 17:40:03 +00002478 for (i = 0; i < mem_reserve_cnt; i++)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002479 prom_printf(" %x - %x\n",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002480 be64_to_cpu(mem_reserve_map[i].base),
2481 be64_to_cpu(mem_reserve_map[i].size));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002482 }
2483#endif
Jimi Xenidis4d1f3f22006-05-18 17:03:05 -05002484 /* Bump mem_reserve_cnt to cause further reservations to fail
2485 * since it's too late.
2486 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002487 mem_reserve_cnt = MEM_RESERVE_MAP_SIZE;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002488
2489 prom_printf("Device tree strings 0x%x -> 0x%x\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002490 dt_string_start, dt_string_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002491 prom_printf("Device tree struct 0x%x -> 0x%x\n",
Anton Blanchard5827d412012-11-26 17:40:03 +00002492 dt_struct_start, dt_struct_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002493}
2494
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002495#ifdef CONFIG_PPC_MAPLE
2496/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2497 * The values are bad, and it doesn't even have the right number of cells. */
2498static void __init fixup_device_tree_maple(void)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002499{
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002500 phandle isa;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002501 u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002502 u32 isa_ranges[6];
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002503 char *name;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002504
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002505 name = "/ht@0/isa@4";
2506 isa = call_prom("finddevice", 1, 1, ADDR(name));
2507 if (!PHANDLE_VALID(isa)) {
2508 name = "/ht@0/isa@6";
2509 isa = call_prom("finddevice", 1, 1, ADDR(name));
2510 rloc = 0x01003000; /* IO space; PCI device = 6 */
2511 }
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002512 if (!PHANDLE_VALID(isa))
2513 return;
2514
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002515 if (prom_getproplen(isa, "ranges") != 12)
2516 return;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002517 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2518 == PROM_ERROR)
2519 return;
2520
2521 if (isa_ranges[0] != 0x1 ||
2522 isa_ranges[1] != 0xf4000000 ||
2523 isa_ranges[2] != 0x00010000)
2524 return;
2525
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002526 prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002527
2528 isa_ranges[0] = 0x1;
2529 isa_ranges[1] = 0x0;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002530 isa_ranges[2] = rloc;
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002531 isa_ranges[3] = 0x0;
2532 isa_ranges[4] = 0x0;
2533 isa_ranges[5] = 0x00010000;
Benjamin Herrenschmidt980a6512006-07-03 17:22:05 +10002534 prom_setprop(isa, name, "ranges",
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002535 isa_ranges, sizeof(isa_ranges));
2536}
Harry Ciao8f101a02009-06-17 16:28:00 -07002537
2538#define CPC925_MC_START 0xf8000000
2539#define CPC925_MC_LENGTH 0x1000000
2540/* The values for memory-controller don't have right number of cells */
2541static void __init fixup_device_tree_maple_memory_controller(void)
2542{
2543 phandle mc;
2544 u32 mc_reg[4];
2545 char *name = "/hostbridge@f8000000";
Harry Ciao8f101a02009-06-17 16:28:00 -07002546 u32 ac, sc;
2547
2548 mc = call_prom("finddevice", 1, 1, ADDR(name));
2549 if (!PHANDLE_VALID(mc))
2550 return;
2551
2552 if (prom_getproplen(mc, "reg") != 8)
2553 return;
2554
Anton Blanchard5827d412012-11-26 17:40:03 +00002555 prom_getprop(prom.root, "#address-cells", &ac, sizeof(ac));
2556 prom_getprop(prom.root, "#size-cells", &sc, sizeof(sc));
Harry Ciao8f101a02009-06-17 16:28:00 -07002557 if ((ac != 2) || (sc != 2))
2558 return;
2559
2560 if (prom_getprop(mc, "reg", mc_reg, sizeof(mc_reg)) == PROM_ERROR)
2561 return;
2562
2563 if (mc_reg[0] != CPC925_MC_START || mc_reg[1] != CPC925_MC_LENGTH)
2564 return;
2565
2566 prom_printf("Fixing up bogus hostbridge on Maple...\n");
2567
2568 mc_reg[0] = 0x0;
2569 mc_reg[1] = CPC925_MC_START;
2570 mc_reg[2] = 0x0;
2571 mc_reg[3] = CPC925_MC_LENGTH;
2572 prom_setprop(mc, name, "reg", mc_reg, sizeof(mc_reg));
2573}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002574#else
2575#define fixup_device_tree_maple()
Harry Ciao8f101a02009-06-17 16:28:00 -07002576#define fixup_device_tree_maple_memory_controller()
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002577#endif
2578
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002579#ifdef CONFIG_PPC_CHRP
Olaf Heringe4805922007-04-04 18:20:04 +02002580/*
2581 * Pegasos and BriQ lacks the "ranges" property in the isa node
2582 * Pegasos needs decimal IRQ 14/15, not hexadecimal
Olaf Hering556ecf92007-08-18 04:27:17 +10002583 * Pegasos has the IDE configured in legacy mode, but advertised as native
Olaf Heringe4805922007-04-04 18:20:04 +02002584 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002585static void __init fixup_device_tree_chrp(void)
2586{
Olaf Heringe4805922007-04-04 18:20:04 +02002587 phandle ph;
2588 u32 prop[6];
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002589 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002590 char *name;
2591 int rc;
2592
2593 name = "/pci@80000000/isa@c";
Olaf Heringe4805922007-04-04 18:20:04 +02002594 ph = call_prom("finddevice", 1, 1, ADDR(name));
2595 if (!PHANDLE_VALID(ph)) {
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002596 name = "/pci@ff500000/isa@6";
Olaf Heringe4805922007-04-04 18:20:04 +02002597 ph = call_prom("finddevice", 1, 1, ADDR(name));
Benjamin Herrenschmidt26c50322006-07-04 14:16:28 +10002598 rloc = 0x01003000; /* IO space; PCI device = 6 */
2599 }
Olaf Heringe4805922007-04-04 18:20:04 +02002600 if (PHANDLE_VALID(ph)) {
2601 rc = prom_getproplen(ph, "ranges");
2602 if (rc == 0 || rc == PROM_ERROR) {
2603 prom_printf("Fixing up missing ISA range on Pegasos...\n");
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002604
Olaf Heringe4805922007-04-04 18:20:04 +02002605 prop[0] = 0x1;
2606 prop[1] = 0x0;
2607 prop[2] = rloc;
2608 prop[3] = 0x0;
2609 prop[4] = 0x0;
2610 prop[5] = 0x00010000;
2611 prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2612 }
2613 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002614
Olaf Heringe4805922007-04-04 18:20:04 +02002615 name = "/pci@80000000/ide@C,1";
2616 ph = call_prom("finddevice", 1, 1, ADDR(name));
2617 if (PHANDLE_VALID(ph)) {
2618 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2619 prop[0] = 14;
2620 prop[1] = 0x0;
Olaf Hering556ecf92007-08-18 04:27:17 +10002621 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2622 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2623 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2624 if (rc == sizeof(u32)) {
2625 prop[0] &= ~0x5;
2626 prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2627 }
Olaf Heringe4805922007-04-04 18:20:04 +02002628 }
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002629}
2630#else
2631#define fixup_device_tree_chrp()
2632#endif
2633
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002634#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002635static void __init fixup_device_tree_pmac(void)
2636{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002637 phandle u3, i2c, mpic;
2638 u32 u3_rev;
2639 u32 interrupts[2];
2640 u32 parent;
2641
2642 /* Some G5s have a missing interrupt definition, fix it up here */
2643 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2644 if (!PHANDLE_VALID(u3))
2645 return;
2646 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2647 if (!PHANDLE_VALID(i2c))
2648 return;
2649 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2650 if (!PHANDLE_VALID(mpic))
2651 return;
2652
2653 /* check if proper rev of u3 */
2654 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2655 == PROM_ERROR)
2656 return;
Benjamin Herrenschmidt7d496972005-11-07 14:36:21 +11002657 if (u3_rev < 0x35 || u3_rev > 0x39)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002658 return;
2659 /* does it need fixup ? */
2660 if (prom_getproplen(i2c, "interrupts") > 0)
2661 return;
2662
2663 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2664
2665 /* interrupt on this revision of u3 is number 0 and level */
2666 interrupts[0] = 0;
2667 interrupts[1] = 1;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002668 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2669 &interrupts, sizeof(interrupts));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002670 parent = (u32)mpic;
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002671 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2672 &parent, sizeof(parent));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002673}
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002674#else
2675#define fixup_device_tree_pmac()
2676#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002677
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002678#ifdef CONFIG_PPC_EFIKA
Grant Likely94d2dde2008-01-24 22:25:32 -07002679/*
2680 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2681 * to talk to the phy. If the phy-handle property is missing, then this
2682 * function is called to add the appropriate nodes and link it to the
2683 * ethernet node.
2684 */
2685static void __init fixup_device_tree_efika_add_phy(void)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002686{
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002687 u32 node;
2688 char prop[64];
Grant Likely94d2dde2008-01-24 22:25:32 -07002689 int rv;
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002690
Grant Likely94d2dde2008-01-24 22:25:32 -07002691 /* Check if /builtin/ethernet exists - bail if it doesn't */
2692 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002693 if (!PHANDLE_VALID(node))
2694 return;
2695
Grant Likely94d2dde2008-01-24 22:25:32 -07002696 /* Check if the phy-handle property exists - bail if it does */
2697 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2698 if (!rv)
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002699 return;
2700
Grant Likely94d2dde2008-01-24 22:25:32 -07002701 /*
2702 * At this point the ethernet device doesn't have a phy described.
2703 * Now we need to add the missing phy node and linkage
2704 */
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002705
Grant Likely94d2dde2008-01-24 22:25:32 -07002706 /* Check for an MDIO bus node - if missing then create one */
Olaf Hering6f4347c2008-01-10 01:06:08 +11002707 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2708 if (!PHANDLE_VALID(node)) {
2709 prom_printf("Adding Ethernet MDIO node\n");
2710 call_prom("interpret", 1, 1,
2711 " s\" /builtin\" find-device"
2712 " new-device"
2713 " 1 encode-int s\" #address-cells\" property"
2714 " 0 encode-int s\" #size-cells\" property"
Grant Likely94d2dde2008-01-24 22:25:32 -07002715 " s\" mdio\" device-name"
2716 " s\" fsl,mpc5200b-mdio\" encode-string"
Olaf Hering6f4347c2008-01-10 01:06:08 +11002717 " s\" compatible\" property"
2718 " 0xf0003000 0x400 reg"
2719 " 0x2 encode-int"
2720 " 0x5 encode-int encode+"
2721 " 0x3 encode-int encode+"
2722 " s\" interrupts\" property"
2723 " finish-device");
2724 };
2725
Grant Likely94d2dde2008-01-24 22:25:32 -07002726 /* Check for a PHY device node - if missing then create one and
2727 * give it's phandle to the ethernet node */
2728 node = call_prom("finddevice", 1, 1,
2729 ADDR("/builtin/mdio/ethernet-phy"));
Olaf Hering6f4347c2008-01-10 01:06:08 +11002730 if (!PHANDLE_VALID(node)) {
2731 prom_printf("Adding Ethernet PHY node\n");
2732 call_prom("interpret", 1, 1,
2733 " s\" /builtin/mdio\" find-device"
2734 " new-device"
2735 " s\" ethernet-phy\" device-name"
2736 " 0x10 encode-int s\" reg\" property"
2737 " my-self"
2738 " ihandle>phandle"
2739 " finish-device"
2740 " s\" /builtin/ethernet\" find-device"
2741 " encode-int"
2742 " s\" phy-handle\" property"
2743 " device-end");
2744 }
Grant Likely94d2dde2008-01-24 22:25:32 -07002745}
Olaf Hering6f4347c2008-01-10 01:06:08 +11002746
Grant Likely94d2dde2008-01-24 22:25:32 -07002747static void __init fixup_device_tree_efika(void)
2748{
2749 int sound_irq[3] = { 2, 2, 0 };
2750 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2751 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2752 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2753 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2754 u32 node;
2755 char prop[64];
2756 int rv, len;
2757
2758 /* Check if we're really running on a EFIKA */
2759 node = call_prom("finddevice", 1, 1, ADDR("/"));
2760 if (!PHANDLE_VALID(node))
2761 return;
2762
2763 rv = prom_getprop(node, "model", prop, sizeof(prop));
2764 if (rv == PROM_ERROR)
2765 return;
2766 if (strcmp(prop, "EFIKA5K2"))
2767 return;
2768
2769 prom_printf("Applying EFIKA device tree fixups\n");
2770
2771 /* Claiming to be 'chrp' is death */
2772 node = call_prom("finddevice", 1, 1, ADDR("/"));
2773 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2774 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2775 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2776
David Woodhouse7f4392c2008-04-14 02:52:38 +10002777 /* CODEGEN,description is exposed in /proc/cpuinfo so
2778 fix that too */
2779 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2780 if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2781 prom_setprop(node, "/", "CODEGEN,description",
2782 "Efika 5200B PowerPC System",
2783 sizeof("Efika 5200B PowerPC System"));
2784
Grant Likely94d2dde2008-01-24 22:25:32 -07002785 /* Fixup bestcomm interrupts property */
2786 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2787 if (PHANDLE_VALID(node)) {
2788 len = prom_getproplen(node, "interrupts");
2789 if (len == 12) {
2790 prom_printf("Fixing bestcomm interrupts property\n");
2791 prom_setprop(node, "/builtin/bestcom", "interrupts",
2792 bcomm_irq, sizeof(bcomm_irq));
2793 }
2794 }
2795
2796 /* Fixup sound interrupts property */
2797 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2798 if (PHANDLE_VALID(node)) {
2799 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2800 if (rv == PROM_ERROR) {
2801 prom_printf("Adding sound interrupts property\n");
2802 prom_setprop(node, "/builtin/sound", "interrupts",
2803 sound_irq, sizeof(sound_irq));
2804 }
2805 }
2806
2807 /* Make sure ethernet phy-handle property exists */
2808 fixup_device_tree_efika_add_phy();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002809}
2810#else
2811#define fixup_device_tree_efika()
2812#endif
2813
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002814static void __init fixup_device_tree(void)
2815{
2816 fixup_device_tree_maple();
Harry Ciao8f101a02009-06-17 16:28:00 -07002817 fixup_device_tree_maple_memory_controller();
Benjamin Herrenschmidte8c0acf2006-07-04 14:06:29 +10002818 fixup_device_tree_chrp();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002819 fixup_device_tree_pmac();
Sylvain Munaut88fd2a92007-02-12 23:13:20 +01002820 fixup_device_tree_efika();
Hollis Blanchard54f4ee12006-05-25 16:36:53 -05002821}
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002822
2823static void __init prom_find_boot_cpu(void)
2824{
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002825 __be32 rval;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002826 ihandle prom_cpu;
2827 phandle cpu_pkg;
2828
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002829 rval = 0;
2830 if (prom_getprop(prom.chosen, "cpu", &rval, sizeof(rval)) <= 0)
Paul Mackerrasa575b802005-10-23 17:23:21 +10002831 return;
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002832 prom_cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002833
2834 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2835
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002836 prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval));
2837 prom.cpu = be32_to_cpu(rval);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002838
Anton Blanchard5827d412012-11-26 17:40:03 +00002839 prom_debug("Booting CPU hw index = %lu\n", prom.cpu);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002840}
2841
2842static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2843{
2844#ifdef CONFIG_BLK_DEV_INITRD
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002845 if (r3 && r4 && r4 != 0xdeadbeef) {
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002846 __be64 val;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002847
Anton Blanchard5827d412012-11-26 17:40:03 +00002848 prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3;
2849 prom_initrd_end = prom_initrd_start + r4;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002850
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002851 val = cpu_to_be64(prom_initrd_start);
Anton Blanchard5827d412012-11-26 17:40:03 +00002852 prom_setprop(prom.chosen, "/chosen", "linux,initrd-start",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002853 &val, sizeof(val));
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10002854 val = cpu_to_be64(prom_initrd_end);
Anton Blanchard5827d412012-11-26 17:40:03 +00002855 prom_setprop(prom.chosen, "/chosen", "linux,initrd-end",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002856 &val, sizeof(val));
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002857
Anton Blanchard5827d412012-11-26 17:40:03 +00002858 reserve_mem(prom_initrd_start,
2859 prom_initrd_end - prom_initrd_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002860
Anton Blanchard5827d412012-11-26 17:40:03 +00002861 prom_debug("initrd_start=0x%x\n", prom_initrd_start);
2862 prom_debug("initrd_end=0x%x\n", prom_initrd_end);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002863 }
2864#endif /* CONFIG_BLK_DEV_INITRD */
2865}
2866
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002867#ifdef CONFIG_PPC64
2868#ifdef CONFIG_RELOCATABLE
2869static void reloc_toc(void)
2870{
2871}
2872
2873static void unreloc_toc(void)
2874{
2875}
2876#else
Anton Blanchard16744002013-03-12 01:51:51 +00002877static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002878{
2879 unsigned long i;
Anton Blanchard16744002013-03-12 01:51:51 +00002880 unsigned long *toc_entry;
2881
2882 /* Get the start of the TOC by using r2 directly. */
2883 asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002884
2885 for (i = 0; i < nr_entries; i++) {
2886 *toc_entry = *toc_entry + offset;
2887 toc_entry++;
2888 }
2889}
2890
2891static void reloc_toc(void)
2892{
2893 unsigned long offset = reloc_offset();
2894 unsigned long nr_entries =
2895 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
2896
Anton Blanchard16744002013-03-12 01:51:51 +00002897 __reloc_toc(offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002898
2899 mb();
2900}
2901
2902static void unreloc_toc(void)
2903{
2904 unsigned long offset = reloc_offset();
2905 unsigned long nr_entries =
2906 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
2907
2908 mb();
2909
Anton Blanchard16744002013-03-12 01:51:51 +00002910 __reloc_toc(-offset, nr_entries);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002911}
2912#endif
2913#endif
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002914
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002915/*
2916 * We enter here early on, when the Open Firmware prom is still
2917 * handling exceptions and the MMU hash table for us.
2918 */
2919
2920unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2921 unsigned long pp,
Paul Mackerras549e8152008-08-30 11:43:47 +10002922 unsigned long r6, unsigned long r7,
2923 unsigned long kbase)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002924{
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002925 unsigned long hdr;
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002926
2927#ifdef CONFIG_PPC32
Paul Mackerras549e8152008-08-30 11:43:47 +10002928 unsigned long offset = reloc_offset();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002929 reloc_got2(offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00002930#else
2931 reloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002932#endif
2933
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002934 /*
2935 * First zero the BSS
2936 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002937 memset(&__bss_start, 0, __bss_stop - __bss_start);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002938
2939 /*
2940 * Init interface to Open Firmware, get some node references,
2941 * like /chosen
2942 */
2943 prom_init_client_services(pp);
2944
2945 /*
Paul Mackerrasa23414b2005-11-10 12:00:55 +11002946 * See if this OF is old enough that we need to do explicit maps
2947 * and other workarounds
2948 */
2949 prom_find_mmu();
2950
2951 /*
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002952 * Init prom stdout device
2953 */
2954 prom_init_stdout();
2955
Anton Blanchard5827d412012-11-26 17:40:03 +00002956 prom_printf("Preparing to boot %s", linux_banner);
Michael Ellermane7943fb2009-03-04 19:02:01 +00002957
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002958 /*
2959 * Get default machine type. At this point, we do not differentiate
2960 * between pSeries SMP and pSeries LPAR
2961 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002962 of_platform = prom_find_machine_type();
2963 prom_printf("Detected machine type: %x\n", of_platform);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002964
Suzuki Poulose0f890c82011-12-14 22:57:15 +00002965#ifndef CONFIG_NONSTATIC_KERNEL
Olaf Heringadd60ef2006-03-23 22:03:57 +01002966 /* Bail if this is a kdump kernel. */
2967 if (PHYSICAL_START > 0)
2968 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
Paul Mackerras549e8152008-08-30 11:43:47 +10002969#endif
Olaf Heringadd60ef2006-03-23 22:03:57 +01002970
2971 /*
2972 * Check for an initrd
2973 */
2974 prom_check_initrd(r3, r4);
2975
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00002976#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002977 /*
2978 * On pSeries, inform the firmware about our capabilities
2979 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002980 if (of_platform == PLATFORM_PSERIES ||
2981 of_platform == PLATFORM_PSERIES_LPAR)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002982 prom_send_capabilities();
2983#endif
2984
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002985 /*
Arnd Bergmannf3f66f52005-10-31 20:08:37 -05002986 * Copy the CPU hold code
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002987 */
Anton Blanchard5827d412012-11-26 17:40:03 +00002988 if (of_platform != PLATFORM_POWERMAC)
Paul Mackerras549e8152008-08-30 11:43:47 +10002989 copy_and_flush(0, kbase, 0x100, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10002990
2991 /*
2992 * Do early parsing of command line
2993 */
2994 early_cmdline_parse();
2995
2996 /*
2997 * Initialize memory management within prom_init
2998 */
2999 prom_init_mem();
3000
3001 /*
3002 * Determine which cpu is actually running right _now_
3003 */
3004 prom_find_boot_cpu();
3005
3006 /*
3007 * Initialize display devices
3008 */
3009 prom_check_displays();
3010
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003011#if defined(CONFIG_PPC64) && defined(__BIG_ENDIAN__)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003012 /*
3013 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
3014 * that uses the allocator, we need to make sure we get the top of memory
3015 * available for us here...
3016 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003017 if (of_platform == PLATFORM_PSERIES)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003018 prom_initialize_tce_table();
3019#endif
3020
3021 /*
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003022 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
3023 * have a usable RTAS implementation.
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003024 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003025 if (of_platform != PLATFORM_POWERMAC &&
3026 of_platform != PLATFORM_OPAL)
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003027 prom_instantiate_rtas();
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003028
3029#ifdef CONFIG_PPC_POWERNV
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003030#ifdef __BIG_ENDIAN__
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003031 /* Detect HAL and try instanciating it & doing takeover */
Anton Blanchard5827d412012-11-26 17:40:03 +00003032 if (of_platform == PLATFORM_PSERIES_LPAR) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003033 prom_query_opal();
Anton Blanchard5827d412012-11-26 17:40:03 +00003034 if (of_platform == PLATFORM_OPAL) {
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003035 prom_opal_hold_cpus();
3036 prom_opal_takeover();
3037 }
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003038 } else
3039#endif /* __BIG_ENDIAN__ */
3040 if (of_platform == PLATFORM_OPAL)
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003041 prom_instantiate_opal();
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003042#endif /* CONFIG_PPC_POWERNV */
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003043
Ashley Lai4a727422012-08-14 18:34:57 -05003044#ifdef CONFIG_PPC64
3045 /* instantiate sml */
3046 prom_instantiate_sml();
3047#endif
3048
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003049 /*
3050 * On non-powermacs, put all CPUs in spin-loops.
3051 *
3052 * PowerMacs use a different mechanism to spin CPUs
Benjamin Herrenschmidtdbe78b42013-09-25 14:02:50 +10003053 *
3054 * (This must be done after instanciating RTAS)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003055 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003056 if (of_platform != PLATFORM_POWERMAC &&
3057 of_platform != PLATFORM_OPAL)
Benjamin Herrenschmidt27f44882011-09-19 18:27:58 +00003058 prom_hold_cpus();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003059
3060 /*
3061 * Fill in some infos for use by the kernel later on
3062 */
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003063 if (prom_memory_limit) {
3064 __be64 val = cpu_to_be64(prom_memory_limit);
Anton Blanchard5827d412012-11-26 17:40:03 +00003065 prom_setprop(prom.chosen, "/chosen", "linux,memory-limit",
Benjamin Herrenschmidt493adff2013-08-07 02:01:38 +10003066 &val, sizeof(val));
3067 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003068#ifdef CONFIG_PPC64
Anton Blanchard5827d412012-11-26 17:40:03 +00003069 if (prom_iommu_off)
3070 prom_setprop(prom.chosen, "/chosen", "linux,iommu-off",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003071 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003072
Anton Blanchard5827d412012-11-26 17:40:03 +00003073 if (prom_iommu_force_on)
3074 prom_setprop(prom.chosen, "/chosen", "linux,iommu-force-on",
Paul Mackerrasa23414b2005-11-10 12:00:55 +11003075 NULL, 0);
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003076
Anton Blanchard5827d412012-11-26 17:40:03 +00003077 if (prom_tce_alloc_start) {
3078 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-start",
3079 &prom_tce_alloc_start,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003080 sizeof(prom_tce_alloc_start));
Anton Blanchard5827d412012-11-26 17:40:03 +00003081 prom_setprop(prom.chosen, "/chosen", "linux,tce-alloc-end",
3082 &prom_tce_alloc_end,
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003083 sizeof(prom_tce_alloc_end));
3084 }
3085#endif
3086
3087 /*
3088 * Fixup any known bugs in the device-tree
3089 */
3090 fixup_device_tree();
3091
3092 /*
3093 * Now finally create the flattened device-tree
3094 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00003095 prom_printf("copying OF device tree...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003096 flatten_device_tree();
3097
Paul Mackerras3825ac02005-11-08 22:48:08 +11003098 /*
3099 * in case stdin is USB and still active on IBM machines...
3100 * Unfortunately quiesce crashes on some powermacs if we have
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003101 * closed stdin already (in particular the powerbook 101). It
3102 * appears that the OPAL version of OFW doesn't like it either.
Paul Mackerras3825ac02005-11-08 22:48:08 +11003103 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003104 if (of_platform != PLATFORM_POWERMAC &&
3105 of_platform != PLATFORM_OPAL)
Paul Mackerras3825ac02005-11-08 22:48:08 +11003106 prom_close_stdin();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003107
3108 /*
3109 * Call OF "quiesce" method to shut down pending DMA's from
3110 * devices etc...
3111 */
Anton Blanchard1f8737a2009-03-31 20:06:15 +00003112 prom_printf("Calling quiesce...\n");
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003113 call_prom("quiesce", 0, 0);
3114
3115 /*
3116 * And finally, call the kernel passing it the flattened device
3117 * tree and NULL as r5, thus triggering the new entry point which
3118 * is common to us and kexec
3119 */
Anton Blanchard5827d412012-11-26 17:40:03 +00003120 hdr = dt_header_start;
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003121
3122 /* Don't print anything after quiesce under OPAL, it crashes OFW */
Anton Blanchard5827d412012-11-26 17:40:03 +00003123 if (of_platform != PLATFORM_OPAL) {
Benjamin Herrenschmidt40dfef62011-11-29 18:22:56 +00003124 prom_printf("returning from prom_init\n");
3125 prom_debug("->dt_header_start=0x%x\n", hdr);
3126 }
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003127
3128#ifdef CONFIG_PPC32
3129 reloc_got2(-offset);
Anton Blanchard5ac47f72012-11-26 17:39:03 +00003130#else
3131 unreloc_toc();
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003132#endif
3133
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003134#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
3135 /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
3136 __start(hdr, kbase, 0, 0, 0,
Anton Blanchard5827d412012-11-26 17:40:03 +00003137 prom_opal_base, prom_opal_entry);
Benjamin Herrenschmidt6e35d5d2011-09-19 18:28:01 +00003138#else
3139 __start(hdr, kbase, 0, 0, 0, 0, 0);
3140#endif
Paul Mackerras9b6b5632005-10-06 12:06:20 +10003141
3142 return 0;
3143}