hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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)),
....@@ -920,9 +1096,11 @@
9201096 },
9211097 };
9221098
1099
+static struct ibm_arch_vec __prombss ibm_architecture_vec ____cacheline_aligned;
1100
+
9231101 /* Old method - ELF header with PT_NOTE sections only works on BE */
9241102 #ifdef __BIG_ENDIAN__
925
-static struct fake_elf {
1103
+static const struct fake_elf {
9261104 Elf32_Ehdr elfhdr;
9271105 Elf32_Phdr phdr[2];
9281106 struct chrpnote {
....@@ -955,7 +1133,7 @@
9551133 u32 ignore_me;
9561134 } rpadesc;
9571135 } rpanote;
958
-} fake_elf = {
1136
+} fake_elf __initconst = {
9591137 .elfhdr = {
9601138 .e_ident = { 0x7f, 'E', 'L', 'F',
9611139 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
....@@ -1020,7 +1198,7 @@
10201198 type[0] = 0;
10211199 prom_getprop(node, "device_type", type, sizeof(type));
10221200
1023
- if (strcmp(type, "cpu"))
1201
+ if (prom_strcmp(type, "cpu"))
10241202 continue;
10251203 /*
10261204 * There is an entry for each smt thread, each entry being
....@@ -1084,10 +1262,17 @@
10841262 switch (val) {
10851263 case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */
10861264 prom_debug("XIVE - either mode supported\n");
1087
- support->xive = true;
1265
+ support->xive = !prom_xive_disable;
10881266 break;
10891267 case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */
10901268 prom_debug("XIVE - exploitation mode supported\n");
1269
+ if (prom_xive_disable) {
1270
+ /*
1271
+ * If we __have__ to do XIVE, we're better off ignoring
1272
+ * the command line rather than not booting.
1273
+ */
1274
+ prom_printf("WARNING: Ignoring cmdline option xive=off\n");
1275
+ }
10911276 support->xive = true;
10921277 break;
10931278 case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
....@@ -1107,10 +1292,8 @@
11071292 prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
11081293 break;
11091294 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
- }
1295
+ if (val & OV5_FEAT(OV5_RADIX_GTSE))
1296
+ support->radix_gtse = !prom_radix_gtse_disable;
11141297 break;
11151298 case OV5_INDX(OV5_XIVE_SUPPORT): /* Interrupt mode */
11161299 prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT),
....@@ -1129,28 +1312,40 @@
11291312 };
11301313 int prop_len = prom_getproplen(prom.chosen,
11311314 "ibm,arch-vec-5-platform-support");
1315
+
1316
+ /*
1317
+ * First copy the architecture vec template
1318
+ *
1319
+ * use memcpy() instead of *vec = *vec_template so that GCC replaces it
1320
+ * by __memcpy() when KASAN is active
1321
+ */
1322
+ memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
1323
+ sizeof(ibm_architecture_vec));
1324
+
11321325 if (prop_len > 1) {
11331326 int i;
1134
- u8 vec[prop_len];
1327
+ u8 vec[8];
11351328 prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
11361329 prop_len);
1137
- prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
1138
- &vec, sizeof(vec));
1330
+ if (prop_len > sizeof(vec))
1331
+ prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n",
1332
+ prop_len);
1333
+ prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", &vec, sizeof(vec));
11391334 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);
1335
+ prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2, vec[i], vec[i + 1]);
1336
+ prom_parse_platform_support(vec[i], vec[i + 1], &supported);
11451337 }
11461338 }
11471339
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");
1340
+ if (supported.radix_mmu && IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
1341
+ /* Radix preferred - Check if GTSE is also supported */
1342
+ prom_debug("Asking for radix\n");
11521343 ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1153
- ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
1344
+ if (supported.radix_gtse)
1345
+ ibm_architecture_vec.vec5.radix_ext =
1346
+ OV5_FEAT(OV5_RADIX_GTSE);
1347
+ else
1348
+ prom_debug("Radix GTSE isn't supported\n");
11541349 } else if (supported.hash_mmu) {
11551350 /* Default to hash mmu (if we can) */
11561351 prom_debug("Asking for hash\n");
....@@ -1225,7 +1420,7 @@
12251420 }
12261421 #endif /* __BIG_ENDIAN__ */
12271422 }
1228
-#endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
1423
+#endif /* CONFIG_PPC_PSERIES */
12291424
12301425 /*
12311426 * Memory allocation strategy... our layout is normally:
....@@ -1266,18 +1461,18 @@
12661461 unsigned long addr = 0;
12671462
12681463 if (align)
1269
- base = _ALIGN_UP(base, align);
1464
+ base = ALIGN(base, align);
12701465 prom_debug("%s(%lx, %lx)\n", __func__, size, align);
12711466 if (ram_top == 0)
12721467 prom_panic("alloc_up() called with mem not initialized\n");
12731468
12741469 if (align)
1275
- base = _ALIGN_UP(alloc_bottom, align);
1470
+ base = ALIGN(alloc_bottom, align);
12761471 else
12771472 base = alloc_bottom;
12781473
12791474 for(; (base + size) <= alloc_top;
1280
- base = _ALIGN_UP(base + 0x100000, align)) {
1475
+ base = ALIGN(base + 0x100000, align)) {
12811476 prom_debug(" trying: 0x%lx\n\r", base);
12821477 addr = (unsigned long)prom_claim(base, size, 0);
12831478 if (addr != PROM_ERROR && addr != 0)
....@@ -1317,7 +1512,7 @@
13171512
13181513 if (highmem) {
13191514 /* Carve out storage for the TCE table. */
1320
- addr = _ALIGN_DOWN(alloc_top_high - size, align);
1515
+ addr = ALIGN_DOWN(alloc_top_high - size, align);
13211516 if (addr <= alloc_bottom)
13221517 return 0;
13231518 /* Will we bump into the RMO ? If yes, check out that we
....@@ -1335,9 +1530,9 @@
13351530 goto bail;
13361531 }
13371532
1338
- base = _ALIGN_DOWN(alloc_top - size, align);
1533
+ base = ALIGN_DOWN(alloc_top - size, align);
13391534 for (; base > alloc_bottom;
1340
- base = _ALIGN_DOWN(base - 0x100000, align)) {
1535
+ base = ALIGN_DOWN(base - 0x100000, align)) {
13411536 prom_debug(" trying: 0x%lx\n\r", base);
13421537 addr = (unsigned long)prom_claim(base, size, 0);
13431538 if (addr != PROM_ERROR && addr != 0)
....@@ -1403,8 +1598,8 @@
14031598 * have our terminator with "size" set to 0 since we are
14041599 * dumb and just copy this entire array to the boot params
14051600 */
1406
- base = _ALIGN_DOWN(base, PAGE_SIZE);
1407
- top = _ALIGN_UP(top, PAGE_SIZE);
1601
+ base = ALIGN_DOWN(base, PAGE_SIZE);
1602
+ top = ALIGN(top, PAGE_SIZE);
14081603 size = top - base;
14091604
14101605 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
....@@ -1421,9 +1616,6 @@
14211616 static void __init prom_init_mem(void)
14221617 {
14231618 phandle node;
1424
-#ifdef DEBUG_PROM
1425
- char *path;
1426
-#endif
14271619 char type[64];
14281620 unsigned int plen;
14291621 cell_t *p, *endp;
....@@ -1445,9 +1637,6 @@
14451637 prom_debug("root_size_cells: %x\n", rsc);
14461638
14471639 prom_debug("scanning memory:\n");
1448
-#ifdef DEBUG_PROM
1449
- path = prom_scratch;
1450
-#endif
14511640
14521641 for (node = 0; prom_next_node(&node); ) {
14531642 type[0] = 0;
....@@ -1460,7 +1649,7 @@
14601649 */
14611650 prom_getprop(node, "name", type, sizeof(type));
14621651 }
1463
- if (strcmp(type, "memory"))
1652
+ if (prom_strcmp(type, "memory"))
14641653 continue;
14651654
14661655 plen = prom_getprop(node, "reg", regbuf, sizeof(regbuf));
....@@ -1472,9 +1661,10 @@
14721661 endp = p + (plen / sizeof(cell_t));
14731662
14741663 #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);
1664
+ memset(prom_scratch, 0, sizeof(prom_scratch));
1665
+ call_prom("package-to-path", 3, 1, node, prom_scratch,
1666
+ sizeof(prom_scratch) - 1);
1667
+ prom_debug(" node %s :\n", prom_scratch);
14781668 #endif /* DEBUG_PROM */
14791669
14801670 while ((endp - p) >= (rac + rsc)) {
....@@ -1562,87 +1752,45 @@
15621752 }
15631753 }
15641754
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)
1755
+#ifdef CONFIG_PPC_SVM
1756
+static int prom_rtas_hcall(uint64_t args)
15761757 {
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];
1758
+ register uint64_t arg1 asm("r3") = H_RTAS;
1759
+ register uint64_t arg2 asm("r4") = args;
15831760
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");
1761
+ asm volatile("sc 1\n" : "=r" (arg1) :
1762
+ "r" (arg1),
1763
+ "r" (arg2) :);
1764
+ return arg1;
16431765 }
16441766
1645
-#endif /* CONFIG_PPC_POWERNV */
1767
+static struct rtas_args __prombss os_term_args;
1768
+
1769
+static void __init prom_rtas_os_term(char *str)
1770
+{
1771
+ phandle rtas_node;
1772
+ __be32 val;
1773
+ u32 token;
1774
+
1775
+ prom_debug("%s: start...\n", __func__);
1776
+ rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1777
+ prom_debug("rtas_node: %x\n", rtas_node);
1778
+ if (!PHANDLE_VALID(rtas_node))
1779
+ return;
1780
+
1781
+ val = 0;
1782
+ prom_getprop(rtas_node, "ibm,os-term", &val, sizeof(val));
1783
+ token = be32_to_cpu(val);
1784
+ prom_debug("ibm,os-term: %x\n", token);
1785
+ if (token == 0)
1786
+ prom_panic("Could not get token for ibm,os-term\n");
1787
+ os_term_args.token = cpu_to_be32(token);
1788
+ os_term_args.nargs = cpu_to_be32(1);
1789
+ os_term_args.nret = cpu_to_be32(1);
1790
+ os_term_args.args[0] = cpu_to_be32(__pa(str));
1791
+ prom_rtas_hcall((uint64_t)&os_term_args);
1792
+}
1793
+#endif /* CONFIG_PPC_SVM */
16461794
16471795 /*
16481796 * Allocate room for and instantiate RTAS
....@@ -1823,19 +1971,19 @@
18231971 prom_getprop(node, "device_type", type, sizeof(type));
18241972 prom_getprop(node, "model", model, sizeof(model));
18251973
1826
- if ((type[0] == 0) || (strstr(type, "pci") == NULL))
1974
+ if ((type[0] == 0) || (prom_strstr(type, "pci") == NULL))
18271975 continue;
18281976
18291977 /* Keep the old logic intact to avoid regression. */
18301978 if (compatible[0] != 0) {
1831
- if ((strstr(compatible, "python") == NULL) &&
1832
- (strstr(compatible, "Speedwagon") == NULL) &&
1833
- (strstr(compatible, "Winnipeg") == NULL))
1979
+ if ((prom_strstr(compatible, "python") == NULL) &&
1980
+ (prom_strstr(compatible, "Speedwagon") == NULL) &&
1981
+ (prom_strstr(compatible, "Winnipeg") == NULL))
18341982 continue;
18351983 } else if (model[0] != 0) {
1836
- if ((strstr(model, "ython") == NULL) &&
1837
- (strstr(model, "peedwagon") == NULL) &&
1838
- (strstr(model, "innipeg") == NULL))
1984
+ if ((prom_strstr(model, "ython") == NULL) &&
1985
+ (prom_strstr(model, "peedwagon") == NULL) &&
1986
+ (prom_strstr(model, "innipeg") == NULL))
18391987 continue;
18401988 }
18411989
....@@ -1863,10 +2011,10 @@
18632011 local_alloc_bottom = base;
18642012
18652013 /* It seems OF doesn't null-terminate the path :-( */
1866
- memset(path, 0, PROM_SCRATCH_SIZE);
2014
+ memset(path, 0, sizeof(prom_scratch));
18672015 /* Call OF to setup the TCE hardware */
18682016 if (call_prom("package-to-path", 3, 1, node,
1869
- path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
2017
+ path, sizeof(prom_scratch) - 1) == PROM_ERROR) {
18702018 prom_printf("package-to-path failed\n");
18712019 }
18722020
....@@ -1984,12 +2132,12 @@
19842132
19852133 type[0] = 0;
19862134 prom_getprop(node, "device_type", type, sizeof(type));
1987
- if (strcmp(type, "cpu") != 0)
2135
+ if (prom_strcmp(type, "cpu") != 0)
19882136 continue;
19892137
19902138 /* Skip non-configured cpus. */
19912139 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1992
- if (strcmp(type, "okay") != 0)
2140
+ if (prom_strcmp(type, "okay") != 0)
19932141 continue;
19942142
19952143 reg = cpu_to_be32(-1); /* make sparse happy */
....@@ -2065,9 +2213,9 @@
20652213 return;
20662214 version[sizeof(version) - 1] = 0;
20672215 /* XXX might need to add other versions here */
2068
- if (strcmp(version, "Open Firmware, 1.0.5") == 0)
2216
+ if (prom_strcmp(version, "Open Firmware, 1.0.5") == 0)
20692217 of_workarounds = OF_WA_CLAIM;
2070
- else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
2218
+ else if (prom_strncmp(version, "FirmWorks,3.", 12) == 0) {
20712219 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
20722220 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
20732221 } else
....@@ -2100,7 +2248,7 @@
21002248 call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
21012249 prom_printf("OF stdout device is: %s\n", of_stdout_device);
21022250 prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
2103
- path, strlen(path) + 1);
2251
+ path, prom_strlen(path) + 1);
21042252
21052253 /* instance-to-package fails on PA-Semi */
21062254 stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
....@@ -2110,7 +2258,7 @@
21102258 /* If it's a display, note it */
21112259 memset(type, 0, sizeof(type));
21122260 prom_getprop(stdout_node, "device_type", type, sizeof(type));
2113
- if (strcmp(type, "display") == 0)
2261
+ if (prom_strcmp(type, "display") == 0)
21142262 prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
21152263 }
21162264 }
....@@ -2131,29 +2279,25 @@
21312279 compat[len] = 0;
21322280 while (i < len) {
21332281 char *p = &compat[i];
2134
- int sl = strlen(p);
2282
+ int sl = prom_strlen(p);
21352283 if (sl == 0)
21362284 break;
2137
- if (strstr(p, "Power Macintosh") ||
2138
- strstr(p, "MacRISC"))
2285
+ if (prom_strstr(p, "Power Macintosh") ||
2286
+ prom_strstr(p, "MacRISC"))
21392287 return PLATFORM_POWERMAC;
21402288 #ifdef CONFIG_PPC64
21412289 /* We must make sure we don't detect the IBM Cell
21422290 * blades as pSeries due to some firmware issues,
21432291 * so we do it here.
21442292 */
2145
- if (strstr(p, "IBM,CBEA") ||
2146
- strstr(p, "IBM,CPBW-1.0"))
2293
+ if (prom_strstr(p, "IBM,CBEA") ||
2294
+ prom_strstr(p, "IBM,CPBW-1.0"))
21472295 return PLATFORM_GENERIC;
21482296 #endif /* CONFIG_PPC64 */
21492297 i += sl + 1;
21502298 }
21512299 }
21522300 #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
-
21572301 /* Try to figure out if it's an IBM pSeries or any other
21582302 * PAPR compliant platform. We assume it is if :
21592303 * - /device_type is "chrp" (please, do NOT use that for future
....@@ -2164,7 +2308,7 @@
21642308 compat, sizeof(compat)-1);
21652309 if (len <= 0)
21662310 return PLATFORM_GENERIC;
2167
- if (strcmp(compat, "chrp"))
2311
+ if (prom_strcmp(compat, "chrp"))
21682312 return PLATFORM_GENERIC;
21692313
21702314 /* Default to pSeries. We need to know if we are running LPAR */
....@@ -2202,7 +2346,7 @@
22022346 ihandle ih;
22032347 int i;
22042348
2205
- static unsigned char default_colors[] = {
2349
+ static const unsigned char default_colors[] __initconst = {
22062350 0x00, 0x00, 0x00,
22072351 0x00, 0x00, 0xaa,
22082352 0x00, 0xaa, 0x00,
....@@ -2226,19 +2370,19 @@
22262370 for (node = 0; prom_next_node(&node); ) {
22272371 memset(type, 0, sizeof(type));
22282372 prom_getprop(node, "device_type", type, sizeof(type));
2229
- if (strcmp(type, "display") != 0)
2373
+ if (prom_strcmp(type, "display") != 0)
22302374 continue;
22312375
22322376 /* It seems OF doesn't null-terminate the path :-( */
22332377 path = prom_scratch;
2234
- memset(path, 0, PROM_SCRATCH_SIZE);
2378
+ memset(path, 0, sizeof(prom_scratch));
22352379
22362380 /*
22372381 * leave some room at the end of the path for appending extra
22382382 * arguments
22392383 */
22402384 if (call_prom("package-to-path", 3, 1, node, path,
2241
- PROM_SCRATCH_SIZE-10) == PROM_ERROR)
2385
+ sizeof(prom_scratch) - 10) == PROM_ERROR)
22422386 continue;
22432387 prom_printf("found display : %s, opening... ", path);
22442388
....@@ -2274,13 +2418,23 @@
22742418 u32 width, height, pitch, addr;
22752419
22762420 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);
2421
+
2422
+ if (prom_getprop(node, "width", &width, 4) == PROM_ERROR)
2423
+ return;
2424
+
2425
+ if (prom_getprop(node, "height", &height, 4) == PROM_ERROR)
2426
+ return;
2427
+
2428
+ if (prom_getprop(node, "linebytes", &pitch, 4) == PROM_ERROR)
2429
+ return;
2430
+
2431
+ if (prom_getprop(node, "address", &addr, 4) == PROM_ERROR)
2432
+ return;
2433
+
22812434 prom_printf("W=%d H=%d LB=%d addr=0x%x\n",
22822435 width, height, pitch, addr);
22832436 btext_setup_display(width, height, 8, pitch, addr);
2437
+ btext_prepare_BAT();
22842438 }
22852439 #endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */
22862440 }
....@@ -2293,7 +2447,7 @@
22932447 {
22942448 void *ret;
22952449
2296
- *mem_start = _ALIGN(*mem_start, align);
2450
+ *mem_start = ALIGN(*mem_start, align);
22972451 while ((*mem_start + needed) > *mem_end) {
22982452 unsigned long room, chunk;
22992453
....@@ -2330,9 +2484,9 @@
23302484 s = os = (char *)dt_string_start;
23312485 s += 4;
23322486 while (s < (char *)dt_string_end) {
2333
- if (strcmp(s, str) == 0)
2487
+ if (prom_strcmp(s, str) == 0)
23342488 return s - os;
2335
- s += strlen(s) + 1;
2489
+ s += prom_strlen(s) + 1;
23362490 }
23372491 return 0;
23382492 }
....@@ -2365,7 +2519,7 @@
23652519 }
23662520
23672521 /* skip "name" */
2368
- if (strcmp(namep, "name") == 0) {
2522
+ if (prom_strcmp(namep, "name") == 0) {
23692523 *mem_start = (unsigned long)namep;
23702524 prev_name = "name";
23712525 continue;
....@@ -2377,7 +2531,7 @@
23772531 namep = sstart + soff;
23782532 } else {
23792533 /* Trim off some if we can */
2380
- *mem_start = (unsigned long)namep + strlen(namep) + 1;
2534
+ *mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
23812535 dt_string_end = *mem_start;
23822536 }
23832537 prev_name = namep;
....@@ -2398,7 +2552,7 @@
23982552 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
23992553 unsigned long soff;
24002554 unsigned char *valp;
2401
- static char pname[MAX_PROPERTY_NAME];
2555
+ static char pname[MAX_PROPERTY_NAME] __prombss;
24022556 int l, room, has_phandle = 0;
24032557
24042558 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
....@@ -2429,13 +2583,13 @@
24292583 *lp++ = *p;
24302584 }
24312585 *lp = 0;
2432
- *mem_start = _ALIGN((unsigned long)lp + 1, 4);
2586
+ *mem_start = ALIGN((unsigned long)lp + 1, 4);
24332587 }
24342588
24352589 /* get it again for debugging */
24362590 path = prom_scratch;
2437
- memset(path, 0, PROM_SCRATCH_SIZE);
2438
- call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
2591
+ memset(path, 0, sizeof(prom_scratch));
2592
+ call_prom("package-to-path", 3, 1, node, path, sizeof(prom_scratch) - 1);
24392593
24402594 /* get and store all properties */
24412595 prev_name = "";
....@@ -2446,7 +2600,7 @@
24462600 break;
24472601
24482602 /* skip "name" */
2449
- if (strcmp(pname, "name") == 0) {
2603
+ if (prom_strcmp(pname, "name") == 0) {
24502604 prev_name = "name";
24512605 continue;
24522606 }
....@@ -2475,20 +2629,17 @@
24752629 /* push property content */
24762630 valp = make_room(mem_start, mem_end, l, 4);
24772631 call_prom("getprop", 4, 1, node, pname, valp, l);
2478
- *mem_start = _ALIGN(*mem_start, 4);
2632
+ *mem_start = ALIGN(*mem_start, 4);
24792633
2480
- if (!strcmp(pname, "phandle"))
2634
+ if (!prom_strcmp(pname, "phandle"))
24812635 has_phandle = 1;
24822636 }
24832637
2484
- /* Add a "linux,phandle" property if no "phandle" property already
2485
- * existed (can happen with OPAL)
2486
- */
2638
+ /* Add a "phandle" property if none already exist */
24872639 if (!has_phandle) {
2488
- soff = dt_find_string("linux,phandle");
2640
+ soff = dt_find_string("phandle");
24892641 if (soff == 0)
2490
- prom_printf("WARNING: Can't find string index for"
2491
- " <linux-phandle> node %s\n", path);
2642
+ prom_printf("WARNING: Can't find string index for <phandle> node %s\n", path);
24922643 else {
24932644 dt_push_token(OF_DT_PROP, mem_start, mem_end);
24942645 dt_push_token(4, mem_start, mem_end);
....@@ -2537,7 +2688,7 @@
25372688 prom_panic ("couldn't get device tree root\n");
25382689
25392690 /* Build header and make room for mem rsv map */
2540
- mem_start = _ALIGN(mem_start, 4);
2691
+ mem_start = ALIGN(mem_start, 4);
25412692 hdr = make_room(&mem_start, &mem_end,
25422693 sizeof(struct boot_param_header), 4);
25432694 dt_header_start = (unsigned long)hdr;
....@@ -2548,10 +2699,10 @@
25482699 dt_string_start = mem_start;
25492700 mem_start += 4; /* hole */
25502701
2551
- /* Add "linux,phandle" in there, we'll need it */
2702
+ /* Add "phandle" in there, we'll need it */
25522703 namep = make_room(&mem_start, &mem_end, 16, 1);
2553
- strcpy(namep, "linux,phandle");
2554
- mem_start = (unsigned long)namep + strlen(namep) + 1;
2704
+ prom_strcpy(namep, "phandle");
2705
+ mem_start = (unsigned long)namep + prom_strlen(namep) + 1;
25552706
25562707 /* Build string array */
25572708 prom_printf("Building dt strings...\n");
....@@ -2873,7 +3024,7 @@
28733024 rv = prom_getprop(node, "model", prop, sizeof(prop));
28743025 if (rv == PROM_ERROR)
28753026 return;
2876
- if (strcmp(prop, "EFIKA5K2"))
3027
+ if (prom_strcmp(prop, "EFIKA5K2"))
28773028 return;
28783029
28793030 prom_printf("Applying EFIKA device tree fixups\n");
....@@ -2881,13 +3032,13 @@
28813032 /* Claiming to be 'chrp' is death */
28823033 node = call_prom("finddevice", 1, 1, ADDR("/"));
28833034 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2884
- if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
3035
+ if (rv != PROM_ERROR && (prom_strcmp(prop, "chrp") == 0))
28853036 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
28863037
28873038 /* CODEGEN,description is exposed in /proc/cpuinfo so
28883039 fix that too */
28893040 rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2890
- if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
3041
+ if (rv != PROM_ERROR && (prom_strstr(prop, "CHRP")))
28913042 prom_setprop(node, "/", "CODEGEN,description",
28923043 "Efika 5200B PowerPC System",
28933044 sizeof("Efika 5200B PowerPC System"));
....@@ -3106,6 +3257,59 @@
31063257 #endif
31073258 #endif
31083259
3260
+#ifdef CONFIG_PPC_SVM
3261
+/*
3262
+ * Perform the Enter Secure Mode ultracall.
3263
+ */
3264
+static int enter_secure_mode(unsigned long kbase, unsigned long fdt)
3265
+{
3266
+ register unsigned long r3 asm("r3") = UV_ESM;
3267
+ register unsigned long r4 asm("r4") = kbase;
3268
+ register unsigned long r5 asm("r5") = fdt;
3269
+
3270
+ asm volatile("sc 2" : "+r"(r3) : "r"(r4), "r"(r5));
3271
+
3272
+ return r3;
3273
+}
3274
+
3275
+/*
3276
+ * Call the Ultravisor to transfer us to secure memory if we have an ESM blob.
3277
+ */
3278
+static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3279
+{
3280
+ int ret;
3281
+
3282
+ if (!prom_svm_enable)
3283
+ return;
3284
+
3285
+ /* Switch to secure mode. */
3286
+ prom_printf("Switching to secure mode.\n");
3287
+
3288
+ /*
3289
+ * The ultravisor will do an integrity check of the kernel image but we
3290
+ * relocated it so the check will fail. Restore the original image by
3291
+ * relocating it back to the kernel virtual base address.
3292
+ */
3293
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
3294
+ relocate(KERNELBASE);
3295
+
3296
+ ret = enter_secure_mode(kbase, fdt);
3297
+
3298
+ /* Relocate the kernel again. */
3299
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
3300
+ relocate(kbase);
3301
+
3302
+ if (ret != U_SUCCESS) {
3303
+ prom_printf("Returned %d from switching to secure mode.\n", ret);
3304
+ prom_rtas_os_term("Switch to secure mode failed.\n");
3305
+ }
3306
+}
3307
+#else
3308
+static void __init setup_secure_guest(unsigned long kbase, unsigned long fdt)
3309
+{
3310
+}
3311
+#endif /* CONFIG_PPC_SVM */
3312
+
31093313 /*
31103314 * We enter here early on, when the Open Firmware prom is still
31113315 * handling exceptions and the MMU hash table for us.
....@@ -3172,7 +3376,7 @@
31723376 */
31733377 early_cmdline_parse();
31743378
3175
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
3379
+#ifdef CONFIG_PPC_PSERIES
31763380 /*
31773381 * On pSeries, inform the firmware about our capabilities
31783382 */
....@@ -3216,14 +3420,8 @@
32163420 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
32173421 * have a usable RTAS implementation.
32183422 */
3219
- if (of_platform != PLATFORM_POWERMAC &&
3220
- of_platform != PLATFORM_OPAL)
3423
+ if (of_platform != PLATFORM_POWERMAC)
32213424 prom_instantiate_rtas();
3222
-
3223
-#ifdef CONFIG_PPC_POWERNV
3224
- if (of_platform == PLATFORM_OPAL)
3225
- prom_instantiate_opal();
3226
-#endif /* CONFIG_PPC_POWERNV */
32273425
32283426 #ifdef CONFIG_PPC64
32293427 /* instantiate sml */
....@@ -3237,8 +3435,7 @@
32373435 *
32383436 * (This must be done after instanciating RTAS)
32393437 */
3240
- if (of_platform != PLATFORM_POWERMAC &&
3241
- of_platform != PLATFORM_OPAL)
3438
+ if (of_platform != PLATFORM_POWERMAC)
32423439 prom_hold_cpus();
32433440
32443441 /*
....@@ -3282,11 +3479,9 @@
32823479 /*
32833480 * in case stdin is USB and still active on IBM machines...
32843481 * 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.
3482
+ * closed stdin already (in particular the powerbook 101).
32873483 */
3288
- if (of_platform != PLATFORM_POWERMAC &&
3289
- of_platform != PLATFORM_OPAL)
3484
+ if (of_platform != PLATFORM_POWERMAC)
32903485 prom_close_stdin();
32913486
32923487 /*
....@@ -3303,11 +3498,8 @@
33033498 */
33043499 hdr = dt_header_start;
33053500
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
- }
3501
+ prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase);
3502
+ prom_debug("->dt_header_start=0x%lx\n", hdr);
33113503
33123504 #ifdef CONFIG_PPC32
33133505 reloc_got2(-offset);
....@@ -3315,13 +3507,10 @@
33153507 unreloc_toc();
33163508 #endif
33173509
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
3510
+ /* Move to secure memory if we're supposed to be secure guests. */
3511
+ setup_secure_guest(kbase, hdr);
3512
+
33233513 __start(hdr, kbase, 0, 0, 0, 0, 0);
3324
-#endif
33253514
33263515 return 0;
33273516 }