hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/arch/powerpc/kernel/prom_init.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Procedures for interfacing to Open Firmware.
34 *
....@@ -6,11 +7,6 @@
67 *
78 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
89 * {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.
1410 */
1511
1612 #undef DEBUG_PROM
....@@ -30,6 +26,7 @@
3026 #include <linux/delay.h>
3127 #include <linux/initrd.h>
3228 #include <linux/bitops.h>
29
+#include <linux/pgtable.h>
3330 #include <asm/prom.h>
3431 #include <asm/rtas.h>
3532 #include <asm/page.h>
....@@ -38,15 +35,17 @@
3835 #include <asm/io.h>
3936 #include <asm/smp.h>
4037 #include <asm/mmu.h>
41
-#include <asm/pgtable.h>
4238 #include <asm/iommu.h>
4339 #include <asm/btext.h>
4440 #include <asm/sections.h>
4541 #include <asm/machdep.h>
46
-#include <asm/opal.h>
4742 #include <asm/asm-prototypes.h>
43
+#include <asm/ultravisor-api.h>
4844
4945 #include <linux/linux_logo.h>
46
+
47
+/* All of prom_init bss lives here */
48
+#define __prombss __section(".bss.prominit")
5049
5150 /*
5251 * Eventually bump that one up
....@@ -87,7 +86,7 @@
8786 #define OF_WORKAROUNDS 0
8887 #else
8988 #define OF_WORKAROUNDS of_workarounds
90
-int of_workarounds;
89
+static int of_workarounds __prombss;
9190 #endif
9291
9392 #define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
....@@ -96,7 +95,7 @@
9695 #define PROM_BUG() do { \
9796 prom_printf("kernel BUG at %s line 0x%x!\n", \
9897 __FILE__, __LINE__); \
99
- __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
98
+ __builtin_trap(); \
10099 } while (0)
101100
102101 #ifdef DEBUG_PROM
....@@ -148,29 +147,35 @@
148147 unsigned long size, unsigned long offset);
149148
150149 /* prom structure */
151
-static struct prom_t __initdata prom;
150
+static struct prom_t __prombss prom;
152151
153
-static unsigned long prom_entry __initdata;
152
+static unsigned long __prombss prom_entry;
154153
155
-#define PROM_SCRATCH_SIZE 256
154
+static char __prombss of_stdout_device[256];
155
+static char __prombss prom_scratch[256];
156156
157
-static char __initdata of_stdout_device[256];
158
-static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
157
+static unsigned long __prombss dt_header_start;
158
+static unsigned long __prombss dt_struct_start, dt_struct_end;
159
+static unsigned long __prombss dt_string_start, dt_string_end;
159160
160
-static unsigned long __initdata dt_header_start;
161
-static unsigned long __initdata dt_struct_start, dt_struct_end;
162
-static unsigned long __initdata dt_string_start, dt_string_end;
163
-
164
-static unsigned long __initdata prom_initrd_start, prom_initrd_end;
161
+static unsigned long __prombss prom_initrd_start, prom_initrd_end;
165162
166163 #ifdef CONFIG_PPC64
167
-static int __initdata prom_iommu_force_on;
168
-static int __initdata prom_iommu_off;
169
-static unsigned long __initdata prom_tce_alloc_start;
170
-static unsigned long __initdata prom_tce_alloc_end;
164
+static int __prombss prom_iommu_force_on;
165
+static int __prombss prom_iommu_off;
166
+static unsigned long __prombss prom_tce_alloc_start;
167
+static unsigned long __prombss prom_tce_alloc_end;
171168 #endif
172169
173
-static bool prom_radix_disable __initdata = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
170
+#ifdef CONFIG_PPC_PSERIES
171
+static bool __prombss prom_radix_disable;
172
+static bool __prombss prom_radix_gtse_disable;
173
+static bool __prombss prom_xive_disable;
174
+#endif
175
+
176
+#ifdef CONFIG_PPC_SVM
177
+static bool __prombss prom_svm_enable;
178
+#endif
174179
175180 struct platform_support {
176181 bool hash_mmu;
....@@ -188,26 +193,25 @@
188193 #define PLATFORM_LPAR 0x0001
189194 #define PLATFORM_POWERMAC 0x0400
190195 #define PLATFORM_GENERIC 0x0500
191
-#define PLATFORM_OPAL 0x0600
192196
193
-static int __initdata of_platform;
197
+static int __prombss of_platform;
194198
195
-static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
199
+static char __prombss prom_cmd_line[COMMAND_LINE_SIZE];
196200
197
-static unsigned long __initdata prom_memory_limit;
201
+static unsigned long __prombss prom_memory_limit;
198202
199
-static unsigned long __initdata alloc_top;
200
-static unsigned long __initdata alloc_top_high;
201
-static unsigned long __initdata alloc_bottom;
202
-static unsigned long __initdata rmo_top;
203
-static unsigned long __initdata ram_top;
203
+static unsigned long __prombss alloc_top;
204
+static unsigned long __prombss alloc_top_high;
205
+static unsigned long __prombss alloc_bottom;
206
+static unsigned long __prombss rmo_top;
207
+static unsigned long __prombss ram_top;
204208
205
-static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
206
-static int __initdata mem_reserve_cnt;
209
+static struct mem_map_entry __prombss mem_reserve_map[MEM_RESERVE_MAP_SIZE];
210
+static int __prombss mem_reserve_cnt;
207211
208
-static cell_t __initdata regbuf[1024];
212
+static cell_t __prombss regbuf[1024];
209213
210
-static bool rtas_has_query_cpu_stopped;
214
+static bool __prombss rtas_has_query_cpu_stopped;
211215
212216
213217 /*
....@@ -221,6 +225,143 @@
221225 #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
222226 #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
223227
228
+/* Copied from lib/string.c and lib/kstrtox.c */
229
+
230
+static int __init prom_strcmp(const char *cs, const char *ct)
231
+{
232
+ unsigned char c1, c2;
233
+
234
+ while (1) {
235
+ c1 = *cs++;
236
+ c2 = *ct++;
237
+ if (c1 != c2)
238
+ return c1 < c2 ? -1 : 1;
239
+ if (!c1)
240
+ break;
241
+ }
242
+ return 0;
243
+}
244
+
245
+static char __init *prom_strcpy(char *dest, const char *src)
246
+{
247
+ char *tmp = dest;
248
+
249
+ while ((*dest++ = *src++) != '\0')
250
+ /* nothing */;
251
+ return tmp;
252
+}
253
+
254
+static int __init prom_strncmp(const char *cs, const char *ct, size_t count)
255
+{
256
+ unsigned char c1, c2;
257
+
258
+ while (count) {
259
+ c1 = *cs++;
260
+ c2 = *ct++;
261
+ if (c1 != c2)
262
+ return c1 < c2 ? -1 : 1;
263
+ if (!c1)
264
+ break;
265
+ count--;
266
+ }
267
+ return 0;
268
+}
269
+
270
+static size_t __init prom_strlen(const char *s)
271
+{
272
+ const char *sc;
273
+
274
+ for (sc = s; *sc != '\0'; ++sc)
275
+ /* nothing */;
276
+ return sc - s;
277
+}
278
+
279
+static int __init prom_memcmp(const void *cs, const void *ct, size_t count)
280
+{
281
+ const unsigned char *su1, *su2;
282
+ int res = 0;
283
+
284
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
285
+ if ((res = *su1 - *su2) != 0)
286
+ break;
287
+ return res;
288
+}
289
+
290
+static char __init *prom_strstr(const char *s1, const char *s2)
291
+{
292
+ size_t l1, l2;
293
+
294
+ l2 = prom_strlen(s2);
295
+ if (!l2)
296
+ return (char *)s1;
297
+ l1 = prom_strlen(s1);
298
+ while (l1 >= l2) {
299
+ l1--;
300
+ if (!prom_memcmp(s1, s2, l2))
301
+ return (char *)s1;
302
+ s1++;
303
+ }
304
+ return NULL;
305
+}
306
+
307
+static size_t __init prom_strlcat(char *dest, const char *src, size_t count)
308
+{
309
+ size_t dsize = prom_strlen(dest);
310
+ size_t len = prom_strlen(src);
311
+ size_t res = dsize + len;
312
+
313
+ /* This would be a bug */
314
+ if (dsize >= count)
315
+ return count;
316
+
317
+ dest += dsize;
318
+ count -= dsize;
319
+ if (len >= count)
320
+ len = count-1;
321
+ memcpy(dest, src, len);
322
+ dest[len] = 0;
323
+ return res;
324
+
325
+}
326
+
327
+#ifdef CONFIG_PPC_PSERIES
328
+static int __init prom_strtobool(const char *s, bool *res)
329
+{
330
+ if (!s)
331
+ return -EINVAL;
332
+
333
+ switch (s[0]) {
334
+ case 'y':
335
+ case 'Y':
336
+ case '1':
337
+ *res = true;
338
+ return 0;
339
+ case 'n':
340
+ case 'N':
341
+ case '0':
342
+ *res = false;
343
+ return 0;
344
+ case 'o':
345
+ case 'O':
346
+ switch (s[1]) {
347
+ case 'n':
348
+ case 'N':
349
+ *res = true;
350
+ return 0;
351
+ case 'f':
352
+ case 'F':
353
+ *res = false;
354
+ return 0;
355
+ default:
356
+ break;
357
+ }
358
+ default:
359
+ break;
360
+ }
361
+
362
+ return -EINVAL;
363
+}
364
+#endif
224365
225366 /* This is the one and *ONLY* place where we actually call open
226367 * firmware.
....@@ -498,14 +639,14 @@
498639 }
499640 }
500641
501
-static inline int prom_getprop(phandle node, const char *pname,
502
- void *value, size_t valuelen)
642
+static inline int __init prom_getprop(phandle node, const char *pname,
643
+ void *value, size_t valuelen)
503644 {
504645 return call_prom("getprop", 4, 1, node, ADDR(pname),
505646 (u32)(unsigned long) value, (u32) valuelen);
506647 }
507648
508
-static inline int prom_getproplen(phandle node, const char *pname)
649
+static inline int __init prom_getproplen(phandle node, const char *pname)
509650 {
510651 return call_prom("getproplen", 2, 1, node, ADDR(pname));
511652 }
....@@ -522,8 +663,8 @@
522663
523664 static char *tohex(unsigned int x)
524665 {
525
- static char digits[] = "0123456789abcdef";
526
- static char result[9];
666
+ static const char digits[] __initconst = "0123456789abcdef";
667
+ static char result[9] __prombss;
527668 int i;
528669
529670 result[8] = 0;
....@@ -552,7 +693,7 @@
552693 add_string(&p, tohex((u32)(unsigned long) value));
553694 add_string(&p, tohex(valuelen));
554695 add_string(&p, tohex(ADDR(pname)));
555
- add_string(&p, tohex(strlen(pname)));
696
+ add_string(&p, tohex(prom_strlen(pname)));
556697 add_string(&p, "property");
557698 *p = 0;
558699 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
....@@ -628,33 +769,34 @@
628769 const char *opt;
629770
630771 char *p;
631
- int l __maybe_unused = 0;
772
+ int l = 0;
632773
633774 prom_cmd_line[0] = 0;
634775 p = prom_cmd_line;
635
- if ((long)prom.chosen > 0)
776
+
777
+ if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && (long)prom.chosen > 0)
636778 l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
637
-#ifdef CONFIG_CMDLINE
638
- if (l <= 0 || p[0] == '\0') /* dbl check */
639
- strlcpy(prom_cmd_line,
640
- CONFIG_CMDLINE, sizeof(prom_cmd_line));
641
-#endif /* CONFIG_CMDLINE */
779
+
780
+ if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || l <= 0 || p[0] == '\0')
781
+ prom_strlcat(prom_cmd_line, " " CONFIG_CMDLINE,
782
+ sizeof(prom_cmd_line));
783
+
642784 prom_printf("command line: %s\n", prom_cmd_line);
643785
644786 #ifdef CONFIG_PPC64
645
- opt = strstr(prom_cmd_line, "iommu=");
787
+ opt = prom_strstr(prom_cmd_line, "iommu=");
646788 if (opt) {
647789 prom_printf("iommu opt is: %s\n", opt);
648790 opt += 6;
649791 while (*opt && *opt == ' ')
650792 opt++;
651
- if (!strncmp(opt, "off", 3))
793
+ if (!prom_strncmp(opt, "off", 3))
652794 prom_iommu_off = 1;
653
- else if (!strncmp(opt, "force", 5))
795
+ else if (!prom_strncmp(opt, "force", 5))
654796 prom_iommu_force_on = 1;
655797 }
656798 #endif
657
- opt = strstr(prom_cmd_line, "mem=");
799
+ opt = prom_strstr(prom_cmd_line, "mem=");
658800 if (opt) {
659801 opt += 4;
660802 prom_memory_limit = prom_memparse(opt, (const char **)&opt);
....@@ -664,13 +806,15 @@
664806 #endif
665807 }
666808
667
- opt = strstr(prom_cmd_line, "disable_radix");
809
+#ifdef CONFIG_PPC_PSERIES
810
+ prom_radix_disable = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
811
+ opt = prom_strstr(prom_cmd_line, "disable_radix");
668812 if (opt) {
669813 opt += 13;
670814 if (*opt && *opt == '=') {
671815 bool val;
672816
673
- if (kstrtobool(++opt, &val))
817
+ if (prom_strtobool(++opt, &val))
674818 prom_radix_disable = false;
675819 else
676820 prom_radix_disable = val;
....@@ -679,9 +823,33 @@
679823 }
680824 if (prom_radix_disable)
681825 prom_debug("Radix disabled from cmdline\n");
826
+
827
+ opt = prom_strstr(prom_cmd_line, "radix_hcall_invalidate=on");
828
+ if (opt) {
829
+ prom_radix_gtse_disable = true;
830
+ prom_debug("Radix GTSE disabled from cmdline\n");
831
+ }
832
+
833
+ opt = prom_strstr(prom_cmd_line, "xive=off");
834
+ if (opt) {
835
+ prom_xive_disable = true;
836
+ prom_debug("XIVE disabled from cmdline\n");
837
+ }
838
+#endif /* CONFIG_PPC_PSERIES */
839
+
840
+#ifdef CONFIG_PPC_SVM
841
+ opt = prom_strstr(prom_cmd_line, "svm=");
842
+ if (opt) {
843
+ bool val;
844
+
845
+ opt += sizeof("svm=") - 1;
846
+ if (!prom_strtobool(opt, &val))
847
+ prom_svm_enable = val;
848
+ }
849
+#endif /* CONFIG_PPC_SVM */
682850 }
683851
684
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
852
+#ifdef CONFIG_PPC_PSERIES
685853 /*
686854 * The architecture vector has an array of PVR mask/value pairs,
687855 * followed by # option vectors - 1, followed by the option vectors.
....@@ -759,7 +927,7 @@
759927 } __packed;
760928
761929 struct ibm_arch_vec {
762
- struct { u32 mask, val; } pvrs[12];
930
+ struct { u32 mask, val; } pvrs[14];
763931
764932 u8 num_vectors;
765933
....@@ -782,7 +950,7 @@
782950 struct option_vector6 vec6;
783951 } __packed;
784952
785
-struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
953
+static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
786954 .pvrs = {
787955 {
788956 .mask = cpu_to_be32(0xfffe0000), /* POWER5/POWER5+ */
....@@ -813,6 +981,14 @@
813981 .val = cpu_to_be32(0x004e0000),
814982 },
815983 {
984
+ .mask = cpu_to_be32(0xffff0000), /* POWER10 */
985
+ .val = cpu_to_be32(0x00800000),
986
+ },
987
+ {
988
+ .mask = cpu_to_be32(0xffffffff), /* all 3.1-compliant */
989
+ .val = cpu_to_be32(0x0f000006),
990
+ },
991
+ {
816992 .mask = cpu_to_be32(0xffffffff), /* all 3.00-compliant */
817993 .val = cpu_to_be32(0x0f000005),
818994 },
....@@ -841,7 +1017,7 @@
8411017 .byte1 = 0,
8421018 .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
8431019 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
844
- .arch_versions3 = OV1_PPC_3_00,
1020
+ .arch_versions3 = OV1_PPC_3_00 | OV1_PPC_3_1,
8451021 },
8461022
8471023 .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)),
....@@ -893,7 +1069,8 @@
8931069 #else
8941070 0,
8951071 #endif
896
- .associativity = OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN),
1072
+ .associativity = OV5_FEAT(OV5_FORM1_AFFINITY) | OV5_FEAT(OV5_PRRN) |
1073
+ OV5_FEAT(OV5_FORM2_AFFINITY),
8971074 .bin_opts = OV5_FEAT(OV5_RESIZE_HPT) | OV5_FEAT(OV5_HP_EVT),
8981075 .micro_checkpoint = 0,
8991076 .reserved0 = 0,
....@@ -920,9 +1097,11 @@
9201097 },
9211098 };
9221099
1100
+static struct ibm_arch_vec __prombss ibm_architecture_vec ____cacheline_aligned;
1101
+
9231102 /* Old method - ELF header with PT_NOTE sections only works on BE */
9241103 #ifdef __BIG_ENDIAN__
925
-static struct fake_elf {
1104
+static const struct fake_elf {
9261105 Elf32_Ehdr elfhdr;
9271106 Elf32_Phdr phdr[2];
9281107 struct chrpnote {
....@@ -955,7 +1134,7 @@
9551134 u32 ignore_me;
9561135 } rpadesc;
9571136 } rpanote;
958
-} fake_elf = {
1137
+} fake_elf __initconst = {
9591138 .elfhdr = {
9601139 .e_ident = { 0x7f, 'E', 'L', 'F',
9611140 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
....@@ -1020,7 +1199,7 @@
10201199 type[0] = 0;
10211200 prom_getprop(node, "device_type", type, sizeof(type));
10221201
1023
- if (strcmp(type, "cpu"))
1202
+ if (prom_strcmp(type, "cpu"))
10241203 continue;
10251204 /*
10261205 * There is an entry for each smt thread, each entry being
....@@ -1084,10 +1263,17 @@
10841263 switch (val) {
10851264 case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */
10861265 prom_debug("XIVE - either mode supported\n");
1087
- support->xive = true;
1266
+ support->xive = !prom_xive_disable;
10881267 break;
10891268 case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */
10901269 prom_debug("XIVE - exploitation mode supported\n");
1270
+ if (prom_xive_disable) {
1271
+ /*
1272
+ * If we __have__ to do XIVE, we're better off ignoring
1273
+ * the command line rather than not booting.
1274
+ */
1275
+ prom_printf("WARNING: Ignoring cmdline option xive=off\n");
1276
+ }
10911277 support->xive = true;
10921278 break;
10931279 case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
....@@ -1107,10 +1293,8 @@
11071293 prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
11081294 break;
11091295 case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
1110
- if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
1111
- prom_debug("Radix - GTSE supported\n");
1112
- support->radix_gtse = true;
1113
- }
1296
+ if (val & OV5_FEAT(OV5_RADIX_GTSE))
1297
+ support->radix_gtse = !prom_radix_gtse_disable;
11141298 break;
11151299 case OV5_INDX(OV5_XIVE_SUPPORT): /* Interrupt mode */
11161300 prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT),
....@@ -1129,28 +1313,40 @@
11291313 };
11301314 int prop_len = prom_getproplen(prom.chosen,
11311315 "ibm,arch-vec-5-platform-support");
1316
+
1317
+ /*
1318
+ * First copy the architecture vec template
1319
+ *
1320
+ * use memcpy() instead of *vec = *vec_template so that GCC replaces it
1321
+ * by __memcpy() when KASAN is active
1322
+ */
1323
+ memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
1324
+ sizeof(ibm_architecture_vec));
1325
+
11321326 if (prop_len > 1) {
11331327 int i;
1134
- u8 vec[prop_len];
1328
+ u8 vec[8];
11351329 prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
11361330 prop_len);
1137
- prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
1138
- &vec, sizeof(vec));
1331
+ if (prop_len > sizeof(vec))
1332
+ prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n",
1333
+ prop_len);
1334
+ prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", &vec, sizeof(vec));
11391335 for (i = 0; i < prop_len; i += 2) {
1140
- prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
1141
- , vec[i]
1142
- , vec[i + 1]);
1143
- prom_parse_platform_support(vec[i], vec[i + 1],
1144
- &supported);
1336
+ prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2, vec[i], vec[i + 1]);
1337
+ prom_parse_platform_support(vec[i], vec[i + 1], &supported);
11451338 }
11461339 }
11471340
1148
- if (supported.radix_mmu && supported.radix_gtse &&
1149
- IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
1150
- /* Radix preferred - but we require GTSE for now */
1151
- prom_debug("Asking for radix with GTSE\n");
1341
+ if (supported.radix_mmu && IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
1342
+ /* Radix preferred - Check if GTSE is also supported */
1343
+ prom_debug("Asking for radix\n");
11521344 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1153
- ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
1345
+ if (supported.radix_gtse)
1346
+ ibm_architecture_vec.vec5.radix_ext =
1347
+ OV5_FEAT(OV5_RADIX_GTSE);
1348
+ else
1349
+ prom_debug("Radix GTSE isn't supported\n");
11541350 } else if (supported.hash_mmu) {
11551351 /* Default to hash mmu (if we can) */
11561352 prom_debug("Asking for hash\n");
....@@ -1225,7 +1421,7 @@
12251421 }
12261422 #endif /* __BIG_ENDIAN__ */
12271423 }
1228
-#endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
1424
+#endif /* CONFIG_PPC_PSERIES */
12291425
12301426 /*
12311427 * Memory allocation strategy... our layout is normally:
....@@ -1266,18 +1462,18 @@
12661462 unsigned long addr = 0;
12671463
12681464 if (align)
1269
- base = _ALIGN_UP(base, align);
1465
+ base = ALIGN(base, align);
12701466 prom_debug("%s(%lx, %lx)\n", __func__, size, align);
12711467 if (ram_top == 0)
12721468 prom_panic("alloc_up() called with mem not initialized\n");
12731469
12741470 if (align)
1275
- base = _ALIGN_UP(alloc_bottom, align);
1471
+ base = ALIGN(alloc_bottom, align);
12761472 else
12771473 base = alloc_bottom;
12781474
12791475 for(; (base + size) <= alloc_top;
1280
- base = _ALIGN_UP(base + 0x100000, align)) {
1476
+ base = ALIGN(base + 0x100000, align)) {
12811477 prom_debug(" trying: 0x%lx\n\r", base);
12821478 addr = (unsigned long)prom_claim(base, size, 0);
12831479 if (addr != PROM_ERROR && addr != 0)
....@@ -1317,7 +1513,7 @@
13171513
13181514 if (highmem) {
13191515 /* Carve out storage for the TCE table. */
1320
- addr = _ALIGN_DOWN(alloc_top_high - size, align);
1516
+ addr = ALIGN_DOWN(alloc_top_high - size, align);
13211517 if (addr <= alloc_bottom)
13221518 return 0;
13231519 /* Will we bump into the RMO ? If yes, check out that we
....@@ -1335,9 +1531,9 @@
13351531 goto bail;
13361532 }
13371533
1338
- base = _ALIGN_DOWN(alloc_top - size, align);
1534
+ base = ALIGN_DOWN(alloc_top - size, align);
13391535 for (; base > alloc_bottom;
1340
- base = _ALIGN_DOWN(base - 0x100000, align)) {
1536
+ base = ALIGN_DOWN(base - 0x100000, align)) {
13411537 prom_debug(" trying: 0x%lx\n\r", base);
13421538 addr = (unsigned long)prom_claim(base, size, 0);
13431539 if (addr != PROM_ERROR && addr != 0)
....@@ -1403,8 +1599,8 @@
14031599 * have our terminator with "size" set to 0 since we are
14041600 * dumb and just copy this entire array to the boot params
14051601 */
1406
- base = _ALIGN_DOWN(base, PAGE_SIZE);
1407
- top = _ALIGN_UP(top, PAGE_SIZE);
1602
+ base = ALIGN_DOWN(base, PAGE_SIZE);
1603
+ top = ALIGN(top, PAGE_SIZE);
14081604 size = top - base;
14091605
14101606 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
....@@ -1421,9 +1617,6 @@
14211617 static void __init prom_init_mem(void)
14221618 {
14231619 phandle node;
1424
-#ifdef DEBUG_PROM
1425
- char *path;
1426
-#endif
14271620 char type[64];
14281621 unsigned int plen;
14291622 cell_t *p, *endp;
....@@ -1445,9 +1638,6 @@
14451638 prom_debug("root_size_cells: %x\n", rsc);
14461639
14471640 prom_debug("scanning memory:\n");
1448
-#ifdef DEBUG_PROM
1449
- path = prom_scratch;
1450
-#endif
14511641
14521642 for (node = 0; prom_next_node(&node); ) {
14531643 type[0] = 0;
....@@ -1460,7 +1650,7 @@
14601650 */
14611651 prom_getprop(node, "name", type, sizeof(type));
14621652 }
1463
- if (strcmp(type, "memory"))
1653
+ if (prom_strcmp(type, "memory"))
14641654 continue;
14651655
14661656 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
....@@ -1472,9 +1662,10 @@
14721662 endp = p + (plen / sizeof(cell_t));
14731663
14741664 #ifdef DEBUG_PROM
1475
- memset(path, 0, PROM_SCRATCH_SIZE);
1476
- call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1477
- prom_debug(" node %s :\n", path);
1665
+ memset(prom_scratch, 0, sizeof(prom_scratch));
1666
+ call_prom("package-to-path", 3, 1, node, prom_scratch,
1667
+ sizeof(prom_scratch) - 1);
1668
+ prom_debug(" node %s :\n", prom_scratch);
14781669 #endif /* DEBUG_PROM */
14791670
14801671 while ((endp - p) >= (rac + rsc)) {
....@@ -1562,87 +1753,45 @@
15621753 }
15631754 }
15641755
1565
-#ifdef CONFIG_PPC_POWERNV
1566
-
1567
-#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1568
-static u64 __initdata prom_opal_base;
1569
-static u64 __initdata prom_opal_entry;
1570
-#endif
1571
-
1572
-/*
1573
- * Allocate room for and instantiate OPAL
1574
- */
1575
-static void __init prom_instantiate_opal(void)
1756
+#ifdef CONFIG_PPC_SVM
1757
+static int prom_rtas_hcall(uint64_t args)
15761758 {
1577
- phandle opal_node;
1578
- ihandle opal_inst;
1579
- u64 base, entry;
1580
- u64 size = 0, align = 0x10000;
1581
- __be64 val64;
1582
- u32 rets[2];
1759
+ register uint64_t arg1 asm("r3") = H_RTAS;
1760
+ register uint64_t arg2 asm("r4") = args;
15831761
1584
- prom_debug("prom_instantiate_opal: start...\n");
1585
-
1586
- opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
1587
- prom_debug("opal_node: %x\n", opal_node);
1588
- if (!PHANDLE_VALID(opal_node))
1589
- return;
1590
-
1591
- val64 = 0;
1592
- prom_getprop(opal_node, "opal-runtime-size", &val64, sizeof(val64));
1593
- size = be64_to_cpu(val64);
1594
- if (size == 0)
1595
- return;
1596
- val64 = 0;
1597
- prom_getprop(opal_node, "opal-runtime-alignment", &val64,sizeof(val64));
1598
- align = be64_to_cpu(val64);
1599
-
1600
- base = alloc_down(size, align, 0);
1601
- if (base == 0) {
1602
- prom_printf("OPAL allocation failed !\n");
1603
- return;
1604
- }
1605
-
1606
- opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
1607
- if (!IHANDLE_VALID(opal_inst)) {
1608
- prom_printf("opening opal package failed (%x)\n", opal_inst);
1609
- return;
1610
- }
1611
-
1612
- prom_printf("instantiating opal at 0x%llx...", base);
1613
-
1614
- if (call_prom_ret("call-method", 4, 3, rets,
1615
- ADDR("load-opal-runtime"),
1616
- opal_inst,
1617
- base >> 32, base & 0xffffffff) != 0
1618
- || (rets[0] == 0 && rets[1] == 0)) {
1619
- prom_printf(" failed\n");
1620
- return;
1621
- }
1622
- entry = (((u64)rets[0]) << 32) | rets[1];
1623
-
1624
- prom_printf(" done\n");
1625
-
1626
- reserve_mem(base, size);
1627
-
1628
- prom_debug("opal base = 0x%llx\n", base);
1629
- prom_debug("opal align = 0x%llx\n", align);
1630
- prom_debug("opal entry = 0x%llx\n", entry);
1631
- prom_debug("opal size = 0x%llx\n", size);
1632
-
1633
- prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
1634
- &base, sizeof(base));
1635
- prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
1636
- &entry, sizeof(entry));
1637
-
1638
-#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1639
- prom_opal_base = base;
1640
- prom_opal_entry = entry;
1641
-#endif
1642
- prom_debug("prom_instantiate_opal: end...\n");
1762
+ asm volatile("sc 1\n" : "=r" (arg1) :
1763
+ "r" (arg1),
1764
+ "r" (arg2) :);
1765
+ return arg1;
16431766 }
16441767
1645
-#endif /* CONFIG_PPC_POWERNV */
1768
+static struct rtas_args __prombss os_term_args;
1769
+
1770
+static void __init prom_rtas_os_term(char *str)
1771
+{
1772
+ phandle rtas_node;
1773
+ __be32 val;
1774
+ u32 token;
1775
+
1776
+ prom_debug("%s: start...\n", __func__);
1777
+ rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1778
+ prom_debug("rtas_node: %x\n", rtas_node);
1779
+ if (!PHANDLE_VALID(rtas_node))
1780
+ return;
1781
+
1782
+ val = 0;
1783
+ prom_getprop(rtas_node, "ibm,os-term", &val, sizeof(val));
1784
+ token = be32_to_cpu(val);
1785
+ prom_debug("ibm,os-term: %x\n", token);
1786
+ if (token == 0)
1787
+ prom_panic("Could not get token for ibm,os-term\n");
1788
+ os_term_args.token = cpu_to_be32(token);
1789
+ os_term_args.nargs = cpu_to_be32(1);
1790
+ os_term_args.nret = cpu_to_be32(1);
1791
+ os_term_args.args[0] = cpu_to_be32(__pa(str));
1792
+ prom_rtas_hcall((uint64_t)&os_term_args);
1793
+}
1794
+#endif /* CONFIG_PPC_SVM */
16461795
16471796 /*
16481797 * Allocate room for and instantiate RTAS
....@@ -1823,19 +1972,19 @@
18231972 prom_getprop(node, "device_type", type, sizeof(type));
18241973 prom_getprop(node, "model", model, sizeof(model));
18251974
1826
- if ((type[0] == 0) || (strstr(type, "pci") == NULL))
1975
+ if ((type[0] == 0) || (prom_strstr(type, "pci") == NULL))
18271976 continue;
18281977
18291978 /* Keep the old logic intact to avoid regression. */
18301979 if (compatible[0] != 0) {
1831
- if ((strstr(compatible, "python") == NULL) &&
1832
- (strstr(compatible, "Speedwagon") == NULL) &&
1833
- (strstr(compatible, "Winnipeg") == NULL))
1980
+ if ((prom_strstr(compatible, "python") == NULL) &&
1981
+ (prom_strstr(compatible, "Speedwagon") == NULL) &&
1982
+ (prom_strstr(compatible, "Winnipeg") == NULL))
18341983 continue;
18351984 } else if (model[0] != 0) {
1836
- if ((strstr(model, "ython") == NULL) &&
1837
- (strstr(model, "peedwagon") == NULL) &&
1838
- (strstr(model, "innipeg") == NULL))
1985
+ if ((prom_strstr(model, "ython") == NULL) &&
1986
+ (prom_strstr(model, "peedwagon") == NULL) &&
1987
+ (prom_strstr(model, "innipeg") == NULL))
18391988 continue;
18401989 }
18411990
....@@ -1863,10 +2012,10 @@
18632012 local_alloc_bottom = base;
18642013
18652014 /* It seems OF doesn't null-terminate the path :-( */
1866
- memset(path, 0, PROM_SCRATCH_SIZE);
2015
+ memset(path, 0, sizeof(prom_scratch));
18672016 /* Call OF to setup the TCE hardware */
18682017 if (call_prom("package-to-path", 3, 1, node,
1869
- path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
2018
+ path, sizeof(prom_scratch) - 1) == PROM_ERROR) {
18702019 prom_printf("package-to-path failed\n");
18712020 }
18722021
....@@ -1984,12 +2133,12 @@
19842133
19852134 type[0] = 0;
19862135 prom_getprop(node, "device_type", type, sizeof(type));
1987
- if (strcmp(type, "cpu") != 0)
2136
+ if (prom_strcmp(type, "cpu") != 0)
19882137 continue;
19892138
19902139 /* Skip non-configured cpus. */
19912140 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1992
- if (strcmp(type, "okay") != 0)
2141
+ if (prom_strcmp(type, "okay") != 0)
19932142 continue;
19942143
19952144 reg = cpu_to_be32(-1); /* make sparse happy */
....@@ -2065,9 +2214,9 @@
20652214 return;
20662215 version[sizeof(version) - 1] = 0;
20672216 /* XXX might need to add other versions here */
2068
- if (strcmp(version, "Open Firmware, 1.0.5") == 0)
2217
+ if (prom_strcmp(version, "Open Firmware, 1.0.5") == 0)
20692218 of_workarounds = OF_WA_CLAIM;
2070
- else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
2219
+ else if (prom_strncmp(version, "FirmWorks,3.", 12) == 0) {
20712220 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
20722221 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
20732222 } else
....@@ -2100,7 +2249,7 @@
21002249 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
21012250 prom_printf("OF stdout device is: %s\n", of_stdout_device);
21022251 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
2103
- path, strlen(path) + 1);
2252
+ path, prom_strlen(path) + 1);
21042253
21052254 /* instance-to-package fails on PA-Semi */
21062255 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
....@@ -2110,7 +2259,7 @@
21102259 /* If it's a display, note it */
21112260 memset(type, 0, sizeof(type));
21122261 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2113
- if (strcmp(type, "display") == 0)
2262
+ if (prom_strcmp(type, "display") == 0)
21142263 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
21152264 }
21162265 }
....@@ -2131,29 +2280,25 @@
21312280 compat[len] = 0;
21322281 while (i < len) {
21332282 char *p = &compat[i];
2134
- int sl = strlen(p);
2283
+ int sl = prom_strlen(p);
21352284 if (sl == 0)
21362285 break;
2137
- if (strstr(p, "Power Macintosh") ||
2138
- strstr(p, "MacRISC"))
2286
+ if (prom_strstr(p, "Power Macintosh") ||
2287
+ prom_strstr(p, "MacRISC"))
21392288 return PLATFORM_POWERMAC;
21402289 #ifdef CONFIG_PPC64
21412290 /* We must make sure we don't detect the IBM Cell
21422291 * blades as pSeries due to some firmware issues,
21432292 * so we do it here.
21442293 */
2145
- if (strstr(p, "IBM,CBEA") ||
2146
- strstr(p, "IBM,CPBW-1.0"))
2294
+ if (prom_strstr(p, "IBM,CBEA") ||
2295
+ prom_strstr(p, "IBM,CPBW-1.0"))
21472296 return PLATFORM_GENERIC;
21482297 #endif /* CONFIG_PPC64 */
21492298 i += sl + 1;
21502299 }
21512300 }
21522301 #ifdef CONFIG_PPC64
2153
- /* Try to detect OPAL */
2154
- if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
2155
- return PLATFORM_OPAL;
2156
-
21572302 /* Try to figure out if it's an IBM pSeries or any other
21582303 * PAPR compliant platform. We assume it is if :
21592304 * - /device_type is "chrp" (please, do NOT use that for future
....@@ -2164,7 +2309,7 @@
21642309 compat, sizeof(compat)-1);
21652310 if (len <= 0)
21662311 return PLATFORM_GENERIC;
2167
- if (strcmp(compat, "chrp"))
2312
+ if (prom_strcmp(compat, "chrp"))
21682313 return PLATFORM_GENERIC;
21692314
21702315 /* Default to pSeries. We need to know if we are running LPAR */
....@@ -2202,7 +2347,7 @@
22022347 ihandle ih;
22032348 int i;
22042349
2205
- static unsigned char default_colors[] = {
2350
+ static const unsigned char default_colors[] __initconst = {
22062351 0x00, 0x00, 0x00,
22072352 0x00, 0x00, 0xaa,
22082353 0x00, 0xaa, 0x00,
....@@ -2226,19 +2371,19 @@
22262371 for (node = 0; prom_next_node(&node); ) {
22272372 memset(type, 0, sizeof(type));
22282373 prom_getprop(node, "device_type", type, sizeof(type));
2229
- if (strcmp(type, "display") != 0)
2374
+ if (prom_strcmp(type, "display") != 0)
22302375 continue;
22312376
22322377 /* It seems OF doesn't null-terminate the path :-( */
22332378 path = prom_scratch;
2234
- memset(path, 0, PROM_SCRATCH_SIZE);
2379
+ memset(path, 0, sizeof(prom_scratch));
22352380
22362381 /*
22372382 * leave some room at the end of the path for appending extra
22382383 * arguments
22392384 */
22402385 if (call_prom("package-to-path", 3, 1, node, path,
2241
- PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2386
+ sizeof(prom_scratch) - 10) == PROM_ERROR)
22422387 continue;
22432388 prom_printf("found display : %s, opening... ", path);
22442389
....@@ -2274,13 +2419,23 @@
22742419 u32 width, height, pitch, addr;
22752420
22762421 prom_printf("Setting btext !\n");
2277
- prom_getprop(node, "width", &width, 4);
2278
- prom_getprop(node, "height", &height, 4);
2279
- prom_getprop(node, "linebytes", &pitch, 4);
2280
- prom_getprop(node, "address", &addr, 4);
2422
+
2423
+ if (prom_getprop(node, "width", &width, 4) == PROM_ERROR)
2424
+ return;
2425
+
2426
+ if (prom_getprop(node, "height", &height, 4) == PROM_ERROR)
2427
+ return;
2428
+
2429
+ if (prom_getprop(node, "linebytes", &pitch, 4) == PROM_ERROR)
2430
+ return;
2431
+
2432
+ if (prom_getprop(node, "address", &addr, 4) == PROM_ERROR)
2433
+ return;
2434
+
22812435 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
22822436 width, height, pitch, addr);
22832437 btext_setup_display(width, height, 8, pitch, addr);
2438
+ btext_prepare_BAT();
22842439 }
22852440 #endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */
22862441 }
....@@ -2293,7 +2448,7 @@
22932448 {
22942449 void *ret;
22952450
2296
- *mem_start = _ALIGN(*mem_start, align);
2451
+ *mem_start = ALIGN(*mem_start, align);
22972452 while ((*mem_start + needed) > *mem_end) {
22982453 unsigned long room, chunk;
22992454
....@@ -2330,9 +2485,9 @@
23302485 s = os = (char *)dt_string_start;
23312486 s += 4;
23322487 while (s < (char *)dt_string_end) {
2333
- if (strcmp(s, str) == 0)
2488
+ if (prom_strcmp(s, str) == 0)
23342489 return s - os;
2335
- s += strlen(s) + 1;
2490
+ s += prom_strlen(s) + 1;
23362491 }
23372492 return 0;
23382493 }
....@@ -2365,7 +2520,7 @@
23652520 }
23662521
23672522 /* skip "name" */
2368
- if (strcmp(namep, "name") == 0) {
2523
+ if (prom_strcmp(namep, "name") == 0) {
23692524 *mem_start = (unsigned long)namep;
23702525 prev_name = "name";
23712526 continue;
....@@ -2377,7 +2532,7 @@
23772532 namep = sstart + soff;
23782533 } else {
23792534 /* Trim off some if we can */
2380
- *mem_start = (unsigned long)namep + strlen(namep) + 1;
2535
+ *mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
23812536 dt_string_end = *mem_start;
23822537 }
23832538 prev_name = namep;
....@@ -2398,7 +2553,7 @@
23982553 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
23992554 unsigned long soff;
24002555 unsigned char *valp;
2401
- static char pname[MAX_PROPERTY_NAME];
2556
+ static char pname[MAX_PROPERTY_NAME] __prombss;
24022557 int l, room, has_phandle = 0;
24032558
24042559 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
....@@ -2429,13 +2584,13 @@
24292584 *lp++ = *p;
24302585 }
24312586 *lp = 0;
2432
- *mem_start = _ALIGN((unsigned long)lp + 1, 4);
2587
+ *mem_start = ALIGN((unsigned long)lp + 1, 4);
24332588 }
24342589
24352590 /* get it again for debugging */
24362591 path = prom_scratch;
2437
- memset(path, 0, PROM_SCRATCH_SIZE);
2438
- call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2592
+ memset(path, 0, sizeof(prom_scratch));
2593
+ call_prom("package-to-path", 3, 1, node, path, sizeof(prom_scratch) - 1);
24392594
24402595 /* get and store all properties */
24412596 prev_name = "";
....@@ -2446,7 +2601,7 @@
24462601 break;
24472602
24482603 /* skip "name" */
2449
- if (strcmp(pname, "name") == 0) {
2604
+ if (prom_strcmp(pname, "name") == 0) {
24502605 prev_name = "name";
24512606 continue;
24522607 }
....@@ -2475,20 +2630,17 @@
24752630 /* push property content */
24762631 valp = make_room(mem_start, mem_end, l, 4);
24772632 call_prom("getprop", 4, 1, node, pname, valp, l);
2478
- *mem_start = _ALIGN(*mem_start, 4);
2633
+ *mem_start = ALIGN(*mem_start, 4);
24792634
2480
- if (!strcmp(pname, "phandle"))
2635
+ if (!prom_strcmp(pname, "phandle"))
24812636 has_phandle = 1;
24822637 }
24832638
2484
- /* Add a "linux,phandle" property if no "phandle" property already
2485
- * existed (can happen with OPAL)
2486
- */
2639
+ /* Add a "phandle" property if none already exist */
24872640 if (!has_phandle) {
2488
- soff = dt_find_string("linux,phandle");
2641
+ soff = dt_find_string("phandle");
24892642 if (soff == 0)
2490
- prom_printf("WARNING: Can't find string index for"
2491
- " <linux-phandle> node %s\n", path);
2643
+ prom_printf("WARNING: Can't find string index for <phandle> node %s\n", path);
24922644 else {
24932645 dt_push_token(OF_DT_PROP, mem_start, mem_end);
24942646 dt_push_token(4, mem_start, mem_end);
....@@ -2537,7 +2689,7 @@
25372689 prom_panic ("couldn't get device tree root\n");
25382690
25392691 /* Build header and make room for mem rsv map */
2540
- mem_start = _ALIGN(mem_start, 4);
2692
+ mem_start = ALIGN(mem_start, 4);
25412693 hdr = make_room(&mem_start, &mem_end,
25422694 sizeof(struct boot_param_header), 4);
25432695 dt_header_start = (unsigned long)hdr;
....@@ -2548,10 +2700,10 @@
25482700 dt_string_start = mem_start;
25492701 mem_start += 4; /* hole */
25502702
2551
- /* Add "linux,phandle" in there, we'll need it */
2703
+ /* Add "phandle" in there, we'll need it */
25522704 namep = make_room(&mem_start, &mem_end, 16, 1);
2553
- strcpy(namep, "linux,phandle");
2554
- mem_start = (unsigned long)namep + strlen(namep) + 1;
2705
+ prom_strcpy(namep, "phandle");
2706
+ mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
25552707
25562708 /* Build string array */
25572709 prom_printf("Building dt strings...\n");
....@@ -2873,7 +3025,7 @@
28733025 rv = prom_getprop(node, "model", prop, sizeof(prop));
28743026 if (rv == PROM_ERROR)
28753027 return;
2876
- if (strcmp(prop, "EFIKA5K2"))
3028
+ if (prom_strcmp(prop, "EFIKA5K2"))
28773029 return;
28783030
28793031 prom_printf("Applying EFIKA device tree fixups\n");
....@@ -2881,13 +3033,13 @@
28813033 /* Claiming to be 'chrp' is death */
28823034 node = call_prom("finddevice", 1, 1, ADDR("/"));
28833035 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2884
- if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
3036
+ if (rv != PROM_ERROR && (prom_strcmp(prop, "chrp") == 0))
28853037 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
28863038
28873039 /* CODEGEN,description is exposed in /proc/cpuinfo so
28883040 fix that too */
28893041 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2890
- if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
3042
+ if (rv != PROM_ERROR && (prom_strstr(prop, "CHRP")))
28913043 prom_setprop(node, "/", "CODEGEN,description",
28923044 "Efika 5200B PowerPC System",
28933045 sizeof("Efika 5200B PowerPC System"));
....@@ -3106,6 +3258,59 @@
31063258 #endif
31073259 #endif
31083260
3261
+#ifdef CONFIG_PPC_SVM
3262
+/*
3263
+ * Perform the Enter Secure Mode ultracall.
3264
+ */
3265
+static int enter_secure_mode(unsigned long kbase, unsigned long fdt)
3266
+{
3267
+ register unsigned long r3 asm("r3") = UV_ESM;
3268
+ register unsigned long r4 asm("r4") = kbase;
3269
+ register unsigned long r5 asm("r5") = fdt;
3270
+
3271
+ asm volatile("sc 2" : "+r"(r3) : "r"(r4), "r"(r5));
3272
+
3273
+ return r3;
3274
+}
3275
+
3276
+/*
3277
+ * Call the Ultravisor to transfer us to secure memory if we have an ESM blob.
3278
+ */
3279
+static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3280
+{
3281
+ int ret;
3282
+
3283
+ if (!prom_svm_enable)
3284
+ return;
3285
+
3286
+ /* Switch to secure mode. */
3287
+ prom_printf("Switching to secure mode.\n");
3288
+
3289
+ /*
3290
+ * The ultravisor will do an integrity check of the kernel image but we
3291
+ * relocated it so the check will fail. Restore the original image by
3292
+ * relocating it back to the kernel virtual base address.
3293
+ */
3294
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
3295
+ relocate(KERNELBASE);
3296
+
3297
+ ret = enter_secure_mode(kbase, fdt);
3298
+
3299
+ /* Relocate the kernel again. */
3300
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
3301
+ relocate(kbase);
3302
+
3303
+ if (ret != U_SUCCESS) {
3304
+ prom_printf("Returned %d from switching to secure mode.\n", ret);
3305
+ prom_rtas_os_term("Switch to secure mode failed.\n");
3306
+ }
3307
+}
3308
+#else
3309
+static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3310
+{
3311
+}
3312
+#endif /* CONFIG_PPC_SVM */
3313
+
31093314 /*
31103315 * We enter here early on, when the Open Firmware prom is still
31113316 * handling exceptions and the MMU hash table for us.
....@@ -3172,7 +3377,7 @@
31723377 */
31733378 early_cmdline_parse();
31743379
3175
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
3380
+#ifdef CONFIG_PPC_PSERIES
31763381 /*
31773382 * On pSeries, inform the firmware about our capabilities
31783383 */
....@@ -3216,14 +3421,8 @@
32163421 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
32173422 * have a usable RTAS implementation.
32183423 */
3219
- if (of_platform != PLATFORM_POWERMAC &&
3220
- of_platform != PLATFORM_OPAL)
3424
+ if (of_platform != PLATFORM_POWERMAC)
32213425 prom_instantiate_rtas();
3222
-
3223
-#ifdef CONFIG_PPC_POWERNV
3224
- if (of_platform == PLATFORM_OPAL)
3225
- prom_instantiate_opal();
3226
-#endif /* CONFIG_PPC_POWERNV */
32273426
32283427 #ifdef CONFIG_PPC64
32293428 /* instantiate sml */
....@@ -3237,8 +3436,7 @@
32373436 *
32383437 * (This must be done after instanciating RTAS)
32393438 */
3240
- if (of_platform != PLATFORM_POWERMAC &&
3241
- of_platform != PLATFORM_OPAL)
3439
+ if (of_platform != PLATFORM_POWERMAC)
32423440 prom_hold_cpus();
32433441
32443442 /*
....@@ -3282,11 +3480,9 @@
32823480 /*
32833481 * in case stdin is USB and still active on IBM machines...
32843482 * Unfortunately quiesce crashes on some powermacs if we have
3285
- * closed stdin already (in particular the powerbook 101). It
3286
- * appears that the OPAL version of OFW doesn't like it either.
3483
+ * closed stdin already (in particular the powerbook 101).
32873484 */
3288
- if (of_platform != PLATFORM_POWERMAC &&
3289
- of_platform != PLATFORM_OPAL)
3485
+ if (of_platform != PLATFORM_POWERMAC)
32903486 prom_close_stdin();
32913487
32923488 /*
....@@ -3303,11 +3499,8 @@
33033499 */
33043500 hdr = dt_header_start;
33053501
3306
- /* Don't print anything after quiesce under OPAL, it crashes OFW */
3307
- if (of_platform != PLATFORM_OPAL) {
3308
- prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
3309
- prom_debug("->dt_header_start=0x%lx\n", hdr);
3310
- }
3502
+ prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
3503
+ prom_debug("->dt_header_start=0x%lx\n", hdr);
33113504
33123505 #ifdef CONFIG_PPC32
33133506 reloc_got2(-offset);
....@@ -3315,13 +3508,10 @@
33153508 unreloc_toc();
33163509 #endif
33173510
3318
-#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
3319
- /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
3320
- __start(hdr, kbase, 0, 0, 0,
3321
- prom_opal_base, prom_opal_entry);
3322
-#else
3511
+ /* Move to secure memory if we're supposed to be secure guests. */
3512
+ setup_secure_guest(kbase, hdr);
3513
+
33233514 __start(hdr, kbase, 0, 0, 0, 0, 0);
3324
-#endif
33253515
33263516 return 0;
33273517 }