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;
-}