Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
841cb4f7
Unverified
Commit
841cb4f7
authored
Jun 18, 2018
by
Dimitris Papastamos
Committed by
GitHub
Jun 18, 2018
Browse files
Merge pull request #1426 from antonio-nino-diaz-arm/an/spm-sync
SPM: Refactor entry and exit of the SP
parents
db1f39b6
14fcc6e1
Changes
2
Hide whitespace changes
Inline
Side-by-side
services/std_svc/spm/spm_main.c
View file @
841cb4f7
...
@@ -81,10 +81,13 @@ int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
...
@@ -81,10 +81,13 @@ int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
}
}
/*******************************************************************************
/*******************************************************************************
* This function takes an SP context pointer and prepares the CPU to enter.
* This function takes an SP context pointer and performs a synchronous entry
* into it.
******************************************************************************/
******************************************************************************/
static
void
spm_sp_prepare
_ent
e
r
(
sp_context_t
*
sp_ctx
)
static
uint64_t
spm_sp_synchronous
_entr
y
(
sp_context_t
*
sp_ctx
)
{
{
uint64_t
rc
;
assert
(
sp_ctx
!=
NULL
);
assert
(
sp_ctx
!=
NULL
);
/* Assign the context of the SP to this CPU */
/* Assign the context of the SP to this CPU */
...
@@ -97,15 +100,32 @@ static void spm_sp_prepare_enter(sp_context_t *sp_ctx)
...
@@ -97,15 +100,32 @@ static void spm_sp_prepare_enter(sp_context_t *sp_ctx)
/* Invalidate TLBs at EL1. */
/* Invalidate TLBs at EL1. */
tlbivmalle1
();
tlbivmalle1
();
dsbish
();
dsbish
();
/* Enter Secure Partition */
rc
=
spm_secure_partition_enter
(
&
sp_ctx
->
c_rt_ctx
);
/* Save secure state */
cm_el1_sysregs_context_save
(
SECURE
);
return
rc
;
}
}
/*******************************************************************************
/*******************************************************************************
* Enter SP after preparing it with spm_sp_prepare_enter().
* This function returns to the place where spm_sp_synchronous_entry() was
* called originally.
******************************************************************************/
******************************************************************************/
static
uint64_t
spm_sp_enter
(
sp_context_t
*
sp_ctx
)
__dead2
static
void
spm_sp_synchronous_exit
(
uint64_t
rc
)
{
{
/* Enter Secure Partition */
sp_context_t
*
ctx
=
&
sp_ctx
;
return
spm_secure_partition_enter
(
&
sp_ctx
->
c_rt_ctx
);
/*
* The SPM must have initiated the original request through a
* synchronous entry into the secure partition. Jump back to the
* original C runtime context with the value of rc in x0;
*/
spm_secure_partition_exit
(
ctx
->
c_rt_ctx
,
rc
);
panic
();
}
}
/*******************************************************************************
/*******************************************************************************
...
@@ -113,7 +133,7 @@ static uint64_t spm_sp_enter(sp_context_t *sp_ctx)
...
@@ -113,7 +133,7 @@ static uint64_t spm_sp_enter(sp_context_t *sp_ctx)
******************************************************************************/
******************************************************************************/
static
int32_t
spm_init
(
void
)
static
int32_t
spm_init
(
void
)
{
{
uint64_t
rc
=
0
;
uint64_t
rc
;
sp_context_t
*
ctx
;
sp_context_t
*
ctx
;
INFO
(
"Secure Partition init...
\n
"
);
INFO
(
"Secure Partition init...
\n
"
);
...
@@ -122,8 +142,7 @@ static int32_t spm_init(void)
...
@@ -122,8 +142,7 @@ static int32_t spm_init(void)
ctx
->
state
=
SP_STATE_RESET
;
ctx
->
state
=
SP_STATE_RESET
;
spm_sp_prepare_enter
(
ctx
);
rc
=
spm_sp_synchronous_entry
(
ctx
);
rc
|=
spm_sp_enter
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
ctx
->
state
=
SP_STATE_IDLE
;
ctx
->
state
=
SP_STATE_IDLE
;
...
@@ -168,6 +187,7 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
...
@@ -168,6 +187,7 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
uint64_t
comm_buffer_address
,
uint64_t
comm_buffer_address
,
uint64_t
comm_size_address
,
void
*
handle
)
uint64_t
comm_size_address
,
void
*
handle
)
{
{
uint64_t
rc
;
sp_context_t
*
ctx
=
&
sp_ctx
;
sp_context_t
*
ctx
=
&
sp_ctx
;
/* Cookie. Reserved for future use. It must be zero. */
/* Cookie. Reserved for future use. It must be zero. */
...
@@ -188,59 +208,29 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
...
@@ -188,59 +208,29 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
/* Save the Normal world context */
/* Save the Normal world context */
cm_el1_sysregs_context_save
(
NON_SECURE
);
cm_el1_sysregs_context_save
(
NON_SECURE
);
/* Wait until the Secure Partition is
IDLE
and set it to
BUSY
. */
/* Wait until the Secure Partition is
idle
and set it to
busy
. */
sp_state_wait_switch
(
ctx
,
SP_STATE_IDLE
,
SP_STATE_BUSY
);
sp_state_wait_switch
(
ctx
,
SP_STATE_IDLE
,
SP_STATE_BUSY
);
/* Jump to the Secure Partition. */
/* Set values for registers on SP entry */
spm_sp_prepare_enter
(
ctx
);
cpu_context_t
*
cpu_ctx
=
&
(
ctx
->
cpu_ctx
);
SMC_RET4
(
&
(
ctx
->
cpu_ctx
),
smc_fid
,
comm_buffer_address
,
comm_size_address
,
plat_my_core_pos
());
}
/*******************************************************************************
* SP_EVENT_COMPLETE_AARCH64 handler
******************************************************************************/
static
uint64_t
sp_event_complete
(
uint64_t
x1
)
{
sp_context_t
*
ctx
=
&
sp_ctx
;
/* Save secure state */
write_ctx_reg
(
get_gpregs_ctx
(
cpu_ctx
),
CTX_GPREG_X0
,
smc_fid
);
cm_el1_sysregs_context_save
(
SECURE
);
write_ctx_reg
(
get_gpregs_ctx
(
cpu_ctx
),
CTX_GPREG_X1
,
comm_buffer_address
);
write_ctx_reg
(
get_gpregs_ctx
(
cpu_ctx
),
CTX_GPREG_X2
,
comm_size_address
);
write_ctx_reg
(
get_gpregs_ctx
(
cpu_ctx
),
CTX_GPREG_X3
,
plat_my_core_pos
());
if
(
ctx
->
state
==
SP_STATE_RESET
)
{
/* Jump to the Secure Partition. */
/*
rc
=
spm_sp_synchronous_entry
(
ctx
);
* SPM reports completion. The SPM must have initiated the
* original request through a synchronous entry into the secure
* partition. Jump back to the original C runtime context.
*/
spm_secure_partition_exit
(
ctx
->
c_rt_ctx
,
x1
);
/* spm_secure_partition_exit doesn't return */
}
/*
* This is the result from the Secure partition of an earlier request.
* Copy the result into the non-secure context and return to the
* non-secure state.
*/
/*
Mark
Secure Partition as idle */
/*
Flag
Secure Partition as idle
.
*/
assert
(
ctx
->
state
==
SP_STATE_BUSY
);
assert
(
ctx
->
state
==
SP_STATE_BUSY
);
sp_state_set
(
ctx
,
SP_STATE_IDLE
);
sp_state_set
(
ctx
,
SP_STATE_IDLE
);
/* Get a reference to the non-secure context */
cpu_context_t
*
ns_cpu_context
=
cm_get_context
(
NON_SECURE
);
assert
(
ns_cpu_context
!=
NULL
);
/* 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
);
/* Return to non-secure world */
SMC_RET1
(
handle
,
rc
);
SMC_RET1
(
ns_cpu_context
,
x1
);
}
}
/*******************************************************************************
/*******************************************************************************
...
@@ -275,7 +265,7 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
...
@@ -275,7 +265,7 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
SMC_RET1
(
handle
,
SPM_VERSION_COMPILED
);
SMC_RET1
(
handle
,
SPM_VERSION_COMPILED
);
case
SP_EVENT_COMPLETE_AARCH64
:
case
SP_EVENT_COMPLETE_AARCH64
:
return
sp_event_complete
(
x1
);
spm_sp_synchronous_exit
(
x1
);
case
SP_MEMORY_ATTRIBUTES_GET_AARCH64
:
case
SP_MEMORY_ATTRIBUTES_GET_AARCH64
:
INFO
(
"Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC
\n
"
);
INFO
(
"Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC
\n
"
);
...
@@ -305,6 +295,8 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
...
@@ -305,6 +295,8 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
/* Handle SMCs from Non-secure world. */
/* Handle SMCs from Non-secure world. */
assert
(
handle
==
cm_get_context
(
NON_SECURE
));
switch
(
smc_fid
)
{
switch
(
smc_fid
)
{
case
MM_VERSION_AARCH32
:
case
MM_VERSION_AARCH32
:
...
...
services/std_svc/spm/spm_private.h
View file @
841cb4f7
...
@@ -35,7 +35,7 @@
...
@@ -35,7 +35,7 @@
#include <stdint.h>
#include <stdint.h>
#include <xlat_tables_v2.h>
#include <xlat_tables_v2.h>
typedef
enum
s
ecure_partition
_state
{
typedef
enum
s
p
_state
{
SP_STATE_RESET
=
0
,
SP_STATE_RESET
=
0
,
SP_STATE_IDLE
,
SP_STATE_IDLE
,
SP_STATE_BUSY
SP_STATE_BUSY
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment