SPM: Add IRQ data in Partition Loading
This patch:
- Adds IRQ load data structure
- Moves IRQ data into Partition load info
- Moves Interrupt initialization from main() to load api
- Updates get_irq_line_for_signal() accordingly
- Moves tfm_irq_list.h to Library Model as it is not used by IPC
Change-Id: I4945e24bd977ef3d3e472bc58dfa618c3fb2d706
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/secure_fw/spm/include/tfm_irq_list.h b/secure_fw/spm/cmsis_func/include/tfm_irq_list.h
similarity index 100%
rename from secure_fw/spm/include/tfm_irq_list.h
rename to secure_fw/spm/cmsis_func/include/tfm_irq_list.h
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index f8eb681..7019b33 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -11,8 +11,6 @@
#include "region.h"
#include "spm_ipc.h"
#include "tfm_hal_platform.h"
-#include "tfm_hal_isolation.h"
-#include "tfm_irq_list.h"
#include "tfm_nspm.h"
#include "tfm_spm_hal.h"
#include "tfm_spm_log.h"
@@ -36,10 +34,8 @@
static fih_int tfm_core_init(void)
{
- size_t i;
enum tfm_hal_status_t hal_status = TFM_HAL_ERROR_GENERIC;
enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
- enum irq_target_state_t irq_target_state = TFM_IRQ_TARGET_STATE_SECURE;
#ifdef TFM_FIH_PROFILE_ON
fih_int fih_rc = FIH_FAILURE;
#endif
@@ -117,21 +113,6 @@
FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
- for (i = 0; i < tfm_core_irq_signals_count; ++i) {
- plat_err = tfm_spm_hal_set_secure_irq_priority(
- tfm_core_irq_signals[i].irq_line,
- tfm_core_irq_signals[i].irq_priority);
- if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
- }
- irq_target_state = tfm_spm_hal_set_irq_target_state(
- tfm_core_irq_signals[i].irq_line,
- TFM_IRQ_TARGET_STATE_SECURE);
- if (irq_target_state != TFM_IRQ_TARGET_STATE_SECURE) {
- FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
- }
- }
-
/* Enable secure peripherals interrupts */
plat_err = tfm_spm_hal_nvic_interrupt_enable();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 3d2623c..e3cb176 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -15,7 +15,6 @@
#include "tfm_wait.h"
#include "internal_errors.h"
#include "tfm_spm_hal.h"
-#include "tfm_irq_list.h"
#include "tfm_api.h"
#include "tfm_secure_api.h"
#include "tfm_memory_utils.h"
@@ -35,6 +34,7 @@
#include "load/service_defs.h"
#include "load/asset_defs.h"
#include "load/spm_load_api.h"
+#include "load/irq_defs.h"
extern struct spm_partition_db_t g_spm_partition_db;
static struct service_t *connection_services_listhead;
@@ -657,12 +657,18 @@
break;
}
- load_services_assuredly(partition, &connection_services_listhead,
- stateless_services_ref_tbl,
- sizeof(stateless_services_ref_tbl));
-
p_ldinf = partition->p_ldinf;
+ if (p_ldinf->nservices) {
+ load_services_assuredly(partition, &connection_services_listhead,
+ stateless_services_ref_tbl,
+ sizeof(stateless_services_ref_tbl));
+ }
+
+ if (p_ldinf->nirqs) {
+ load_irqs_assuredly(partition);
+ }
+
/* Init mmio assets */
if (p_ldinf->nassets > 0) {
if (tfm_spm_partition_get_privileged_mode(p_ldinf->flags) ==
@@ -713,23 +719,6 @@
partition->signals_allowed |= PSA_DOORBELL;
- /* TODO: This can be optimized by generating the assigned signal
- * in code generation time.
- */
- for (j = 0; j < tfm_core_irq_signals_count; ++j) {
- if (tfm_core_irq_signals[j].partition_id == p_ldinf->pid) {
- partition->signals_allowed |=
- tfm_core_irq_signals[j].signal_value;
- if ((p_ldinf->psa_ff_ver & PARTITION_INFO_VERSION_MASK)
- == 0x0100) {
- tfm_spm_hal_enable_irq(tfm_core_irq_signals[j].irq_line);
- } else if ((p_ldinf->psa_ff_ver & PARTITION_INFO_VERSION_MASK)
- == 0x0101) {
- tfm_spm_hal_disable_irq(tfm_core_irq_signals[j].irq_line);
- }
- }
- }
-
tfm_event_init(&partition->event);
BI_LIST_INIT_NODE(&partition->msg_list);
@@ -922,22 +911,25 @@
__enable_irq();
}
-int32_t get_irq_line_for_signal(int32_t partition_id, psa_signal_t signal)
+struct irq_load_info_t *get_irq_info_for_signal(
+ const struct partition_load_info_t *p_ldinf,
+ psa_signal_t signal)
{
size_t i;
+ struct irq_load_info_t *irq_info;
if (!IS_ONLY_ONE_BIT_IN_UINT32(signal)) {
- return -1;
+ return NULL;
}
- for (i = 0; i < tfm_core_irq_signals_count; ++i) {
- if (tfm_core_irq_signals[i].partition_id == partition_id &&
- tfm_core_irq_signals[i].signal_value == signal) {
- return tfm_core_irq_signals[i].irq_line;
+ irq_info = (struct irq_load_info_t *)LOAD_INFO_IRQ(p_ldinf);
+ for (i = 0; i < p_ldinf->nirqs; i++) {
+ if (irq_info[i].signal == signal) {
+ return &irq_info[i];
}
}
- return SPM_ERROR_GENERIC;
+ return NULL;
}
#if !defined(__ARM_ARCH_8_1M_MAIN__)
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index aee6f2c..a694f8d 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -449,18 +449,20 @@
void notify_with_signal(int32_t partition_id, psa_signal_t signal);
/**
- * \brief Return the IRQ line number associated with a signal
+ * \brief Return the IRQ load info context pointer associated with a signal
*
- * \param[in] partition_id The ID of the partition in which we look for
- * the signal.
- * \param[in] signal The signal to query for.
+ * \param[in] p_ldinf The load info of the partition in which we look
+ * for the signal.
+ * \param[in] signal The signal to query for.
*
- * \retval None-negative value The irq line associated with signal
- * \retval Negative value if one of more the following are true:
+ * \retval NULL if one of more the following are true:
* - the \ref signal indicates more than one signal
* - the \ref signal does not belong to the
* partition.
+ * \retval Any other value The load info pointer associated with the signal
*/
-int32_t get_irq_line_for_signal(int32_t partition_id, psa_signal_t signal);
+struct irq_load_info_t *get_irq_info_for_signal(
+ const struct partition_load_info_t *p_ldinf,
+ psa_signal_t signal);
#endif /* __SPM_IPC_H__ */
diff --git a/secure_fw/spm/cmsis_psa/static_load.c b/secure_fw/spm/cmsis_psa/static_load.c
index e47f4fe..680907b 100644
--- a/secure_fw/spm/cmsis_psa/static_load.c
+++ b/secure_fw/spm/cmsis_psa/static_load.c
@@ -10,6 +10,8 @@
#include "region.h"
#include "region_defs.h"
#include "spm_ipc.h"
+#include "tfm_plat_defs.h"
+#include "tfm_spm_hal.h"
#include "utilities.h"
#include "load/partition_defs.h"
#include "load/spm_load_api.h"
@@ -163,3 +165,41 @@
}
}
}
+
+void load_irqs_assuredly(struct partition_t *p_partition)
+{
+ struct irq_load_info_t *p_irq_info;
+ const struct partition_load_info_t *p_ldinf;
+ uint32_t i;
+
+ if (!p_partition) {
+ tfm_core_panic();
+ }
+
+ p_ldinf = p_partition->p_ldinf;
+ p_irq_info = (struct irq_load_info_t *)LOAD_INFO_IRQ(p_ldinf);
+
+ for (i = 0; i < p_ldinf->nirqs; i++) {
+ p_partition->signals_allowed |= p_irq_info[i].signal;
+
+ if (tfm_spm_hal_set_secure_irq_priority(p_irq_info[i].source,
+ TFM_DEFAULT_SECURE_IRQ_PRIOTITY)
+ != TFM_PLAT_ERR_SUCCESS) {
+ tfm_core_panic();
+ }
+
+ if (tfm_spm_hal_set_irq_target_state(p_irq_info[i].source,
+ TFM_IRQ_TARGET_STATE_SECURE)
+ != TFM_PLAT_ERR_SUCCESS) {
+ tfm_core_panic();
+ }
+
+ if ((p_ldinf->psa_ff_ver & PARTITION_INFO_VERSION_MASK) == 0x0100) {
+ tfm_spm_hal_enable_irq(p_irq_info[i].source);
+ } else if ((p_ldinf->psa_ff_ver & PARTITION_INFO_VERSION_MASK)
+ == 0x0101) {
+ tfm_spm_hal_disable_irq(p_irq_info[i].source);
+ }
+ p_irq_info++;
+ }
+}
diff --git a/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template b/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
index 146ff72..f5faa43 100644
--- a/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
+++ b/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
@@ -7,61 +7,13 @@
{{utilities.donotedit_warning}}
-{% for partition in partitions %}
-#ifdef {{partition.attr.conditional}}
-#include "{{partition.header_file}}"
-#endif /* {{partition.attr.conditional}} */
-
-{% endfor %}
-
-#include "cmsis_compiler.h"
-{% macro _irq_record(partition_name, signal, line, priority) -%}
-{ {{ partition_name }}, {{ signal }}, {{ line }}, {{ priority }} },
-{%- endmacro %}
-
-/* Definitions of the signals of the IRQs (if any) */
-const struct tfm_core_irq_signal_data_t tfm_core_irq_signals[] = {
-{% for partition in partitions %}
- {% if partition.manifest.irqs %}
- {% if partition.attr.conditional %}
-#ifdef {{partition.attr.conditional}}
- {% endif %}
- {% for irq in partition.manifest.irqs %}
- {% set irq_data = namespace() %}
- {% if irq.source %}
- {% set irq_data.line = irq.source %}
- {% else %}
-#error "Interrupt source isn't provided for 'irqs' in partition {{partition.manifest.name}}"
- {% endif %}
- {% if partition.manifest.psa_framework_version == 1.0 %}
- {% set irq_data.signal = irq.signal %}
- {% else %}
- {% set irq_data.signal = irq.name + "_SIGNAL" %}
- {% endif %}
- {% if irq.tfm_irq_priority %}
- {% set irq_data.priority = irq.tfm_irq_priority %}
- {% else %}
- {% set irq_data.priority = "TFM_DEFAULT_SECURE_IRQ_PRIORITY" %}
- {% endif %}
- {{ _irq_record(partition.manifest.name, irq_data.signal, irq_data.line, irq_data.priority) }}
- {% endfor %}
- {% if partition.attr.conditional %}
-#endif /* {{partition.attr.conditional}} */
- {% endif %}
- {% endif %}
-{% endfor %}
- {0, 0, 0, 0} /* add dummy element to avoid non-standard empty array */
-};
-
-const size_t tfm_core_irq_signals_count = (sizeof(tfm_core_irq_signals) /
- sizeof(*tfm_core_irq_signals)) - 1; /* adjust for the dummy element */
-
/* Definitions of privileged IRQ handlers (if any) */
{% for partition in partitions %}
{% if partition.manifest.irqs %}
{% if partition.attr.conditional %}
#ifdef {{partition.attr.conditional}}
{% endif %}
+#include "{{partition.header_file}}"
{% for irq in partition.manifest.irqs %}
{% set irq_data = namespace() %}
{% if partition.manifest.psa_framework_version == 1.0 %}
diff --git a/secure_fw/spm/cmsis_psa/tfm_spm_db_ipc.inc.template b/secure_fw/spm/cmsis_psa/tfm_spm_db_ipc.inc.template
index 9e8c992..8081ac7 100644
--- a/secure_fw/spm/cmsis_psa/tfm_spm_db_ipc.inc.template
+++ b/secure_fw/spm/cmsis_psa/tfm_spm_db_ipc.inc.template
@@ -19,23 +19,6 @@
#error "Please do not add 'heap_size' for partition '{{partition.manifest.name}}', the dynamic memory allocation is not supported now!"
{% endif %}
{% endfor %}
-/**************************************************************************/
-/** IRQ count per partition */
-/**************************************************************************/
-{% for partition in partitions %}
- {% if partition.attr.conditional %}
-#ifdef {{partition.attr.conditional}}
- {% endif %}
- {% if partition.manifest.irqs %}
-#define TFM_PARTITION_{{partition.manifest.name}}_IRQ_COUNT {{partition.manifest.irqs | length() }}
- {% else %}
-#define TFM_PARTITION_{{partition.manifest.name}}_IRQ_COUNT 0
- {% endif %}
- {% if partition.attr.conditional %}
-#endif /* {{partition.attr.conditional}} */
- {% endif %}
-
-{% endfor %}
/**************************************************************************/
/** The partition list for the DB */
diff --git a/secure_fw/spm/ffm/psa_client_service_apis.c b/secure_fw/spm/ffm/psa_client_service_apis.c
index 87c7f3b..6cc823b 100644
--- a/secure_fw/spm/ffm/psa_client_service_apis.c
+++ b/secure_fw/spm/ffm/psa_client_service_apis.c
@@ -17,6 +17,7 @@
#include "tfm_rpc.h"
#include "tfm_spm_hal.h"
#include "tfm_psa_call_param.h"
+#include "load/irq_defs.h"
#include "load/partition_defs.h"
#include "load/service_defs.h"
@@ -574,7 +575,7 @@
void tfm_spm_psa_eoi(uint32_t *args)
{
psa_signal_t irq_signal;
- int32_t irq_line = 0;
+ struct irq_load_info_t *irq_info = NULL;
struct partition_t *partition = NULL;
TFM_CORE_ASSERT(args != NULL);
@@ -585,9 +586,9 @@
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
+ irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
/* It is a fatal error if passed signal is not an interrupt signal. */
- if (irq_line < 0) {
+ if (!irq_info) {
tfm_core_panic();
}
@@ -598,8 +599,8 @@
partition->signals_asserted &= ~irq_signal;
- tfm_spm_hal_clear_pending_irq(irq_line);
- tfm_spm_hal_enable_irq(irq_line);
+ tfm_spm_hal_clear_pending_irq((IRQn_Type)(irq_info->source));
+ tfm_spm_hal_enable_irq((IRQn_Type)(irq_info->source));
}
void tfm_spm_psa_panic(void)
@@ -615,7 +616,7 @@
{
struct partition_t *partition;
psa_signal_t irq_signal;
- uint32_t irq_line;
+ struct irq_load_info_t *irq_info;
irq_signal = (psa_signal_t)args[0];
@@ -624,19 +625,19 @@
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
- if (irq_line < 0) {
+ irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
+ if (!irq_info) {
tfm_core_panic();
}
- tfm_spm_hal_enable_irq((IRQn_Type)irq_line);
+ tfm_spm_hal_enable_irq((IRQn_Type)(irq_info->source));
}
psa_irq_status_t tfm_spm_irq_disable(uint32_t *args)
{
struct partition_t *partition;
psa_signal_t irq_signal;
- uint32_t irq_line;
+ struct irq_load_info_t *irq_info;
irq_signal = (psa_signal_t)args[0];
@@ -645,12 +646,12 @@
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
- if (irq_line < 0) {
+ irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
+ if (!irq_info) {
tfm_core_panic();
}
- tfm_spm_hal_disable_irq((IRQn_Type)irq_line);
+ tfm_spm_hal_disable_irq((IRQn_Type)(irq_info->source));
return 1;
}
diff --git a/secure_fw/spm/include/load/irq_defs.h b/secure_fw/spm/include/load/irq_defs.h
new file mode 100644
index 0000000..db0abec
--- /dev/null
+++ b/secure_fw/spm/include/load/irq_defs.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __IRQ_DEFS_H__
+#define __IRQ_DEFS_H__
+
+#include "psa/service.h"
+
+#define TFM_DEFAULT_SECURE_IRQ_PRIOTITY 128
+
+struct irq_load_info_t {
+ uint32_t source; /* IRQ source (number/index) */
+ uint32_t flih_func; /* FLIH function - 0 if SLIH */
+ psa_signal_t signal; /* The signal assigned for IRQ */
+};
+
+#endif /* __IRQ_DEFS_H__ */
diff --git a/secure_fw/spm/include/load/partition_defs.h b/secure_fw/spm/include/load/partition_defs.h
index 119359e..9eb3ea9 100644
--- a/secure_fw/spm/include/load/partition_defs.h
+++ b/secure_fw/spm/include/load/partition_defs.h
@@ -57,6 +57,7 @@
uint32_t ndeps; /* Dependency number */
uint32_t nservices; /* Service number */
uint32_t nassets; /* Asset numbers */
+ uint32_t nirqs; /* Number of IRQ owned by Partition */
} __attribute__((aligned(4)));
#endif /* __PARTITION_DEFS_H__ */
diff --git a/secure_fw/spm/include/load/spm_load_api.h b/secure_fw/spm/include/load/spm_load_api.h
index c9fde2d..5bc1aed 100644
--- a/secure_fw/spm/include/load/spm_load_api.h
+++ b/secure_fw/spm/include/load/spm_load_api.h
@@ -10,6 +10,7 @@
#define __SPM_LOAD_API_H__
#include "asset_defs.h"
+#include "irq_defs.h"
#include "partition_defs.h"
#include "service_defs.h"
#include "spm_ipc.h"
@@ -21,7 +22,8 @@
(sizeof(*(pldinf)) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t) + \
(pldinf)->ndeps * sizeof(uint32_t) + \
(pldinf)->nservices * sizeof(struct service_load_info_t) + \
- (pldinf)->nassets * sizeof(struct asset_desc_t))
+ (pldinf)->nassets * sizeof(struct asset_desc_t) + \
+ (pldinf)->nirqs * sizeof(struct irq_load_info_t))
/* 'Allocate' stack based on load info */
#define LOAD_ALLOCED_STACK_ADDR(pldinf) (*((uintptr_t *)(pldinf + 1)))
@@ -33,6 +35,9 @@
#define LOAD_INFO_ASSET(pldinf) \
((uintptr_t)LOAD_INFO_SERVICE(pldinf) + \
(pldinf)->nservices * sizeof(struct service_load_info_t))
+#define LOAD_INFO_IRQ(pldinf) \
+ ((uintptr_t)LOAD_INFO_ASSET(pldinf) + \
+ (pldinf)->nassets * sizeof(struct asset_desc_t))
/*
* Allocate a partition object and return if a load is successful.
@@ -54,4 +59,12 @@
struct service_t **stateless_service_ref_tbl,
size_t ref_tbl_size);
+/*
+ * Append IRQ signals to Partition signals.
+ * Set initial IRQ enabled status according to framework version.
+ * And initialize the IRQ.
+ * Any error within this API causes system to panic.
+ */
+void load_irqs_assuredly(struct partition_t *p_partition);
+
#endif /* __SPM_LOAD_API_H__ */