aboutsummaryrefslogtreecommitdiffstats
path: root/services/spd/tlkd
diff options
context:
space:
mode:
Diffstat (limited to 'services/spd/tlkd')
-rw-r--r--services/spd/tlkd/tlkd_common.c8
-rw-r--r--services/spd/tlkd/tlkd_main.c94
-rw-r--r--services/spd/tlkd/tlkd_pm.c26
3 files changed, 97 insertions, 31 deletions
diff --git a/services/spd/tlkd/tlkd_common.c b/services/spd/tlkd/tlkd_common.c
index dbe6c2e34..820bd8a72 100644
--- a/services/spd/tlkd/tlkd_common.c
+++ b/services/spd/tlkd/tlkd_common.c
@@ -38,16 +38,16 @@ uint64_t tlkd_va_translate(uintptr_t va, int type)
int at = type & AT_MASK;
switch (at) {
case 0:
- ats12e1r(va);
+ AT(ats12e1r, va);
break;
case 1:
- ats12e1w(va);
+ AT(ats12e1w, va);
break;
case 2:
- ats12e0r(va);
+ AT(ats12e0r, va);
break;
case 3:
- ats12e0w(va);
+ AT(ats12e0w, va);
break;
default:
assert(0); /* Unreachable */
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index 3cfc52db4..ecac43522 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +15,7 @@
* responsible for initialising and maintaining communication with the SP.
******************************************************************************/
#include <assert.h>
+#include <bl31/interrupt_mgmt.h>
#include <errno.h>
#include <stddef.h>
@@ -49,6 +51,50 @@ DEFINE_SVC_UUID2(tlk_uuid,
static int32_t tlkd_init(void);
/*******************************************************************************
+ * Secure Payload Dispatcher's timer interrupt handler
+ ******************************************************************************/
+static uint64_t tlkd_interrupt_handler(uint32_t id,
+ uint32_t flags,
+ void *handle,
+ void *cookie)
+{
+ cpu_context_t *s_cpu_context;
+ int irq = plat_ic_get_pending_interrupt_id();
+
+ /* acknowledge the interrupt and mark it complete */
+ (void)plat_ic_acknowledge_interrupt();
+ plat_ic_end_of_interrupt(irq);
+
+ /*
+ * Disable the routing of NS interrupts from secure world to
+ * EL3 while interrupted on this core.
+ */
+ disable_intr_rm_local(INTR_TYPE_S_EL1, SECURE);
+
+ /* Check the security state when the exception was generated */
+ assert(get_interrupt_src_ss(flags) == NON_SECURE);
+ assert(handle == cm_get_context(NON_SECURE));
+
+ /* Save non-secure state */
+ cm_el1_sysregs_context_save(NON_SECURE);
+
+ /* Get a reference to the secure context */
+ s_cpu_context = cm_get_context(SECURE);
+ assert(s_cpu_context);
+
+ /*
+ * Restore non-secure state. There is no need to save the
+ * secure system register context since the SP was supposed
+ * to preserve it during S-EL1 interrupt handling.
+ */
+ cm_el1_sysregs_context_restore(SECURE);
+ cm_set_next_eret_context(SECURE);
+
+ /* Provide the IRQ number to the SPD */
+ SMC_RET4(s_cpu_context, (uint32_t)TLK_IRQ_FIRED, 0, (uint32_t)irq, 0);
+}
+
+/*******************************************************************************
* Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
* (aarch32/aarch64) if not already known and initialises the context for entry
* into the SP for its initialisation.
@@ -56,6 +102,8 @@ static int32_t tlkd_init(void);
static int32_t tlkd_setup(void)
{
entry_point_info_t *tlk_ep_info;
+ uint32_t flags;
+ int32_t ret;
/*
* Get information about the Secure Payload (BL32) image. Its
@@ -86,6 +134,18 @@ static int32_t tlkd_setup(void)
tlk_ep_info->pc,
&tlk_ctx);
+ /* get a list of all S-EL1 IRQs from the platform */
+
+ /* register interrupt handler */
+ flags = 0;
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+ tlkd_interrupt_handler,
+ flags);
+ if (ret != 0) {
+ ERROR("failed to register tlkd interrupt handler (%d)\n", ret);
+ }
+
/*
* All TLK SPD initialization done. Now register our init function
* with BL31 for deferred invocation
@@ -212,6 +272,9 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
case TLK_TA_LAUNCH_OP:
case TLK_TA_SEND_EVENT:
case TLK_RESUME_FID:
+ case TLK_SET_BL_VERSION:
+ case TLK_LOCK_BL_INTERFACE:
+ case TLK_BL_RPMB_SERVICE:
if (!ns)
SMC_RET1(handle, SMC_UNK);
@@ -370,7 +433,6 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
*/
case TLK_SUSPEND_DONE:
case TLK_RESUME_DONE:
- case TLK_SYSTEM_OFF_DONE:
if (ns)
SMC_RET1(handle, SMC_UNK);
@@ -385,6 +447,34 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
break;
/*
+ * This function ID is used by SP to indicate that it has completed
+ * handling the secure interrupt.
+ */
+ case TLK_IRQ_DONE:
+
+ if (ns)
+ SMC_RET1(handle, SMC_UNK);
+
+ assert(handle == cm_get_context(SECURE));
+
+ /* save secure world context */
+ cm_el1_sysregs_context_save(SECURE);
+
+ /* Get a reference to the non-secure context */
+ ns_cpu_context = cm_get_context(NON_SECURE);
+ assert(ns_cpu_context);
+
+ /*
+ * Restore non-secure state. There is no need to save the
+ * secure system register context since the SP was supposed
+ * to preserve it during S-EL1 interrupt handling.
+ */
+ cm_el1_sysregs_context_restore(NON_SECURE);
+ cm_set_next_eret_context(NON_SECURE);
+
+ SMC_RET0(ns_cpu_context);
+
+ /*
* Return the number of service function IDs implemented to
* provide service to non-secure
*/
diff --git a/services/spd/tlkd/tlkd_pm.c b/services/spd/tlkd/tlkd_pm.c
index 7d1959bce..ed5bf7761 100644
--- a/services/spd/tlkd/tlkd_pm.c
+++ b/services/spd/tlkd/tlkd_pm.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -98,29 +99,6 @@ static void cpu_resume_handler(u_register_t suspend_level)
}
/*******************************************************************************
- * System is about to be reset. Inform the SP to allow any book-keeping
- ******************************************************************************/
-static void system_off_handler(void)
-{
- int cpu = read_mpidr() & MPIDR_CPU_MASK;
- gp_regs_t *gp_regs;
-
- /* TLK runs only on CPU0 */
- if (cpu != 0)
- return;
-
- /* pass system off/reset events to TLK */
- gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx);
- write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_OFF);
-
- /*
- * Enter the SP. We do not care about the return value because we
- * must continue with the shutdown anyway.
- */
- (void)tlkd_synchronous_sp_entry(&tlk_ctx);
-}
-
-/*******************************************************************************
* Structure populated by the Dispatcher to be given a chance to perform any
* bookkeeping before PSCI executes a power mgmt. operation.
******************************************************************************/
@@ -128,6 +106,4 @@ const spd_pm_ops_t tlkd_pm_ops = {
.svc_migrate_info = cpu_migrate_info,
.svc_suspend = cpu_suspend_handler,
.svc_suspend_finish = cpu_resume_handler,
- .svc_system_off = system_off_handler,
- .svc_system_reset = system_off_handler
};