Merge "test(spm): test FFA_FEATURES with NPI, SRI, MEI"
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index 3938c2f..0630753 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -654,4 +654,34 @@
return (uint64_t)ret.arg4;
}
+/**
+ * Request SP to send indirect message to FF-A endpoint.
+ *
+ * Command ID is string: MSGREQ.
+ */
+#define CACTUS_REQ_MSG_SEND_CMD U(0x4d5347524551a)
+
+static inline struct ffa_value cactus_req_ind_msg_send_cmd(
+ ffa_id_t source, ffa_id_t dest, ffa_id_t receiver,
+ ffa_id_t sender, uint32_t flags)
+{
+ return cactus_send_cmd(source, dest, CACTUS_REQ_MSG_SEND_CMD,
+ flags, receiver, sender, 0);
+}
+
+static inline ffa_id_t cactus_msg_send_receiver(struct ffa_value ret)
+{
+ return (ffa_id_t)ret.arg5;
+}
+
+static inline ffa_id_t cactus_msg_send_sender(struct ffa_value ret)
+{
+ return (ffa_id_t)ret.arg6;
+}
+
+static inline uint64_t cactus_msg_send_flags(struct ffa_value ret)
+{
+ return (uint64_t)ret.arg4;
+}
+
#endif
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 3ae43d2..08befd0 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -11,6 +11,8 @@
#include <tftf_lib.h>
#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
/* This error code must be different to the ones used by FFA */
#define FFA_TFTF_ERROR -42
@@ -132,6 +134,10 @@
/** Query interrupt ID of the Managed Exit Interrupt. */
#define FFA_FEATURE_MEI 0x3U
+/** Minimum and maximum buffer size reported by FFA_FEATURES(FFA_RXTX_MAP) */
+#define FFA_RXTX_MAP_MIN_BUF_4K 0
+#define FFA_RXTX_MAP_MAX_BUF_PAGE_COUNT 1
+
/** Partition property: partition supports receipt of direct requests. */
#define FFA_PARTITION_DIRECT_REQ_RECV (UINT32_C(1) << 0)
@@ -290,6 +296,48 @@
typedef uint64_t ffa_notification_bitmap_t;
+/**
+ * Partition message header as specified by table 6.2 from FF-A v1.1 EAC0
+ * specification.
+ */
+struct ffa_partition_rxtx_header {
+ uint32_t flags;
+ /* MBZ */
+ uint32_t reserved;
+ /* Offset from the beginning of the buffer to the message payload. */
+ uint32_t offset;
+ /* Sender(Bits[31:16]) and Receiver(Bits[15:0]) endpoint IDs. */
+ ffa_id_t receiver;
+ ffa_id_t sender;
+ /* Size of message in buffer. */
+ uint32_t size;
+};
+
+#define FFA_RXTX_HEADER_SIZE sizeof(struct ffa_partition_rxtx_header)
+
+static inline void ffa_rxtx_header_init(
+ ffa_id_t sender, ffa_id_t receiver, uint32_t size,
+ struct ffa_partition_rxtx_header *header)
+{
+ header->flags = 0;
+ header->reserved = 0;
+ header->offset = FFA_RXTX_HEADER_SIZE;
+ header->sender = sender;
+ header->receiver = receiver;
+ header->size = size;
+}
+
+/* The maximum length possible for a single message. */
+#define FFA_PARTITION_MSG_PAYLOAD_MAX (PAGE_SIZE - FFA_RXTX_HEADER_SIZE)
+
+struct ffa_partition_msg {
+ struct ffa_partition_rxtx_header header;
+ char payload[FFA_PARTITION_MSG_PAYLOAD_MAX];
+};
+
+/* The maximum length possible for a single message. */
+#define FFA_MSG_PAYLOAD_MAX PAGE_SIZE
+
#define FFA_NOTIFICATION(ID) (UINT64_C(1) << ID)
#define MAX_FFA_NOTIFICATIONS UINT32_C(64)
@@ -306,30 +354,64 @@
#define FFA_NOTIFICATIONS_FLAG_BITMAP_SPM UINT32_C(0x1 << 2)
#define FFA_NOTIFICATIONS_FLAG_BITMAP_HYP UINT32_C(0x1 << 3)
+#define FFA_NOTIFICATION_SPM_BUFFER_FULL_MASK FFA_NOTIFICATION(0)
+#define FFA_NOTIFICATION_HYP_BUFFER_FULL_MASK FFA_NOTIFICATION(32)
+
/**
* The following is an SGI ID, that the SPMC configures as non-secure, as
* suggested by the FF-A v1.1 specification, in section 9.4.1.
*/
#define FFA_SCHEDULE_RECEIVER_INTERRUPT_ID 8
-#define FFA_NOTIFICATIONS_BITMAP(lo, hi) \
- (ffa_notification_bitmap_t)(lo) | \
- (((ffa_notification_bitmap_t)hi << 32) & 0xFFFFFFFF00000000ULL)
-
-#define FFA_NOTIFICATIONS_FLAGS_VCPU_ID(id) UINT32_C((id & 0xFFFF) << 16)
-
-static inline ffa_notification_bitmap_t ffa_notifications_get_from_sp(
- struct ffa_value val)
+/**
+ * Helper function to assemble a 64-bit sized bitmap, from the 32-bit sized lo
+ * and hi.
+ * Helpful as FF-A specification defines that the notifications interfaces
+ * arguments are 32-bit registers.
+ */
+static inline ffa_notification_bitmap_t ffa_notification_bitmap(uint32_t lo,
+ uint32_t hi)
{
- return FFA_NOTIFICATIONS_BITMAP(val.arg2, val.arg3);
+ return (ffa_notification_bitmap_t)hi << 32U | lo;
}
-static inline ffa_notification_bitmap_t ffa_notifications_get_from_vm(
+static inline ffa_notification_bitmap_t ffa_notification_get_from_sp(
struct ffa_value val)
{
- return FFA_NOTIFICATIONS_BITMAP(val.arg4, val.arg5);
+ return ffa_notification_bitmap((uint32_t)val.arg2,
+ (uint32_t)val.arg3);
}
+static inline ffa_notification_bitmap_t ffa_notification_get_from_vm(
+ struct ffa_value val)
+{
+ return ffa_notification_bitmap((uint32_t)val.arg4,
+ (uint32_t)val.arg5);
+}
+
+static inline ffa_notification_bitmap_t ffa_notification_get_from_framework(
+ struct ffa_value val)
+{
+ return ffa_notification_bitmap((uint32_t)val.arg6,
+ (uint32_t)val.arg7);
+}
+
+ /**
+ * Helper functions to check for buffer full notification.
+ */
+static inline bool is_ffa_hyp_buffer_full_notification(
+ ffa_notification_bitmap_t framework)
+{
+ return (framework & FFA_NOTIFICATION_HYP_BUFFER_FULL_MASK) != 0U;
+}
+
+static inline bool is_ffa_spm_buffer_full_notification(
+ ffa_notification_bitmap_t framework)
+{
+ return (framework & FFA_NOTIFICATION_SPM_BUFFER_FULL_MASK) != 0U;
+}
+
+
/*
* FFA_NOTIFICATION_INFO_GET is a SMC64 interface.
* The following macros are defined for SMC64 implementation.
@@ -343,21 +425,21 @@
#define FFA_NOTIFICATIONS_LIST_SHIFT(l) (2 * (l - 1) + 12)
#define FFA_NOTIFICATIONS_LIST_SIZE_MASK 0x3U
-static inline uint32_t ffa_notifications_info_get_lists_count(
+static inline uint32_t ffa_notification_info_get_lists_count(
struct ffa_value ret)
{
return (uint32_t)(ret.arg2 >> FFA_NOTIFICATIONS_LISTS_COUNT_SHIFT)
& FFA_NOTIFICATIONS_LISTS_COUNT_MASK;
}
-static inline uint32_t ffa_notifications_info_get_list_size(
+static inline uint32_t ffa_notification_info_get_list_size(
struct ffa_value ret, uint32_t list)
{
return (uint32_t)(ret.arg2 >> FFA_NOTIFICATIONS_LIST_SHIFT(list)) &
FFA_NOTIFICATIONS_LIST_SIZE_MASK;
}
-static inline bool ffa_notifications_info_get_more_pending(struct ffa_value ret)
+static inline bool ffa_notification_info_get_more_pending(struct ffa_value ret)
{
return (ret.arg2 & FFA_NOTIFICATIONS_INFO_GET_FLAG_MORE_PENDING) != 0U;
}
@@ -785,10 +867,13 @@
struct ffa_value ffa_features_with_input_property(uint32_t feature,
uint32_t param);
struct ffa_value ffa_partition_info_get(const struct ffa_uuid uuid);
+struct ffa_value ffa_rx_release_with_id(ffa_id_t vm_id);
struct ffa_value ffa_rx_release(void);
struct ffa_value ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
struct ffa_value ffa_rxtx_unmap_with_id(uint32_t id);
struct ffa_value ffa_rxtx_unmap(void);
+struct ffa_value ffa_msg_send2_with_id(uint32_t flags, ffa_id_t sender);
+struct ffa_value ffa_msg_send2(uint32_t flags);
struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
uint32_t fragment_length);
struct ffa_value ffa_mem_lend(uint32_t descriptor_length,
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 0e6081e..577e8cf 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -150,6 +150,7 @@
#define FFA_RX_RELEASE FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
#define FFA_RXTX_MAP_SMC32 FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
#define FFA_RXTX_UNMAP FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
+#define FFA_MSG_SEND2 FFA_FID(SMC_32, FFA_FNUM_MSG_SEND2)
#define FFA_PARTITION_INFO_GET FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
#define FFA_ID_GET FFA_FID(SMC_32, FFA_FNUM_ID_GET)
#define FFA_MSG_POLL FFA_FID(SMC_32, FFA_FNUM_MSG_POLL)
diff --git a/include/runtime_services/pmf.h b/include/runtime_services/pmf.h
index d2ed412..5192999 100644
--- a/include/runtime_services/pmf.h
+++ b/include/runtime_services/pmf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,17 +24,18 @@
#define PMF_CACHE_MAINT (1 << 0)
#define PMF_NO_CACHE_MAINT 0
+#define PMF_SMC_VERSION U(0x00000001)
/*
* Defines for PMF SMC function ids.
*/
#ifndef __aarch64__
-#define PMF_SMC_GET_TIMESTAMP 0x82000010
+#define PMF_SMC_GET_TIMESTAMP 0x87000020
+#define PMF_SMC_GET_VERSION 0x87000021
#else
-#define PMF_SMC_GET_TIMESTAMP 0xC2000010
+#define PMF_SMC_GET_TIMESTAMP 0xC7000020
+#define PMF_SMC_GET_VERSION 0xC7000021
#endif
-#define PMF_NUM_SMC_CALLS 2
-
/* Following are the supported PMF service IDs */
#define PMF_PSCI_STAT_SVC_ID 0
#define PMF_RT_INSTR_SVC_ID 1
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index ad2ba08..fb1f61e 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -150,4 +150,10 @@
ffa_id_t receiver_id,
uint32_t mem_func);
+bool receive_indirect_message(void *buffer, size_t buffer_size, void *recv,
+ ffa_id_t *sender, ffa_id_t receiver,
+ ffa_id_t own_id);
+struct ffa_value send_indirect_message(
+ ffa_id_t from, ffa_id_t to, void *send, const void *payload,
+ size_t payload_size, uint32_t send_flags);
#endif /* SPM_COMMON_H */
diff --git a/include/runtime_services/ven_el3_svc.h b/include/runtime_services/ven_el3_svc.h
new file mode 100644
index 0000000..3a61ecd
--- /dev/null
+++ b/include/runtime_services/ven_el3_svc.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VEN_EL3_SVC_H
+#define VEN_EL3_SVC_H
+
+/*
+ * Definitions related to the Vendor-Specific El3 as per the SMC Calling Convention.
+ */
+
+/* VEN_EL3_SMC_32 0x87000000U */
+/* VEN_EL3_SMC_64 0xC7000000U */
+
+#define VEN_EL3_SVC_UID 0x8700ff01
+/* 0x8700ff02 is reserved */
+#define VEN_EL3_SVC_VERSION 0x8700ff03
+
+#define VEN_EL3_SVC_VERSION_MAJOR 1
+#define VEN_EL3_SVC_VERSION_MINOR 0
+
+#endif /* VEN_EL3_SVC_H */
diff --git a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
index e715e49..c643475 100644
--- a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
+++ b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -81,8 +81,18 @@
stp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET]
stp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET]
mrs x1, hcr_el2
+ /*
+ * Check if the processor supports SME
+ */
+ mrs x2, id_aa64pfr1_el1
+ tst x2, #(1 << 25)
+ bne 3f
str x1, [x0, #SUSPEND_CTX_HCR_OFFSET]
ret
+
+3: mrs x2, SMCR_EL2
+ stp x1, x2, [x0, #SUSPEND_CTX_HCR_OFFSET]
+ ret
endfunc __tftf_save_arch_context
/*
@@ -120,13 +130,24 @@
msr ttbr0_el2, x3
msr tcr_el2, x4
msr vbar_el2, x5
+ /*
+ * Check if the processor supports SME
+ */
+ mrs x2, id_aa64pfr1_el1
+ tst x2, #(1 << 25)
+ bne 3f
ldr x1, [x0, #SUSPEND_CTX_HCR_OFFSET]
msr hcr_el2, x1
+ b 4f
+
+3: ldp x1, x2, [x0, #SUSPEND_CTX_HCR_OFFSET]
+ msr hcr_el2, x1
+ msr SMCR_EL2, x2
/*
* TLB invalidations need to be completed before enabling MMU
*/
- dsb nsh
+4: dsb nsh
msr sctlr_el2, x6
/* Ensure the MMU enable takes effect immediately */
isb
diff --git a/lib/power_management/suspend/suspend_private.h b/lib/power_management/suspend/suspend_private.h
index 2ccf7a3..debd84f 100644
--- a/lib/power_management/suspend/suspend_private.h
+++ b/lib/power_management/suspend/suspend_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,8 +10,9 @@
/*
* Number of system registers we need to save/restore across a CPU suspend:
* EL1: MAIR, CPACR, TTBR0, TCR, VBAR, SCTLR
- * EL2: MAIR, CPTR, TTBR0, TCR, VBAR, SCTLR, HCR
+ * EL2: MAIR, CPTR, TTBR0, TCR, VBAR, SCTLR, HCR, SMCR
* APIAKeyLo_EL1 and APIAKeyHi_EL1 (if enabled).
+ * On need basis other registers can be included in tftf_suspend_context.
*/
#if ENABLE_PAUTH
#define NR_CTX_REGS 10
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 4e86e3d..0755749 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -51,6 +51,7 @@
cactus_message_loop.c \
cactus_test_simd.c \
cactus_test_direct_messaging.c \
+ cactus_test_indirect_message.c \
cactus_test_interrupts.c \
cactus_test_memory_sharing.c \
cactus_tests_smmuv3.c \
diff --git a/spm/cactus/cactus_tests/cactus_test_indirect_message.c b/spm/cactus/cactus_tests/cactus_test_indirect_message.c
new file mode 100644
index 0000000..085d72f
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_test_indirect_message.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cactus_message_loop.h"
+#include <cactus_test_cmds.h>
+#include "debug.h"
+#include "ffa_helpers.h"
+#include "utils_def.h"
+#include <ffa_endpoints.h>
+#include <spm_common.h>
+
+CACTUS_CMD_HANDLER(req_msg_send, CACTUS_REQ_MSG_SEND_CMD)
+{
+ struct ffa_value ret;
+ const ffa_id_t vm_id = ffa_dir_msg_dest(*args);
+ const ffa_id_t source = ffa_dir_msg_source(*args);
+ const ffa_id_t receiver = cactus_msg_send_receiver(*args);
+ const ffa_id_t sender = cactus_msg_send_sender(*args);
+ const char message[] = "Testing FF-A message.";
+
+ VERBOSE("%x requested to send indirect message to %x as %x(own %x)\n",
+ ffa_dir_msg_source(*args), receiver, sender, vm_id);
+
+ ret = send_indirect_message(sender, receiver, mb->send, message,
+ ARRAY_SIZE(message), 0);
+
+ if (is_ffa_call_error(ret)) {
+ ERROR("Failed to send indirect message.\n");
+ return cactus_error_resp(vm_id,
+ source,
+ ffa_error_code(ret));
+ }
+
+ return cactus_success_resp(vm_id, source, 0);
+}
diff --git a/spm/cactus/cactus_tests/cactus_test_notifications.c b/spm/cactus/cactus_tests/cactus_test_notifications.c
index 6d7b41b..420f942 100644
--- a/spm/cactus/cactus_tests/cactus_test_notifications.c
+++ b/spm/cactus/cactus_tests/cactus_test_notifications.c
@@ -109,8 +109,8 @@
VERBOSE("Notifications returned:\n"
" from sp: %llx\n"
" from vm: %llx\n",
- ffa_notifications_get_from_sp(ret),
- ffa_notifications_get_from_vm(ret));
+ ffa_notification_get_from_sp(ret),
+ ffa_notification_get_from_vm(ret));
/* If requested to check the status of NPI, for the respective CPU. */
if (cactus_notifications_check_npi_handled(*args)) {
@@ -126,8 +126,8 @@
}
return cactus_notifications_get_success_resp(
- vm_id, source, ffa_notifications_get_from_sp(ret),
- ffa_notifications_get_from_vm(ret));
+ vm_id, source, ffa_notification_get_from_sp(ret),
+ ffa_notification_get_from_vm(ret));
}
CACTUS_CMD_HANDLER(notifications_set, CACTUS_NOTIFICATIONS_SET_CMD)
diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus.dts b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
index 3effb39..4d95069 100644
--- a/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
@@ -27,7 +27,7 @@
entrypoint-offset = <0x00002000>;
xlat-granule = <0>; /* 4KiB */
boot-order = <0>;
- messaging-method = <3>; /* Direct messaging only */
+ messaging-method = <7>; /* Indirect Messaging and direct messaging. */
ns-interrupts-action = <1>; /* Managed exit is supported */
notification-support; /* Support receipt of notifications. */
diff --git a/spm/cactus/plat/arm/tc/fdts/cactus.dts b/spm/cactus/plat/arm/tc/fdts/cactus.dts
index 31b9e8e..a4c71fe 100644
--- a/spm/cactus/plat/arm/tc/fdts/cactus.dts
+++ b/spm/cactus/plat/arm/tc/fdts/cactus.dts
@@ -25,7 +25,7 @@
entrypoint-offset = <0x00002000>;
xlat-granule = <0>; /* 4KiB */
boot-order = <0>;
- messaging-method = <3>; /* Direct messaging only */
+ messaging-method = <7>; /* Indirect messaging and direct messaging. */
notification-support; /* Support receipt of notifications. */
managed-exit; /* Managed exit supported */
run-time-model = <1>; /* Run to completion */
diff --git a/tftf/tests/aarch32_tests_to_skip.txt b/tftf/tests/aarch32_tests_to_skip.txt
index 210d465..6913cb1 100644
--- a/tftf/tests/aarch32_tests_to_skip.txt
+++ b/tftf/tests/aarch32_tests_to_skip.txt
@@ -18,3 +18,4 @@
FF-A Notifications
RMI and SPM tests
FF-A SMCCC compliance
+FF-A Indirect Messaging
diff --git a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
new file mode 100644
index 0000000..0b3b6e3
--- /dev/null
+++ b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psci.h>
+#include <smccc.h>
+#include <ven_el3_svc.h>
+#include <tftf_lib.h>
+#include <uuid_utils.h>
+
+/*
+ * Vendor-Specific EL3 UUID as returned by the implementation in the Trusted
+ * Firmware.
+ */
+static const uuid_t armtf_ven_el3_svc_uuid = {
+ {0xb6, 0x01, 0x1d, 0xca},
+ {0x57, 0xc4},
+ {0x40, 0x7e},
+ 0x83, 0xf0,
+ {0xa7, 0xed, 0xda, 0xf0, 0xdf, 0x6c}
+};
+
+/**
+ * @Test_Aim@ Query the Vendor-Specific El3 Service
+ *
+ * This test targets the implementation of the vendor-specific el3 in the Trusted
+ * Firmware. If it is interfaced with a different implementation then this test
+ * will most likely fail because the values returned by the service won't be the
+ * ones expected.
+ *
+ * The following queries are performed:
+ * 1) Call UID
+ * 2) Call count - is reserved and is expected to fail
+ * 3) Call revision details
+ */
+test_result_t test_query_ven_el3_svc(void)
+{
+ smc_args ven_el3_svc_args;
+ smc_ret_values ret;
+ uuid_t ven_el3_svc_uuid;
+ char uuid_str[UUID_STR_SIZE];
+ test_result_t test_result = TEST_RESULT_SUCCESS;
+
+ /* Standard Service Call UID */
+ ven_el3_svc_args.fid = VEN_EL3_SVC_UID;
+ ret = tftf_smc(&ven_el3_svc_args);
+
+ make_uuid_from_4words(&ven_el3_svc_uuid,
+ ret.ret0, ret.ret1, ret.ret2, ret.ret3);
+ if (!uuid_equal(&ven_el3_svc_uuid, &armtf_ven_el3_svc_uuid)) {
+ tftf_testcase_printf("Wrong UUID: expected %s,\n",
+ uuid_to_str(&armtf_ven_el3_svc_uuid, uuid_str));
+ tftf_testcase_printf(" got %s\n",
+ uuid_to_str(&ven_el3_svc_uuid, uuid_str));
+ test_result = TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Standard Service Call Count which is reserved for vendor-specific el3
+ * This will return an unkown smc.
+ */
+ ven_el3_svc_args.fid = VEN_EL3_SVC_UID + 1;
+ ret = tftf_smc(&ven_el3_svc_args);
+
+ if (ret.ret0 != SMC_UNKNOWN) {
+ tftf_testcase_printf("Querying Vendor-Specific el3 service call count"
+ " which is reserved failed\n");
+ test_result = TEST_RESULT_FAIL;
+ }
+
+ /* Vendor-Specific El3 Service Call for version details */
+ ven_el3_svc_args.fid = VEN_EL3_SVC_VERSION;
+ ret = tftf_smc(&ven_el3_svc_args);
+
+ if ((ret.ret0 != VEN_EL3_SVC_VERSION_MAJOR) ||
+ (ret.ret1 != VEN_EL3_SVC_VERSION_MINOR)) {
+ tftf_testcase_printf(
+ "Vendor Specific El3 service reported wrong version: expected {%u.%u}, got {%llu.%llu}\n",
+ VEN_EL3_SVC_VERSION_MAJOR, VEN_EL3_SVC_VERSION_MINOR,
+ (unsigned long long)ret.ret0,
+ (unsigned long long)ret.ret1);
+ test_result = TEST_RESULT_FAIL;
+ }
+
+ return test_result;
+}
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 6db193c..b5bb091 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -465,16 +465,23 @@
return ffa_service_call(&args);
}
-/* Query SPMD that the rx buffer of the partition can be released */
-struct ffa_value ffa_rx_release(void)
+/* Querying the SPMC to release the rx buffers of the VM ID. */
+struct ffa_value ffa_rx_release_with_id(ffa_id_t vm_id)
{
struct ffa_value args = {
- .fid = FFA_RX_RELEASE
+ .fid = FFA_RX_RELEASE,
+ .arg1 = (uint64_t)vm_id,
};
return ffa_service_call(&args);
}
+/* Query SPMC that the rx buffer of the partition can be released */
+struct ffa_value ffa_rx_release(void)
+{
+ return ffa_rx_release_with_id(0);
+}
+
/* Map the RXTX buffer */
struct ffa_value ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages)
{
@@ -514,6 +521,39 @@
return ffa_service_call(&args);
}
+/**
+ * Copies data from the sender's send buffer to the recipient's receive buffer
+ * and notifies the receiver.
+ *
+ * `flags` may include a 'Delay Schedule Receiver interrupt'.
+ *
+ * Returns FFA_SUCCESS if the message is sent, or an error code otherwise:
+ * - INVALID_PARAMETERS: one or more of the parameters do not conform.
+ * - BUSY: receiver's mailbox was full.
+ * - DENIED: receiver is not in a state to handle the request or doesn't
+ * support indirect messages.
+ */
+struct ffa_value ffa_msg_send2_with_id(uint32_t flags, ffa_id_t sender)
+{
+ struct ffa_value args = {
+ .fid = FFA_MSG_SEND2,
+ .arg1 = sender << 16,
+ .arg2 = flags,
+ .arg3 = FFA_PARAM_MBZ,
+ .arg4 = FFA_PARAM_MBZ,
+ .arg5 = FFA_PARAM_MBZ,
+ .arg6 = FFA_PARAM_MBZ,
+ .arg7 = FFA_PARAM_MBZ
+ };
+
+ return ffa_service_call(&args);
+}
+
+struct ffa_value ffa_msg_send2(uint32_t flags)
+{
+ return ffa_msg_send2_with_id(flags, 0);
+}
+
/* Donate memory to another partition */
struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
uint32_t fragment_length)
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index a65fdb8..8fb3a72 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -10,6 +10,7 @@
#include <cactus_test_cmds.h>
#include <debug.h>
#include <ffa_endpoints.h>
+#include <assert.h>
#include <ffa_svc.h>
#include <lib/extensions/sve.h>
#include <spm_common.h>
@@ -844,3 +845,107 @@
return ffa_memory_access_init(receiver_id, data_access,
instruction_access, 0, NULL);
}
+
+/**
+ * Receives message from the mailbox, copies it into the 'buffer', gets the
+ * pending framework notifications and releases the RX buffer.
+ * Returns false if it fails to copy the message to `buffer`, or true
+ * otherwise.
+ */
+bool receive_indirect_message(void *buffer, size_t buffer_size, void *recv,
+ ffa_id_t *sender, ffa_id_t receiver, ffa_id_t own_id)
+{
+ const struct ffa_partition_msg *message;
+ struct ffa_partition_rxtx_header header;
+ ffa_id_t source_vm_id;
+ const uint32_t *payload;
+ struct ffa_value ret;
+ ffa_notification_bitmap_t fwk_notif;
+
+ if (buffer_size > FFA_MSG_PAYLOAD_MAX) {
+ return false;
+ }
+
+ ret = ffa_notification_get(receiver, 0,
+ FFA_NOTIFICATIONS_FLAG_BITMAP_SPM);
+ if (is_ffa_call_error(ret)) {
+ return false;
+ }
+
+ fwk_notif = ffa_notification_get_from_framework(ret);
+
+ if (fwk_notif == 0U) {
+ ERROR("Expected Rx buffer full notification.");
+ return false;
+ }
+
+ message = (const struct ffa_partition_msg *)recv;
+ memcpy(&header, message, sizeof(struct ffa_partition_rxtx_header));
+
+ source_vm_id = header.sender;
+
+ if (is_ffa_spm_buffer_full_notification(fwk_notif)) {
+ /*
+ * Expect the sender to always have been an SP.
+ */
+ assert(IS_SP_ID(source_vm_id));
+ }
+
+ if (header.size > buffer_size) {
+ ERROR("Error in rxtx header. Message size: %#x; "
+ "buffer size: %lu\n",
+ header.size, buffer_size);
+ return false;
+ }
+
+ payload = (const uint32_t *)message->payload;
+
+ /* Get message to free the RX buffer. */
+ memcpy(buffer, payload, header.size);
+
+ /* Check receiver ID against own ID. */
+ if (receiver != own_id) {
+ ret = ffa_rx_release_with_id(receiver);
+ } else {
+ ret = ffa_rx_release();
+ }
+
+ if (is_ffa_call_error(ret)) {
+ ERROR("Failed to release the rx buffer\n");
+ return false;
+ }
+
+ if (receiver != header.receiver) {
+ ERROR("Header receiver: %x different than expected receiver: %x\n",
+ header.receiver, receiver);
+ return false;
+ }
+
+
+ if (sender != NULL) {
+ *sender = source_vm_id;
+ }
+
+ return true;
+}
+
+/**
+ * Sends an indirect message: initializes the `ffa_rxtx_header`, copies the
+ * payload to the TX buffer.
+ * Uses the `send_flags` if any are provided in the call to FFA_MSG_SEND2.
+ */
+struct ffa_value send_indirect_message(
+ ffa_id_t from, ffa_id_t to, void *send, const void *payload,
+ size_t payload_size, uint32_t send_flags)
+{
+ struct ffa_partition_msg *message = (struct ffa_partition_msg *)send;
+
+ /* Initialize message header. */
+ ffa_rxtx_header_init(from, to, payload_size, &message->header);
+
+ /* Fill TX buffer with payload. */
+ memcpy(message->payload, payload, payload_size);
+
+ /* Send the message. */
+ return ffa_msg_send2(send_flags);
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 0a345d4..bd0df07 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -7,6 +7,7 @@
#include <arch_helpers.h>
#include <cactus_test_cmds.h>
#include "ffa_helpers.h"
+#include "tftf_lib.h"
#include <debug.h>
#include <ffa_endpoints.h>
#include <ffa_svc.h>
@@ -115,3 +116,55 @@
return host_cmp_result();
}
+
+/**
+ * Map the NS RXTX buffers to the SPM, invoke the TRP delegation
+ * service to change the RX buffer PAS to realm, invoke the
+ * FFA_PARTITON_INFO_GET interface, such that SPM does NS access
+ * to realm region and triggers GPF.
+ */
+test_result_t test_ffa_rxtx_to_realm_pas(void)
+{
+ struct mailbox_buffers mb;
+ u_register_t retmm;
+ struct ffa_value ret;
+
+ GET_TFTF_MAILBOX(mb);
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /* Delegate the shared page to Realm. */
+ retmm = host_rmi_granule_delegate((u_register_t)mb.recv);
+ if (retmm != 0UL) {
+ ERROR("Granule delegate failed, ret=0x%lx\n", retmm);
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_partition_info_get((struct ffa_uuid){{0}});
+
+ if (!is_expected_ffa_error(ret, FFA_ERROR_ABORTED)) {
+ ERROR("FFA_PARTITON_INFO_GET should terminate with"
+ "FFA_ERROR_ABORTED\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Undelegate the shared page. */
+ retmm = host_rmi_granule_undelegate((u_register_t)mb.recv);
+ if (retmm != 0UL) {
+ ERROR("Granule undelegate failed, ret=0x%lx\n", retmm);
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_partition_info_get((struct ffa_uuid){{0}});
+
+ if (is_ffa_call_error(ret)) {
+ ERROR("FFA_PARTITON_INFO_GET should succeed.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ ffa_rx_release();
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c
new file mode 100644
index 0000000..5a60a21
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2024 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "ffa_helpers.h"
+#include "spm_common.h"
+#include "tftf_lib.h"
+#include <debug.h>
+#include <smccc.h>
+
+#include <arch_helpers.h>
+#include <cactus_test_cmds.h>
+#include <ffa_endpoints.h>
+#include <ffa_svc.h>
+#include <host_realm_helper.h>
+#include <platform.h>
+#include <spm_test_helpers.h>
+#include <test_helpers.h>
+
+static const struct ffa_uuid expected_sp_uuids[] = {
+ {PRIMARY_UUID},
+ };
+
+const char expected_msg[] = "Testing FF-A message.";
+
+/*
+ *
+ * Used as the RX/TX buffers belonging to VM 1 in the forwarding FFA_RXTX_MAP
+ * tests.
+ */
+static __aligned(PAGE_SIZE) uint8_t vm1_rx_buffer[PAGE_SIZE];
+static __aligned(PAGE_SIZE) uint8_t vm1_tx_buffer[PAGE_SIZE];
+
+test_result_t test_ffa_indirect_message_sp_to_vm(void)
+{
+ struct ffa_value ret;
+ struct mailbox_buffers mb;
+ ffa_id_t header_sender;
+ const ffa_id_t vm_id = 1;
+ const ffa_id_t sender = SP_ID(1);
+ char msg[300];
+
+ /**********************************************************************
+ * Check SPMC has ffa_version and expected FF-A endpoints are deployed.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ GET_TFTF_MAILBOX(mb);
+
+ ret = ffa_rxtx_map_forward(mb.send, vm_id, vm1_rx_buffer,
+ vm1_tx_buffer);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to map buffers RX %p TX %p for VM %x\n",
+ vm1_tx_buffer, vm1_tx_buffer, vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_bitmap_create(vm_id, PLATFORM_CORE_COUNT);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to create bitmap for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Request SP to send message. */
+ ret = cactus_req_ind_msg_send_cmd(
+ HYP_ID, sender, vm_id, sender, 0);
+
+ if (!is_ffa_direct_response(ret) &&
+ cactus_get_response(ret) != CACTUS_SUCCESS) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!receive_indirect_message(&msg, ARRAY_SIZE(msg), (void *)vm1_rx_buffer,
+ &header_sender, vm_id, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (strncmp(msg, expected_msg, ARRAY_SIZE(expected_msg)) != 0) {
+ ERROR("Unexpected message: %s, expected: %s\n", msg, expected_msg);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (header_sender != sender) {
+ ERROR("Unexpected endpoints. Sender: %x Expected: %x\n",
+ header_sender, sender);
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_bitmap_destroy(vm_id);
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_rxtx_unmap_with_id(vm_id);
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test message sent from SP to VM when VM's RX is realm, the operation fails
+ * smoothly.
+ */
+test_result_t test_ffa_indirect_message_sp_to_vm_rx_realm_fail(void)
+{
+ struct ffa_value ret;
+ struct mailbox_buffers mb;
+ const ffa_id_t vm_id = 1;
+ const ffa_id_t sender = SP_ID(1);
+ ffa_id_t header_sender;
+ u_register_t ret_rmm;
+ char msg[300];
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /**********************************************************************
+ * Check SPMC has ffa_version and expected FF-A endpoints are deployed.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ GET_TFTF_MAILBOX(mb);
+
+ /* Map RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_map_forward(mb.send, vm_id, vm1_rx_buffer,
+ vm1_tx_buffer);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to map buffers RX %p TX %p for VM %x\n",
+ vm1_rx_buffer, vm1_tx_buffer, vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Create bitmap only to then demonstrate that the message can't
+ * be sent, as there are no pending notifications to the VM.
+ */
+ ret = ffa_notification_bitmap_create(vm_id, PLATFORM_CORE_COUNT);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to create bitmap for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Delegate RX buffer of VM to realm.
+ */
+ ret_rmm = host_rmi_granule_delegate((u_register_t)vm1_rx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Delegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Request SP to send message. */
+ ret = cactus_req_ind_msg_send_cmd(
+ HYP_ID, sender, vm_id, sender, 0);
+
+ if (!is_ffa_direct_response(ret) &&
+ cactus_get_response(ret) != FFA_ERROR_ABORTED) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Undelegate to reestablish the same security state for PAS. */
+ ret_rmm = host_rmi_granule_undelegate((u_register_t)vm1_rx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Undelegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Expect that attempting to receive message shall fail. */
+ if (receive_indirect_message(&msg, ARRAY_SIZE(msg), (void *)vm1_rx_buffer,
+ NULL, vm_id, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Redo the test so we check after undelegating the memory.
+ * After undelegating, the SPMC should be able to complete the
+ * operation.
+ */
+ ret = cactus_req_ind_msg_send_cmd(
+ HYP_ID, sender, vm_id, sender, 0);
+
+ if (!is_ffa_direct_response(ret) &&
+ cactus_get_response(ret) != CACTUS_SUCCESS) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!receive_indirect_message(&msg, ARRAY_SIZE(msg), (void *)vm1_rx_buffer,
+ &header_sender, vm_id, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (strncmp(msg, expected_msg, ARRAY_SIZE(expected_msg)) != 0) {
+ ERROR("Unexpected message: %s, expected: %s\n", msg, expected_msg);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (header_sender != sender) {
+ ERROR("Unexpected endpoints. Sender: %x Expected: %x\n",
+ header_sender, sender);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Cleaning up after the test: */
+
+ /* Destroy bitmap of VM. */
+ ret = ffa_notification_bitmap_destroy(vm_id);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to destroy bitmap for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Unmap RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_unmap_with_id(vm_id);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to unmap RXTX for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test message sent from VM to SP, when VM TX is in realm PAS, the operation
+ * fails smoothly.
+ */
+test_result_t test_ffa_indirect_message_vm_to_sp_tx_realm_fail(void)
+{
+ struct ffa_value ret;
+ struct mailbox_buffers mb;
+ const ffa_id_t vm_id = 1;
+ const ffa_id_t receiver = SP_ID(1);
+ u_register_t ret_rmm;
+ char payload[] = "Poisonous...";
+ struct ffa_partition_msg *message = (struct ffa_partition_msg *)vm1_tx_buffer;
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /**********************************************************************
+ * Check SPMC has ffa_version and expected FF-A endpoints are deployed.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ GET_TFTF_MAILBOX(mb);
+
+ /* Map RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_map_forward(mb.send, vm_id, vm1_rx_buffer,
+ vm1_tx_buffer);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to map buffers RX %p TX %p for VM %x\n",
+ vm1_rx_buffer, vm1_tx_buffer, vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Initialize message header. */
+ ffa_rxtx_header_init(vm_id, receiver, ARRAY_SIZE(payload), &message->header);
+
+ /* Fill TX buffer with payload. */
+ memcpy(message->payload, payload, ARRAY_SIZE(payload));
+
+ /* Delegate TX buffer of VM to realm PAS. */
+ ret_rmm = host_rmi_granule_delegate((u_register_t)vm1_tx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Delegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Expect that attempting to send message shall fail. */
+ ret = ffa_msg_send2_with_id(0, vm_id);
+
+ if (!is_expected_ffa_error(ret, FFA_ERROR_ABORTED)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Undelegate to reestablish the same security state for PAS. */
+ ret_rmm = host_rmi_granule_undelegate((u_register_t)vm1_tx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Undelegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Unmap RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_unmap_with_id(vm_id);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to unmap RXTX for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index f2c2634..ca6c75a 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -536,8 +536,8 @@
* ffa_notification_get.
*/
success_ret = (ffa_func_id(*ret) == FFA_SUCCESS_SMC32);
- from_sp = ffa_notifications_get_from_sp(*ret);
- from_vm = ffa_notifications_get_from_vm(*ret);
+ from_sp = ffa_notification_get_from_sp(*ret);
+ from_vm = ffa_notification_get_from_vm(*ret);
}
if (success_ret != true ||
@@ -557,19 +557,19 @@
struct ffa_value *ret, uint16_t *ids, uint32_t *lists_sizes,
const uint32_t max_ids_count, uint32_t lists_count, bool more_pending)
{
- if (lists_count != ffa_notifications_info_get_lists_count(*ret) ||
- more_pending != ffa_notifications_info_get_more_pending(*ret)) {
+ if (lists_count != ffa_notification_info_get_lists_count(*ret) ||
+ more_pending != ffa_notification_info_get_more_pending(*ret)) {
ERROR("Notification info get not as expected.\n"
" Lists counts: %u; more pending %u\n",
- ffa_notifications_info_get_lists_count(*ret),
- ffa_notifications_info_get_more_pending(*ret));
+ ffa_notification_info_get_lists_count(*ret),
+ ffa_notification_info_get_more_pending(*ret));
dump_ffa_value(*ret);
return false;
}
for (uint32_t i = 0; i < lists_count; i++) {
uint32_t cur_size =
- ffa_notifications_info_get_list_size(*ret,
+ ffa_notification_info_get_list_size(*ret,
i + 1);
if (lists_sizes[i] != cur_size) {
@@ -1268,6 +1268,10 @@
result = TEST_RESULT_FAIL;
}
+ if (!notifications_bitmap_destroy(per_vcpu_receiver)) {
+ result = TEST_RESULT_FAIL;
+ }
+
return result;
}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 3c03d5f..621fc69 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -129,6 +129,41 @@
return TEST_RESULT_SUCCESS;
}
+/**
+ * Test that `FFA_FEATURES(FFA_RXTX_MAP_SMC64)` returns a parameter explaining
+ * the maximum and minimum buffer size on v1.2 or greater.
+ */
+test_result_t test_ffa_features_rxtx_map(void)
+{
+
+ struct ffa_value args = {
+ .fid = FFA_FEATURES,
+ .arg1 = FFA_RXTX_MAP_SMC64,
+ };
+ struct ffa_value ret;
+ uint32_t param;
+ const uint32_t expected_param = (FFA_RXTX_MAP_MIN_BUF_4K << 0) |
+ (FFA_RXTX_MAP_MAX_BUF_PAGE_COUNT << 16);
+
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+
+ ret = ffa_service_call(&args);
+ if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) {
+ ERROR("FFA_FEATURES failed: %d(%d)\n", ffa_func_id(ret),
+ ffa_error_code(ret));
+ return TEST_RESULT_FAIL;
+ }
+
+ param = ret.arg2;
+ if (param != expected_param) {
+ ERROR("Unexpected param (expected %d, got %d)\n",
+ expected_param, param);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
/******************************************************************************
* FF-A Version ABI Tests
******************************************************************************/
@@ -384,16 +419,20 @@
ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
vm1_tx_buffer);
- if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
return TEST_RESULT_FAIL;
+ }
ret = ffa_rxtx_unmap_with_id(VM_ID(1));
- if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
return TEST_RESULT_FAIL;
+ }
ret = ffa_rxtx_unmap();
- if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
return TEST_RESULT_FAIL;
+ }
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/sip_service/test_debugfs.c b/tftf/tests/runtime_services/sip_service/test_debugfs.c
index 6c626e9..39a1bf9 100644
--- a/tftf/tests/runtime_services/sip_service/test_debugfs.c
+++ b/tftf/tests/runtime_services/sip_service/test_debugfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,9 +13,15 @@
#define SMC_OK (0)
#define DEBUGFS_VERSION (0x00000001)
-#define DEBUGFS_SMC_64 (0xC2000030)
#define MAX_PATH_LEN (256)
+#ifndef __aarch64__
+#define DEBUGFS_SMC 0x87000010
+#else
+#define DEBUGFS_SMC 0xC7000010
+#endif
+
+
/* DebugFS shared buffer area */
#ifndef PLAT_ARM_DEBUGFS_BASE
#define PLAT_ARM_DEBUGFS_BASE (0x81000000)
@@ -64,7 +70,7 @@
smc_ret_values ret;
smc_args args;
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = INIT;
args.arg2 = phys_addr;
ret = tftf_smc(&args);
@@ -77,7 +83,7 @@
smc_ret_values ret;
smc_args args;
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = VERSION;
ret = tftf_smc(&args);
@@ -92,7 +98,7 @@
strlcpy(parms->open.fname, name, MAX_PATH_LEN);
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = OPEN;
args.arg2 = (u_register_t) flags;
ret = tftf_smc(&args);
@@ -105,7 +111,7 @@
smc_ret_values ret;
smc_args args;
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = READ;
args.arg2 = (u_register_t) fd;
args.arg3 = (u_register_t) size;
@@ -125,7 +131,7 @@
smc_ret_values ret;
smc_args args;
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = CLOSE;
args.arg2 = (u_register_t) fd;
@@ -144,7 +150,7 @@
strlcpy(parms->mount.where, where, MAX_PATH_LEN);
strlcpy(parms->mount.spec, spec, MAX_PATH_LEN);
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = MOUNT;
ret = tftf_smc(&args);
@@ -160,7 +166,7 @@
strlcpy(parms->stat.path, name, MAX_PATH_LEN);
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = STAT;
ret = tftf_smc(&args);
@@ -178,7 +184,7 @@
smc_ret_values ret;
smc_args args;
- args.fid = DEBUGFS_SMC_64;
+ args.fid = DEBUGFS_SMC;
args.arg1 = SEEK;
args.arg2 = (u_register_t) fd;
args.arg3 = (u_register_t) offset;
diff --git a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
index 3c1fdaf..43685e4 100644
--- a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
+++ b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
@@ -63,6 +63,26 @@
return ret.ret0;
}
+/*
+ * Simple check to see if we are able to probe
+ * pmf versioning under vendor specific el3.
+ */
+test_result_t test_check_pmf_version(void)
+{
+ smc_args args = { 0 };
+ smc_ret_values ret;
+
+ args.fid = PMF_SMC_GET_VERSION;
+ ret = tftf_smc(&args);
+
+ if (ret.ret1 != PMF_SMC_VERSION)
+ {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
static int cycles_to_ns(uint64_t cycles, uint64_t freq, uint64_t *ns)
{
if (cycles > UINT64_MAX / 1000000000 || freq == 0)
diff --git a/tftf/tests/tests-memory-access.mk b/tftf/tests/tests-memory-access.mk
index 13b2241..5c71b2e 100644
--- a/tftf/tests/tests-memory-access.mk
+++ b/tftf/tests/tests-memory-access.mk
@@ -27,4 +27,6 @@
test_ffa_memory_sharing.c \
test_ffa_setup_and_discovery.c \
spm_test_helpers.c \
+ test_ffa_exceptions.c \
+ test_ffa_indirect_messaging.c \
)
diff --git a/tftf/tests/tests-memory-access.xml b/tftf/tests/tests-memory-access.xml
index 4318cc9..f1d96e2 100644
--- a/tftf/tests/tests-memory-access.xml
+++ b/tftf/tests/tests-memory-access.xml
@@ -43,6 +43,12 @@
function="s_memory_cannot_be_accessed_in_ns" />
</testsuite>
+ <testsuite name="SP exceptions"
+ description="SP exceptions" >
+ <testcase name="Access from a SP to a Realm region"
+ function="rl_memory_cannot_be_accessed_in_s" />
+ </testsuite>
+
<testsuite name="Invalid memory access with RME extension"
description="Invalid memory access with RME extension">
<testcase name="Access Realm memory from NS world"
@@ -57,6 +63,12 @@
function="test_ffa_mem_send_sp_realm_memory" />
<testcase name="FF-A memory share fail realm memory other constituent"
function="test_ffa_mem_lend_sp_realm_memory_separate_constituent" />
+ <testcase name="FF-A partition info get after NWd RX is in realm PAS"
+ function="test_ffa_rxtx_to_realm_pas" />
+ <testcase name="FF-A Indirect message fails if VM RX is realm"
+ function="test_ffa_indirect_message_sp_to_vm_rx_realm_fail" />
+ <testcase name="FF-A Indirect message fails if VM TX is realm"
+ function="test_ffa_indirect_message_vm_to_sp_tx_realm_fail" />
</testsuite>
</testsuites>
diff --git a/tftf/tests/tests-psci.mk b/tftf/tests/tests-psci.mk
index 0be0cef..597ee8c 100644
--- a/tftf/tests/tests-psci.mk
+++ b/tftf/tests/tests-psci.mk
@@ -1,15 +1,9 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-TESTS_SOURCES += \
- $(addprefix tftf/tests/runtime_services/standard_service/, \
- query_std_svc.c \
- unknown_smc.c \
- )
-
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/standard_service/psci/api_tests/, \
affinity_info/test_psci_affinity_info.c \
diff --git a/tftf/tests/tests-psci.xml b/tftf/tests/tests-psci.xml
index e9c612b..918d9a7 100644
--- a/tftf/tests/tests-psci.xml
+++ b/tftf/tests/tests-psci.xml
@@ -1,24 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
<testsuites>
- <!--
- Strictly speaking, this testsuite is not testing PSCI but we put it here
- nonetheless to avoid having it alone in a separate XML file.
- -->
- <testsuite name="Query runtime services" description="Generic queries as defined by the SMCCC">
- <testcase name="Unknown SMC" function="test_unknown_smc" />
- <testcase name="Query Standard Service" function="test_query_std_svc" />
- </testsuite>
-
<testsuite name="PSCI Version" description="Check the version of PSCI implemented">
- <testcase name="PSCI Version" function="test_psci_version" />
+ <testcase name="PSCI Version" function="test_psci_version" />
</testsuite>
<testsuite name="PSCI Affinity Info" description="Test PSCI AFFINITY_INFO support">
diff --git a/tftf/tests/tests-smc.mk b/tftf/tests/tests-smc.mk
index 8496cd1..5d86bf6 100644
--- a/tftf/tests/tests-smc.mk
+++ b/tftf/tests/tests-smc.mk
@@ -1,7 +1,14 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-TESTS_SOURCES += tftf/tests/runtime_services/generic/generic_smc.c
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/runtime_services/, \
+ generic/generic_smc.c \
+ standard_service/query_std_svc.c \
+ standard_service/unknown_smc.c \
+ el3/query_ven_el3_svc.c \
+ )
+
diff --git a/tftf/tests/tests-smc.xml b/tftf/tests/tests-smc.xml
index 56f987d..d63cfc3 100644
--- a/tftf/tests/tests-smc.xml
+++ b/tftf/tests/tests-smc.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -16,4 +16,11 @@
<testcase name="Yielding SMC64" function="smc64_yielding" />
</testsuite>
+ <testsuite name="Query runtime services" description="Generic queries as defined by the SMCCC">
+ <testcase name="Unknown SMC" function="test_unknown_smc" />
+ <testcase name="Query Standard Service" function="test_query_std_svc" />
+ <testcase name="Query Vendor-Specific Service" function="test_query_ven_el3_svc" />
+ <testcase name="Probe PMF Version" function="test_check_pmf_version" />
+ </testsuite>
+
</testsuites>
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index b094e87..1ac5e84 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -14,6 +14,7 @@
spm_common.c \
spm_test_helpers.c \
test_ffa_direct_messaging.c \
+ test_ffa_indirect_messaging.c \
test_ffa_interrupts.c \
test_ffa_secure_interrupts.c \
test_ffa_memory_sharing.c \
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 21d4631..cbddb98 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -11,6 +11,8 @@
description="Test FF-A Setup and Discovery interfaces" >
<testcase name="Test FFA_FEATURES"
function="test_ffa_features" />
+ <testcase name="Test FFA_FEATURES (FFA_RXTX_MAP)"
+ function="test_ffa_features_rxtx_map" />
<testcase name="Same FFA version as SPM"
function="test_ffa_version_equal" />
@@ -68,14 +70,6 @@
function="test_smccc_ext_callee_preserved" />
</testsuite>
- <testsuite name="SP exceptions"
- description="SP exceptions" >
-
- <testcase name="Access from a SP to a Realm region"
- function="rl_memory_cannot_be_accessed_in_s" />
-
- </testsuite>
-
<testsuite name="FF-A Direct messaging"
description="Test FF-A Direct messaging" >
@@ -241,4 +235,10 @@
function="test_ffa_notifications_sp_signals_vm_per_vcpu" />
</testsuite>
+ <testsuite name="FF-A Indirect Messaging"
+ description="Test FF-A Indirect messaging" >
+ <testcase name="FF-A Indirect Message from SP to VM"
+ function="test_ffa_indirect_message_sp_to_vm" />
+ </testsuite>
+
</testsuites>