SPM: Share 'memcpy' and 'memset' with partitions

TF-M applies isolation rule I3, which allows code-sharing between
cross-domain components. This makes separating fundamental APIs
such as memset/memcpy less significant. This patch shares these
two fundamental APIs memset/memcpy between SPM and partitions.

A slight optimization is made on the implementation - removes
unnecessary half-word copying.

Change-Id: I7d4c931aefd94d56468806ab768048da156e4656
Signed-off-by: Ken Liu <Ken.Liu@arm.com>
diff --git a/secure_fw/partitions/lib/sprt/CMakeLists.txt b/secure_fw/partitions/lib/sprt/CMakeLists.txt
index 1e7a19b..fede342 100644
--- a/secure_fw/partitions/lib/sprt/CMakeLists.txt
+++ b/secure_fw/partitions/lib/sprt/CMakeLists.txt
@@ -18,11 +18,11 @@
 target_sources(tfm_sprt
     PRIVATE
         ./crt_memcmp.c
-        ./crt_memcpy.c
         ./crt_memmove.c
-        ./crt_memset.c
         ./crt_strnlen.c
         ./service_api.c
+        ${CMAKE_SOURCE_DIR}/secure_fw/shared/crt_memcpy.c
+        ${CMAKE_SOURCE_DIR}/secure_fw/shared/crt_memset.c
         $<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./sprt_partition_metadata_indicator.c>
         $<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./sprt_main.c>
         $<$<BOOL:${CONFIG_TFM_SPM_BACKEND_IPC}>:./sfn_common_thread.c>
diff --git a/secure_fw/partitions/lib/sprt/crt_impl_private.h b/secure_fw/partitions/lib/sprt/crt_impl_private.h
deleted file mode 100644
index b427f0c..0000000
--- a/secure_fw/partitions/lib/sprt/crt_impl_private.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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/crt_memcpy.c b/secure_fw/partitions/lib/sprt/crt_memcpy.c
deleted file mode 100644
index 21a6301..0000000
--- a/secure_fw/partitions/lib/sprt/crt_memcpy.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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
index b24a39d..a4dbf7b 100644
--- a/secure_fw/partitions/lib/sprt/crt_memmove.c
+++ b/secure_fw/partitions/lib/sprt/crt_memmove.c
@@ -10,41 +10,35 @@
 
 static void *memcpy_r(void *dest, const void *src, size_t n)
 {
-    union tfm_mem_addr_t p_dest, p_src;
+    union composite_addr_t p_dst, p_src;
 
-    p_dest.uint_addr = (uintptr_t)dest + n;
-    p_src.uint_addr = (uintptr_t)src + n;
+    p_dst.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);
+    while (n && (ADDR_WORD_UNALIGNED(p_dst.uint_addr) ||
+                 ADDR_WORD_UNALIGNED(p_src.uint_addr))) {
+        *(--p_dst.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);
+        *(--p_dst.p_word) = *(--p_src.p_word);
         n -= sizeof(uint32_t);
     }
 
     /* Byte copy for the remaining bytes. */
     while (n--) {
-        *(--p_dest.p_byte) = *(--p_src.p_byte);
+        *(--p_dst.p_byte) = *(--p_src.p_byte);
     }
 
     return dest;
 }
 
+/* Mind the direction for copying in memcpy! */
+#define memcpy_f memcpy
+
 /*
  * For overlapped memory area:
  * 1) overlapped: use reverse memory move.
@@ -52,15 +46,9 @@
  */
 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);
+        return memcpy_f(dest, src, n);
     } else {
-        memcpy_r(dest, src, n);
+        return 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
deleted file mode 100644
index 92dd5a1..0000000
--- a/secure_fw/partitions/lib/sprt/crt_memset.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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;
-}