SPM: Changes to Secure Partition API for FLIH
The patch includes the changes to Secure Partition API for FLIH
defined by FF-M v1.1 alpha:
- Adding psa_reset_signal() which is for FLIH signals
- Limiting psa_eoi() to SLIH signals
Change-Id: I6b99eb6df3013c898627a48fa98d41c0e7bc5888
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/interface/include/psa/service.h b/interface/include/psa/service.h
index 8cd6556..12efd2e 100644
--- a/interface/include/psa/service.h
+++ b/interface/include/psa/service.h
@@ -46,12 +46,19 @@
/* An IPC message type that indicates the end of a connection. */
#define PSA_IPC_DISCONNECT (-2)
+/* FLIH return types */
+#define PSA_FLIH_NO_SIGNAL ((psa_flih_result_t) 0)
+#define PSA_FLIH_SIGNAL ((psa_flih_result_t) 1)
+
/* Store a set of one or more Secure Partition signals */
typedef uint32_t psa_signal_t;
/* A type used to temporarily store a previous interrupt state. */
typedef uint32_t psa_irq_status_t;
+/* The type of the return value from an FLIH function */
+typedef uint32_t psa_flih_result_t;
+
/**
* Describe a message received by an RoT Service after calling \ref psa_get().
*/
@@ -252,6 +259,7 @@
* \arg irq_signal is not an interrupt signal.
* \arg irq_signal indicates more than one signal.
* \arg irq_signal is not currently asserted.
+ * \arg The interrupt is not using SLIH.
*/
void psa_eoi(psa_signal_t irq_signal);
@@ -273,8 +281,8 @@
*
* \retval void
* \retval "PROGRAMMER ERROR" If one or more of the following are true:
- * \ref irq_signal is not an interrupt signal.
- * \ref irq_signal indicates more than one signal.
+ * \arg \a irq_signal is not an interrupt signal.
+ * \arg \a irq_signal indicates more than one signal.
*/
void psa_irq_enable(psa_signal_t irq_signal);
@@ -290,13 +298,31 @@
* \retval 0 The interrupt was disabled prior to this call.
* 1 The interrupt was enabled prior to this call.
* \retval "PROGRAMMER ERROR" If one or more of the following are true:
- * \ref irq_signal is not an interrupt signal.
- * \ref irq_signal indicates more than one signal.
+ * \arg \a irq_signal is not an interrupt signal.
+ * \arg \a irq_signal indicates more than one signal.
*
* \note The current implementation always return 1. Do not use the return.
*/
psa_irq_status_t psa_irq_disable(psa_signal_t irq_signal);
+/**
+ * \brief Reset the signal for an interrupt that is using FLIH handling.
+ *
+ * \param[in] irq_signal The interrupt signal to be reset.
+ * This must have a single bit set, corresponding to a
+ * currently asserted signal for an interrupt that is
+ * defined to use FLIH handling.
+ *
+ * \retval void
+ * \retval "Programmer Error" if one or more of the following are true:
+ * \arg \a irq_signal is not a signal for an interrupt
+ * that is specified with FLIH handling in the Secure
+ * Partition manifest.
+ * \arg \a irq_signal indicates more than one signal.
+ * \arg \a irq_signal is not currently asserted.
+ */
+void psa_reset_signal(psa_signal_t irq_signal);
+
#ifdef __cplusplus
}
#endif
diff --git a/interface/src/psa/psa_service.c b/interface/src/psa/psa_service.c
index a8ecef4..211c36f 100644
--- a/interface/src/psa/psa_service.c
+++ b/interface/src/psa/psa_service.c
@@ -119,3 +119,11 @@
"BX LR \n"
: : "I" (TFM_SVC_PSA_IRQ_DISABLE));
}
+
+__attribute__((naked))
+void psa_reset_signal(psa_signal_t irq_signal)
+{
+ __ASM volatile("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_RESET_SIGNAL));
+}
diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
index cdad232..e02753a 100644
--- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
@@ -114,6 +114,9 @@
break;
case TFM_SVC_PSA_IRQ_DISABLE:
return tfm_spm_irq_disable(ctx);
+ case TFM_SVC_PSA_RESET_SIGNAL:
+ tfm_spm_psa_reset_signal(ctx);
+ break;
default:
#ifdef PLATFORM_SVC_HANDLERS
return (platform_svc_handlers(svc_num, ctx, lr));
diff --git a/secure_fw/spm/ffm/psa_client_service_apis.c b/secure_fw/spm/ffm/psa_client_service_apis.c
index 6cc823b..9cb287f 100644
--- a/secure_fw/spm/ffm/psa_client_service_apis.c
+++ b/secure_fw/spm/ffm/psa_client_service_apis.c
@@ -592,6 +592,11 @@
tfm_core_panic();
}
+ if (irq_info->flih_func) {
+ /* This API is for SLIH IRQs only */
+ psa_panic();
+ }
+
/* It is a fatal error if passed signal is not currently asserted */
if ((partition->signals_asserted & irq_signal) == 0) {
tfm_core_panic();
@@ -655,3 +660,38 @@
return 1;
}
+
+void tfm_spm_psa_reset_signal(uint32_t *args)
+{
+ psa_signal_t irq_signal;
+ struct irq_load_info_t *irq_info;
+ struct partition_t *partition;
+
+ if (!args) {
+ tfm_core_panic();
+ }
+
+ irq_signal = (psa_signal_t)args[0];
+
+ partition = tfm_spm_get_running_partition();
+ if (!partition) {
+ tfm_core_panic();
+ }
+
+ irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
+ if (!irq_info) {
+ tfm_core_panic();
+ }
+
+ if (!irq_info->flih_func) {
+ /* This API is for FLIH IRQs only */
+ tfm_core_panic();
+ }
+
+ if ((partition->signals_asserted & irq_signal) == 0) {
+ /* The signal is not asserted */
+ tfm_core_panic();
+ }
+
+ partition->signals_asserted &= ~irq_signal;
+}
diff --git a/secure_fw/spm/ffm/psa_client_service_apis.h b/secure_fw/spm/ffm/psa_client_service_apis.h
index acbe373..166890a 100644
--- a/secure_fw/spm/ffm/psa_client_service_apis.h
+++ b/secure_fw/spm/ffm/psa_client_service_apis.h
@@ -273,9 +273,9 @@
* \retval void
* \retval "Does not return" The call is invalid, if one or more of the
* following are true:
- * - irq_signal does not belong to the calling
- * partition.
- * - irq_signal indicates more than one signal.
+ * \arg irq_signal does not belong to the calling
+ * partition.
+ * \arg irq_signal indicates more than one signal.
*/
void tfm_spm_irq_enable(uint32_t *args);
@@ -288,10 +288,25 @@
* 1 The interrupt was enabled prior to this call
* \retval "Does not return" The call is invalid, if one or more of the
* following are true:
- * - irq_signal does not belong to the calling
- * partition.
- * - irq_signal indicates more than one signal.
+ * \arg irq_signal does not belong to the calling
+ * partition.
+ * \arg irq_signal indicates more than one signal.
*/
psa_irq_status_t tfm_spm_irq_disable(uint32_t *args);
+/**
+ * \brief SVC handler for \ref psa_reset_signal.
+ *
+ * \param[in] args Include all input arguments: irq_signal.
+ *
+ * \retval void
+ * \retval "Does not return" if one or more of the following are true:
+ * \arg irq_signal is not a signal for an interrupt
+ * that is specified with FLIH handling in the Secure
+ * Partition manifest.
+ * \arg irq_signal indicates more than one signal.
+ * \arg irq_signal is not currently asserted.
+ */
+void tfm_spm_psa_reset_signal(uint32_t *args);
+
#endif /* __PSA_CLIENT_SERVICE_APIS_H__ */
diff --git a/secure_fw/spm/include/interface/svc_num.h b/secure_fw/spm/include/interface/svc_num.h
index 23b9e04..955d7bf 100644
--- a/secure_fw/spm/include/interface/svc_num.h
+++ b/secure_fw/spm/include/interface/svc_num.h
@@ -37,6 +37,7 @@
#define TFM_SVC_PSA_LIFECYCLE (0x10)
#define TFM_SVC_PSA_IRQ_ENABLE (0x11)
#define TFM_SVC_PSA_IRQ_DISABLE (0x12)
+#define TFM_SVC_PSA_RESET_SIGNAL (0x13)
/* TF-M specific, starts from 0x40 */
#define TFM_SVC_SPM_REQUEST (0x40)
#define TFM_SVC_GET_BOOT_DATA (0x41)