Commit 4b427bd4 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #919 from davidcunado-arm/dc/smc_yielding_generic

Update terminology: standard SMC to yielding SMC
parents 062dd378 16292f54
...@@ -180,7 +180,7 @@ endfunc tsp_entrypoint ...@@ -180,7 +180,7 @@ endfunc tsp_entrypoint
* ------------------------------------------- * -------------------------------------------
*/ */
func tsp_vector_table func tsp_vector_table
b tsp_std_smc_entry b tsp_yield_smc_entry
b tsp_fast_smc_entry b tsp_fast_smc_entry
b tsp_cpu_on_entry b tsp_cpu_on_entry
b tsp_cpu_off_entry b tsp_cpu_off_entry
...@@ -189,7 +189,7 @@ func tsp_vector_table ...@@ -189,7 +189,7 @@ func tsp_vector_table
b tsp_sel1_intr_entry b tsp_sel1_intr_entry
b tsp_system_off_entry b tsp_system_off_entry
b tsp_system_reset_entry b tsp_system_reset_entry
b tsp_abort_std_smc_entry b tsp_abort_yield_smc_entry
endfunc tsp_vector_table endfunc tsp_vector_table
/*--------------------------------------------- /*---------------------------------------------
...@@ -437,12 +437,12 @@ endfunc tsp_fast_smc_entry ...@@ -437,12 +437,12 @@ endfunc tsp_fast_smc_entry
/*--------------------------------------------- /*---------------------------------------------
* This entrypoint is used by the TSPD to ask * This entrypoint is used by the TSPD to ask
* the TSP to service a std smc request. * the TSP to service a Yielding SMC request.
* We will enable preemption during execution * We will enable preemption during execution
* of tsp_smc_handler. * of tsp_smc_handler.
* --------------------------------------------- * ---------------------------------------------
*/ */
func tsp_std_smc_entry func tsp_yield_smc_entry
msr daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT msr daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
bl tsp_smc_handler bl tsp_smc_handler
msr daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT msr daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
...@@ -450,15 +450,15 @@ func tsp_std_smc_entry ...@@ -450,15 +450,15 @@ func tsp_std_smc_entry
/* Should never reach here */ /* Should never reach here */
no_ret plat_panic_handler no_ret plat_panic_handler
endfunc tsp_std_smc_entry endfunc tsp_yield_smc_entry
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* This entrypoint is used by the TSPD to abort a pre-empted Standard * This entrypoint is used by the TSPD to abort a pre-empted Yielding
* SMC. It could be on behalf of non-secure world or because a CPU * SMC. It could be on behalf of non-secure world or because a CPU
* suspend/CPU off request needs to abort the preempted SMC. * suspend/CPU off request needs to abort the preempted SMC.
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
func tsp_abort_std_smc_entry func tsp_abort_yield_smc_entry
/* /*
* Exceptions masking is already done by the TSPD when entering this * Exceptions masking is already done by the TSPD when entering this
...@@ -477,4 +477,4 @@ func tsp_abort_std_smc_entry ...@@ -477,4 +477,4 @@ func tsp_abort_std_smc_entry
/* Should never reach here */ /* Should never reach here */
bl plat_panic_handler bl plat_panic_handler
endfunc tsp_abort_std_smc_entry endfunc tsp_abort_yield_smc_entry
/* /*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -372,7 +372,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func, ...@@ -372,7 +372,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func,
tsp_stats[linear_id].eret_count++; tsp_stats[linear_id].eret_count++;
INFO("TSP: cpu 0x%lx received %s smc 0x%lx\n", read_mpidr(), INFO("TSP: cpu 0x%lx received %s smc 0x%lx\n", read_mpidr(),
((func >> 31) & 1) == 1 ? "fast" : "standard", ((func >> 31) & 1) == 1 ? "fast" : "yielding",
func); func);
INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(),
tsp_stats[linear_id].smc_count, tsp_stats[linear_id].smc_count,
...@@ -418,7 +418,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func, ...@@ -418,7 +418,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func,
/******************************************************************************* /*******************************************************************************
* TSP smc abort handler. This function is called when aborting a preemtped * TSP smc abort handler. This function is called when aborting a preemtped
* standard SMC request. It should cleanup all resources owned by the SMC * yielding SMC request. It should cleanup all resources owned by the SMC
* handler such as locks or dynamically allocated memory so following SMC * handler such as locks or dynamically allocated memory so following SMC
* request are executed in a clean environment. * request are executed in a clean environment.
******************************************************************************/ ******************************************************************************/
......
/* /*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -93,7 +93,8 @@ static int32_t validate_rt_svc_desc(const rt_svc_desc_t *desc) ...@@ -93,7 +93,8 @@ static int32_t validate_rt_svc_desc(const rt_svc_desc_t *desc)
if (desc->end_oen >= OEN_LIMIT) if (desc->end_oen >= OEN_LIMIT)
return -EINVAL; return -EINVAL;
if (desc->call_type != SMC_TYPE_FAST && desc->call_type != SMC_TYPE_STD) if (desc->call_type != SMC_TYPE_FAST &&
desc->call_type != SMC_TYPE_YIELD)
return -EINVAL; return -EINVAL;
/* A runtime service having no init or handle function doesn't make sense */ /* A runtime service having no init or handle function doesn't make sense */
...@@ -143,7 +144,7 @@ void runtime_svc_init(void) ...@@ -143,7 +144,7 @@ void runtime_svc_init(void)
/* /*
* The runtime service may have separate rt_svc_desc_t * The runtime service may have separate rt_svc_desc_t
* for its fast smc and standard smc. Since the service itself * for its fast smc and yielding smc. Since the service itself
* need to be initialized only once, only one of them will have * need to be initialized only once, only one of them will have
* an initialisation routine defined. Call the initialisation * an initialisation routine defined. Call the initialisation
* routine for this runtime service, if it is defined. * routine for this runtime service, if it is defined.
......
...@@ -686,7 +686,7 @@ Software (BL31). ...@@ -686,7 +686,7 @@ Software (BL31).
The design of the runtime services depends heavily on the concepts and The design of the runtime services depends heavily on the concepts and
definitions described in the [SMCCC], in particular SMC Function IDs, Owning definitions described in the [SMCCC], in particular SMC Function IDs, Owning
Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and SMC64 calling Entity Numbers (OEN), Fast and Yielding calls, and the SMC32 and SMC64 calling
conventions. Please refer to that document for more detailed explanation of conventions. Please refer to that document for more detailed explanation of
these terms. these terms.
...@@ -812,7 +812,7 @@ SMC Function which indicates the SMC64 calling convention: such calls are ...@@ -812,7 +812,7 @@ SMC Function which indicates the SMC64 calling convention: such calls are
ignored and return the Unknown SMC Function Identifier result code `0xFFFFFFFF` ignored and return the Unknown SMC Function Identifier result code `0xFFFFFFFF`
in R0/X0. in R0/X0.
Bit[31] (fast/standard call) and bits[29:24] (owning entity number) of the SMC Bit[31] (fast/yielding call) and bits[29:24] (owning entity number) of the SMC
Function ID are combined to index into the `rt_svc_descs_indices[]` array. The Function ID are combined to index into the `rt_svc_descs_indices[]` array. The
resulting value might indicate a service that has no handler, in this case the resulting value might indicate a service that has no handler, in this case the
framework will also report an Unknown SMC Function ID. Otherwise, the value is framework will also report an Unknown SMC Function ID. Otherwise, the value is
......
...@@ -761,7 +761,7 @@ invoked. ...@@ -761,7 +761,7 @@ invoked.
3. It sets the `ELR_EL3` system register to `tsp_sel1_intr_entry` and sets the 3. It sets the `ELR_EL3` system register to `tsp_sel1_intr_entry` and sets the
`SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to `SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to
`TSP_HANDLE_SEL1_INTR_AND_RETURN`. If the TSP was preempted earlier by a non `TSP_HANDLE_SEL1_INTR_AND_RETURN`. If the TSP was preempted earlier by a non
secure interrupt during `standard` SMC processing, save the registers that secure interrupt during `yielding` SMC processing, save the registers that
will be trashed, which is the `ELR_EL3` and `SPSR_EL3`, in order to be able will be trashed, which is the `ELR_EL3` and `SPSR_EL3`, in order to be able
to re-enter TSP for Secure-EL1 interrupt processing. It does not need to to re-enter TSP for Secure-EL1 interrupt processing. It does not need to
save any other secure context since the TSP is expected to preserve it save any other secure context since the TSP is expected to preserve it
...@@ -809,17 +809,17 @@ upon receiving an SMC with `TSP_HANDLED_S_EL1_INTR` as the function identifier: ...@@ -809,17 +809,17 @@ upon receiving an SMC with `TSP_HANDLED_S_EL1_INTR` as the function identifier:
##### 2.3.2.4 Test secure payload dispatcher non-secure interrupt handling ##### 2.3.2.4 Test secure payload dispatcher non-secure interrupt handling
The TSP in Secure-EL1 can be preempted by a non-secure interrupt during The TSP in Secure-EL1 can be preempted by a non-secure interrupt during
`standard` SMC processing or by a higher priority EL3 interrupt during `yielding` SMC processing or by a higher priority EL3 interrupt during
Secure-EL1 interrupt processing. Currently only non-secure interrupts can Secure-EL1 interrupt processing. Currently only non-secure interrupts can
cause preemption of TSP since there are no EL3 interrupts in the cause preemption of TSP since there are no EL3 interrupts in the
system. system.
It should be noted that while TSP is preempted, the TSPD only allows entry into It should be noted that while TSP is preempted, the TSPD only allows entry into
the TSP either for Secure-EL1 interrupt handling or for resuming the preempted the TSP either for Secure-EL1 interrupt handling or for resuming the preempted
`standard` SMC in response to the `TSP_FID_RESUME` SMC from the normal world. `yielding` SMC in response to the `TSP_FID_RESUME` SMC from the normal world.
(See Section 3). (See Section 3).
The non-secure interrupt triggered in Secure-EL1 during `standard` SMC processing The non-secure interrupt triggered in Secure-EL1 during `yielding` SMC processing
can be routed to either EL3 or Secure-EL1 and is controlled by build option can be routed to either EL3 or Secure-EL1 and is controlled by build option
`TSP_NS_INTR_ASYNC_PREEMPT` (see Section 2.2.2.1). If the build option is set, `TSP_NS_INTR_ASYNC_PREEMPT` (see Section 2.2.2.1). If the build option is set,
the TSPD will set the routing model for the non-secure interrupt to be routed to the TSPD will set the routing model for the non-secure interrupt to be routed to
...@@ -835,7 +835,7 @@ further handling. ...@@ -835,7 +835,7 @@ further handling.
If the `TSP_NS_INTR_ASYNC_PREEMPT` build option is zero (default), the default If the `TSP_NS_INTR_ASYNC_PREEMPT` build option is zero (default), the default
routing model for non-secure interrupt in secure state is in effect routing model for non-secure interrupt in secure state is in effect
i.e. __TEL3=0, CSS=0__. During `standard` SMC processing, the IRQ i.e. __TEL3=0, CSS=0__. During `yielding` SMC processing, the IRQ
exceptions are unmasked i.e. `PSTATE.I=0`, and a non-secure interrupt will exceptions are unmasked i.e. `PSTATE.I=0`, and a non-secure interrupt will
trigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose trigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose
register context and issues an SMC with `TSP_PREEMPTED` as the function register context and issues an SMC with `TSP_PREEMPTED` as the function
...@@ -860,7 +860,7 @@ invoked: ...@@ -860,7 +860,7 @@ invoked:
4. `SMC_PREEMPTED` is set in x0 and return to non secure state after 4. `SMC_PREEMPTED` is set in x0 and return to non secure state after
restoring non secure context. restoring non secure context.
The Normal World is expected to resume the TSP after the `standard` SMC preemption The Normal World is expected to resume the TSP after the `yielding` SMC preemption
by issuing an SMC with `TSP_FID_RESUME` as the function identifier (see section 3). by issuing an SMC with `TSP_FID_RESUME` as the function identifier (see section 3).
The TSPD service takes the following actions in `tspd_smc_handler()` function The TSPD service takes the following actions in `tspd_smc_handler()` function
upon receiving this SMC: upon receiving this SMC:
...@@ -951,9 +951,9 @@ The TSP handles interrupts under the asynchronous model as follows. ...@@ -951,9 +951,9 @@ The TSP handles interrupts under the asynchronous model as follows.
----------------------- -----------------------
### 3.1 Implication of preempted SMC on Non-Secure Software ### 3.1 Implication of preempted SMC on Non-Secure Software
A `standard` SMC call to Secure payload can be preempted by a non-secure A `yielding` SMC call to Secure payload can be preempted by a non-secure
interrupt and the execution can return to the non-secure world for handling interrupt and the execution can return to the non-secure world for handling
the interrupt (For details on `standard` SMC refer [SMC calling convention]). the interrupt (For details on `yielding` SMC refer [SMC calling convention]).
In this case, the SMC call has not completed its execution and the execution In this case, the SMC call has not completed its execution and the execution
must return back to the secure payload to resume the preempted SMC call. must return back to the secure payload to resume the preempted SMC call.
This can be achieved by issuing an SMC call which instructs to resume the This can be achieved by issuing an SMC call which instructs to resume the
...@@ -964,26 +964,26 @@ a fast SMC call. ...@@ -964,26 +964,26 @@ a fast SMC call.
In the Test Secure Payload implementation, `TSP_FID_RESUME` is designated In the Test Secure Payload implementation, `TSP_FID_RESUME` is designated
as the resume SMC FID. It is important to note that `TSP_FID_RESUME` is a as the resume SMC FID. It is important to note that `TSP_FID_RESUME` is a
`standard` SMC which means it too can be be preempted. The typical non `yielding` SMC which means it too can be be preempted. The typical non
secure software sequence for issuing a `standard` SMC would look like this, secure software sequence for issuing a `yielding` SMC would look like this,
assuming `P.STATE.I=0` in the non secure state : assuming `P.STATE.I=0` in the non secure state :
int rc; int rc;
rc = smc(TSP_STD_SMC_FID, ...); /* Issue a Standard SMC call */ rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */
/* The pending non-secure interrupt is handled by the interrupt handler /* The pending non-secure interrupt is handled by the interrupt handler
and returns back here. */ and returns back here. */
while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */ while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */
rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */ rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */
} }
The `TSP_STD_SMC_FID` is any `standard` SMC function identifier and the smc() The `TSP_YIELD_SMC_FID` is any `yielding` SMC function identifier and the smc()
function invokes a SMC call with the required arguments. The pending non-secure function invokes a SMC call with the required arguments. The pending non-secure
interrupt causes an IRQ exception and the IRQ handler registered at the interrupt causes an IRQ exception and the IRQ handler registered at the
exception vector handles the non-secure interrupt and returns. The return value exception vector handles the non-secure interrupt and returns. The return value
from the SMC call is tested for `SMC_PREEMPTED` to check whether it is from the SMC call is tested for `SMC_PREEMPTED` to check whether it is
preempted. If it is, then the resume SMC call `TSP_FID_RESUME` is issued. The preempted. If it is, then the resume SMC call `TSP_FID_RESUME` is issued. The
return value of the SMC call is tested again to check if it is preempted. return value of the SMC call is tested again to check if it is preempted.
This is done in a loop till the SMC call succeeds or fails. If a `standard` This is done in a loop till the SMC call succeeds or fails. If a `yielding`
SMC is preempted, until it is resumed using `TSP_FID_RESUME` SMC and SMC is preempted, until it is resumed using `TSP_FID_RESUME` SMC and
completed, the current TSPD prevents any other SMC call from re-entering completed, the current TSPD prevents any other SMC call from re-entering
TSP by returning `SMC_UNK` error. TSP by returning `SMC_UNK` error.
......
...@@ -51,9 +51,9 @@ of these terms. ...@@ -51,9 +51,9 @@ of these terms.
The SMC Function Identifier includes a OEN field. These values and their The SMC Function Identifier includes a OEN field. These values and their
meaning are described in [SMCCC] and summarized in table 1 below. Some entities meaning are described in [SMCCC] and summarized in table 1 below. Some entities
are allocated a range of of OENs. The OEN must be interpreted in conjunction are allocated a range of of OENs. The OEN must be interpreted in conjunction
with the SMC call type, which is either _Fast_ or _Standard_. Fast calls are with the SMC call type, which is either _Fast_ or _Yielding_. Fast calls are
uninterruptible whereas Standard calls can be pre-empted. The majority of uninterruptible whereas Yielding calls can be pre-empted. The majority of
Owning Entities only have allocated ranges for Fast calls: Standard calls are Owning Entities only have allocated ranges for Fast calls: Yielding calls are
reserved exclusively for Trusted OS providers or for interoperability with reserved exclusively for Trusted OS providers or for interoperability with
legacy 32-bit software that predates the [SMCCC]. legacy 32-bit software that predates the [SMCCC].
...@@ -67,8 +67,8 @@ legacy 32-bit software that predates the [SMCCC]. ...@@ -67,8 +67,8 @@ legacy 32-bit software that predates the [SMCCC].
Fast 48-49 Trusted Application calls Fast 48-49 Trusted Application calls
Fast 50-63 Trusted OS calls Fast 50-63 Trusted OS calls
Std 0- 1 Reserved for existing ARMv7 calls Yielding 0- 1 Reserved for existing ARMv7 calls
Std 2-63 Trusted OS Standard Calls Yielding 2-63 Trusted OS Standard Calls
_Table 1: Service types and their corresponding Owning Entity Numbers_ _Table 1: Service types and their corresponding Owning Entity Numbers_
...@@ -115,7 +115,7 @@ initialization and call handler functions. ...@@ -115,7 +115,7 @@ initialization and call handler functions.
* `_start` and `_end` values must be based on the `OEN_*` values defined in * `_start` and `_end` values must be based on the `OEN_*` values defined in
[`smcc.h`] [`smcc.h`]
* `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD` * `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_YIELD`
* `_setup` is the initialization function with the `rt_svc_init` signature: * `_setup` is the initialization function with the `rt_svc_init` signature:
...@@ -138,7 +138,7 @@ to ensure that the following conditions are met: ...@@ -138,7 +138,7 @@ to ensure that the following conditions are met:
1. The `_start` OEN is not greater than the `_end` OEN 1. The `_start` OEN is not greater than the `_end` OEN
2. The `_end` OEN does not exceed the maximum OEN value (63) 2. The `_end` OEN does not exceed the maximum OEN value (63)
3. The `_type` is one of `SMC_TYPE_FAST` or `SMC_TYPE_STD` 3. The `_type` is one of `SMC_TYPE_FAST` or `SMC_TYPE_YIELD`
4. `_setup` and `_smch` routines have been specified 4. `_setup` and `_smch` routines have been specified
[`std_svc_setup.c`] provides an example of registering a runtime service: [`std_svc_setup.c`] provides an example of registering a runtime service:
......
/* /*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#define TSP_SYSTEM_RESET_DONE 0xf2000009 #define TSP_SYSTEM_RESET_DONE 0xf2000009
/* /*
* Function identifiers to handle S-El1 interrupt through the synchronous * Function identifiers to handle S-EL1 interrupt through the synchronous
* handling model. If the TSP was previously interrupted then control has to * handling model. If the TSP was previously interrupted then control has to
* be returned to the TSPD after handling the interrupt else execution can * be returned to the TSPD after handling the interrupt else execution can
* remain in the TSP. * remain in the TSP.
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
/* /*
* Identifiers for various TSP services. Corresponding function IDs (whether * Identifiers for various TSP services. Corresponding function IDs (whether
* fast or standard) are generated by macros defined below * fast or yielding) are generated by macros defined below
*/ */
#define TSP_ADD 0x2000 #define TSP_ADD 0x2000
#define TSP_SUB 0x2001 #define TSP_SUB 0x2001
...@@ -74,15 +74,15 @@ ...@@ -74,15 +74,15 @@
/* /*
* Generate function IDs for TSP services to be used in SMC calls, by * Generate function IDs for TSP services to be used in SMC calls, by
* appropriately setting bit 31 to differentiate standard and fast SMC calls * appropriately setting bit 31 to differentiate yielding and fast SMC calls
*/ */
#define TSP_STD_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000)) #define TSP_YIELD_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000))
#define TSP_FAST_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000) | (1u << 31)) #define TSP_FAST_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000) | (1u << 31))
/* SMC function ID to request a previously preempted std smc */ /* SMC function ID to request a previously preempted yielding smc */
#define TSP_FID_RESUME TSP_STD_FID(0x3000) #define TSP_FID_RESUME TSP_YIELD_FID(0x3000)
/* /*
* SMC function ID to request abortion of a previously preempted std smc. A * SMC function ID to request abortion of a previously preempted yielding SMC. A
* fast SMC is used so that the TSP abort handler does not have to be * fast SMC is used so that the TSP abort handler does not have to be
* reentrant. * reentrant.
*/ */
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
typedef uint32_t tsp_vector_isn_t; typedef uint32_t tsp_vector_isn_t;
typedef struct tsp_vectors { typedef struct tsp_vectors {
tsp_vector_isn_t std_smc_entry; tsp_vector_isn_t yield_smc_entry;
tsp_vector_isn_t fast_smc_entry; tsp_vector_isn_t fast_smc_entry;
tsp_vector_isn_t cpu_on_entry; tsp_vector_isn_t cpu_on_entry;
tsp_vector_isn_t cpu_off_entry; tsp_vector_isn_t cpu_off_entry;
...@@ -125,7 +125,7 @@ typedef struct tsp_vectors { ...@@ -125,7 +125,7 @@ typedef struct tsp_vectors {
tsp_vector_isn_t sel1_intr_entry; tsp_vector_isn_t sel1_intr_entry;
tsp_vector_isn_t system_off_entry; tsp_vector_isn_t system_off_entry;
tsp_vector_isn_t system_reset_entry; tsp_vector_isn_t system_reset_entry;
tsp_vector_isn_t abort_std_smc_entry; tsp_vector_isn_t abort_yield_smc_entry;
} tsp_vectors_t; } tsp_vectors_t;
......
...@@ -61,7 +61,10 @@ ...@@ -61,7 +61,10 @@
#define SMC_OK 0 #define SMC_OK 0
#define SMC_UNK 0xffffffff #define SMC_UNK 0xffffffff
#define SMC_TYPE_FAST ULL(1) #define SMC_TYPE_FAST ULL(1)
#if !ERROR_DEPRECATED
#define SMC_TYPE_STD 0 #define SMC_TYPE_STD 0
#endif
#define SMC_TYPE_YIELD 0
#define SMC_PREEMPTED 0xfffffffe #define SMC_PREEMPTED 0xfffffffe
/******************************************************************************* /*******************************************************************************
* Owning entity number definitions inside the function id as per the SMC * Owning entity number definitions inside the function id as per the SMC
...@@ -75,7 +78,7 @@ ...@@ -75,7 +78,7 @@
#define OEN_SIP_END 2 #define OEN_SIP_END 2
#define OEN_OEM_START 3 #define OEN_OEM_START 3
#define OEN_OEM_END 3 #define OEN_OEM_END 3
#define OEN_STD_START 4 /* Standard Calls */ #define OEN_STD_START 4 /* Standard Service Calls */
#define OEN_STD_END 4 #define OEN_STD_END 4
#define OEN_TAP_START 48 /* Trusted Applications */ #define OEN_TAP_START 48 /* Trusted Applications */
#define OEN_TAP_END 49 #define OEN_TAP_END 49
......
...@@ -65,7 +65,7 @@ void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point, ...@@ -65,7 +65,7 @@ void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point,
tsp_ctx->mpidr = read_mpidr_el1(); tsp_ctx->mpidr = read_mpidr_el1();
tsp_ctx->state = 0; tsp_ctx->state = 0;
set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF); set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF);
clr_std_smc_active_flag(tsp_ctx->state); clr_yield_smc_active_flag(tsp_ctx->state);
cm_set_context(&tsp_ctx->cpu_ctx, SECURE); cm_set_context(&tsp_ctx->cpu_ctx, SECURE);
...@@ -140,18 +140,18 @@ void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret) ...@@ -140,18 +140,18 @@ void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret)
******************************************************************************/ ******************************************************************************/
int tspd_abort_preempted_smc(tsp_context_t *tsp_ctx) int tspd_abort_preempted_smc(tsp_context_t *tsp_ctx)
{ {
if (!get_std_smc_active_flag(tsp_ctx->state)) if (!get_yield_smc_active_flag(tsp_ctx->state))
return 0; return 0;
/* Abort any preempted SMC request */ /* Abort any preempted SMC request */
clr_std_smc_active_flag(tsp_ctx->state); clr_yield_smc_active_flag(tsp_ctx->state);
/* /*
* Arrange for an entry into the test secure payload. It will * Arrange for an entry into the test secure payload. It will
* be returned via TSP_ABORT_DONE case in tspd_smc_handler. * be returned via TSP_ABORT_DONE case in tspd_smc_handler.
*/ */
cm_set_elr_el3(SECURE, cm_set_elr_el3(SECURE,
(uint64_t) &tsp_vectors->abort_std_smc_entry); (uint64_t) &tsp_vectors->abort_yield_smc_entry);
uint64_t rc = tspd_synchronous_sp_entry(tsp_ctx); uint64_t rc = tspd_synchronous_sp_entry(tsp_ctx);
if (rc != 0) if (rc != 0)
......
/* /*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -102,7 +102,7 @@ uint64_t tspd_handle_sp_preemption(void *handle) ...@@ -102,7 +102,7 @@ uint64_t tspd_handle_sp_preemption(void *handle)
cm_set_next_eret_context(NON_SECURE); cm_set_next_eret_context(NON_SECURE);
/* /*
* The TSP was preempted during STD SMC execution. * The TSP was preempted during execution of a Yielding SMC Call.
* Return back to the normal world with SMC_PREEMPTED as error * Return back to the normal world with SMC_PREEMPTED as error
* code in x0. * code in x0.
*/ */
...@@ -146,7 +146,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id, ...@@ -146,7 +146,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
* context since the TSP is supposed to preserve it during S-EL1 * context since the TSP is supposed to preserve it during S-EL1
* interrupt handling. * interrupt handling.
*/ */
if (get_std_smc_active_flag(tsp_ctx->state)) { if (get_yield_smc_active_flag(tsp_ctx->state)) {
tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
CTX_SPSR_EL3); CTX_SPSR_EL3);
tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
...@@ -345,7 +345,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -345,7 +345,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* Restore the relevant EL3 state which saved to service * Restore the relevant EL3 state which saved to service
* this SMC. * this SMC.
*/ */
if (get_std_smc_active_flag(tsp_ctx->state)) { if (get_yield_smc_active_flag(tsp_ctx->state)) {
SMC_SET_EL3(&tsp_ctx->cpu_ctx, SMC_SET_EL3(&tsp_ctx->cpu_ctx,
CTX_SPSR_EL3, CTX_SPSR_EL3,
tsp_ctx->saved_spsr_el3); tsp_ctx->saved_spsr_el3);
...@@ -461,7 +461,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -461,7 +461,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
#endif #endif
/* /*
* This function ID is used only by the SP to indicate it has finished * This function ID is used only by the SP to indicate it has finished
* aborting a preempted Standard SMC request. * aborting a preempted Yielding SMC Call.
*/ */
case TSP_ABORT_DONE: case TSP_ABORT_DONE:
...@@ -509,10 +509,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -509,10 +509,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
case TSP_FAST_FID(TSP_MUL): case TSP_FAST_FID(TSP_MUL):
case TSP_FAST_FID(TSP_DIV): case TSP_FAST_FID(TSP_DIV):
case TSP_STD_FID(TSP_ADD): case TSP_YIELD_FID(TSP_ADD):
case TSP_STD_FID(TSP_SUB): case TSP_YIELD_FID(TSP_SUB):
case TSP_STD_FID(TSP_MUL): case TSP_YIELD_FID(TSP_MUL):
case TSP_STD_FID(TSP_DIV): case TSP_YIELD_FID(TSP_DIV):
if (ns) { if (ns) {
/* /*
* This is a fresh request from the non-secure client. * This is a fresh request from the non-secure client.
...@@ -523,7 +523,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -523,7 +523,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
assert(handle == cm_get_context(NON_SECURE)); assert(handle == cm_get_context(NON_SECURE));
/* Check if we are already preempted */ /* Check if we are already preempted */
if (get_std_smc_active_flag(tsp_ctx->state)) if (get_yield_smc_active_flag(tsp_ctx->state))
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
cm_el1_sysregs_context_save(NON_SECURE); cm_el1_sysregs_context_save(NON_SECURE);
...@@ -553,13 +553,14 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -553,13 +553,14 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
cm_set_elr_el3(SECURE, (uint64_t) cm_set_elr_el3(SECURE, (uint64_t)
&tsp_vectors->fast_smc_entry); &tsp_vectors->fast_smc_entry);
} else { } else {
set_std_smc_active_flag(tsp_ctx->state); set_yield_smc_active_flag(tsp_ctx->state);
cm_set_elr_el3(SECURE, (uint64_t) cm_set_elr_el3(SECURE, (uint64_t)
&tsp_vectors->std_smc_entry); &tsp_vectors->yield_smc_entry);
#if TSP_NS_INTR_ASYNC_PREEMPT #if TSP_NS_INTR_ASYNC_PREEMPT
/* /*
* Enable the routing of NS interrupts to EL3 * Enable the routing of NS interrupts to EL3
* during STD SMC processing on this core. * during processing of a Yielding SMC Call on
* this core.
*/ */
enable_intr_rm_local(INTR_TYPE_NS, SECURE); enable_intr_rm_local(INTR_TYPE_NS, SECURE);
#endif #endif
...@@ -585,13 +586,13 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -585,13 +586,13 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
/* Restore non-secure state */ /* Restore non-secure state */
cm_el1_sysregs_context_restore(NON_SECURE); cm_el1_sysregs_context_restore(NON_SECURE);
cm_set_next_eret_context(NON_SECURE); cm_set_next_eret_context(NON_SECURE);
if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_STD) { if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_YIELD) {
clr_std_smc_active_flag(tsp_ctx->state); clr_yield_smc_active_flag(tsp_ctx->state);
#if TSP_NS_INTR_ASYNC_PREEMPT #if TSP_NS_INTR_ASYNC_PREEMPT
/* /*
* Disable the routing of NS interrupts to EL3 * Disable the routing of NS interrupts to EL3
* after STD SMC processing is finished on this * after processing of a Yielding SMC Call on
* core. * this core is finished.
*/ */
disable_intr_rm_local(INTR_TYPE_NS, SECURE); disable_intr_rm_local(INTR_TYPE_NS, SECURE);
#endif #endif
...@@ -602,8 +603,8 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -602,8 +603,8 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
break; break;
/* /*
* Request from the non-secure world to abort a preempted Standard SMC * Request from the non-secure world to abort a preempted Yielding SMC
* call. * Call.
*/ */
case TSP_FID_ABORT: case TSP_FID_ABORT:
/* ABORT should only be invoked by normal world */ /* ABORT should only be invoked by normal world */
...@@ -635,7 +636,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -635,7 +636,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
/* /*
* Request from non secure world to resume the preempted * Request from non secure world to resume the preempted
* Standard SMC call. * Yielding SMC Call.
*/ */
case TSP_FID_RESUME: case TSP_FID_RESUME:
/* RESUME should be invoked only by normal world */ /* RESUME should be invoked only by normal world */
...@@ -652,7 +653,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -652,7 +653,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
assert(handle == cm_get_context(NON_SECURE)); assert(handle == cm_get_context(NON_SECURE));
/* Check if we are already preempted before resume */ /* Check if we are already preempted before resume */
if (!get_std_smc_active_flag(tsp_ctx->state)) if (!get_yield_smc_active_flag(tsp_ctx->state))
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
cm_el1_sysregs_context_save(NON_SECURE); cm_el1_sysregs_context_save(NON_SECURE);
...@@ -664,7 +665,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, ...@@ -664,7 +665,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
#if TSP_NS_INTR_ASYNC_PREEMPT #if TSP_NS_INTR_ASYNC_PREEMPT
/* /*
* Enable the routing of NS interrupts to EL3 during resumption * Enable the routing of NS interrupts to EL3 during resumption
* of STD SMC call on this core. * of a Yielding SMC Call on this core.
*/ */
enable_intr_rm_local(INTR_TYPE_NS, SECURE); enable_intr_rm_local(INTR_TYPE_NS, SECURE);
#endif #endif
...@@ -724,13 +725,13 @@ DECLARE_RT_SVC( ...@@ -724,13 +725,13 @@ DECLARE_RT_SVC(
tspd_smc_handler tspd_smc_handler
); );
/* Define a SPD runtime service descriptor for standard SMC calls */ /* Define a SPD runtime service descriptor for Yielding SMC Calls */
DECLARE_RT_SVC( DECLARE_RT_SVC(
tspd_std, tspd_std,
OEN_TOS_START, OEN_TOS_START,
OEN_TOS_END, OEN_TOS_END,
SMC_TYPE_STD, SMC_TYPE_YIELD,
NULL, NULL,
tspd_smc_handler tspd_smc_handler
); );
/* /*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
/* /*
* This flag is used by the TSPD to determine if the TSP is servicing a standard * This flag is used by the TSPD to determine if the TSP is servicing a yielding
* SMC request prior to programming the next entry into the TSP e.g. if TSP * SMC request prior to programming the next entry into the TSP e.g. if TSP
* execution is preempted by a non-secure interrupt and handed control to the * execution is preempted by a non-secure interrupt and handed control to the
* normal world. If another request which is distinct from what the TSP was * normal world. If another request which is distinct from what the TSP was
...@@ -65,15 +65,16 @@ ...@@ -65,15 +65,16 @@
* reject the new request or service it while ensuring that the previous context * reject the new request or service it while ensuring that the previous context
* is not corrupted. * is not corrupted.
*/ */
#define STD_SMC_ACTIVE_FLAG_SHIFT 2 #define YIELD_SMC_ACTIVE_FLAG_SHIFT 2
#define STD_SMC_ACTIVE_FLAG_MASK 1 #define YIELD_SMC_ACTIVE_FLAG_MASK 1
#define get_std_smc_active_flag(state) ((state >> STD_SMC_ACTIVE_FLAG_SHIFT) \ #define get_yield_smc_active_flag(state) \
& STD_SMC_ACTIVE_FLAG_MASK) ((state >> YIELD_SMC_ACTIVE_FLAG_SHIFT) \
#define set_std_smc_active_flag(state) (state |= \ & YIELD_SMC_ACTIVE_FLAG_MASK)
1 << STD_SMC_ACTIVE_FLAG_SHIFT) #define set_yield_smc_active_flag(state) (state |= \
#define clr_std_smc_active_flag(state) (state &= \ 1 << YIELD_SMC_ACTIVE_FLAG_SHIFT)
~(STD_SMC_ACTIVE_FLAG_MASK \ #define clr_yield_smc_active_flag(state) (state &= \
<< STD_SMC_ACTIVE_FLAG_SHIFT)) ~(YIELD_SMC_ACTIVE_FLAG_MASK \
<< YIELD_SMC_ACTIVE_FLAG_SHIFT))
/******************************************************************************* /*******************************************************************************
* Secure Payload execution state information i.e. aarch32 or aarch64 * Secure Payload execution state information i.e. aarch32 or aarch64
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment