mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-06-04 14:10:01 +00:00
arm-bsp/trusted-firmware-a: add firmware update support for TC
Signed-off-by: Davidson K <davidson.kumaresan@arm.com> Change-Id: Ice2396de4705ed7859c2334678170ef7f17e4709 Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
From 16f183e3c09d64fee92638ea9d0017ac7973ddf8 Mon Sep 17 00:00:00 2001
|
||||
From: Tudor Cretu <tudor.cretu@arm.com>
|
||||
Date: Fri, 24 Sep 2021 12:09:53 +0000
|
||||
Subject: [PATCH 1/2] feat(plat/tc): add firmware update secure partition
|
||||
|
||||
Firmware update is a trusted service secure partition that implements
|
||||
the PSA firmware update specification. It executes in the secure world
|
||||
in total compute platform.
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Signed-off-by: Tudor Cretu <tudor.cretu@arm.com>
|
||||
Change-Id: I6223d247b078de8c03b068185bf120b3d502f500
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts | 9 ++++++++-
|
||||
plat/arm/board/tc/fdts/tc_tb_fw_config.dts | 4 ++++
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
|
||||
index 92e2ddda6..23ad06888 100644
|
||||
--- a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
|
||||
+++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
|
||||
@@ -28,7 +28,7 @@
|
||||
load_address = <0xfd280000>;
|
||||
vcpu_count = <8>;
|
||||
#ifdef TS_SP_FW_CONFIG
|
||||
- mem_size = <26738688>; /* 25MB TZC DRAM */
|
||||
+ mem_size = <20447232>; /* 19MB TZC DRAM */
|
||||
#else
|
||||
mem_size = <30928896>; /* 29MB TZC DRAM */
|
||||
#endif
|
||||
@@ -48,6 +48,13 @@
|
||||
vcpu_count = <1>;
|
||||
mem_size = <2097152>; /* 2MB TZC DRAM */
|
||||
};
|
||||
+ vm4 {
|
||||
+ is_ffa_partition;
|
||||
+ debug_name = "firmware-update";
|
||||
+ load_address = <0xfe600000>;
|
||||
+ vcpu_count = <1>;
|
||||
+ mem_size = <6291456>; /* 6MB TZC DRAM */
|
||||
+ };
|
||||
#endif
|
||||
};
|
||||
|
||||
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
|
||||
index a5bb520fe..2c640b363 100644
|
||||
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
|
||||
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
|
||||
@@ -41,6 +41,10 @@
|
||||
uuid = "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0";
|
||||
load-address = <0xfec00000>;
|
||||
};
|
||||
+ firmware-update {
|
||||
+ uuid = "6823a838-1b06-470e-9774-0cce8bfb53fd";
|
||||
+ load-address = <0xfe600000>;
|
||||
+ };
|
||||
#endif
|
||||
#if OPTEE_SP_FW_CONFIG
|
||||
op-tee {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
From a8cdd6c67d26c15642338a45279db5e39cf4e565 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Fri, 3 Jun 2022 18:16:31 +0530
|
||||
Subject: [PATCH 2/2] feat(plat/tc): reserve 4 MB for stmm communication used
|
||||
for firmware update
|
||||
|
||||
The firmware update secure partition and u-boot communicates using
|
||||
the stmm communication layer and it needs a dedicated memory region.
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I8d4da5c26843d225983dcaee0757694a6d43234c
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
fdts/tc.dts | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/fdts/tc.dts b/fdts/tc.dts
|
||||
index dc86958bf..cb504c4a2 100644
|
||||
--- a/fdts/tc.dts
|
||||
+++ b/fdts/tc.dts
|
||||
@@ -217,6 +217,11 @@
|
||||
reg = <0x00000000 0xf8e00000 0 0x00200000>;
|
||||
no-map;
|
||||
};
|
||||
+
|
||||
+ fwu_mm@0xfca00000 {
|
||||
+ reg = <0x00000000 0xfca00000 0 0x00400000>;
|
||||
+ no-map;
|
||||
+ };
|
||||
};
|
||||
|
||||
psci {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -15,6 +15,8 @@ SRC_URI:append = " \
|
||||
file://0005-feat-plat-tc-add-spmc-manifest-with-trusty-sp.patch \
|
||||
file://0006-feat-plat-tc-update-dts-with-trusty-compatible-strin.patch \
|
||||
file://0007-feat-arm-tc-Update-trusty-load-address-in-dts-files.patch \
|
||||
file://0008-feat-plat-tc-add-firmware-update-secure-partition.patch \
|
||||
file://0009-feat-plat-tc-reserve-4-MB-for-stmm-communication-use.patch \
|
||||
file://generate_metadata.py \
|
||||
"
|
||||
|
||||
|
||||
+2611
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
From 8dd3e03bd83939746b6a849dce37435ea7581032 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Thu, 14 Jul 2022 19:35:41 +0530
|
||||
Subject: [PATCH 3/7] arm: total_compute: enable psci
|
||||
|
||||
psci is used for system reset
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: Iff4f769dc5e64b6000e892d77a011102b090acfd
|
||||
Upstream-Status: Submitted [https://patchwork.ozlabs.org/project/uboot/patch/20220809102652.23776-1-davidson.kumaresan@arm.com/]
|
||||
---
|
||||
arch/arm/dts/total_compute.dts | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/dts/total_compute.dts b/arch/arm/dts/total_compute.dts
|
||||
index 4399269a44..96edacda0b 100644
|
||||
--- a/arch/arm/dts/total_compute.dts
|
||||
+++ b/arch/arm/dts/total_compute.dts
|
||||
@@ -45,4 +45,8 @@
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "bp:clock24mhz";
|
||||
};
|
||||
+ psci {
|
||||
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
|
||||
+ method = "smc";
|
||||
+ };
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 6eee50e5376356b1faeb30507b411120a8b5c7d1 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Mon, 6 Jun 2022 15:13:15 +0530
|
||||
Subject: [PATCH 4/7] arm_ffa: rxtx_map should use 64 bit calls
|
||||
|
||||
rxtx_map deals with the 64 bit addresses and hence the 64 bit calls
|
||||
should be used
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: Iec1251266e61139767588d683d60bada1ed10abe
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
include/arm_ffa.h | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/arm_ffa.h b/include/arm_ffa.h
|
||||
index 313f46f747..9627107079 100644
|
||||
--- a/include/arm_ffa.h
|
||||
+++ b/include/arm_ffa.h
|
||||
@@ -58,12 +58,13 @@
|
||||
ARM_SMCCC_OWNER_STANDARD, (func_num))
|
||||
|
||||
#define FFA_SMC_32(func_num) FFA_SMC(ARM_SMCCC_SMC_32, (func_num))
|
||||
+#define FFA_SMC_64(func_num) FFA_SMC(ARM_SMCCC_SMC_64, (func_num))
|
||||
|
||||
#define FFA_VERSION FFA_SMC_32(0x63)
|
||||
#define FFA_ID_GET FFA_SMC_32(0x69)
|
||||
#define FFA_FEATURES FFA_SMC_32(0x64)
|
||||
#define FFA_PARTITION_INFO_GET FFA_SMC_32(0x68)
|
||||
-#define FFA_RXTX_MAP FFA_SMC_32(0x66)
|
||||
+#define FFA_RXTX_MAP FFA_SMC_64(0x66)
|
||||
#define FFA_RXTX_UNMAP FFA_SMC_32(0x67)
|
||||
#define FFA_RX_RELEASE FFA_SMC_32(0x65)
|
||||
#define FFA_MSG_SEND_DIRECT_REQ FFA_SMC_32(0x6F)
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+993
@@ -0,0 +1,993 @@
|
||||
From 6d26058401bce6012173b5341cdf4de72772a1c2 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Mon, 6 Jun 2022 13:19:07 +0530
|
||||
Subject: [PATCH 5/7] efi_firmware: add new fmp driver that supports arm fwu
|
||||
specification
|
||||
|
||||
This fmp driver communicates to the firmware update secure partition
|
||||
executing in the secure world which is an implementation of the arm
|
||||
psa specification for the firmware update. The communication to the
|
||||
firmware update secure partition is based on stmm and arm ff-a framework.
|
||||
|
||||
It implements only the get_image_info and set_image api.
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I94c2cad210c32a60a8a0594cacf530b68ab6a09d
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
include/efi_firmware_arm_psa.h | 218 +++++++++++
|
||||
include/efi_loader.h | 1 +
|
||||
lib/efi_loader/Kconfig | 9 +
|
||||
lib/efi_loader/Makefile | 1 +
|
||||
lib/efi_loader/efi_capsule.c | 8 +
|
||||
lib/efi_loader/efi_firmware.c | 134 +++++++
|
||||
lib/efi_loader/efi_firmware_arm_psa.c | 520 ++++++++++++++++++++++++++
|
||||
7 files changed, 891 insertions(+)
|
||||
create mode 100644 include/efi_firmware_arm_psa.h
|
||||
create mode 100644 lib/efi_loader/efi_firmware_arm_psa.c
|
||||
|
||||
diff --git a/include/efi_firmware_arm_psa.h b/include/efi_firmware_arm_psa.h
|
||||
new file mode 100644
|
||||
index 0000000000..82f932066c
|
||||
--- /dev/null
|
||||
+++ b/include/efi_firmware_arm_psa.h
|
||||
@@ -0,0 +1,218 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 Arm Limited
|
||||
+ */
|
||||
+
|
||||
+#ifndef _EFI_FIRMWARE_ARM_PSA_H
|
||||
+#define _EFI_FIRMWARE_ARM_PSA_H
|
||||
+
|
||||
+#include <efi_loader.h>
|
||||
+#include <mm_communication.h>
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#define PSA_FWU_DIRECTORY_UUID \
|
||||
+ EFI_GUID(0xdeee58d9, 0x5147, 0x4ad3, \
|
||||
+ 0xa2, 0x90, 0x77, 0x66, 0x6e, 0x23, 0x41, 0xa5)
|
||||
+
|
||||
+#define PSA_FWU_SP_UUID \
|
||||
+ EFI_GUID(0x6823a838, 0x1b06, 0x470e, \
|
||||
+ 0x97, 0x74, 0x0c, 0xce, 0x8b, 0xfb, 0x53, 0xfd)
|
||||
+
|
||||
+#define FFA_FWU_SP_UUID \
|
||||
+ {0x68, 0x23, 0xa8, 0x38, 0x1b, 0x06, 0x47, \
|
||||
+ 0x0e, 0x97, 0x74, 0x0c, 0xce, 0x8b, 0xfb, 0x53, 0xfd}
|
||||
+
|
||||
+#define FWU_DISCOVER 0
|
||||
+#define FWU_BEGIN_STAGING 1
|
||||
+#define FWU_END_STAGING 2
|
||||
+#define FWU_CANCEL_STAGING 3
|
||||
+#define FWU_OPEN 4
|
||||
+#define FWU_WRITE_STREAM 5
|
||||
+#define FWU_READ_STREAM 6
|
||||
+#define FWU_COMMIT 7
|
||||
+#define FWU_ACCEPT_IMAGE 9
|
||||
+#define FWU_SELECT_PREVIOUS 10
|
||||
+
|
||||
+#define FWU_SUCCESS 0
|
||||
+#define FWU_UNKNOWN ((int32_t)-1)
|
||||
+#define FWU_BUSY ((int32_t)-2)
|
||||
+#define FWU_OUT_OF_BOUNDS ((int32_t)-3)
|
||||
+#define FWU_AUTH_FAIL ((int32_t)-4)
|
||||
+#define FWU_NO_PERMISSION ((int32_t)-5)
|
||||
+#define FWU_DENIED ((int32_t)-6)
|
||||
+#define FWU_RESUME ((int32_t)-7)
|
||||
+
|
||||
+#define MAX_IMAGES 5
|
||||
+
|
||||
+typedef int32_t fwu_status_t;
|
||||
+
|
||||
+struct fwu_image_info_entry {
|
||||
+ efi_guid_t image_guid;
|
||||
+ uint32_t client_permissions;
|
||||
+ uint32_t img_max_size;
|
||||
+ uint32_t lowest_acceptable_version;
|
||||
+ uint32_t img_version;
|
||||
+ uint32_t accepted;
|
||||
+ uint32_t reserved;
|
||||
+}__packed;
|
||||
+
|
||||
+struct fwu_image_directory {
|
||||
+ uint32_t directory_version;
|
||||
+ uint32_t num_images;
|
||||
+ uint32_t active_index;
|
||||
+ uint32_t boot_index;
|
||||
+ struct fwu_image_info_entry entries[MAX_IMAGES];
|
||||
+}__packed;
|
||||
+
|
||||
+int __efi_runtime arm_psa_get_image_info(
|
||||
+ efi_uintn_t *image_info_size,
|
||||
+ struct efi_firmware_image_descriptor *image_info,
|
||||
+ u32 *descriptor_version,
|
||||
+ u8 *descriptor_count,
|
||||
+ efi_uintn_t *descriptor_size,
|
||||
+ u32 *package_version,
|
||||
+ u16 **package_version_name
|
||||
+);
|
||||
+
|
||||
+int __efi_runtime arm_psa_update(
|
||||
+ const void *image,
|
||||
+ u8 image_index,
|
||||
+ efi_uintn_t image_size
|
||||
+);
|
||||
+
|
||||
+struct mm_fwu_discover_arg {
|
||||
+ uint32_t func_id;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_discover_ret {
|
||||
+ uint32_t status;
|
||||
+ uint8_t version_major;
|
||||
+ uint8_t version_minor;
|
||||
+ uint16_t num_func;
|
||||
+ uint8_t function_presence[];
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_begin_staging_arg {
|
||||
+ uint32_t func_id;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_begin_staging_ret {
|
||||
+ uint32_t status;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_end_staging_arg {
|
||||
+ uint32_t func_id;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_end_staging_ret {
|
||||
+ uint32_t status;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_cancel_staging_arg {
|
||||
+ uint32_t func_id;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_cancel_staging_ret {
|
||||
+ uint32_t status;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_open_arg {
|
||||
+ uint32_t func_id;
|
||||
+ efi_guid_t image_guid;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_open_ret {
|
||||
+ uint32_t status;
|
||||
+ uint32_t handle;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_write_stream_arg {
|
||||
+ uint32_t func_id;
|
||||
+ uint32_t handle;
|
||||
+ uint32_t data_len;
|
||||
+ uint8_t payload[];
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_write_stream_ret {
|
||||
+ uint32_t status;
|
||||
+};
|
||||
+
|
||||
+struct mm_fwu_read_stream_arg {
|
||||
+ uint32_t func_id;
|
||||
+ uint32_t handle;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_read_stream_ret {
|
||||
+ uint32_t status;
|
||||
+ uint32_t read_bytes;
|
||||
+ uint32_t total_bytes;
|
||||
+ uint8_t payload[];
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_commit_arg {
|
||||
+ uint32_t func_id;
|
||||
+ uint32_t handle;
|
||||
+ uint32_t acceptance_req;
|
||||
+ uint32_t max_atomic_len;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_commit_ret {
|
||||
+ uint32_t status;
|
||||
+ uint32_t progress;
|
||||
+ uint32_t total_work;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_accept_arg {
|
||||
+ uint32_t func_id;
|
||||
+ uint32_t reserved;
|
||||
+ efi_guid_t image_type_uuid;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_accept_ret {
|
||||
+ uint32_t status;
|
||||
+};
|
||||
+
|
||||
+struct mm_fwu_select_previous_arg {
|
||||
+ uint32_t func_id;
|
||||
+}__packed;
|
||||
+
|
||||
+struct mm_fwu_select_previous_ret {
|
||||
+ uint32_t status;
|
||||
+}__packed;
|
||||
+
|
||||
+inline static void *get_fwu_hdr(struct efi_mm_communicate_header *mm_hdr)
|
||||
+{
|
||||
+ const efi_guid_t fwu_sp_guid = PSA_FWU_SP_UUID;
|
||||
+ guidcpy(&mm_hdr->header_guid, &fwu_sp_guid);
|
||||
+ return mm_hdr->data;
|
||||
+}
|
||||
+
|
||||
+#define GET_HDR(name) \
|
||||
+static inline struct mm_fwu_##name * \
|
||||
+get_fwu_##name (struct efi_mm_communicate_header *mm_hdr) \
|
||||
+{ \
|
||||
+ return (struct mm_fwu_##name *)get_fwu_hdr(mm_hdr); \
|
||||
+} \
|
||||
+
|
||||
+GET_HDR(discover_arg)
|
||||
+GET_HDR(discover_ret)
|
||||
+GET_HDR(begin_staging_arg)
|
||||
+GET_HDR(begin_staging_ret)
|
||||
+GET_HDR(end_staging_arg)
|
||||
+GET_HDR(end_staging_ret)
|
||||
+GET_HDR(cancel_staging_arg)
|
||||
+GET_HDR(cancel_staging_ret)
|
||||
+GET_HDR(open_arg)
|
||||
+GET_HDR(open_ret)
|
||||
+GET_HDR(write_stream_arg)
|
||||
+GET_HDR(write_stream_ret)
|
||||
+GET_HDR(read_stream_arg)
|
||||
+GET_HDR(read_stream_ret)
|
||||
+GET_HDR(commit_arg)
|
||||
+GET_HDR(commit_ret)
|
||||
+GET_HDR(accept_arg)
|
||||
+GET_HDR(accept_ret)
|
||||
+GET_HDR(select_previous_arg)
|
||||
+GET_HDR(select_previous_ret)
|
||||
+
|
||||
+#endif /* _EFI_FIRMWARE_ARM_PSA_H */
|
||||
diff --git a/include/efi_loader.h b/include/efi_loader.h
|
||||
index af36639ec6..7327c87497 100644
|
||||
--- a/include/efi_loader.h
|
||||
+++ b/include/efi_loader.h
|
||||
@@ -961,6 +961,7 @@ u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name,
|
||||
|
||||
extern const struct efi_firmware_management_protocol efi_fmp_fit;
|
||||
extern const struct efi_firmware_management_protocol efi_fmp_raw;
|
||||
+extern const struct efi_firmware_management_protocol efi_fmp_arm_psa;
|
||||
|
||||
/* Capsule update */
|
||||
efi_status_t EFIAPI efi_update_capsule(
|
||||
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
|
||||
index e5e35fe51f..f99d436f16 100644
|
||||
--- a/lib/efi_loader/Kconfig
|
||||
+++ b/lib/efi_loader/Kconfig
|
||||
@@ -168,6 +168,15 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT
|
||||
Select this option if you want to enable capsule-based
|
||||
firmware update using Firmware Management Protocol.
|
||||
|
||||
+config EFI_CAPSULE_FIRMWARE_ARM_PSA
|
||||
+ bool "FMP driver for ARM PSA FWU specification"
|
||||
+ depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
|
||||
+ select EFI_CAPSULE_FIRMWARE
|
||||
+ help
|
||||
+ Select this option if you want to enable firmware management protocol
|
||||
+ driver that supports the ARM PSA firmware update specification as
|
||||
+ mentioned in https://developer.arm.com/documentation/den0118/a/
|
||||
+
|
||||
config EFI_CAPSULE_FIRMWARE_FIT
|
||||
bool "FMP driver for FIT images"
|
||||
depends on FIT
|
||||
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
|
||||
index 034d26cf01..f986ac6417 100644
|
||||
--- a/lib/efi_loader/Makefile
|
||||
+++ b/lib/efi_loader/Makefile
|
||||
@@ -38,6 +38,7 @@ obj-y += efi_boottime.o
|
||||
obj-y += efi_helper.o
|
||||
obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
|
||||
obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o
|
||||
+obj-$(CONFIG_EFI_CAPSULE_FIRMWARE_ARM_PSA) += efi_firmware_arm_psa.o
|
||||
obj-y += efi_console.o
|
||||
obj-y += efi_device_path.o
|
||||
obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o
|
||||
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
|
||||
index f00440163d..3154fc51d3 100644
|
||||
--- a/lib/efi_loader/efi_capsule.c
|
||||
+++ b/lib/efi_loader/efi_capsule.c
|
||||
@@ -1041,6 +1041,14 @@ efi_status_t __weak efi_load_capsule_drivers(void)
|
||||
&efi_fmp_raw, NULL));
|
||||
}
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_ARM_PSA)) {
|
||||
+ handle = NULL;
|
||||
+ ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
|
||||
+ &handle,
|
||||
+ &efi_guid_firmware_management_protocol,
|
||||
+ &efi_fmp_arm_psa, NULL));
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
|
||||
index a5ff32f121..3356559af8 100644
|
||||
--- a/lib/efi_loader/efi_firmware.c
|
||||
+++ b/lib/efi_loader/efi_firmware.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <common.h>
|
||||
#include <charset.h>
|
||||
#include <dfu.h>
|
||||
+#include <efi_firmware_arm_psa.h>
|
||||
#include <efi_loader.h>
|
||||
#include <image.h>
|
||||
#include <signatures.h>
|
||||
@@ -478,3 +479,136 @@ const struct efi_firmware_management_protocol efi_fmp_raw = {
|
||||
.set_package_info = efi_firmware_set_package_info_unsupported,
|
||||
};
|
||||
#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_RAW */
|
||||
+
|
||||
+#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_ARM_PSA
|
||||
+/*
|
||||
+ * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
|
||||
+ * method that supports the arm psa firmware update specification.
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
+ * efi_firmware_arm_psa_get_image_info - return information about the
|
||||
+ * current firmware image
|
||||
+ * @this: Protocol instance
|
||||
+ * @image_info_size: Size of @image_info
|
||||
+ * @image_info: Image information
|
||||
+ * @descriptor_version: Pointer to version number
|
||||
+ * @descriptor_count: Pointer to number of descriptors
|
||||
+ * @descriptor_size: Pointer to descriptor size
|
||||
+ * package_version: Package version
|
||||
+ * package_version_name: Package version's name
|
||||
+ *
|
||||
+ * Return information bout the current firmware image in @image_info.
|
||||
+ * @image_info will consist of a number of descriptors.
|
||||
+ *
|
||||
+ * Return status code
|
||||
+ */
|
||||
+
|
||||
+static
|
||||
+efi_status_t EFIAPI efi_firmware_arm_psa_get_image_info(
|
||||
+ struct efi_firmware_management_protocol *this,
|
||||
+ efi_uintn_t *image_info_size,
|
||||
+ struct efi_firmware_image_descriptor *image_info,
|
||||
+ u32 *descriptor_version,
|
||||
+ u8 *descriptor_count,
|
||||
+ efi_uintn_t *descriptor_size,
|
||||
+ u32 *package_version,
|
||||
+ u16 **package_version_name)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this,
|
||||
+ image_info_size, image_info,
|
||||
+ descriptor_version, descriptor_count, descriptor_size,
|
||||
+ package_version, package_version_name);
|
||||
+
|
||||
+ if (!image_info_size)
|
||||
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
|
||||
+
|
||||
+ if (*image_info_size &&
|
||||
+ (!image_info || !descriptor_version || !descriptor_count ||
|
||||
+ !descriptor_size || !package_version || !package_version_name))
|
||||
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
|
||||
+
|
||||
+ ret = arm_psa_get_image_info(image_info_size, image_info,
|
||||
+ descriptor_version, descriptor_count,
|
||||
+ descriptor_size,
|
||||
+ package_version, package_version_name);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ if (ret == -ENOMEM)
|
||||
+ return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
|
||||
+ else
|
||||
+ return EFI_EXIT(EFI_DEVICE_ERROR);
|
||||
+ }
|
||||
+
|
||||
+ return EFI_EXIT(EFI_SUCCESS);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * efi_firmware_arm_psa_set_image - update the firmware image
|
||||
+ * @this: Protocol instance
|
||||
+ * @image_index: Image index number
|
||||
+ * @image: New image
|
||||
+ * @image_size: Size of new image
|
||||
+ * @vendor_code: Vendor-specific update policy
|
||||
+ * @progress: Function to report the progress of update
|
||||
+ * @abort_reason: Pointer to string of abort reason
|
||||
+ *
|
||||
+ * Update the firmware to new image, following the arm psa firmware
|
||||
+ * update specification.
|
||||
+ * @vendor_code, @progress and @abort_reason are not supported.
|
||||
+ *
|
||||
+ * Return: status code
|
||||
+ */
|
||||
+static
|
||||
+efi_status_t EFIAPI efi_firmware_arm_psa_set_image(
|
||||
+ struct efi_firmware_management_protocol *this,
|
||||
+ u8 image_index,
|
||||
+ const void *image,
|
||||
+ efi_uintn_t image_size,
|
||||
+ const void *vendor_code,
|
||||
+ efi_status_t (*progress)(efi_uintn_t completion),
|
||||
+ u16 **abort_reason)
|
||||
+{
|
||||
+ u32 fmp_hdr_signature;
|
||||
+ const struct fmp_payload_header *header;
|
||||
+
|
||||
+ EFI_ENTRY("%p %d %p %zd %p %p %p\n", this, image_index, image,
|
||||
+ image_size, vendor_code, progress, abort_reason);
|
||||
+
|
||||
+ if (!image)
|
||||
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
|
||||
+
|
||||
+ /* TODO: capsule authentication */
|
||||
+
|
||||
+ fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
|
||||
+ header = (void *)image;
|
||||
+
|
||||
+ if (!memcmp(&header->signature, &fmp_hdr_signature,
|
||||
+ sizeof(fmp_hdr_signature))) {
|
||||
+ /*
|
||||
+ * When building the capsule with the scripts in
|
||||
+ * edk2, a FMP header is inserted above the capsule
|
||||
+ * payload. Compensate for this header to get the
|
||||
+ * actual payload that is to be updated.
|
||||
+ */
|
||||
+ image = (unsigned char *)image + header->header_size;
|
||||
+ image_size -= header->header_size;
|
||||
+ }
|
||||
+
|
||||
+ if (arm_psa_update(image, image_index, image_size))
|
||||
+ return EFI_EXIT(EFI_DEVICE_ERROR);
|
||||
+
|
||||
+ return EFI_EXIT(EFI_SUCCESS);
|
||||
+}
|
||||
+
|
||||
+const struct efi_firmware_management_protocol efi_fmp_arm_psa = {
|
||||
+ .get_image_info = efi_firmware_arm_psa_get_image_info,
|
||||
+ .get_image = efi_firmware_get_image_unsupported,
|
||||
+ .set_image = efi_firmware_arm_psa_set_image,
|
||||
+ .check_image = efi_firmware_check_image_unsupported,
|
||||
+ .get_package_info = efi_firmware_get_package_info_unsupported,
|
||||
+ .set_package_info = efi_firmware_set_package_info_unsupported,
|
||||
+};
|
||||
+#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_ARM_PSA */
|
||||
diff --git a/lib/efi_loader/efi_firmware_arm_psa.c b/lib/efi_loader/efi_firmware_arm_psa.c
|
||||
new file mode 100644
|
||||
index 0000000000..ab575f0124
|
||||
--- /dev/null
|
||||
+++ b/lib/efi_loader/efi_firmware_arm_psa.c
|
||||
@@ -0,0 +1,520 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+/*
|
||||
+ * Copyright (C) 2022 Arm Limited
|
||||
+ */
|
||||
+
|
||||
+#include <arm_ffa_helper.h>
|
||||
+#include <configs/total_compute.h>
|
||||
+#include <efi_firmware_arm_psa.h>
|
||||
+#include <efi_loader.h>
|
||||
+#include <malloc.h>
|
||||
+#include <mapmem.h>
|
||||
+#include <mm_communication.h>
|
||||
+
|
||||
+/* MM return codes */
|
||||
+#define MM_SUCCESS 0
|
||||
+
|
||||
+#define ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64 0xC4000061
|
||||
+#define ARM_SVC_ID_SP_EVENT_COMPLETE ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64
|
||||
+
|
||||
+__efi_runtime_data static u16 mm_sp_id;
|
||||
+__efi_runtime_data static int fwu_initialized = 0;
|
||||
+__efi_runtime_data struct fwu_image_directory cached_image_directory;
|
||||
+__efi_runtime_data struct efi_mm_communicate_header *mm_hdr;
|
||||
+__efi_runtime_data void *mm_comm_buf;
|
||||
+
|
||||
+/**
|
||||
+ * ffa_discover_mm_sp_id() - Query the MM partition ID
|
||||
+ *
|
||||
+ * Use the FF-A driver to get the MM partition ID.
|
||||
+ * If multiple partitions are found, use the first one
|
||||
+ *
|
||||
+ * Return:
|
||||
+ *
|
||||
+ * 0 on success
|
||||
+ */
|
||||
+static int __efi_runtime ffa_discover_mm_sp_id(void)
|
||||
+{
|
||||
+ struct ffa_interface_data func_data = {0};
|
||||
+ u32 count = 0;
|
||||
+ int ret;
|
||||
+ struct ffa_partition_info *parts_info;
|
||||
+ static union ffa_partition_uuid fwu_sp_uuid = {.bytes = FFA_FWU_SP_UUID};
|
||||
+
|
||||
+ /*
|
||||
+ * get from the driver the count of the SPs matching the UUID
|
||||
+ */
|
||||
+ func_data.data0_size = sizeof(fwu_sp_uuid);
|
||||
+ func_data.data0 = &fwu_sp_uuid;
|
||||
+ func_data.data1_size = sizeof(count);
|
||||
+ func_data.data1 = &count;
|
||||
+
|
||||
+ ret = ffa_helper_get_partitions_info(&func_data);
|
||||
+ if (ret != FFA_ERR_STAT_SUCCESS) {
|
||||
+ log_err("EFI: Failure in querying partitions count (error code: %d)\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!count) {
|
||||
+ log_info("EFI: No MM partition found\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * pre-allocate a buffer to be filled by the driver
|
||||
+ * with ffa_partition_info structs
|
||||
+ */
|
||||
+ parts_info = calloc(count, sizeof(struct ffa_partition_info));
|
||||
+ if (!parts_info)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ log_info("EFI: Pre-allocating %d partition(s) info structures\n", count);
|
||||
+
|
||||
+ func_data.data1_size = count * sizeof(struct ffa_partition_info);
|
||||
+ func_data.data1 = parts_info;
|
||||
+
|
||||
+ /*
|
||||
+ * ask the driver to fill the
|
||||
+ * buffer with the SPs info
|
||||
+ */
|
||||
+ ret = ffa_helper_get_partitions_info(&func_data);
|
||||
+ if (ret != FFA_ERR_STAT_SUCCESS) {
|
||||
+ log_err("EFI: Failure in querying partition(s) info (error code: %d)\n", ret);
|
||||
+ free(parts_info);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * MM SPs found , use the first one
|
||||
+ */
|
||||
+
|
||||
+ mm_sp_id = parts_info[0].id;
|
||||
+
|
||||
+ log_info("EFI: MM partition ID 0x%x\n", mm_sp_id);
|
||||
+
|
||||
+ free(parts_info);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ffa_notify_mm_sp() - Announce there is data in the shared buffer
|
||||
+ *
|
||||
+ * Notifies the MM partition in the trusted world that
|
||||
+ * data is available in the shared buffer.
|
||||
+ * This is a blocking call during which trusted world has exclusive access
|
||||
+ * to the MM shared buffer.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ *
|
||||
+ * 0 on success
|
||||
+ */
|
||||
+static int __efi_runtime ffa_notify_mm_sp(void)
|
||||
+{
|
||||
+ struct ffa_interface_data func_data = {0};
|
||||
+ struct ffa_send_direct_data msg = {0};
|
||||
+ int ret;
|
||||
+ u32 sp_event_complete;
|
||||
+ int sp_event_ret;
|
||||
+
|
||||
+ func_data.data0_size = sizeof(mm_sp_id);
|
||||
+ func_data.data0 = &mm_sp_id;
|
||||
+
|
||||
+ msg.a3 = FFA_SHARED_MM_BUFFER_ADDR;
|
||||
+ msg.a4 = FFA_SHARED_MM_BUFFER_SIZE;
|
||||
+ func_data.data1_size = sizeof(msg);
|
||||
+ func_data.data1 = &msg;
|
||||
+
|
||||
+ ret = ffa_helper_msg_send_direct_req(&func_data);
|
||||
+ if (ret != FFA_ERR_STAT_SUCCESS) {
|
||||
+ log_err("EFI: Failure to notify the MM SP , FF-A error (%d)\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ sp_event_complete = msg.a3;
|
||||
+ sp_event_ret = (int)msg.a4;
|
||||
+
|
||||
+ if (sp_event_complete == ARM_SVC_ID_SP_EVENT_COMPLETE && sp_event_ret == MM_SUCCESS)
|
||||
+ return 0;
|
||||
+
|
||||
+ log_err("EFI: Failure to notify the MM SP (0x%x , %d)\n",
|
||||
+ sp_event_complete,
|
||||
+ sp_event_ret);
|
||||
+
|
||||
+ return -EACCES;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_discover(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_discover_arg *discover_arg = get_fwu_discover_arg(mm_hdr);
|
||||
+ struct mm_fwu_discover_ret *discover_ret = get_fwu_discover_ret(mm_hdr);
|
||||
+
|
||||
+ discover_arg->func_id = FWU_DISCOVER;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_discover_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (discover_ret->version_major != 1) {
|
||||
+ log_err("FWU: Unsupported Update Agent version\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ /* TODO: check other parameters as well */
|
||||
+
|
||||
+ return discover_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_begin_staging(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_begin_staging_arg *begin_staging_arg = get_fwu_begin_staging_arg(mm_hdr);
|
||||
+ struct mm_fwu_begin_staging_ret *begin_staging_ret = get_fwu_begin_staging_ret(mm_hdr);
|
||||
+
|
||||
+ begin_staging_arg->func_id = FWU_BEGIN_STAGING;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_begin_staging_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return begin_staging_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_end_staging(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_end_staging_arg *end_staging_arg = get_fwu_end_staging_arg(mm_hdr);
|
||||
+ struct mm_fwu_end_staging_ret *end_staging_ret = get_fwu_end_staging_ret(mm_hdr);
|
||||
+
|
||||
+ end_staging_arg->func_id = FWU_END_STAGING;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_end_staging_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return end_staging_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_cancel_staging(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_cancel_staging_arg *cancel_staging_arg = get_fwu_cancel_staging_arg(mm_hdr);
|
||||
+ struct mm_fwu_cancel_staging_ret *cancel_staging_ret = get_fwu_cancel_staging_ret(mm_hdr);
|
||||
+
|
||||
+ cancel_staging_arg->func_id = FWU_CANCEL_STAGING;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_cancel_staging_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return cancel_staging_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_open(const efi_guid_t *img_uuid, uint32_t *handle)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_open_arg *open_hdr = get_fwu_open_arg(mm_hdr);
|
||||
+ struct mm_fwu_open_ret *open_ret = get_fwu_open_ret(mm_hdr);
|
||||
+
|
||||
+ open_hdr->func_id = FWU_OPEN;
|
||||
+ guidcpy(&open_hdr->image_guid, img_uuid);
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_open_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ *handle = open_ret->handle;
|
||||
+
|
||||
+ return open_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_read_stream(uint32_t handle, uint8_t *buffer, uint32_t buffer_size)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_read_stream_arg *read_stream_hdr = get_fwu_read_stream_arg(mm_hdr);
|
||||
+ struct mm_fwu_read_stream_ret *read_stream_ret = get_fwu_read_stream_ret(mm_hdr);
|
||||
+ uint32_t payload_size = FFA_SHARED_MM_BUFFER_SIZE - sizeof(struct mm_fwu_read_stream_ret)
|
||||
+ - sizeof(struct efi_mm_communicate_header);
|
||||
+ uint32_t read_offset = 0, read_size, total_size;
|
||||
+
|
||||
+ do {
|
||||
+ read_stream_hdr->func_id = FWU_READ_STREAM;
|
||||
+ read_stream_hdr->handle = handle;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_read_stream_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (read_stream_ret->status)
|
||||
+ return read_stream_ret->status;
|
||||
+
|
||||
+ read_size = read_stream_ret->read_bytes;
|
||||
+ total_size = read_stream_ret->total_bytes;
|
||||
+
|
||||
+ log_info("FWU: read bytes / total bytes : %d/%d\n", read_size, total_size);
|
||||
+
|
||||
+ if ((read_size <= payload_size) && (read_offset + read_size <= buffer_size))
|
||||
+ memcpy(buffer + read_offset, read_stream_ret->payload, read_size);
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ read_offset += read_size;
|
||||
+
|
||||
+ if (read_offset > total_size)
|
||||
+ return -EINVAL;
|
||||
+ } while (total_size != read_offset);
|
||||
+
|
||||
+ return read_stream_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_write_stream(uint32_t handle, const uint8_t *buffer, uint32_t remaining_size)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_write_stream_arg *write_stream_arg = get_fwu_write_stream_arg(mm_hdr);
|
||||
+ struct mm_fwu_write_stream_ret *write_stream_ret = get_fwu_write_stream_ret(mm_hdr);
|
||||
+ uint32_t write_size;
|
||||
+ uint32_t payload_size = FFA_SHARED_MM_BUFFER_SIZE - sizeof(struct mm_fwu_write_stream_arg)
|
||||
+ - sizeof(struct efi_mm_communicate_header);
|
||||
+
|
||||
+ while (remaining_size) {
|
||||
+ write_size = (remaining_size < payload_size) ? remaining_size : payload_size;
|
||||
+ write_stream_arg->func_id = FWU_WRITE_STREAM;
|
||||
+ write_stream_arg->handle = handle;
|
||||
+ write_stream_arg->data_len = write_size;
|
||||
+ memcpy(write_stream_arg->payload, buffer, write_size);
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_write_stream_arg) + write_size;
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if(write_stream_ret->status)
|
||||
+ return write_stream_ret->status;
|
||||
+
|
||||
+ remaining_size -= write_size;
|
||||
+ buffer += write_size;
|
||||
+
|
||||
+ log_info("FWU: write size = %d, remaining size = %d\n",
|
||||
+ write_size, remaining_size);
|
||||
+ }
|
||||
+
|
||||
+ return write_stream_ret->status;
|
||||
+}
|
||||
+
|
||||
+static fwu_status_t __efi_runtime fwu_commit(uint32_t handle, bool client_accept)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct mm_fwu_commit_arg *commit_arg = get_fwu_commit_arg(mm_hdr);
|
||||
+ struct mm_fwu_commit_ret *commit_ret = get_fwu_commit_ret(mm_hdr);
|
||||
+
|
||||
+ do {
|
||||
+ commit_arg->func_id = FWU_COMMIT;
|
||||
+ commit_arg->handle = handle;
|
||||
+ commit_arg->acceptance_req = client_accept;
|
||||
+ commit_arg->max_atomic_len = 0;
|
||||
+
|
||||
+ mm_hdr->message_len = sizeof(struct mm_fwu_commit_arg);
|
||||
+
|
||||
+ ret = ffa_notify_mm_sp();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ log_info("FWU: commit progress %d/%d (work/total_work)\n",
|
||||
+ commit_ret->progress, commit_ret->total_work);
|
||||
+
|
||||
+ } while(commit_ret->status==FWU_RESUME);
|
||||
+
|
||||
+ return commit_ret->status;
|
||||
+}
|
||||
+
|
||||
+int __efi_runtime arm_psa_update(
|
||||
+ const void *image,
|
||||
+ u8 image_index,
|
||||
+ efi_uintn_t image_size
|
||||
+)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ uint32_t handle;
|
||||
+
|
||||
+ if(image_index >= cached_image_directory.num_images)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = fwu_begin_staging();
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: begin staging failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = fwu_open(&cached_image_directory.entries[image_index].image_guid, &handle);
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: firmware image open failed, ret = %d\n", ret);
|
||||
+ goto cancel_staging;
|
||||
+ }
|
||||
+
|
||||
+ ret = fwu_write_stream(handle, (uint8_t *)image, image_size);
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: write stream failed, ret = %d\n", ret);
|
||||
+ goto cancel_staging;
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: implement client driven image acceptance */
|
||||
+ ret = fwu_commit(handle, 0);
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: commit failed, ret = %d\n", ret);
|
||||
+ goto cancel_staging;
|
||||
+ }
|
||||
+
|
||||
+ ret = fwu_end_staging();
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: end staging failed, ret = %d\n", ret);
|
||||
+ goto cancel_staging;
|
||||
+ }
|
||||
+
|
||||
+ log_info("successfully updated the image at index %d\n", image_index);
|
||||
+ return ret;
|
||||
+
|
||||
+cancel_staging:
|
||||
+ if (fwu_cancel_staging())
|
||||
+ log_err("FWU: cancel staging failed, ret = %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int __efi_runtime read_image_directory(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t handle;
|
||||
+
|
||||
+ const efi_guid_t fwu_directory_uuid = PSA_FWU_DIRECTORY_UUID;
|
||||
+
|
||||
+ ret = fwu_open(&fwu_directory_uuid, &handle);
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: open image directory failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = fwu_read_stream(handle, (uint8_t *)&cached_image_directory, sizeof(cached_image_directory));
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: read stream failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if(cached_image_directory.num_images > MAX_IMAGES) {
|
||||
+ log_err("FWU: image limit exceeded.\n");
|
||||
+ log_err("FWU: number of images present: %d, max number of images supported: %d\n",
|
||||
+ cached_image_directory.num_images, MAX_IMAGES);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int update_agent_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ffa_discover_mm_sp_id();
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: discover update agent failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ mm_comm_buf = (void *)map_sysmem((phys_addr_t)FFA_SHARED_MM_BUFFER_ADDR, 0);
|
||||
+ mm_hdr = (struct efi_mm_communicate_header *)mm_comm_buf;
|
||||
+
|
||||
+ ret = fwu_discover();
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: discover failed, ret = %d\n", ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = read_image_directory();
|
||||
+ if (ret) {
|
||||
+ log_err("FWU: reading image directory failed, ret = %d\n", ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ fwu_initialized = 1;
|
||||
+ return ret;
|
||||
+out:
|
||||
+ unmap_sysmem(mm_comm_buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int __efi_runtime arm_psa_get_image_info(
|
||||
+ efi_uintn_t *image_info_size,
|
||||
+ struct efi_firmware_image_descriptor *image_info,
|
||||
+ u32 *descriptor_version,
|
||||
+ u8 *descriptor_count,
|
||||
+ efi_uintn_t *descriptor_size,
|
||||
+ u32 *package_version,
|
||||
+ u16 **package_version_name)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ int required_image_info_size;
|
||||
+
|
||||
+ if (!fwu_initialized) {
|
||||
+ ret = update_agent_init();
|
||||
+ if (ret) {
|
||||
+ log_err("update agent init failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ required_image_info_size = cached_image_directory.num_images *
|
||||
+ sizeof(struct efi_firmware_image_descriptor);
|
||||
+
|
||||
+ if (*image_info_size < required_image_info_size) {
|
||||
+ *image_info_size = required_image_info_size;
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
|
||||
+ *descriptor_count = cached_image_directory.num_images;
|
||||
+ *descriptor_size = required_image_info_size;
|
||||
+ *package_version = 0xffffffff; /* not supported */
|
||||
+ *package_version_name = NULL; /* not supported */
|
||||
+
|
||||
+ for (int i = 0; i < cached_image_directory.num_images; i++) {
|
||||
+ image_info[i].image_index = i+1;
|
||||
+ guidcpy(&image_info[i].image_type_id, &cached_image_directory.entries[i].image_guid);
|
||||
+ image_info[i].image_id = i;
|
||||
+ image_info[i].image_id_name = NULL; /* not supported */
|
||||
+ image_info[i].version = cached_image_directory.entries[i].img_version;
|
||||
+ image_info[i].version_name = NULL; /* not supported */
|
||||
+ image_info[i].size = cached_image_directory.entries[i].img_max_size;
|
||||
+
|
||||
+ image_info[i].attributes_supported =
|
||||
+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
|
||||
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
|
||||
+ image_info[i].attributes_setting =
|
||||
+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
|
||||
+
|
||||
+ /* Check if the capsule authentication is enabled */
|
||||
+ if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE))
|
||||
+ image_info[i].attributes_setting |=
|
||||
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
|
||||
+
|
||||
+ image_info[i].lowest_supported_image_version =
|
||||
+ cached_image_directory.entries[i].lowest_acceptable_version;
|
||||
+ image_info[i].last_attempt_version = 0;
|
||||
+ image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
|
||||
+ image_info[i].hardware_instance = 1;
|
||||
+ image_info[i].dependencies = NULL; /* not supported */
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From 2ab887402b9e22842d07e5f2fe1ac54518555af5 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Mon, 6 Jun 2022 13:24:42 +0530
|
||||
Subject: [PATCH 6/7] arm: total_compute: enable capsule update
|
||||
|
||||
It includes:
|
||||
* Enabling runtime capsule update
|
||||
* Enabling efidebug command line tool
|
||||
* Enabling the FMP driver that supports ARM PSA firmware update specification
|
||||
* Predefining the carved out memory to be used for MM communication
|
||||
* Enabling FF-A transport driver and adding an entry in dts
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I6d6c70c6fc386d6c40def800a7417c1ce4b8acf5
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
arch/arm/dts/total_compute.dts | 7 +++++++
|
||||
configs/total_compute_defconfig | 5 +++++
|
||||
include/configs/total_compute.h | 4 ++++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/dts/total_compute.dts b/arch/arm/dts/total_compute.dts
|
||||
index 96edacda0b..9b2cbfb452 100644
|
||||
--- a/arch/arm/dts/total_compute.dts
|
||||
+++ b/arch/arm/dts/total_compute.dts
|
||||
@@ -45,8 +45,15 @@
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "bp:clock24mhz";
|
||||
};
|
||||
+
|
||||
psci {
|
||||
compatible = "arm,psci-1.0", "arm,psci-0.2";
|
||||
method = "smc";
|
||||
};
|
||||
+
|
||||
+ arm_ffa {
|
||||
+ compatible = "arm,ffa";
|
||||
+ method = "smc";
|
||||
+ status = "okay";
|
||||
+ };
|
||||
};
|
||||
diff --git a/configs/total_compute_defconfig b/configs/total_compute_defconfig
|
||||
index 6a375543cd..531ce41cd3 100644
|
||||
--- a/configs/total_compute_defconfig
|
||||
+++ b/configs/total_compute_defconfig
|
||||
@@ -52,3 +52,8 @@ CONFIG_SYS_FLASH_PROTECTION=y
|
||||
CONFIG_SYS_FLASH_CFI=y
|
||||
CONFIG_LIBAVB=y
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
+CONFIG_ARM_FFA_TRANSPORT=y
|
||||
+CONFIG_CMD_EFIDEBUG=y
|
||||
+CONFIG_EFI_CAPSULE_FIRMWARE_ARM_PSA=y
|
||||
+CONFIG_EFI_CAPSULE_ON_DISK=y
|
||||
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
|
||||
diff --git a/include/configs/total_compute.h b/include/configs/total_compute.h
|
||||
index 62bdb4f6a3..4b00f47ec6 100644
|
||||
--- a/include/configs/total_compute.h
|
||||
+++ b/include/configs/total_compute.h
|
||||
@@ -59,4 +59,8 @@
|
||||
#define CONFIG_SYS_FLASH_EMPTY_INFO /* flinfo indicates empty blocks */
|
||||
#define FLASH_MAX_SECTOR_SIZE 0x00040000
|
||||
|
||||
+/* Shared buffer used for communication between u-boot and the FWU SP */
|
||||
+#define FFA_SHARED_MM_BUFFER_SIZE 4 * 1024 * 1024 /* 4 MB */
|
||||
+#define FFA_SHARED_MM_BUFFER_ADDR (0xFCA00000)
|
||||
+
|
||||
#endif /* __TOTAL_COMPUTE_H */
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
From 47be0456ea1760837d2de857e57842e595e9ea5e Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Mon, 27 Jun 2022 14:11:27 +0530
|
||||
Subject: [PATCH 7/7] arm_ffa: unmap rxtx buffer before exiting u-boot
|
||||
|
||||
The linux kernel ffa driver will be used after the kernel boots. It
|
||||
will try to map its own rxtx buffer. But there can be only one rxtx
|
||||
buffer mapped from the non secure world. Since the rxtx buffer of
|
||||
the u-boot is no longer used and we have to map the rxtx buffer of
|
||||
the linux kernel, the rxtx buffer of the u-boot should be unmapped.
|
||||
|
||||
This will not be needed after the efi runtime services are enabled
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I9deb6283d81f791185aa0a32d205b394d6d91f76
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
drivers/arm-ffa/core.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/drivers/arm-ffa/core.c b/drivers/arm-ffa/core.c
|
||||
index 98e2d2fa17..0c619439cb 100644
|
||||
--- a/drivers/arm-ffa/core.c
|
||||
+++ b/drivers/arm-ffa/core.c
|
||||
@@ -1470,6 +1470,16 @@ static const struct udevice_id ffa_match_id[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * Unmap the rxtx buffer before exiting u-boot
|
||||
+ * This avoids conflicts with the linux kernel ffa driver
|
||||
+ */
|
||||
+
|
||||
+static int ffa_remove(struct udevice *dev)
|
||||
+{
|
||||
+ return ffa_unmap_rxtx_buffers();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Declaring the arm_ffa driver under UCLASS_FFA
|
||||
*/
|
||||
@@ -1481,4 +1491,6 @@ U_BOOT_DRIVER(arm_ffa) = {
|
||||
.of_to_plat = ffa_of_to_plat,
|
||||
.probe = ffa_probe,
|
||||
.plat_auto = sizeof(struct ffa_pdata),
|
||||
+ .remove = ffa_remove,
|
||||
+ .flags = DM_FLAG_OS_PREPARE,
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -87,4 +87,10 @@ SRC_URI:append:juno = " file://0001-arm-juno-add-custom-bootcmd-to-autoboot-from
|
||||
SRC_URI:append:tc = " \
|
||||
file://bootargs.cfg \
|
||||
file://0001-arm-total_compute-update-secure-dram-size.patch \
|
||||
file://0002-arm_ffa-introducing-Arm-FF-A-low-level-driver.patch \
|
||||
file://0003-arm-total_compute-enable-psci.patch \
|
||||
file://0004-arm_ffa-rxtx_map-should-use-64-bit-calls.patch \
|
||||
file://0005-efi_firmware-add-new-fmp-driver-that-supports-arm-fw.patch \
|
||||
file://0006-arm-total_compute-enable-capsule-update.patch \
|
||||
file://0007-arm_ffa-unmap-rxtx-buffer-before-exiting-u-boot.patch \
|
||||
"
|
||||
|
||||
Reference in New Issue
Block a user