TFM Core: Add support for ARMv8-M baseline to TF-M Core

Supported assembly instructions and their variants differ on mainline and
baseline ARMv8-M architecture. This change adds compile time selectable
alternative implementation to support baseline.

Change-Id: Icf82e6381edec724f35947309d3d6fe99f7ce588
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/secure_fw/core/tfm_handler.c b/secure_fw/core/tfm_handler.c
index 9b9e0fa..6c3130c 100644
--- a/secure_fw/core/tfm_handler.c
+++ b/secure_fw/core/tfm_handler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -141,6 +141,7 @@
     }
 }
 
+#if defined(__ARM_ARCH_8M_MAIN__)
 __attribute__((naked)) void SVC_Handler(void)
 {
     __ASM(
@@ -154,6 +155,29 @@
     "BL      SVCHandler_main\n"
     "POP     {r1, pc}\n");
 }
+#elif defined(__ARM_ARCH_8M_BASE__)
+__attribute__((naked)) void SVC_Handler(void)
+{
+    __ASM(
+    "MOVS    r0, #4\n"  /* Check store SP in thread mode to r0 */
+    "MOV     r1, lr\n"
+    "TST     r0, r1\n"
+    "BEQ     handler\n"
+    "MRS     r0, PSP\n"  /* Coming from thread mode */
+    "B sp_stored\n"
+    "handler:\n"
+    "MRS     r0, MSP\n"  /* Coming from handler mode */
+    "sp_stored:\n"
+    "PUSH    {r0, lr}\n"
+    "MOV     r1, sp\n"
+    "adds    r1, r1, #4\n"
+    "BL      SVCHandler_main\n"
+    "POP     {r1, pc}\n");
+}
+#else
+#error "Unsupported ARM Architecture."
+#endif
+
 
 int32_t SVCHandler_main(uint32_t *svc_args, uint32_t *lr_ptr)
 {
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index 7aefd4f..d2d885a 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -313,6 +313,7 @@
     return TFM_SUCCESS;
 }
 
+#if defined(__ARM_ARCH_8M_MAIN__)
 __attribute__((naked)) static int32_t tfm_core_exc_return_to_service(void)
 {
     /* Save all callee-saved registers to prevent malicious service from
@@ -327,6 +328,42 @@
 "return_from_service:\n"
     "POP    {r4-r12, pc}\n");
 }
+#elif defined(__ARM_ARCH_8M_BASE__)
+__attribute__((naked)) static int32_t tfm_core_exc_return_to_service(void)
+{
+    /* Save all callee-saved registers to prevent malicious service from
+     * modifying execution state.
+     * Save LR for return address.
+     * r12 is used as padding for 8-byte stack alignment
+     */
+    __ASM(
+    "PUSH   {lr}\n"
+    "PUSH   {r4-r7}\n"
+    "MOV    r4, r8\n"
+    "MOV    r5, r9\n"
+    "MOV    r6, r10\n"
+    "MOV    r7, r11\n"
+    "PUSH   {r4-r7}\n"
+    "MOV    r4, r12\n"
+    "PUSH   {r4}\n"
+    "MOVS   r0, #2\n"
+    "MVNS   r0, r0\n"
+    "BX     r0\n"
+"return_from_service:\n"
+    "POP    {r4}\n"
+    "MOV    r12, r4\n"
+    "POP    {r4-r7}\n"
+    "MOV    r8, r4\n"
+    "MOV    r9, r5\n"
+    "MOV    r10, r6\n"
+    "MOV    r11, r7\n"
+    "POP    {r4-r7}\n"
+    "POP    {pc}\n");
+}
+#else
+#error "Unsupported ARM Architecture."
+#endif
+
 extern void return_from_service(void);
 
 static int32_t tfm_core_call_service(struct tfm_sfn_req_s *desc_ptr)