refactor: added "sp_pkg" module
Added module "sp_pkg" to init and help operate the SP pkg, such that
hafnium can cleanly retrieve the FF-A manifest's and the boot info's
base address.
Change-Id: Ieb6925c487a4dac9b460353ba82a00d670176037
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/manifest.c b/src/manifest.c
index 502d412..96396e4 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -12,6 +12,7 @@
#include "hf/assert.h"
#include "hf/check.h"
#include "hf/dlog.h"
+#include "hf/sp_pkg.h"
#include "hf/static_assert.h"
#include "hf/std.h"
@@ -756,92 +757,63 @@
struct manifest_vm *vm, ffa_vm_id_t vm_id, struct mpool *ppool)
{
enum manifest_return_code ret = MANIFEST_ERROR_NOT_COMPATIBLE;
- uintpaddr_t sp_pkg_addr;
- paddr_t sp_pkg_start;
- paddr_t sp_pkg_end;
- struct sp_pkg_header *sp_pkg;
- size_t sp_header_dtb_size;
- paddr_t sp_dtb_addr;
+ uintpaddr_t load_address;
+ struct sp_pkg_header header;
struct fdt sp_fdt;
+ vaddr_t pkg_start;
+ vaddr_t manifest_address;
/*
* This must have been hinted as being an FF-A partition,
* return straight with failure if this is not the case.
*/
if (!vm->is_ffa_partition) {
+ return ret;
+ }
+
+ TRY(read_uint64(node, "load_address", &load_address));
+ if (!is_aligned(load_address, PAGE_SIZE)) {
return MANIFEST_ERROR_NOT_COMPATIBLE;
}
- TRY(read_uint64(node, "load_address", &sp_pkg_addr));
- if (!is_aligned(sp_pkg_addr, PAGE_SIZE)) {
- return MANIFEST_ERROR_NOT_COMPATIBLE;
+ assert(load_address != 0U);
+
+ if (!sp_pkg_init(stage1_locked, pa_init(load_address), &header,
+ ppool)) {
+ return ret;
}
- /* Map top of package as a single page to extract the header */
- sp_pkg_start = pa_init(sp_pkg_addr);
- sp_pkg_end = pa_add(sp_pkg_start, PAGE_SIZE);
- sp_pkg = mm_identity_map(stage1_locked, sp_pkg_start,
- pa_add(sp_pkg_start, PAGE_SIZE), MM_MODE_R,
- ppool);
- CHECK(sp_pkg != NULL);
+ pkg_start = va_init(load_address);
- dlog_verbose("Package load address %#x\n", sp_pkg_addr);
-
- if (sp_pkg->magic != SP_PKG_HEADER_MAGIC) {
- dlog_error("Invalid package magic.\n");
- goto exit_unmap;
- }
-
- if (sp_pkg->version != SP_PKG_HEADER_VERSION) {
- dlog_error("Invalid package version.\n");
- goto exit_unmap;
- }
-
- /* TODO: Do not map 2 pages. */
- sp_header_dtb_size = align_up(sp_pkg->pm_size, 2 * PAGE_SIZE);
-
- if ((vm_id != HF_PRIMARY_VM_ID) &&
- (sp_header_dtb_size >= vm->secondary.mem_size)) {
+ if (vm_id != HF_PRIMARY_VM_ID &&
+ sp_pkg_get_mem_size(&header) >= vm->secondary.mem_size) {
dlog_error("Invalid package header or DT size.\n");
- goto exit_unmap;
+ goto out;
}
- if (sp_header_dtb_size > PAGE_SIZE) {
- /* Map remainder of header + DTB */
- sp_pkg_end = pa_add(sp_pkg_start, sp_header_dtb_size);
-
- sp_pkg = mm_identity_map(stage1_locked, sp_pkg_start,
- sp_pkg_end, MM_MODE_R, ppool);
- CHECK(sp_pkg != NULL);
- }
-
- sp_dtb_addr = pa_add(sp_pkg_start, sp_pkg->pm_offset);
-
- /* Since the address is from pa_addr allow the cast */
- // NOLINTNEXTLINE(performance-no-int-to-ptr)
- if (!fdt_init_from_ptr(&sp_fdt, (void *)pa_addr(sp_dtb_addr),
- sp_pkg->pm_size)) {
+ manifest_address = va_add(va_init(load_address), header.pm_offset);
+ if (!fdt_init_from_ptr(&sp_fdt, ptr_from_va(manifest_address),
+ header.pm_size)) {
dlog_error("FDT failed validation.\n");
- goto exit_unmap;
+ goto out;
}
ret = parse_ffa_manifest(&sp_fdt, vm);
if (ret != MANIFEST_SUCCESS) {
dlog_error("Error parsing partition manifest: %s.\n",
manifest_strerror(ret));
- goto exit_unmap;
+ goto out;
}
- if (vm->partition.load_addr != sp_pkg_addr) {
+ if (vm->partition.load_addr != load_address) {
dlog_warning(
"Partition's load address at its manifest differs"
" from specified in partition's package.\n");
- vm->partition.load_addr = sp_pkg_addr;
+ vm->partition.load_addr = load_address;
}
-exit_unmap:
- CHECK(mm_unmap(stage1_locked, sp_pkg_start, sp_pkg_end, ppool));
-
+out:
+ sp_pkg_deinit(stage1_locked, pkg_start, &header, ppool);
return ret;
}