1 /*
2 * Copyright 2019 The Hafnium Authors.
3 *
4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
7 */
8
9 #include "hf/cpio.h"
10 #include "hf/dlog.h"
11 #include "hf/fdt_handler.h"
12 #include "hf/fdt_patch.h"
13 #include "hf/plat/boot_flow.h"
14 #include "hf/std.h"
15
16 /* Set by arch-specific boot-time hook. */
17 uintreg_t plat_boot_flow_fdt_addr;
18
19 /**
20 * Returns the physical address of board FDT. This was passed to Hafnium in the
21 * first kernel arg by the boot loader.
22 */
plat_boot_flow_get_fdt_addr(void)23 paddr_t plat_boot_flow_get_fdt_addr(void)
24 {
25 return pa_init((uintpaddr_t)plat_boot_flow_fdt_addr);
26 }
27
28 /**
29 * When handing over to the primary, give it the same FDT address that was given
30 * to Hafnium. The FDT may have been modified during Hafnium init.
31 */
plat_boot_flow_get_kernel_arg(void)32 uintreg_t plat_boot_flow_get_kernel_arg(void)
33 {
34 return plat_boot_flow_fdt_addr;
35 }
36
37 /**
38 * Load initrd range from the board FDT.
39 */
plat_boot_flow_get_initrd_range(const struct fdt * fdt,paddr_t * begin,paddr_t * end)40 bool plat_boot_flow_get_initrd_range(const struct fdt *fdt, paddr_t *begin,
41 paddr_t *end)
42 {
43 return fdt_find_initrd(fdt, begin, end);
44 }
45
plat_boot_flow_update(struct mm_stage1_locked stage1_locked,const struct manifest * manifest,struct boot_params_update * update,struct memiter * cpio,struct mpool * ppool)46 bool plat_boot_flow_update(struct mm_stage1_locked stage1_locked,
47 const struct manifest *manifest,
48 struct boot_params_update *update,
49 struct memiter *cpio, struct mpool *ppool)
50 {
51 struct memiter primary_initrd;
52 const struct string *filename =
53 &manifest->vm[HF_PRIMARY_VM_INDEX].primary.ramdisk_filename;
54
55 if (string_is_empty(filename)) {
56 memiter_init(&primary_initrd, NULL, 0);
57 } else if (!cpio_get_file(cpio, filename, &primary_initrd)) {
58 dlog_error("Unable to find primary initrd \"%s\".\n",
59 string_data(filename));
60 return false;
61 }
62
63 update->initrd_begin = pa_from_va(va_from_ptr(primary_initrd.next));
64 update->initrd_end = pa_from_va(va_from_ptr(primary_initrd.limit));
65
66 return fdt_patch(stage1_locked, plat_boot_flow_get_fdt_addr(), update,
67 ppool);
68 }
69