aboutsummaryrefslogtreecommitdiff
path: root/secure_fw
diff options
context:
space:
mode:
Diffstat (limited to 'secure_fw')
-rw-r--r--secure_fw/partitions/partition_load_info.template40
-rw-r--r--secure_fw/spm/cmsis_func/include/tfm_irq_list.h (renamed from secure_fw/spm/include/tfm_irq_list.h)0
-rw-r--r--secure_fw/spm/cmsis_psa/main.c19
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.c50
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.h16
-rw-r--r--secure_fw/spm/cmsis_psa/static_load.c40
-rw-r--r--secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template50
-rw-r--r--secure_fw/spm/cmsis_psa/tfm_spm_db_ipc.inc.template17
-rw-r--r--secure_fw/spm/ffm/psa_client_service_apis.c27
-rw-r--r--secure_fw/spm/include/load/irq_defs.h21
-rw-r--r--secure_fw/spm/include/load/partition_defs.h1
-rw-r--r--secure_fw/spm/include/load/spm_load_api.h15
12 files changed, 158 insertions, 138 deletions
diff --git a/secure_fw/partitions/partition_load_info.template b/secure_fw/partitions/partition_load_info.template
index 5bbb42b918..6c40c55dbb 100644
--- a/secure_fw/partitions/partition_load_info.template
+++ b/secure_fw/partitions/partition_load_info.template
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <stddef.h>
#include "region.h"
+#include "load/irq_defs.h"
#include "load/partition_defs.h"
#include "load/service_defs.h"
#include "load/asset_defs.h"
@@ -18,7 +19,7 @@
#include "psa_manifest/sid.h"
#include "psa_manifest/{{manifest_out_basename}}.h"
-{% set counter = namespace(dep_counter=0, service_counter=0, asset_counter=0) %}
+{% set counter = namespace(dep_counter=0, service_counter=0, asset_counter=0, irq_counter=0) %}
{% if manifest.dependencies %}
{% for dep in manifest.dependencies %}
{% set counter.dep_counter = counter.dep_counter + 1 %}
@@ -34,6 +35,11 @@
{% set counter.asset_counter = counter.asset_counter + 1 %}
{% endfor %}
{% endif %}
+{% if manifest.irqs %}
+ {% for irq in manifest.irqs %}
+ {% set counter.irq_counter = counter.irq_counter + 1 %}
+ {% endfor %}
+{% endif %}
#define {{"%-55s"|format(manifest.name|upper + "_NDEPS")}} ({{"%d"|format(counter.dep_counter)}})
#define {{"%-55s"|format(manifest.name|upper + "_NSERVS")}} ({{"%d"|format(counter.service_counter)}})
#if TFM_LVL == 3
@@ -41,6 +47,7 @@
#else
#define {{"%-55s"|format(manifest.name|upper + "_NASSETS")}} ({{"%d"|format(counter.asset_counter)}})
#endif
+#define {{"%-55s"|format(manifest.name|upper + "_NIRQS")}} ({{"%d"|format(counter.irq_counter)}})
/* Memory region declaration */
#if TFM_LVL == 3
@@ -72,6 +79,9 @@ struct partition_{{manifest.name|lower}}_load_info_t {
struct asset_desc_t assets[{{(manifest.name|upper + "_NASSETS")}}];
{% endif %}
#endif
+{% if manifest.irqs %}
+ struct irq_load_info_t irqs[{{(manifest.name|upper + "_NIRQS")}}];
+{% endif %}
} __attribute__((aligned(4)));
/* Partition load, deps, service load data. Put to a dedicated section. */
@@ -104,6 +114,7 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
.ndeps = {{(manifest.name|upper + "_NDEPS")}},
.nservices = {{(manifest.name|upper + "_NSERVS")}},
.nassets = {{(manifest.name|upper + "_NASSETS")}},
+ .nirqs = {{(manifest.name|upper + "_NIRQS")}},
},
.stack_addr = (uintptr_t){{manifest.name|lower}}_stack,
.heap_addr = 0,
@@ -161,7 +172,7 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
#endif
{% endif %}
{% endfor %}
- }
+ },
#else
{% if manifest.mmio_regions %}
.assets = {
@@ -177,7 +188,30 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
#endif
{% endif %}
{% endfor %}
- }
+ },
{% endif %}
#endif
+{% if manifest.irqs %}
+ .irqs = {
+ {% for irq in manifest.irqs %}
+ {% set irq_info = namespace() %}
+ {% set irq_info.source = irq.source %}
+ {% if manifest.psa_framework_version == 1.1 and irq.handling == "FLIH" %}
+ {% set irq_info.flih_func = "(uint32_t)" + irq.name|lower + "_flih" %}
+ {% else %}
+ {% set irq_info.flih_func = 0 %}
+ {% endif %}
+ {% if manifest.psa_framework_version == 1.0 %}
+ {% set irq_info.signal = irq.signal %}
+ {% else %}
+ {% set irq_info.signal = irq.name + "_SIGNAL" %}
+ {% endif %}
+ {
+ .source = {{irq_info.source}},
+ .flih_func = {{irq_info.flih_func}},
+ .signal = {{irq_info.signal}},
+ },
+ {% endfor %}
+ },
+{% endif %}
};
diff --git a/secure_fw/spm/include/tfm_irq_list.h b/secure_fw/spm/cmsis_func/include/tfm_irq_list.h
index fbe01ad7e0..fbe01ad7e0 100644
--- a/secure_fw/spm/include/tfm_irq_list.h
+++ b/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 f8eb68108d..7019b33d97 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 @@ REGION_DECLARE(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Base);
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 @@ static fih_int tfm_core_init(void)
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 3d2623c40c..e3cb1763f5 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 @@ uint32_t tfm_spm_init(void)
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 @@ uint32_t tfm_spm_init(void)
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 @@ void tfm_set_irq_signal(uint32_t partition_id, psa_signal_t signal,
__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 aee6f2c6cd..a694f8d82b 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -449,18 +449,20 @@ void update_caller_outvec_len(struct tfm_msg_body_t *msg);
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 e47f4fe025..680907b0c3 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_services_assuredly(struct partition_t *p_partition,
}
}
}
+
+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 146ff72207..f5faa43ad9 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 9e8c9922ee..8081ac7ec0 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 87c7f3bd46..6cc823b611 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_clear(void)
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 @@ void tfm_spm_psa_eoi(uint32_t *args)
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 @@ void tfm_spm_psa_eoi(uint32_t *args)
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 @@ void tfm_spm_irq_enable(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];
@@ -624,19 +625,19 @@ void tfm_spm_irq_enable(uint32_t *args)
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 @@ psa_irq_status_t tfm_spm_irq_disable(uint32_t *args)
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 0000000000..db0abec88c
--- /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 119359ed82..9eb3ea978b 100644
--- a/secure_fw/spm/include/load/partition_defs.h
+++ b/secure_fw/spm/include/load/partition_defs.h
@@ -57,6 +57,7 @@ struct partition_load_info_t {
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 c9fde2d1c9..5bc1aed06b 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 @@ void load_services_assuredly(struct partition_t *p_partition,
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__ */