blob: 47ff26a897e3d209bf16c8825ff178897bc35ce7 [file] [log] [blame]
J-Alves35315782022-01-25 17:58:32 +00001/*
2 * Copyright 2022 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/boot_info.h"
10
11#include "hf/assert.h"
12#include "hf/dlog.h"
J-Alves7e67d102022-04-13 13:22:39 +010013#include "hf/ffa.h"
J-Alves35315782022-01-25 17:58:32 +000014#include "hf/memiter.h"
15#include "hf/std.h"
16
17#include "vmapi/hf/ffa.h"
18
19/**
J-Alves7e67d102022-04-13 13:22:39 +010020 * Initializes the ffa_boot_info_header in accordance to the specification.
21 */
22static void ffa_boot_info_header_init(struct ffa_boot_info_header *header,
23 size_t blob_size)
24{
25 assert(header != NULL);
26 assert(blob_size != 0U);
27
28 header->signature = FFA_BOOT_INFO_SIG;
29 header->version = FFA_BOOT_INFO_VERSION;
30 header->info_blob_size = blob_size;
31 header->desc_size = sizeof(struct ffa_boot_info_desc);
32 header->desc_count = 0;
33 header->desc_offset =
34 (uint32_t)offsetof(struct ffa_boot_info_header, boot_info);
35 header->reserved = 0U;
36}
37
38static void ffa_boot_info_desc_init(struct ffa_boot_info_desc *info_desc,
39 uint8_t content_format, bool std_type,
40 uint8_t type_id, uint32_t size,
41 uint64_t content)
42{
43 assert(info_desc != NULL);
44
45 /*
46 * Init name size with 0s, as it is currently unused. Data can be
47 * identified checking the type field.
48 */
49 memset_s(info_desc, FFA_BOOT_INFO_NAME_LEN, 0, FFA_BOOT_INFO_NAME_LEN);
50
51 info_desc->type = std_type == true ? FFA_BOOT_INFO_TYPE_STD
52 : FFA_BOOT_INFO_TYPE_IMPDEF;
53 info_desc->type <<= FFA_BOOT_INFO_TYPE_SHIFT;
54 info_desc->type |= (type_id & FFA_BOOT_INFO_TYPE_ID_MASK);
55
56 info_desc->reserved = 0U;
57 info_desc->flags =
58 ((content_format << FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_SHIFT) &
59 FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_MASK);
60 info_desc->size = size;
61 info_desc->content = content;
62}
63
64/*
65 * Write initialization parameter to the boot info descriptor array.
66 */
67static void boot_info_write_desc(struct ffa_boot_info_header *header,
68 uint8_t content_format, bool std_type,
69 uint8_t type_id, uint32_t size,
70 uint64_t content,
71 const size_t max_info_desc_count)
72{
73 assert(header != NULL);
74
75 /* Check that writing the data won't surpass the blob memory limit. */
76 if (header->desc_count >= max_info_desc_count) {
77 dlog_error(
78 "Boot info memory is full. No space for a "
79 "descriptor.\n");
80 return;
81 }
82
83 ffa_boot_info_desc_init(&header->boot_info[header->desc_count],
84 content_format, std_type, type_id, size,
85 content);
86
87 header->desc_count++;
88}
89
90/**
J-Alves35315782022-01-25 17:58:32 +000091 * Looks for the FF-A manifest boot information node, and writes the
92 * requested information into the boot info memory.
93 */
J-Alves6e0abc42024-12-30 16:51:16 +000094bool ffa_boot_info_node(struct fdt_node *boot_info_node,
95 struct partition_pkg *pkg)
J-Alves35315782022-01-25 17:58:32 +000096{
97 struct memiter data;
J-Alves6e0abc42024-12-30 16:51:16 +000098 struct ffa_boot_info_header *boot_info_header;
99 const size_t boot_info_size =
100 pa_difference(pkg->boot_info.begin, pkg->boot_info.end);
J-Alves7e67d102022-04-13 13:22:39 +0100101 const size_t max_boot_info_desc_count =
Madhukar Pappireddy00d3b632024-06-03 18:32:44 -0500102 (boot_info_size -
103 offsetof(struct ffa_boot_info_header, boot_info)) /
104 sizeof(struct ffa_boot_info_desc);
J-Alves35315782022-01-25 17:58:32 +0000105
106 assert(boot_info_node != NULL);
J-Alves6e0abc42024-12-30 16:51:16 +0000107 assert(pkg != NULL);
108
109 boot_info_header = (struct ffa_boot_info_header *)ptr_from_va(
110 va_from_pa(pkg->boot_info.begin));
111
J-Alves7e67d102022-04-13 13:22:39 +0100112 assert(boot_info_header != NULL);
J-Alves35315782022-01-25 17:58:32 +0000113
J-Alves7e67d102022-04-13 13:22:39 +0100114 /*
115 * FF-A v1.1 EAC0 specification states the region for the boot info
116 * descriptors, and the contents of the boot info shall be contiguous.
117 * Together they constitute the boot info blob. The are for the boot
118 * info blob is allocated in the SP's respective package.
119 * Retrieve from the SP package the size of the region for the boot info
120 * descriptors. The size of boot info contents to be incremented,
121 * depending on the info specified in the partition's FF-A manifest.
122 */
123 ffa_boot_info_header_init(boot_info_header, boot_info_size);
J-Alves35315782022-01-25 17:58:32 +0000124
125 if (!fdt_is_compatible(boot_info_node, "arm,ffa-manifest-boot-info")) {
126 dlog_verbose("The node 'boot-info' is not compatible.\n");
127 return false;
128 }
129
130 dlog_verbose(" FF-A Boot Info:\n");
131
132 if (fdt_read_property(boot_info_node, "ffa_manifest", &data) &&
133 memiter_size(&data) == 0U) {
J-Alves6e0abc42024-12-30 16:51:16 +0000134 ipaddr_t manifest_address = ipa_from_pa(pkg->pm.begin);
135 const uint32_t pm_size =
136 pa_difference(pkg->pm.begin, pkg->pm.end);
J-Alves7e67d102022-04-13 13:22:39 +0100137
J-Alves35315782022-01-25 17:58:32 +0000138 dlog_verbose(" FF-A Manifest\n");
J-Alves6e0abc42024-12-30 16:51:16 +0000139 boot_info_write_desc(boot_info_header,
140 FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_ADDR,
141 true, FFA_BOOT_INFO_TYPE_ID_FDT, pm_size,
142 ipa_addr(manifest_address),
143 max_boot_info_desc_count);
J-Alves7e67d102022-04-13 13:22:39 +0100144
145 /*
146 * Incrementing the size of the boot information blob with the
147 * size of the partition's manifest.
148 */
J-Alves6e0abc42024-12-30 16:51:16 +0000149 boot_info_header->info_blob_size += pm_size;
J-Alves7e67d102022-04-13 13:22:39 +0100150
151 /*
152 * Flush the data cache in case partition initializes with
153 * caches disabled.
154 */
155 arch_mm_flush_dcache((void *)boot_info_header,
156 boot_info_header->info_blob_size);
J-Alves35315782022-01-25 17:58:32 +0000157 return true;
158 }
159
160 return false;
161}