Test: Duplicate log interface between TF-M and tf-m-tests
SPM and Partitions will use different log api, so there will be no
shared log api under 'interface' folder in future. Duplicate log
interface here for NS usage. The log api is copied from TF-M v1.1.
Change-Id: I1209c57366ee32a1d2a1d4524d156dad7a110d1f
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index e3ee923..d7577cf 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -72,7 +72,7 @@
"${CMAKE_CURRENT_LIST_DIR}/main_ns.c"
"${CMAKE_CURRENT_LIST_DIR}/tfm_integ_test.c"
"${CMAKE_CURRENT_LIST_DIR}/os_wrapper_cmsis_rtos_v2.c"
- "${TFM_ROOT_DIR}/interface/src/log/tfm_log_raw.c"
+ "${CMAKE_CURRENT_LIST_DIR}/../log/tfm_log_raw.c"
)
if (NOT DEFINED TFM_MULTI_CORE_TOPOLOGY OR NOT TFM_MULTI_CORE_TOPOLOGY)
diff --git a/app/main_ns.c b/app/main_ns.c
index fc874bd..53a4f47 100644
--- a/app/main_ns.c
+++ b/app/main_ns.c
@@ -25,7 +25,7 @@
#include "tfm_ns_mailbox.h"
#endif
#include "log/tfm_assert.h"
-#include "log/tfm_log.h"
+#include "tfm_log.h"
#include "uart_stdout.h"
#include "region.h"
diff --git a/app/tfm_log.h b/app/tfm_log.h
new file mode 100644
index 0000000..5b8a06f
--- /dev/null
+++ b/app/tfm_log.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_LOG_H__
+#define __TFM_LOG_H__
+
+#include "log/tfm_log_raw.h"
+
+/* Functions and macros in this file is for 'thread mode' usage. */
+
+#define LOG_MSG(...) tfm_log_printf(__VA_ARGS__)
+
+#endif /* __TFM_LOG_H__ */
diff --git a/log/tfm_log_raw.c b/log/tfm_log_raw.c
new file mode 100644
index 0000000..86cf1c3
--- /dev/null
+++ b/log/tfm_log_raw.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include "uart_stdout.h"
+
+#define PRINT_BUFF_SIZE 32
+#define NUM_BUFF_SIZE 12
+
+struct formatted_buffer_t {
+ size_t pos;
+ uint8_t buf[PRINT_BUFF_SIZE];
+};
+
+const char hex_digits_lo[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+const char hex_digits_up[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+static void _tfm_flush_formatted_buffer(struct formatted_buffer_t *pb,
+ uint8_t data)
+{
+ pb->buf[pb->pos++] = data;
+ if (pb->pos >= PRINT_BUFF_SIZE) {
+ pb->pos = 0;
+ /* uart flush and print here. */
+ stdio_output_string(pb->buf, PRINT_BUFF_SIZE);
+ }
+}
+
+static int _tfm_string_output(struct formatted_buffer_t *pb,
+ const char *str)
+{
+ int count = 0;
+
+ while (*str) {
+ _tfm_flush_formatted_buffer(pb, *str++);
+ count++;
+ }
+
+ return count;
+}
+
+static int _tfm_dec_num_output(struct formatted_buffer_t *pb,
+ int32_t num, uint8_t sign)
+{
+ int count = 0;
+ uint8_t num_buff[NUM_BUFF_SIZE] = {0};
+ uint32_t number = (uint32_t)num;
+ uint32_t k = 0;
+
+ if (sign == 'd' && num < 0) {
+ _tfm_flush_formatted_buffer(pb, '-');
+ count++;
+ number = -num;
+ }
+
+ do {
+ num_buff[k++] = '0' + number % 10;
+ number /= 10;
+ } while (number);
+
+ while (k) {
+ _tfm_flush_formatted_buffer(pb, num_buff[--k]);
+ count++;
+ }
+
+ return count;
+}
+
+static int _tfm_hex_num_output(struct formatted_buffer_t *pb, uint32_t num,
+ const char *hex_digits)
+{
+ int count = 0;
+ uint8_t num_buff[NUM_BUFF_SIZE] = {0};
+ uint32_t k = 0;
+
+ do {
+ num_buff[k++] = hex_digits[num & 0x0f];
+ num >>= 4;
+ } while (num);
+
+ while (k) {
+ _tfm_flush_formatted_buffer(pb, num_buff[--k]);
+ count++;
+ }
+
+ return count;
+}
+
+static int _tfm_log_vprintf(const char *fmt, va_list ap)
+{
+ int count = 0;
+ struct formatted_buffer_t outputbuf;
+
+ outputbuf.pos = 0;
+
+ while (*fmt) {
+ if (*fmt == '%') {
+ switch (*(++fmt)) {
+ case 'd':
+ case 'i':
+ count += _tfm_dec_num_output(&outputbuf,
+ va_arg(ap, int32_t), 'd');
+ break;
+ case 'u':
+ count += _tfm_dec_num_output(&outputbuf,
+ va_arg(ap, int32_t), 'u');
+ break;
+ case 'x':
+ count += _tfm_hex_num_output(&outputbuf, va_arg(ap, uint32_t),
+ hex_digits_lo);
+ break;
+ case 'X':
+ count += _tfm_hex_num_output(&outputbuf, va_arg(ap, uint32_t),
+ hex_digits_up);
+ break;
+ case 'p':
+ count += _tfm_string_output(&outputbuf, "0x");
+ count += _tfm_hex_num_output(&outputbuf, va_arg(ap, uint32_t),
+ hex_digits_lo);
+ break;
+ case 's':
+ count += _tfm_string_output(&outputbuf, va_arg(ap, char*));
+ break;
+ case 'c':
+ _tfm_flush_formatted_buffer(&outputbuf,
+ (uint8_t)va_arg(ap, int32_t));
+ count++;
+ break;
+ case '%':
+ _tfm_flush_formatted_buffer(&outputbuf, '%');
+ count++;
+ break;
+ default:
+ count += _tfm_string_output(&outputbuf, "[Unsupported Tag]");
+ continue;
+ }
+ fmt++;
+ } else {
+ _tfm_flush_formatted_buffer(&outputbuf, *fmt++);
+ count++;
+ }
+ }
+
+ /* End of printf, flush buf */
+ if (outputbuf.pos) {
+ count += stdio_output_string(outputbuf.buf, outputbuf.pos);
+ }
+
+ return count;
+}
+
+int tfm_log_printf(const char *fmt, ...)
+{
+ int count = 0;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = _tfm_log_vprintf(fmt, ap);
+ va_end(ap);
+
+ return count;
+}
diff --git a/log/tfm_log_raw.h b/log/tfm_log_raw.h
new file mode 100644
index 0000000..7a5a942
--- /dev/null
+++ b/log/tfm_log_raw.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_LOG_RAW_H__
+#define __TFM_LOG_RAW_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Prints log messages
+ *
+ * \param[in] fmt Formatted string
+ * \param[in] ... Viriable length argument
+ *
+ * \return Number of chars printed
+ *
+ * \note This function has the similar input argument format as
+ * the 'printf' function. But it supports only some basic
+ * formats like 'sdicpuxX' and '%'. It will output
+ * "[Unsupported Tag]" when none of the above formats match
+ *
+ * \details The following output formats are supported.
+ * %s - string
+ * %d - decimal signed integer (same for %i)
+ * %u - decimal unsigned integer
+ * %x - hex in lowercase
+ * %X - hex in uppercase
+ * %p - hex address of a pointer in lowercase
+ * %c - character
+ * %% - the '%' symbol
+ */
+int tfm_log_printf(const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_LOG_RAW_H__ */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 969a941..02b3bc5 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -150,11 +150,12 @@
add_subdirectory(${TFM_ROOT_DIR}/lib/ext/qcbor ${CMAKE_CURRENT_BINARY_DIR}/qcbor)
endif()
+set(TEST_SRC "${CMAKE_CURRENT_LIST_DIR}/../log/tfm_log_raw.c")
if (TFM_BUILD_IN_SPE)
#Build the secure library. Even though secure tests files depend on
#tfm_qcbor, this is not expressed here as the tfm_attest library is expected
#to hold the compiled tfm_qcbor files.
- add_library(tfm_secure_tests STATIC ${ALL_SRC_C} ${ALL_SRC_C_S})
+ add_library(tfm_secure_tests STATIC ${ALL_SRC_C} ${ALL_SRC_C_S} ${TEST_SRC})
if (ENABLE_ATTESTATION_SERVICE_TESTS)
target_sources(tfm_secure_tests PRIVATE $<TARGET_OBJECTS:tfm_t_cose_verify> $<TARGET_OBJECTS:tfm_qcbor_decode>)
endif()
@@ -182,7 +183,7 @@
else ()
#Build the non-secure library
set(CMAKE_STATIC_LIBRARY_PREFIX_C "lib")
- add_library(tfm_non_secure_tests STATIC ${ALL_SRC_C} ${ALL_SRC_C_NS})
+ add_library(tfm_non_secure_tests STATIC ${ALL_SRC_C} ${ALL_SRC_C_NS} ${TEST_SRC})
embedded_target_include_directories(TARGET tfm_non_secure_tests PATH ${CMSIS_DIR}/RTOS2/Include ABSOLUTE APPEND)