SPM: Restructure memory operation functions
SPM calls spm_memcpy/spm_memset, and SP just calls memset, memcpy,
memmove and memcmp. SPM has its own header files for
spm_memcpy/spm_memset prototypes, while SP relies on toolchain headers
string.h for prototypes.
As -fno-builtin is applied, our memcpy would replace the same function
in toolchain library.
Change-Id: Iab240c96e06d55144daa0125b2d17574b648f9e1
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/secure_fw/partitions/lib/sprt/CMakeLists.inc b/secure_fw/partitions/lib/sprt/CMakeLists.inc
index 3f2b798..e4f1bd7 100644
--- a/secure_fw/partitions/lib/sprt/CMakeLists.inc
+++ b/secure_fw/partitions/lib/sprt/CMakeLists.inc
@@ -25,9 +25,10 @@
endif()
set (LIBSPRT_C_SRC
- "${LIBSPRT_DIR}/tfm_libsprt_c_memcpy.c"
- "${LIBSPRT_DIR}/tfm_libsprt_c_memmove.c"
- "${LIBSPRT_DIR}/tfm_libsprt_c_memcmp.c"
+ "${LIBSPRT_DIR}/crt_memcpy.c"
+ "${LIBSPRT_DIR}/crt_memmove.c"
+ "${LIBSPRT_DIR}/crt_memcmp.c"
+ "${LIBSPRT_DIR}/crt_memset.c"
"${LIBSPRT_DIR}/service_api.c"
"${TFM_ROOT_DIR}/interface/src/log/tfm_log_raw.c")
diff --git a/secure_fw/partitions/lib/sprt/crt_impl_private.h b/secure_fw/partitions/lib/sprt/crt_impl_private.h
new file mode 100644
index 0000000..b427f0c
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/crt_impl_private.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __CRT_IMPL_PRIVATE_H__
+#define __CRT_IMPL_PRIVATE_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define GET_MEM_ADDR_BIT0(x) ((x) & 0x1)
+#define GET_MEM_ADDR_BIT1(x) ((x) & 0x2)
+
+union tfm_mem_addr_t {
+ uintptr_t uint_addr; /* Address */
+ uint8_t *p_byte; /* Byte copy */
+ uint16_t *p_dbyte; /* Double byte copy */
+ uint32_t *p_qbyte; /* Quad byte copy */
+};
+
+#endif /* __CRT_IMPL_PRIVATE_H__ */
diff --git a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcmp.c b/secure_fw/partitions/lib/sprt/crt_memcmp.c
similarity index 76%
rename from secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcmp.c
rename to secure_fw/partitions/lib/sprt/crt_memcmp.c
index 149e18c..0370ff0 100644
--- a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcmp.c
+++ b/secure_fw/partitions/lib/sprt/crt_memcmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -8,7 +8,7 @@
#include <stddef.h>
#include <stdint.h>
-int tfm_sprt_c_memcmp(const void *s1, const void *s2, size_t n)
+int memcmp(const void *s1, const void *s2, size_t n)
{
int result = 0;
const uint8_t *p1 = (const uint8_t *)s1;
diff --git a/secure_fw/partitions/lib/sprt/crt_memcpy.c b/secure_fw/partitions/lib/sprt/crt_memcpy.c
new file mode 100644
index 0000000..21a6301
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/crt_memcpy.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "crt_impl_private.h"
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ union tfm_mem_addr_t p_dest, p_src;
+
+ p_dest.uint_addr = (uintptr_t)dest;
+ p_src.uint_addr = (uintptr_t)src;
+
+ /* Byte copy for unaligned address. check the last bit of address. */
+ while (n && (GET_MEM_ADDR_BIT0(p_dest.uint_addr) ||
+ GET_MEM_ADDR_BIT0(p_src.uint_addr))) {
+ *p_dest.p_byte++ = *p_src.p_byte++;
+ n--;
+ }
+
+ /*
+ * Double byte copy for aligned address.
+ * Check the 2nd last bit of address.
+ */
+ while (n >= sizeof(uint16_t) && (GET_MEM_ADDR_BIT1(p_dest.uint_addr) ||
+ GET_MEM_ADDR_BIT1(p_src.uint_addr))) {
+ *(p_dest.p_dbyte)++ = *(p_src.p_dbyte)++;
+ n -= sizeof(uint16_t);
+ }
+
+ /* Quad byte copy for aligned address. */
+ while (n >= sizeof(uint32_t)) {
+ *(p_dest.p_qbyte)++ = *(p_src.p_qbyte)++;
+ n -= sizeof(uint32_t);
+ }
+
+ /* Byte copy for the remaining bytes. */
+ while (n--) {
+ *p_dest.p_byte++ = *p_src.p_byte++;
+ }
+
+ return dest;
+}
diff --git a/secure_fw/partitions/lib/sprt/crt_memmove.c b/secure_fw/partitions/lib/sprt/crt_memmove.c
new file mode 100644
index 0000000..b24a39d
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/crt_memmove.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+#include "crt_impl_private.h"
+
+static void *memcpy_r(void *dest, const void *src, size_t n)
+{
+ union tfm_mem_addr_t p_dest, p_src;
+
+ p_dest.uint_addr = (uintptr_t)dest + n;
+ p_src.uint_addr = (uintptr_t)src + n;
+
+ /* Byte copy for unaligned address. check the last bit of address. */
+ while (n && (GET_MEM_ADDR_BIT0(p_dest.uint_addr) ||
+ GET_MEM_ADDR_BIT0(p_src.uint_addr))) {
+ *(--p_dest.p_byte) = *(--p_src.p_byte);
+ n--;
+ }
+
+ /* Double byte copy for aligned address.
+ * Check the 2nd last bit of address.
+ */
+ while (n >= sizeof(uint16_t) && (GET_MEM_ADDR_BIT1(p_dest.uint_addr) ||
+ GET_MEM_ADDR_BIT1(p_src.uint_addr))) {
+ *(--p_dest.p_dbyte) = *(--p_src.p_dbyte);
+ n -= sizeof(uint16_t);
+ }
+
+ /* Quad byte copy for aligned address. */
+ while (n >= sizeof(uint32_t)) {
+ *(--p_dest.p_qbyte) = *(--p_src.p_qbyte);
+ n -= sizeof(uint32_t);
+ }
+
+ /* Byte copy for the remaining bytes. */
+ while (n--) {
+ *(--p_dest.p_byte) = *(--p_src.p_byte);
+ }
+
+ return dest;
+}
+
+/*
+ * For overlapped memory area:
+ * 1) overlapped: use reverse memory move.
+ * 2) non-overlapped: use forward memory move.
+ */
+void *memmove(void *dest, const void *src, size_t n)
+{
+ /*
+ * FixMe: Add a "assert (dest == NULL || src == NULL)" here
+ * after "assert()" for sprtl is implemented.
+ */
+ if (src >= dest) {
+ memcpy(dest, src, n);
+ } else {
+ memcpy_r(dest, src, n);
+ }
+
+ return dest;
+}
diff --git a/secure_fw/partitions/lib/sprt/crt_memset.c b/secure_fw/partitions/lib/sprt/crt_memset.c
new file mode 100644
index 0000000..92dd5a1
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/crt_memset.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "crt_impl_private.h"
+
+void *memset(void *s, int c, size_t n)
+{
+ union tfm_mem_addr_t p_mem;
+ uint32_t quad_pattern;
+
+ p_mem.p_byte = (uint8_t *)s;
+ quad_pattern = (((uint8_t)c) << 24) | (((uint8_t)c) << 16) |
+ (((uint8_t)c) << 8) | ((uint8_t)c);
+
+ while (n && (p_mem.uint_addr & (sizeof(uint32_t) - 1))) {
+ *p_mem.p_byte++ = (uint8_t)c;
+ n--;
+ }
+
+ while (n >= sizeof(uint32_t)) {
+ *p_mem.p_qbyte++ = quad_pattern;
+ n -= sizeof(uint32_t);
+ }
+
+ while (n--) {
+ *p_mem.p_byte++ = (uint8_t)c;
+ }
+
+ return s;
+}
diff --git a/secure_fw/partitions/lib/sprt/tfm_libsprt_c.h b/secure_fw/partitions/lib/sprt/tfm_libsprt_c.h
deleted file mode 100644
index f303dc4..0000000
--- a/secure_fw/partitions/lib/sprt/tfm_libsprt_c.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __TFM_LIBSPRT_C_H__
-#define __TFM_LIBSPRT_C_H__
-
-#include <stddef.h>
-
-/**
- * \brief This function moves 'n' bytes from 'src' to 'dest'.
- *
- * \param[out] dest Destination address
- * \param[in] src Source address
- * \param[in] n Number of bytes to be moved
- *
- * \retval dest Destination address
- * \note Memory overlap has been taken into consideration
- * and processed properly in the function.
- */
-void *tfm_sprt_c_memmove(void *dest, const void *src, size_t n);
-
-/**
- * \brief This function copies 'n' bytes from 'src' to 'dest'.
- *
- * \param[out] dest Destination address
- * \param[in] src Source address
- * \param[in] n Number of bytes to be copied
- *
- * \retval dest Destination address
- * \note It has the same effect as tfm_sprt_c_memmove().
- */
-void *tfm_sprt_c_memcpy(void *dest, const void *src, size_t n);
-
-/**
- * \brief Compare the first 'n' bytes of the memory areas 's1' and 's2'.
- *
- * \param[in] s1 The address of the first memory area
- * \param[in] s2 The address of the second memory area
- * \param[in] n The size(Byte) to compare
- *
- * \retval > 0 The first n bytes of s1 great than the first n
- * bytes of s2
- * \retval < 0 The first n bytes of s1 less than the first n
- * bytes of s2
- * \retval = 0 The first n bytes of s1 equal to the first n
- * bytes of s2
- */
-int tfm_sprt_c_memcmp(const void *s1, const void *s2, size_t n);
-
-#endif /* __TFM_LIBSPRT_C_H__ */
diff --git a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcpy.c b/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcpy.c
deleted file mode 100644
index 919d051..0000000
--- a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memcpy.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include <stddef.h>
-#include "tfm_libsprt_c.h"
-
-void *tfm_sprt_c_memcpy(void *dest, const void *src, size_t n)
-{
- return tfm_sprt_c_memmove(dest, src, n);
-}
diff --git a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memmove.c b/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memmove.c
deleted file mode 100644
index e46747e..0000000
--- a/secure_fw/partitions/lib/sprt/tfm_libsprt_c_memmove.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include <stdint.h>
-#include <stddef.h>
-#include "tfm_libsprt_c.h"
-
-#define GET_MEM_ADDR_BIT0(x) ((x) & 0x1)
-#define GET_MEM_ADDR_BIT1(x) ((x) & 0x2)
-
-union tfm_mem_addr_t {
- uintptr_t uint_addr;
- uint8_t *p_byte;
- uint16_t *p_dbyte;
- uint32_t *p_qbyte;
-};
-
-/*
- * Consider 3 conditions.
- * 1) quad-byte copy (qbyte)
- * 2) double-byte copy (dbyte)
- * 3) byte copy
- *
- * And for overlapped memory area.
- * 1) overlapped: use backward memory move.
- * 2) non-overlapped: use forward memory move.
- */
-
-static void *tfm_memmove_forward(void *dest, const void *src, size_t n)
-{
- union tfm_mem_addr_t p_dest, p_src;
-
- p_dest.uint_addr = (uintptr_t)dest;
- p_src.uint_addr = (uintptr_t)src;
-
- /* byte copy for unaligned address. check the last bit of address. */
- while (n && (GET_MEM_ADDR_BIT0(p_dest.uint_addr) ||
- GET_MEM_ADDR_BIT0(p_src.uint_addr))) {
- *p_dest.p_byte++ = *p_src.p_byte++;
- n--;
- }
-
- /* dbyte-copy for aligned address. check the 2nd last bit of address. */
- while (n >= sizeof(uint16_t) && (GET_MEM_ADDR_BIT1(p_dest.uint_addr) ||
- GET_MEM_ADDR_BIT1(p_src.uint_addr))) {
- *(p_dest.p_dbyte)++ = *(p_src.p_dbyte)++;
- n -= sizeof(uint16_t);
- }
-
- /* qbyte-copy for aligned address. */
- while (n >= sizeof(uint32_t)) {
- *(p_dest.p_qbyte)++ = *(p_src.p_qbyte)++;
- n -= sizeof(uint32_t);
- }
-
- /* byte copy for the remaining bytes. */
- while (n--) {
- *p_dest.p_byte++ = *p_src.p_byte++;
- }
-
- return dest;
-}
-
-static void *tfm_memmove_backward(void *dest, const void *src, size_t n)
-{
- union tfm_mem_addr_t p_dest, p_src;
-
- p_dest.uint_addr = (uintptr_t)dest + n;
- p_src.uint_addr = (uintptr_t)src + n;
-
- /* byte copy for unaligned address. check the last bit of address. */
- while (n && (GET_MEM_ADDR_BIT0(p_dest.uint_addr) ||
- GET_MEM_ADDR_BIT0(p_src.uint_addr))) {
- *(--p_dest.p_byte) = *(--p_src.p_byte);
- n--;
- }
-
- /* dbyte-copy for aligned address. check the 2nd last bit of address. */
- while (n >= sizeof(uint16_t) && (GET_MEM_ADDR_BIT1(p_dest.uint_addr) ||
- GET_MEM_ADDR_BIT1(p_src.uint_addr))) {
- *(--p_dest.p_dbyte) = *(--p_src.p_dbyte);
- n -= sizeof(uint16_t);
- }
-
- /* qbyte-copy for aligned address. */
- while (n >= sizeof(uint32_t)) {
- *(--p_dest.p_qbyte) = *(--p_src.p_qbyte);
- n -= sizeof(uint32_t);
- }
-
- /* byte copy for the remaining bytes. */
- while (n--) {
- *(--p_dest.p_byte) = *(--p_src.p_byte);
- }
-
- return dest;
-}
-
-void *tfm_sprt_c_memmove(void *dest, const void *src, size_t n)
-{
- /*
- * FixMe: Add a "assert (dest == NULL || src == NULL)" here
- * after "assert()" for sprtl is implemented.
- */
- if (src < dest) {
- tfm_memmove_backward(dest, src, n);
- } else {
- tfm_memmove_forward(dest, src, n);
- }
-
- return dest;
-}