blob: c6c101876e61c8697f9752b361b2bf96c7154b32 [file] [log] [blame]
Andrew Scullb401ba32018-11-09 10:30:54 +00001/*
2 * Copyright 2018 Google LLC
3 *
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
41void plat_get_initrd_range(paddr_t *begin, paddr_t *end)
42{
43 *begin = layout_initrd_begin();
44 *end = layout_initrd_end();
45}
46
47/**
48 * Default implementation assumes the FDT address is passed to the kernel.
49 *
50 * TODO: make this part of the VM configuration as secondary VMs will also need
51 * to take arguments.
52 */
53#pragma weak plat_get_kernel_arg
54uintreg_t plat_get_kernel_arg(void)
55{
56 return (uintreg_t)pa_addr(plat_get_fdt_addr());
57}
58
59/**
60 * Default implementation extracts the boot parameters from the FDT but the
61 * initrd is provided separately.
62 */
63#pragma weak plat_get_boot_params
64bool plat_get_boot_params(struct boot_params *p)
65{
66 struct fdt_header *fdt;
67 struct fdt_node n;
68 bool ret = false;
69
70 plat_get_initrd_range(&p->initrd_begin, &p->initrd_end);
71 p->kernel_arg = plat_get_kernel_arg();
72
73 /* Get the memory map from the FDT. */
74 fdt = fdt_map(plat_get_fdt_addr(), &n);
75 if (!fdt) {
76 return false;
77 }
78
79 if (!fdt_find_child(&n, "")) {
80 dlog("Unable to find FDT root node.\n");
81 goto out_unmap_fdt;
82 }
83
84 p->mem_ranges_count = 0;
85 fdt_find_memory_ranges(&n, p);
86
87 ret = true;
88
89out_unmap_fdt:
90 if (!fdt_unmap(fdt)) {
91 dlog("Unable to unmap fdt.");
92 return false;
93 }
94
95 return ret;
96}
97
98/**
99 * Default implementation updates the FDT which is the argument passed to the
100 * primary VM's kernel.
101 *
102 * TODO: in future, each VM will declare whether it expects an argument passed
103 * and that will be static data e.g. it will provide its own FDT so there will
104 * be no FDT modification. This is done because each VM has a very different
105 * view of the system and we don't want to force VMs to require loader code when
106 * another loader can load the data for it.
107 */
108#pragma weak plat_update_boot_params
109bool plat_update_boot_params(struct boot_params_update *p)
110{
111 return fdt_patch(plat_get_fdt_addr(), p);
112}