aboutsummaryrefslogtreecommitdiff
path: root/services/spd/tlkd
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2015-03-13 14:59:03 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2015-03-31 10:06:51 +0530
commit6e159e7a8c0dd73d6e95b8cbc1d8035d67da4bab (patch)
tree400e83c5a11cdce346d09c27ae5cb471bf14964a /services/spd/tlkd
parent77199df7bceba229a8a2f9b8473088f969737d85 (diff)
downloadtrusted-firmware-a-6e159e7a8c0dd73d6e95b8cbc1d8035d67da4bab.tar.gz
Translate secure/non-secure virtual addresses
This patch adds functionality to translate virtual addresses from secure or non-secure worlds. This functionality helps Trusted Apps to share virtual addresses directly and allows the NS world to pass virtual addresses to TLK directly. Change-Id: I77b0892963e0e839c448b5d0532920fb7e54dc8e Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'services/spd/tlkd')
-rw-r--r--services/spd/tlkd/tlkd_common.c58
-rw-r--r--services/spd/tlkd/tlkd_main.c19
-rw-r--r--services/spd/tlkd/tlkd_private.h6
3 files changed, 83 insertions, 0 deletions
diff --git a/services/spd/tlkd/tlkd_common.c b/services/spd/tlkd/tlkd_common.c
index 5944174d57..b19e27d06d 100644
--- a/services/spd/tlkd/tlkd_common.c
+++ b/services/spd/tlkd/tlkd_common.c
@@ -35,6 +35,64 @@
#include <string.h>
#include "tlkd_private.h"
+#define AT_MASK 3
+
+/*******************************************************************************
+ * This function helps the SP to translate NS/S virtual addresses.
+ ******************************************************************************/
+uint64_t tlkd_va_translate(uintptr_t va, int type)
+{
+ uint64_t pa;
+
+ if (type & TLK_TRANSLATE_NS_VADDR) {
+
+ /* save secure context */
+ cm_el1_sysregs_context_save(SECURE);
+
+ /* restore non-secure context */
+ cm_el1_sysregs_context_restore(NON_SECURE);
+
+ /* switch NS bit to start using 64-bit, non-secure mappings */
+ write_scr(cm_get_scr_el3(NON_SECURE));
+ isb();
+ }
+
+ int at = type & AT_MASK;
+ switch (at) {
+ case 0:
+ ats12e1r(va);
+ break;
+ case 1:
+ ats12e1w(va);
+ break;
+ case 2:
+ ats12e0r(va);
+ break;
+ case 3:
+ ats12e0w(va);
+ break;
+ default:
+ assert(0);
+ }
+
+ /* get the (NS/S) physical address */
+ isb();
+ pa = read_par_el1();
+
+ /* Restore secure state */
+ if (type & TLK_TRANSLATE_NS_VADDR) {
+
+ /* restore secure context */
+ cm_el1_sysregs_context_restore(SECURE);
+
+ /* switch NS bit to start using 32-bit, secure mappings */
+ write_scr(cm_get_scr_el3(SECURE));
+ isb();
+ }
+
+ return pa;
+}
+
/*******************************************************************************
* Given a secure payload entrypoint, register width, cpu id & pointer to a
* context data structure, this function will create a secure context ready for
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index 8d2d437ed5..eb6b89de5a 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.c
@@ -188,6 +188,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
{
cpu_context_t *ns_cpu_context;
uint32_t ns;
+ uint64_t vaddr, type, par;
/* Passing a NULL context is a critical programming error */
assert(handle);
@@ -247,6 +248,24 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
SMC_RET0(&tlk_ctx.cpu_ctx);
/*
+ * Translate NS/EL1-S virtual addresses
+ */
+ case TLK_VA_TRANSLATE:
+ if (ns || !tlk_args_results_buf)
+ SMC_RET1(handle, SMC_UNK);
+
+ /* virtual address and type: ns/s */
+ vaddr = tlk_args_results_buf->args[0];
+ type = tlk_args_results_buf->args[1];
+
+ par = tlkd_va_translate(vaddr, type);
+
+ /* Save PA for use by the SP on return */
+ store_tlk_args_results(par, 0, 0, 0);
+
+ SMC_RET0(handle);
+
+ /*
* This is a request from the SP to mark completion of
* a standard function ID.
*/
diff --git a/services/spd/tlkd/tlkd_private.h b/services/spd/tlkd/tlkd_private.h
index 88e720a7e9..271c24ca2b 100644
--- a/services/spd/tlkd/tlkd_private.h
+++ b/services/spd/tlkd/tlkd_private.h
@@ -57,6 +57,11 @@
<< STD_SMC_ACTIVE_FLAG_SHIFT))
/*******************************************************************************
+ * Translate virtual address received from the NS world
+ ******************************************************************************/
+#define TLK_TRANSLATE_NS_VADDR 4
+
+/*******************************************************************************
* Secure Payload execution state information i.e. aarch32 or aarch64
******************************************************************************/
#define SP_AARCH32 MODE_RW_32
@@ -124,6 +129,7 @@ typedef struct tlk_context {
/*******************************************************************************
* Function & Data prototypes
******************************************************************************/
+uint64_t tlkd_va_translate(uintptr_t va, int type);
uint64_t tlkd_enter_sp(uint64_t *c_rt_ctx);
void __dead2 tlkd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
uint64_t tlkd_synchronous_sp_entry(tlk_context_t *tlk_ctx);