diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2015-03-13 14:59:03 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2015-03-31 10:06:51 +0530 |
commit | 6e159e7a8c0dd73d6e95b8cbc1d8035d67da4bab (patch) | |
tree | 400e83c5a11cdce346d09c27ae5cb471bf14964a /services/spd/tlkd | |
parent | 77199df7bceba229a8a2f9b8473088f969737d85 (diff) | |
download | trusted-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.c | 58 | ||||
-rw-r--r-- | services/spd/tlkd/tlkd_main.c | 19 | ||||
-rw-r--r-- | services/spd/tlkd/tlkd_private.h | 6 |
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); |