PSA FF-A: add partition manifest parsing
Add PSA FF-A partition manifest structure to VM manifest. Add FF-A
partition package structure (comprises header + image dtb + image
payload). Parse FF-A partition manifest DT if requested by the
is_ffa_partition DTS boolean.
This assumes Hafnium entry point is directly fed with the hypervisor
manifest pointer address (rather than the initrd image).
For a regular VM, the entry point is the start address of the VM
workspace allocated by Hafnium from the mem ranges provided in
hypervisor manifest. If the VM is an FF-A compliant partition,
the VM entry point is extrapolated from the FF-A partition manifest
(start of the workspace as SP header load address plus entry point
offset from partition DTS).
Change-Id: I6947646d0cd6eb3c4d97a31aa589244b365c8486
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
diff --git a/src/init.c b/src/init.c
index 5652897..ccf496e 100644
--- a/src/init.c
+++ b/src/init.c
@@ -106,24 +106,39 @@
pa_addr(params.mem_ranges[i].end) - 1);
}
- dlog_info("Ramdisk range: %#x - %#x\n", pa_addr(params.initrd_begin),
- pa_addr(params.initrd_end) - 1);
+ /*
+ * Hafnium manifest is either gathered from the ramdisk or passed
+ * directly to Hafnium entry point by the earlier bootloader stage.
+ * If the ramdisk start address is non-zero it hints the manifest
+ * shall be looked up from the ramdisk. If zero, assume the address
+ * passed to Hafnium entry point is the manifest address.
+ */
+ if (pa_addr(params.initrd_begin)) {
+ dlog_info("Ramdisk range: %#x - %#x\n",
+ pa_addr(params.initrd_begin),
+ pa_addr(params.initrd_end) - 1);
- /* Map initrd in, and initialise cpio parser. */
- initrd = mm_identity_map(mm_stage1_locked, params.initrd_begin,
- params.initrd_end, MM_MODE_R, &ppool);
- if (!initrd) {
- panic("Unable to map initrd.");
+ /* Map initrd in, and initialise cpio parser. */
+ initrd = mm_identity_map(mm_stage1_locked, params.initrd_begin,
+ params.initrd_end, MM_MODE_R, &ppool);
+ if (!initrd) {
+ panic("Unable to map initrd.");
+ }
+
+ memiter_init(
+ &cpio, initrd,
+ pa_difference(params.initrd_begin, params.initrd_end));
+
+ if (!cpio_get_file(&cpio, &manifest_fname, &manifest_it)) {
+ panic("Could not find manifest in initrd.");
+ }
+ } else {
+ manifest_it = fdt.buf;
}
- memiter_init(&cpio, initrd,
- pa_difference(params.initrd_begin, params.initrd_end));
+ manifest_ret = manifest_init(mm_stage1_locked, &manifest, &manifest_it,
+ &ppool);
- if (!cpio_get_file(&cpio, &manifest_fname, &manifest_it)) {
- panic("Could not find manifest in initrd.");
- }
-
- manifest_ret = manifest_init(&manifest, &manifest_it);
if (manifest_ret != MANIFEST_SUCCESS) {
panic("Could not parse manifest: %s.",
manifest_strerror(manifest_ret));