blob: d6c5a4a8a00afe5a31a9d41677983dbba189fc20 [file] [log] [blame]
Andrew Scullb401ba32018-11-09 10:30:54 +00001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scullb401ba32018-11-09 10:30:54 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "hf/boot_params.h"
18#include "hf/dlog.h"
19#include "hf/fdt_handler.h"
20#include "hf/layout.h"
21
22/**
23 * Default implementation assumes the FDT has been linked into the image.
24 *
25 * This can be overridden e.g. to provide a fixed address or an address passed
26 * by the loader.
27 */
28#pragma weak plat_get_fdt_addr
29paddr_t plat_get_fdt_addr(void)
30{
31 return layout_fdt_begin();
32}
33
34/**
35 * Default implementation assumes the initrd has been linked into the image.
36 *
37 * This can be overridden e.g. to provide a fixed address or an address passed
38 * by the loader.
39 */
40#pragma weak plat_get_initrd_range
Andrew Scull3c0a90a2019-07-01 11:55:53 +010041void plat_get_initrd_range(struct mm_stage1_locked stage1_locked,
42 paddr_t *begin, paddr_t *end, struct mpool *ppool)
Andrew Scullb401ba32018-11-09 10:30:54 +000043{
Andrew Scull3c0a90a2019-07-01 11:55:53 +010044 (void)stage1_locked;
Wedson Almeida Filho22d5eaa2018-12-16 00:38:49 +000045 (void)ppool;
46
Andrew Scullb401ba32018-11-09 10:30:54 +000047 *begin = layout_initrd_begin();
48 *end = layout_initrd_end();
49}
50
51/**
52 * Default implementation assumes the FDT address is passed to the kernel.
53 *
54 * TODO: make this part of the VM configuration as secondary VMs will also need
55 * to take arguments.
56 */
57#pragma weak plat_get_kernel_arg
58uintreg_t plat_get_kernel_arg(void)
59{
60 return (uintreg_t)pa_addr(plat_get_fdt_addr());
61}
62
63/**
64 * Default implementation extracts the boot parameters from the FDT but the
65 * initrd is provided separately.
66 */
67#pragma weak plat_get_boot_params
Andrew Scull3c0a90a2019-07-01 11:55:53 +010068bool plat_get_boot_params(struct mm_stage1_locked stage1_locked,
69 struct boot_params *p, struct mpool *ppool)
Andrew Scullb401ba32018-11-09 10:30:54 +000070{
71 struct fdt_header *fdt;
72 struct fdt_node n;
73 bool ret = false;
74
Andrew Scull3c0a90a2019-07-01 11:55:53 +010075 plat_get_initrd_range(stage1_locked, &p->initrd_begin, &p->initrd_end,
76 ppool);
Andrew Scullb401ba32018-11-09 10:30:54 +000077 p->kernel_arg = plat_get_kernel_arg();
78
79 /* Get the memory map from the FDT. */
Andrew Scull3c0a90a2019-07-01 11:55:53 +010080 fdt = fdt_map(stage1_locked, plat_get_fdt_addr(), &n, ppool);
Andrew Scullb401ba32018-11-09 10:30:54 +000081 if (!fdt) {
82 return false;
83 }
84
85 if (!fdt_find_child(&n, "")) {
86 dlog("Unable to find FDT root node.\n");
87 goto out_unmap_fdt;
88 }
89
Andrew Scullbb3ab6c2018-11-26 20:38:49 +000090 fdt_find_cpus(&n, p->cpu_ids, &p->cpu_count);
91
Andrew Scullb401ba32018-11-09 10:30:54 +000092 p->mem_ranges_count = 0;
93 fdt_find_memory_ranges(&n, p);
94
95 ret = true;
96
97out_unmap_fdt:
Andrew Scull3c0a90a2019-07-01 11:55:53 +010098 if (!fdt_unmap(stage1_locked, fdt, ppool)) {
Andrew Scullb401ba32018-11-09 10:30:54 +000099 dlog("Unable to unmap fdt.");
100 return false;
101 }
102
103 return ret;
104}
105
106/**
107 * Default implementation updates the FDT which is the argument passed to the
108 * primary VM's kernel.
109 *
110 * TODO: in future, each VM will declare whether it expects an argument passed
111 * and that will be static data e.g. it will provide its own FDT so there will
112 * be no FDT modification. This is done because each VM has a very different
113 * view of the system and we don't want to force VMs to require loader code when
114 * another loader can load the data for it.
115 */
116#pragma weak plat_update_boot_params
Andrew Scull3c0a90a2019-07-01 11:55:53 +0100117bool plat_update_boot_params(struct mm_stage1_locked stage1_locked,
118 struct boot_params_update *p, struct mpool *ppool)
Andrew Scullb401ba32018-11-09 10:30:54 +0000119{
Andrew Scull3c0a90a2019-07-01 11:55:53 +0100120 return fdt_patch(stage1_locked, plat_get_fdt_addr(), p, ppool);
Andrew Scullb401ba32018-11-09 10:30:54 +0000121}