hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/powerpc/boot/main.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) Paul Mackerras 1997.
34 *
45 * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117 #include <stdarg.h>
128 #include <stddef.h>
....@@ -108,7 +104,7 @@
108104 {
109105 /* If we have an image attached to us, it overrides anything
110106 * supplied by the loader. */
111
- if (_initrd_end > _initrd_start) {
107
+ if (&_initrd_end > &_initrd_start) {
112108 printf("Attached initrd image at 0x%p-0x%p\n\r",
113109 _initrd_start, _initrd_end);
114110 initrd_addr = (unsigned long)_initrd_start;
....@@ -149,6 +145,46 @@
149145
150146 return (struct addr_range){(void *)initrd_addr, initrd_size};
151147 }
148
+
149
+#ifdef __powerpc64__
150
+static void prep_esm_blob(struct addr_range vmlinux, void *chosen)
151
+{
152
+ unsigned long esm_blob_addr, esm_blob_size;
153
+
154
+ /* Do we have an ESM (Enter Secure Mode) blob? */
155
+ if (&_esm_blob_end <= &_esm_blob_start)
156
+ return;
157
+
158
+ printf("Attached ESM blob at 0x%p-0x%p\n\r",
159
+ _esm_blob_start, _esm_blob_end);
160
+ esm_blob_addr = (unsigned long)_esm_blob_start;
161
+ esm_blob_size = _esm_blob_end - _esm_blob_start;
162
+
163
+ /*
164
+ * If the ESM blob is too low it will be clobbered when the
165
+ * kernel relocates to its final location. In this case,
166
+ * allocate a safer place and move it.
167
+ */
168
+ if (esm_blob_addr < vmlinux.size) {
169
+ void *old_addr = (void *)esm_blob_addr;
170
+
171
+ printf("Allocating 0x%lx bytes for esm_blob ...\n\r",
172
+ esm_blob_size);
173
+ esm_blob_addr = (unsigned long)malloc(esm_blob_size);
174
+ if (!esm_blob_addr)
175
+ fatal("Can't allocate memory for ESM blob !\n\r");
176
+ printf("Relocating ESM blob 0x%lx <- 0x%p (0x%lx bytes)\n\r",
177
+ esm_blob_addr, old_addr, esm_blob_size);
178
+ memmove((void *)esm_blob_addr, old_addr, esm_blob_size);
179
+ }
180
+
181
+ /* Tell the kernel ESM blob address via device tree. */
182
+ setprop_val(chosen, "linux,esm-blob-start", (u32)(esm_blob_addr));
183
+ setprop_val(chosen, "linux,esm-blob-end", (u32)(esm_blob_addr + esm_blob_size));
184
+}
185
+#else
186
+static inline void prep_esm_blob(struct addr_range vmlinux, void *chosen) { }
187
+#endif
152188
153189 /* A buffer that may be edited by tools operating on a zImage binary so as to
154190 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
....@@ -218,6 +254,7 @@
218254 vmlinux = prep_kernel();
219255 initrd = prep_initrd(vmlinux, chosen,
220256 loader_info.initrd_addr, loader_info.initrd_size);
257
+ prep_esm_blob(vmlinux, chosen);
221258 prep_cmdline(chosen);
222259
223260 printf("Finalizing device tree...");