Merge "fix(spm): reference to ffa_value struct fields"
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 0ad8c42..1635bf8 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -685,6 +685,9 @@
 struct ffa_value ffa_notification_get(ffa_id_t receiver, uint32_t vcpu_id,
 				      uint32_t flags);
 struct ffa_value ffa_notification_info_get(void);
+
+struct ffa_value ffa_console_log(const char* message, size_t char_count);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* FFA_HELPERS_H */
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 4a62a79..8307e11 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -101,6 +101,9 @@
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
 
+/* Implementation defined function numbers */
+#define FFA_FNUM_CONSOLE_LOG			U(0x8A)
+
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
 #define FFA_SUCCESS_SMC32	FFA_FID(SMC_32, FFA_FNUM_SUCCESS)
@@ -141,6 +144,9 @@
 	FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET)
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 
+/* Implementation defined SMC32 FIDs */
+#define FFA_CONSOLE_LOG_SMC32	FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
+
 /* FFA SMC64 FIDs */
 #define FFA_SUCCESS_SMC64	FFA_FID(SMC_64, FFA_FNUM_SUCCESS)
 #define FFA_RXTX_MAP_SMC64	FFA_FID(SMC_64, FFA_FNUM_RXTX_MAP)
@@ -157,6 +163,9 @@
 	FFA_FID(SMC_64, FFA_FNUM_SECONDARY_EP_REGISTER)
 #define FFA_NOTIFICATION_INFO_GET_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
+
+/* Implementation defined SMC64 FIDs */
+#define FFA_CONSOLE_LOG_SMC64	FFA_FID(SMC_64, FFA_FNUM_CONSOLE_LOG)
 /*
  * Reserve a special value for traffic targeted to the Hypervisor or SPM.
  */
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index 252eba0..dd98459 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -189,6 +189,19 @@
 	announce_test_end(test_spm_id_get);
 }
 
+void ffa_console_log_test(void)
+{
+	const char *test_name = "FFA_CONSOLE_LOG SMC Function";
+	announce_test_start(test_name);
+
+	const char test_string[] = "[FFA_CONSOLE_LOG]: Hello World!\n";
+	struct ffa_value ret = ffa_console_log(test_string, sizeof(test_string));
+
+	expect(ffa_func_id(ret), FFA_SUCCESS_SMC32);
+
+	announce_test_end(test_name);
+}
+
 void ffa_tests(struct mailbox_buffers *mb)
 {
 	const char *test_ffa = "FFA Interfaces";
@@ -198,6 +211,7 @@
 	ffa_features_test();
 	ffa_version_test();
 	ffa_spm_id_get_test();
+	ffa_console_log_test();
 	ffa_partition_info_get_test(mb);
 
 	announce_test_section_end(test_ffa);
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index e5c2590..d67a42e 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -3,11 +3,12 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <smccc.h>
+#include <assert.h>
 
 #include <ffa_endpoints.h>
 #include <ffa_helpers.h>
 #include <ffa_svc.h>
+#include <smccc.h>
 
 struct ffa_value ffa_service_call(struct ffa_value *args)
 {
@@ -633,3 +634,40 @@
 
 	return ffa_service_call(&args);
 }
+
+static size_t char_to_arg_helper(const char *message, size_t size,
+				 u_register_t *arg)
+{
+	size_t to_write = size > sizeof(uint64_t) ? sizeof(uint64_t) : size;
+
+	for (int i = 0; i < to_write; i++) {
+		((char *)arg)[i] = message[i];
+	}
+	return to_write;
+}
+
+struct ffa_value ffa_console_log(const char *message, size_t char_count)
+{
+	struct ffa_value args = {
+		.fid = FFA_CONSOLE_LOG_SMC64,
+		.arg1 = char_count,
+	};
+	size_t written = 0;
+
+	assert(char_count <= sizeof(uint64_t) * 6);
+
+	written += char_to_arg_helper(&message[written], char_count - written,
+			&args.arg2);
+	written += char_to_arg_helper(&message[written], char_count - written,
+			&args.arg3);
+	written += char_to_arg_helper(&message[written], char_count - written,
+			&args.arg4);
+	written += char_to_arg_helper(&message[written], char_count - written,
+			&args.arg5);
+	written += char_to_arg_helper(&message[written], char_count - written,
+			&args.arg6);
+	char_to_arg_helper(&message[written], char_count - written,
+			&args.arg7);
+
+	return ffa_service_call(&args);
+}