SPM: Ensure Thread arch context is updated when thread sleeps

When a Partition thread waits for events, the arch context(PSP)
should be updated to the thread struct so that when it is woken up
the return value can be set by referring to the PSP -
tfm_core_thrd_set_retval.

The PSP is updated in PendSV Handler.
As PendSV has the lowest priority, it could be preempted by any
interrupts.
In interrupt handling, Partition Thread could be woken up while
the PSP in thread struct has not been updated yet.

This patch adds tfm_arch_get_ctx() function to get context value
to ctx struct. And it is called wherever it is needed.
This call is ensured to update the thread context as it's called in
SVC Hander code.

This patch also renames the tfm_arch_update_ctx to tfm_arch_set_ctx
to match the new API and reflects what it does more properly.

Change-Id: I66bed1f28b3d0243beb6a47d7bd6c41a5afdda0a
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
index 4f2fb3a..5058dd8 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -118,11 +118,21 @@
 }
 
 /**
+ * \brief Get architecture context value into context struct
+ *
+ * \param[in] p_actx        Pointer of context data
+ */
+__STATIC_INLINE void tfm_arch_get_ctx(struct tfm_arch_ctx_t *p_actx)
+{
+    p_actx->sp = __get_PSP();
+}
+
+/**
  * \brief Update architecture context value into hardware
  *
  * \param[in] p_actx        Pointer of context data
  */
-__STATIC_INLINE void tfm_arch_update_ctx(struct tfm_arch_ctx_t *p_actx)
+__STATIC_INLINE void tfm_arch_set_ctx(struct tfm_arch_ctx_t *p_actx)
 {
     __set_PSP(p_actx->sp);
 }
diff --git a/secure_fw/spm/cmsis_psa/tfm_thread.c b/secure_fw/spm/cmsis_psa/tfm_thread.c
index ca18e75..43a128a 100644
--- a/secure_fw/spm/cmsis_psa/tfm_thread.c
+++ b/secure_fw/spm/cmsis_psa/tfm_thread.c
@@ -134,7 +134,7 @@
     TFM_CORE_ASSERT(pth != NULL);
     TFM_CORE_ASSERT(pth->arch_ctx.sp != 0);
 
-    tfm_arch_update_ctx(&pth->arch_ctx);
+    tfm_arch_set_ctx(&pth->arch_ctx);
 
     CURR_THRD = pth;
 
diff --git a/secure_fw/spm/cmsis_psa/tfm_wait.c b/secure_fw/spm/cmsis_psa/tfm_wait.c
index a8f11fa..561174b 100644
--- a/secure_fw/spm/cmsis_psa/tfm_wait.c
+++ b/secure_fw/spm/cmsis_psa/tfm_wait.c
@@ -14,6 +14,7 @@
 
     pevnt->owner = tfm_core_thrd_get_curr();
     tfm_core_thrd_set_state(pevnt->owner, THRD_STATE_BLOCK);
+    tfm_arch_get_ctx(&(pevnt->owner->arch_ctx));
     tfm_core_thrd_activate_schedule();
 }
 
diff --git a/secure_fw/spm/include/tfm_arch_v8m.h b/secure_fw/spm/include/tfm_arch_v8m.h
index a51c8c6..5fbc2b2 100644
--- a/secure_fw/spm/include/tfm_arch_v8m.h
+++ b/secure_fw/spm/include/tfm_arch_v8m.h
@@ -138,11 +138,22 @@
 }
 
 /**
- * \brief Update architecture context value into hardware
+ * \brief Get architecture context value into context struct
  *
  * \param[in] p_actx        Pointer of context data
  */
-__STATIC_INLINE void tfm_arch_update_ctx(struct tfm_arch_ctx_t *p_actx)
+__STATIC_INLINE void tfm_arch_get_ctx(struct tfm_arch_ctx_t *p_actx)
+{
+    p_actx->sp = __get_PSP();
+    p_actx->sp_limit = __get_PSPLIM();
+}
+
+/**
+ * \brief Set architecture context value into hardware
+ *
+ * \param[in] p_actx        Pointer of context data
+ */
+__STATIC_INLINE void tfm_arch_set_ctx(struct tfm_arch_ctx_t *p_actx)
 {
     __set_PSP(p_actx->sp);
     __set_PSPLIM(p_actx->sp_limit);