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/partitions/partition_load_info.template b/secure_fw/partitions/partition_load_info.template
index 5bbb42b..6c40c55 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 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 @@
         .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 @@
 #endif
     {% endif %}
 {% endfor %}
-    }
+    },
 #else
 {% if manifest.mmio_regions %}
     .assets                         = {
@@ -177,7 +188,30 @@
 #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
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__ */