1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Derived from Xen 4.19's $xen/arch/arm/setup.c.
4 *
5 * bookkeeping routines.
6 *
7 * Tim Deegan <tim@xen.org>
8 * Copyright (c) 2011 Citrix Systems.
9 * Copyright (c) 2024 Raptor Engineering LLC
10 */
11
12 #include <xen/acpi.h>
13 #include <xen/bootinfo.h>
14 #include <xen/bug.h>
15 #include <xen/device_tree.h>
16 #include <xen/init.h>
17 #include <xen/libfdt/libfdt-xen.h>
18 #include <xen/mm.h>
19
20 #include <asm/setup.h>
21
22 struct bootinfo __initdata bootinfo = BOOTINFO_INIT;
23
boot_module_kind_as_string(boot_module_kind kind)24 const char * __init boot_module_kind_as_string(boot_module_kind kind)
25 {
26 switch ( kind )
27 {
28 case BOOTMOD_XEN: return "Xen";
29 case BOOTMOD_FDT: return "Device Tree";
30 case BOOTMOD_KERNEL: return "Kernel";
31 case BOOTMOD_RAMDISK: return "Ramdisk";
32 case BOOTMOD_XSM_POLICY: return "XSM Policy";
33 case BOOTMOD_GUEST_DTB: return "DTB";
34 case BOOTMOD_MICROCODE: return "Microcode";
35 case BOOTMOD_UNKNOWN: return "Unknown";
36 default: BUG();
37 }
38 }
39
dt_unreserved_regions(paddr_t s,paddr_t e,void (* cb)(paddr_t ps,paddr_t pe),unsigned int first)40 static void __init dt_unreserved_regions(paddr_t s, paddr_t e,
41 void (*cb)(paddr_t ps, paddr_t pe),
42 unsigned int first)
43 {
44 const struct membanks *reserved_mem = bootinfo_get_reserved_mem();
45 #ifdef CONFIG_STATIC_SHM
46 const struct membanks *shmem = bootinfo_get_shmem();
47 unsigned int offset;
48 #endif
49 unsigned int i;
50
51 /*
52 * i is the current boot_module we are evaluating across all possible
53 * kinds.
54 */
55 for ( i = first; i < reserved_mem->nr_banks; i++ )
56 {
57 paddr_t r_s = reserved_mem->bank[i].start;
58 paddr_t r_e = r_s + reserved_mem->bank[i].size;
59
60 if ( s < r_e && r_s < e )
61 {
62 dt_unreserved_regions(r_e, e, cb, i + 1);
63 dt_unreserved_regions(s, r_s, cb, i + 1);
64 return;
65 }
66 }
67
68 #ifdef CONFIG_STATIC_SHM
69 /*
70 * When retrieving the corresponding shared memory addresses
71 * below, we need to index the shmem->bank starting from 0, hence
72 * we need to use i - reserved_mem->nr_banks.
73 */
74 offset = reserved_mem->nr_banks;
75 for ( ; i - offset < shmem->nr_banks; i++ )
76 {
77 paddr_t r_s, r_e;
78
79 r_s = shmem->bank[i - offset].start;
80
81 /* Shared memory banks can contain INVALID_PADDR as start */
82 if ( INVALID_PADDR == r_s )
83 continue;
84
85 r_e = r_s + shmem->bank[i - offset].size;
86
87 if ( s < r_e && r_s < e )
88 {
89 dt_unreserved_regions(r_e, e, cb, i + 1);
90 dt_unreserved_regions(s, r_s, cb, i + 1);
91 return;
92 }
93 }
94 #endif
95
96 cb(s, e);
97 }
98
99 /*
100 * TODO: '*_end' could be 0 if the bank/region is at the end of the physical
101 * address space. This is for now not handled as it requires more rework.
102 */
meminfo_overlap_check(const struct membanks * mem,paddr_t region_start,paddr_t region_size,bool allow_memreserve_overlap)103 static bool __init meminfo_overlap_check(const struct membanks *mem,
104 paddr_t region_start,
105 paddr_t region_size,
106 bool allow_memreserve_overlap)
107 {
108 paddr_t bank_start = INVALID_PADDR, bank_end = 0;
109 paddr_t region_end = region_start + region_size;
110 unsigned int i, bank_num = mem->nr_banks;
111
112 for ( i = 0; i < bank_num; i++ )
113 {
114 bank_start = mem->bank[i].start;
115 bank_end = bank_start + mem->bank[i].size;
116
117 if ( INVALID_PADDR == bank_start || region_end <= bank_start ||
118 region_start >= bank_end )
119 continue;
120
121 /*
122 * If allow_memreserve_overlap is set, this check allows a region to be
123 * included in a MEMBANK_FDT_RESVMEM bank, but struct membanks *mem of
124 * type STATIC_SHARED_MEMORY don't set the bank[].type field because
125 * that is declared in a union with a field that is instead used,
126 * in any case this restriction is ok since STATIC_SHARED_MEMORY banks
127 * are not meant to clash with FDT /memreserve/ ranges.
128 */
129 if ( allow_memreserve_overlap && mem->type != STATIC_SHARED_MEMORY &&
130 region_start >= bank_start && region_end <= bank_end &&
131 mem->bank[i].type == MEMBANK_FDT_RESVMEM )
132 continue;
133
134 printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with bank[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n",
135 region_start, region_end, i, bank_start, bank_end);
136 return true;
137 }
138
139 return false;
140 }
141
142 /*
143 * TODO: '*_end' could be 0 if the module/region is at the end of the physical
144 * address space. This is for now not handled as it requires more rework.
145 */
boot_modules_overlap_check(struct boot_modules * boot_modules,paddr_t region_start,paddr_t region_size)146 static bool __init boot_modules_overlap_check(struct boot_modules *boot_modules,
147 paddr_t region_start,
148 paddr_t region_size)
149 {
150 paddr_t mod_start = INVALID_PADDR, mod_end = 0;
151 paddr_t region_end = region_start + region_size;
152 unsigned int i, mod_num = boot_modules->nr_mods;
153
154 for ( i = 0; i < mod_num; i++ )
155 {
156 mod_start = boot_modules->module[i].start;
157 mod_end = mod_start + boot_modules->module[i].size;
158
159 if ( region_end <= mod_start || region_start >= mod_end )
160 continue;
161 else
162 {
163 printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with mod[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n",
164 region_start, region_end, i, mod_start, mod_end);
165 return true;
166 }
167 }
168
169 return false;
170 }
171
fw_unreserved_regions(paddr_t s,paddr_t e,void (* cb)(paddr_t ps,paddr_t pe),unsigned int first)172 void __init fw_unreserved_regions(paddr_t s, paddr_t e,
173 void (*cb)(paddr_t ps, paddr_t pe),
174 unsigned int first)
175 {
176 if ( acpi_disabled )
177 dt_unreserved_regions(s, e, cb, first);
178 else
179 cb(s, e);
180 }
181
182 /*
183 * Given an input physical address range, check if this range is overlapping
184 * with the existing reserved memory regions defined in bootinfo.
185 * Return true if the input physical address range is overlapping with any
186 * existing reserved memory regions, otherwise false.
187 */
check_reserved_regions_overlap(paddr_t region_start,paddr_t region_size,bool allow_memreserve_overlap)188 bool __init check_reserved_regions_overlap(paddr_t region_start,
189 paddr_t region_size,
190 bool allow_memreserve_overlap)
191 {
192 const struct membanks *mem_banks[] = {
193 bootinfo_get_reserved_mem(),
194 #ifdef CONFIG_ACPI
195 bootinfo_get_acpi(),
196 #endif
197 #ifdef CONFIG_STATIC_SHM
198 bootinfo_get_shmem(),
199 #endif
200 };
201 unsigned int i;
202
203 /*
204 * Check if input region is overlapping with reserved memory banks or
205 * ACPI EfiACPIReclaimMemory (when ACPI feature is enabled) or static
206 * shared memory banks (when static shared memory feature is enabled)
207 */
208 for ( i = 0; i < ARRAY_SIZE(mem_banks); i++ )
209 if ( meminfo_overlap_check(mem_banks[i], region_start, region_size,
210 allow_memreserve_overlap) )
211 return true;
212
213 /* Check if input region is overlapping with boot_modules */
214 if ( boot_modules_overlap_check(&bootinfo.modules,
215 region_start, region_size) )
216 return true;
217
218 return false;
219 }
220
add_boot_module(boot_module_kind kind,paddr_t start,paddr_t size,bool domU)221 struct boot_module __init *add_boot_module(boot_module_kind kind,
222 paddr_t start, paddr_t size,
223 bool domU)
224 {
225 struct boot_modules *mods = &bootinfo.modules;
226 struct boot_module *mod;
227 unsigned int i;
228
229 if ( mods->nr_mods == MAX_MODULES )
230 {
231 printk("Ignoring %s boot module at %"PRIpaddr"-%"PRIpaddr" (too many)\n",
232 boot_module_kind_as_string(kind), start, start + size);
233 return NULL;
234 }
235
236 /*
237 * u-boot adds boot module such as ramdisk to the /memreserve/, since these
238 * ranges are saved in reserved_mem at this stage, allow an eventual exact
239 * match with MEMBANK_FDT_RESVMEM banks.
240 */
241 if ( check_reserved_regions_overlap(start, size, true) )
242 return NULL;
243
244 for ( i = 0 ; i < mods->nr_mods ; i++ )
245 {
246 mod = &mods->module[i];
247 if ( mod->kind == kind && mod->start == start )
248 {
249 if ( !domU )
250 mod->domU = false;
251 return mod;
252 }
253 }
254
255 mod = &mods->module[mods->nr_mods++];
256 mod->kind = kind;
257 mod->start = start;
258 mod->size = size;
259 mod->domU = domU;
260
261 return mod;
262 }
263
264 /*
265 * boot_module_find_by_kind can only be used to return Xen modules (e.g
266 * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest
267 * modules.
268 */
boot_module_find_by_kind(boot_module_kind kind)269 struct boot_module * __init boot_module_find_by_kind(boot_module_kind kind)
270 {
271 struct boot_modules *mods = &bootinfo.modules;
272 struct boot_module *mod;
273 int i;
274 for (i = 0 ; i < mods->nr_mods ; i++ )
275 {
276 mod = &mods->module[i];
277 if ( mod->kind == kind && !mod->domU )
278 return mod;
279 }
280 return NULL;
281 }
282
add_boot_cmdline(const char * name,const char * cmdline,boot_module_kind kind,paddr_t start,bool domU)283 void __init add_boot_cmdline(const char *name, const char *cmdline,
284 boot_module_kind kind, paddr_t start, bool domU)
285 {
286 struct bootcmdlines *cmds = &bootinfo.cmdlines;
287 struct bootcmdline *cmd;
288
289 if ( cmds->nr_mods == MAX_MODULES )
290 {
291 printk("Ignoring %s cmdline (too many)\n", name);
292 return;
293 }
294
295 cmd = &cmds->cmdline[cmds->nr_mods++];
296 cmd->kind = kind;
297 cmd->domU = domU;
298 cmd->start = start;
299
300 ASSERT(strlen(name) <= DT_MAX_NAME);
301 safe_strcpy(cmd->dt_name, name);
302
303 if ( strlen(cmdline) > BOOTMOD_MAX_CMDLINE )
304 panic("module %s command line too long\n", name);
305 safe_strcpy(cmd->cmdline, cmdline);
306 }
307
308 /*
309 * boot_cmdline_find_by_kind can only be used to return Xen modules (e.g
310 * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest
311 * modules.
312 */
boot_cmdline_find_by_kind(boot_module_kind kind)313 struct bootcmdline * __init boot_cmdline_find_by_kind(boot_module_kind kind)
314 {
315 struct bootcmdlines *cmds = &bootinfo.cmdlines;
316 struct bootcmdline *cmd;
317 int i;
318
319 for ( i = 0 ; i < cmds->nr_mods ; i++ )
320 {
321 cmd = &cmds->cmdline[i];
322 if ( cmd->kind == kind && !cmd->domU )
323 return cmd;
324 }
325 return NULL;
326 }
327
boot_cmdline_find_by_name(const char * name)328 struct bootcmdline * __init boot_cmdline_find_by_name(const char *name)
329 {
330 struct bootcmdlines *mods = &bootinfo.cmdlines;
331 struct bootcmdline *mod;
332 unsigned int i;
333
334 for (i = 0 ; i < mods->nr_mods ; i++ )
335 {
336 mod = &mods->cmdline[i];
337 if ( strcmp(mod->dt_name, name) == 0 )
338 return mod;
339 }
340 return NULL;
341 }
342
boot_module_find_by_addr_and_kind(boot_module_kind kind,paddr_t start)343 struct boot_module * __init boot_module_find_by_addr_and_kind(
344 boot_module_kind kind, paddr_t start)
345 {
346 struct boot_modules *mods = &bootinfo.modules;
347 struct boot_module *mod;
348 unsigned int i;
349
350 for (i = 0 ; i < mods->nr_mods ; i++ )
351 {
352 mod = &mods->module[i];
353 if ( mod->kind == kind && mod->start == start )
354 return mod;
355 }
356 return NULL;
357 }
358
359 /*
360 * Return the end of the non-module region starting at s. In other
361 * words return s the start of the next modules after s.
362 *
363 * On input *end is the end of the region which should be considered
364 * and it is updated to reflect the end of the module, clipped to the
365 * end of the region if it would run over.
366 */
next_module(paddr_t s,paddr_t * end)367 static paddr_t __init next_module(paddr_t s, paddr_t *end)
368 {
369 struct boot_modules *mi = &bootinfo.modules;
370 paddr_t lowest = ~(paddr_t)0;
371 int i;
372
373 for ( i = 0; i < mi->nr_mods; i++ )
374 {
375 paddr_t mod_s = mi->module[i].start;
376 paddr_t mod_e = mod_s + mi->module[i].size;
377
378 if ( !mi->module[i].size )
379 continue;
380
381 if ( mod_s < s )
382 continue;
383 if ( mod_s > lowest )
384 continue;
385 if ( mod_s > *end )
386 continue;
387 lowest = mod_s;
388 *end = min(*end, mod_e);
389 }
390 return lowest;
391 }
392
393 /*
394 * Populate the boot allocator.
395 * If a static heap was not provided by the admin, all the RAM but the
396 * following regions will be added:
397 * - Modules (e.g., Xen, Kernel)
398 * - Reserved regions
399 * - Xenheap (CONFIG_SEPARATE_XENHEAP only)
400 * If a static heap was provided by the admin, populate the boot
401 * allocator with the corresponding regions only, but with Xenheap excluded
402 * on CONFIG_SEPARATE_XENHEAP.
403 */
populate_boot_allocator(void)404 void __init populate_boot_allocator(void)
405 {
406 unsigned int i;
407 const struct membanks *banks = bootinfo_get_mem();
408 const struct membanks *reserved_mem = bootinfo_get_reserved_mem();
409 paddr_t s, e;
410
411 if ( using_static_heap )
412 {
413 for ( i = 0 ; i < reserved_mem->nr_banks; i++ )
414 {
415 if ( reserved_mem->bank[i].type != MEMBANK_STATIC_HEAP )
416 continue;
417
418 s = reserved_mem->bank[i].start;
419 e = s + reserved_mem->bank[i].size;
420 #ifdef CONFIG_SEPARATE_XENHEAP
421 /* Avoid the xenheap, note that the xenheap cannot across a bank */
422 if ( s <= mfn_to_maddr(directmap_mfn_start) &&
423 e >= mfn_to_maddr(directmap_mfn_end) )
424 {
425 init_boot_pages(s, mfn_to_maddr(directmap_mfn_start));
426 init_boot_pages(mfn_to_maddr(directmap_mfn_end), e);
427 }
428 else
429 #endif
430 init_boot_pages(s, e);
431 }
432
433 return;
434 }
435
436 for ( i = 0; i < banks->nr_banks; i++ )
437 {
438 const struct membank *bank = &banks->bank[i];
439 paddr_t bank_end = bank->start + bank->size;
440
441 s = bank->start;
442 while ( s < bank_end )
443 {
444 paddr_t n = bank_end;
445
446 e = next_module(s, &n);
447
448 if ( e == ~(paddr_t)0 )
449 e = n = bank_end;
450
451 /*
452 * Module in a RAM bank other than the one which we are
453 * not dealing with here.
454 */
455 if ( e > bank_end )
456 e = bank_end;
457
458 #ifdef CONFIG_SEPARATE_XENHEAP
459 /* Avoid the xenheap */
460 if ( s < mfn_to_maddr(directmap_mfn_end) &&
461 mfn_to_maddr(directmap_mfn_start) < e )
462 {
463 e = mfn_to_maddr(directmap_mfn_start);
464 n = mfn_to_maddr(directmap_mfn_end);
465 }
466 #endif
467
468 fw_unreserved_regions(s, e, init_boot_pages, 0);
469 s = n;
470 }
471 }
472 }
473
474 /*
475 * Local variables:
476 * mode: C
477 * c-file-style: "BSD"
478 * c-basic-offset: 4
479 * indent-tabs-mode: nil
480 * End:
481 */
482