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
d9b1128b
Commit
d9b1128b
authored
Jul 28, 2014
by
danh-arm
Browse files
Merge pull request #169 from achingupta/ag/tf-issues#198
Ag/tf issues#198
parents
592dd7cb
539a7b38
Changes
26
Hide whitespace changes
Inline
Side-by-side
services/std_svc/psci/psci_afflvl_suspend.c
View file @
d9b1128b
...
...
@@ -126,8 +126,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
unsigned
int
power_state
)
{
unsigned
int
plat_state
;
unsigned
long
psci_entrypoint
,
sctlr
;
el3_state_t
*
saved_el3_state
;
unsigned
long
psci_entrypoint
;
uint32_t
ns_scr_el3
=
read_scr_el3
();
uint32_t
ns_sctlr_el1
=
read_sctlr_el1
();
int
rc
;
...
...
@@ -170,37 +169,14 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
*/
cm_el3_sysregs_context_save
(
NON_SECURE
);
/*
* The EL3 state to PoC since it will be accessed after a
* reset with the caches turned off
*/
saved_el3_state
=
get_el3state_ctx
(
cm_get_context
(
NON_SECURE
));
flush_dcache_range
((
uint64_t
)
saved_el3_state
,
sizeof
(
*
saved_el3_state
));
/* Set the secure world (EL3) re-entry point after BL1 */
psci_entrypoint
=
(
unsigned
long
)
psci_aff_suspend_finish_entry
;
/*
* Arch. management. Perform the necessary steps to flush all
* cpu caches.
*
* TODO: This power down sequence varies across cpus so it needs to be
* abstracted out on the basis of the MIDR like in cpu_reset_handler().
* Do the bare minimal for the time being. Fix this before porting to
* Cortex models.
*/
sctlr
=
read_sctlr_el3
();
sctlr
&=
~
SCTLR_C_BIT
;
write_sctlr_el3
(
sctlr
);
isb
();
/* ensure MMU disable takes immediate effect */
/*
* CAUTION: This flush to the level of unification makes an assumption
* about the cache hierarchy at affinity level 0 (cpu) in the platform.
* Ideally the platform should tell psci which levels to flush to exit
* coherency.
*/
dcsw_op_louis
(
DCCISW
);
psci_do_pwrdown_cache_maintenance
(
MPIDR_AFFLVL0
);
/*
* Plat. management: Allow the platform to perform the
...
...
@@ -379,9 +355,6 @@ static int psci_call_suspend_handlers(mpidr_aff_map_nodes_t mpidr_nodes,
* the lowest to the highest affinity level implemented by the platform because
* to turn off affinity level X it is neccesary to turn off affinity level X - 1
* first.
*
* CAUTION: This function is called with coherent stacks so that coherency can
* be turned off and caches can be flushed safely.
******************************************************************************/
int
psci_afflvl_suspend
(
unsigned
long
entrypoint
,
unsigned
long
context_id
,
...
...
@@ -467,9 +440,11 @@ static unsigned int psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node)
/* Get the index for restoring the re-entry information */
/*
* Arch. management: Restore the stashed EL3 architectural
* context from the 'cpu_context' structure for this cpu.
* Arch. management: Enable the data cache, manage stack memory and
* restore the stashed EL3 architectural context from the 'cpu_context'
* structure for this cpu.
*/
psci_do_pwrup_cache_maintenance
();
cm_el3_sysregs_context_restore
(
NON_SECURE
);
/*
...
...
@@ -575,4 +550,3 @@ const afflvl_power_on_finisher_t psci_afflvl_suspend_finishers[] = {
psci_afflvl1_suspend_finish
,
psci_afflvl2_suspend_finish
,
};
services/std_svc/psci/psci_common.c
View file @
d9b1128b
...
...
@@ -390,9 +390,6 @@ static int psci_call_power_on_handlers(mpidr_aff_map_nodes_t mpidr_nodes,
* the highest to the lowest affinity level implemented by the platform because
* to turn on affinity level X it is neccesary to turn on affinity level X + 1
* first.
*
* CAUTION: This function is called with coherent stacks so that coherency and
* the mmu can be turned on safely.
******************************************************************************/
void
psci_afflvl_power_on_finish
(
int
start_afflvl
,
int
end_afflvl
,
...
...
services/std_svc/psci/psci_entry.S
View file @
d9b1128b
...
...
@@ -31,6 +31,7 @@
#include <arch.h>
#include <asm_macros.S>
#include <psci.h>
#include <xlat_tables.h>
.
globl
psci_aff_on_finish_entry
.
globl
psci_aff_suspend_finish_entry
...
...
@@ -43,11 +44,6 @@
*
upon
whether
it
was
resumed
from
suspend
or
simply
*
turned
on
,
call
the
common
power
on
finisher
with
*
the
handlers
(
chosen
depending
upon
original
state
)
.
*
For
ease
,
the
finisher
is
called
with
coherent
*
stacks
.
This
allows
the
cluster
/
cpu
finishers
to
*
enter
coherency
and
enable
the
mmu
without
running
*
into
issues
.
We
switch
back
to
normal
stacks
once
*
all
this
is
done
.
*
-----------------------------------------------------
*/
func
psci_aff_on_finish_entry
...
...
@@ -78,8 +74,34 @@ psci_aff_common_finish_entry:
*/
msr
spsel
,
#
0
/
*
--------------------------------------------
*
Give
ourselves
a
stack
whose
memory
will
be
*
marked
as
Normal
-
IS
-
WBWA
when
the
MMU
is
*
enabled
.
*
--------------------------------------------
*/
mrs
x0
,
mpidr_el1
bl
platform_set_coherent_stack
bl
platform_set_stack
/
*
--------------------------------------------
*
Enable
the
MMU
with
the
DCache
disabled
.
It
*
is
safe
to
use
stacks
allocated
in
normal
*
memory
as
a
result
.
All
memory
accesses
are
*
marked
nGnRnE
when
the
MMU
is
disabled
.
So
*
all
the
stack
writes
will
make
it
to
memory
.
*
All
memory
accesses
are
marked
Non
-
cacheable
*
when
the
MMU
is
enabled
but
D
$
is
disabled
.
*
So
used
stack
memory
is
guaranteed
to
be
*
visible
immediately
after
the
MMU
is
enabled
*
Enabling
the
DCache
at
the
same
time
as
the
*
MMU
can
lead
to
speculatively
fetched
and
*
possibly
stale
stack
memory
being
read
from
*
other
caches
.
This
can
lead
to
coherency
*
issues
.
*
--------------------------------------------
*/
mov
x0
,
#
DISABLE_DCACHE
bl
bl31_plat_enable_mmu
/
*
---------------------------------------------
*
Call
the
finishers
starting
from
affinity
...
...
@@ -95,60 +117,10 @@ psci_aff_common_finish_entry:
mov
x0
,
#
MPIDR_AFFLVL0
bl
psci_afflvl_power_on_finish
/
*
--------------------------------------------
*
Give
ourselves
a
stack
allocated
in
Normal
*
-
IS
-
WBWA
memory
*
--------------------------------------------
*/
mrs
x0
,
mpidr_el1
bl
platform_set_stack
b
el3_exit
_panic
:
b
_panic
/
*
-----------------------------------------------------
*
The
following
two
stubs
give
the
calling
cpu
a
*
coherent
stack
to
allow
flushing
of
caches
without
*
suffering
from
stack
coherency
issues
*
-----------------------------------------------------
*/
func
__psci_cpu_off
func_prologue
sub
sp
,
sp
,
#
0x10
stp
x19
,
x20
,
[
sp
,
#
0
]
mov
x19
,
sp
mrs
x0
,
mpidr_el1
bl
platform_set_coherent_stack
bl
psci_cpu_off
mov
sp
,
x19
ldp
x19
,
x20
,
[
sp
,#
0
]
add
sp
,
sp
,
#
0x10
func_epilogue
ret
func
__psci_cpu_suspend
func_prologue
sub
sp
,
sp
,
#
0x20
stp
x19
,
x20
,
[
sp
,
#
0
]
stp
x21
,
x22
,
[
sp
,
#
0x10
]
mov
x19
,
sp
mov
x20
,
x0
mov
x21
,
x1
mov
x22
,
x2
mrs
x0
,
mpidr_el1
bl
platform_set_coherent_stack
mov
x0
,
x20
mov
x1
,
x21
mov
x2
,
x22
bl
psci_cpu_suspend
mov
sp
,
x19
ldp
x21
,
x22
,
[
sp
,#
0x10
]
ldp
x19
,
x20
,
[
sp
,#
0
]
add
sp
,
sp
,
#
0x20
func_epilogue
ret
/
*
--------------------------------------------
*
This
function
is
called
to
indicate
to
the
*
power
controller
that
it
is
safe
to
power
...
...
services/std_svc/psci/psci_helpers.S
0 → 100644
View file @
d9b1128b
/*
*
Copyright
(
c
)
2014
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
Redistribution
and
use
in
source
and
binary
forms
,
with
or
without
*
modification
,
are
permitted
provided
that
the
following
conditions
are
met
:
*
*
Redistributions
of
source
code
must
retain
the
above
copyright
notice
,
this
*
list
of
conditions
and
the
following
disclaimer
.
*
*
Redistributions
in
binary
form
must
reproduce
the
above
copyright
notice
,
*
this
list
of
conditions
and
the
following
disclaimer
in
the
documentation
*
and
/
or
other
materials
provided
with
the
distribution
.
*
*
Neither
the
name
of
ARM
nor
the
names
of
its
contributors
may
be
used
*
to
endorse
or
promote
products
derived
from
this
software
without
specific
*
prior
written
permission
.
*
*
THIS
SOFTWARE
IS
PROVIDED
BY
THE
COPYRIGHT
HOLDERS
AND
CONTRIBUTORS
"AS IS"
*
AND
ANY
EXPRESS
OR
IMPLIED
WARRANTIES
,
INCLUDING
,
BUT
NOT
LIMITED
TO
,
THE
*
IMPLIED
WARRANTIES
OF
MERCHANTABILITY
AND
FITNESS
FOR
A
PARTICULAR
PURPOSE
*
ARE
DISCLAIMED
.
IN
NO
EVENT
SHALL
THE
COPYRIGHT
HOLDER
OR
CONTRIBUTORS
BE
*
LIABLE
FOR
ANY
DIRECT
,
INDIRECT
,
INCIDENTAL
,
SPECIAL
,
EXEMPLARY
,
OR
*
CONSEQUENTIAL
DAMAGES
(
INCLUDING
,
BUT
NOT
LIMITED
TO
,
PROCUREMENT
OF
*
SUBSTITUTE
GOODS
OR
SERVICES
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
*
INTERRUPTION
)
HOWEVER
CAUSED
AND
ON
ANY
THEORY
OF
LIABILITY
,
WHETHER
IN
*
CONTRACT
,
STRICT
LIABILITY
,
OR
TORT
(
INCLUDING
NEGLIGENCE
OR
OTHERWISE
)
*
ARISING
IN
ANY
WAY
OUT
OF
THE
USE
OF
THIS
SOFTWARE
,
EVEN
IF
ADVISED
OF
THE
*
POSSIBILITY
OF
SUCH
DAMAGE
.
*/
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
.
globl
psci_do_pwrdown_cache_maintenance
.
globl
psci_do_pwrup_cache_maintenance
/*
-----------------------------------------------------------------------
*
void
psci_do_pwrdown_cache_maintenance
(
uint32_t
affinity
level
)
;
*
*
This
function
performs
cache
maintenance
before
this
cpu
is
powered
*
off
.
The
levels
of
cache
affected
are
determined
by
the
affinity
level
*
which
is
passed
as
the
argument
.
Additionally
,
this
function
also
*
ensures
that
stack
memory
is
correctly
flushed
out
to
avoid
coherency
*
issues
due
to
a
change
in
its
memory
attributes
after
the
data
cache
*
is
disabled
.
*
-----------------------------------------------------------------------
*/
func
psci_do_pwrdown_cache_maintenance
stp
x29
,
x30
,
[
sp
,#-
16
]!
stp
x19
,
x20
,
[
sp
,#-
16
]!
/
*
---------------------------------------------
*
Disable
the
Data
Cache
.
*
---------------------------------------------
*/
mrs
x1
,
sctlr_el3
bic
x1
,
x1
,
#
SCTLR_C_BIT
msr
sctlr_el3
,
x1
isb
/
*
---------------------------------------------
*
Determine
to
how
many
levels
of
cache
will
be
*
subject
to
cache
maintenance
.
Affinity
level
*
0
implies
that
only
the
cpu
is
being
powered
*
down
.
Only
the
L1
data
cache
needs
to
be
*
flushed
to
the
PoU
in
this
case
.
For
a
higher
*
affinity
level
we
are
assuming
that
a
flush
*
of
L1
data
and
L2
unified
cache
is
enough
.
*
This
information
should
be
provided
by
the
*
platform
.
*
---------------------------------------------
*/
cmp
x0
,
#
MPIDR_AFFLVL0
mov
x0
,
#
DCCISW
b.ne
flush_caches_to_poc
/
*
---------------------------------------------
*
Flush
L1
cache
to
PoU
.
*
---------------------------------------------
*/
bl
dcsw_op_louis
b
do_stack_maintenance
/
*
---------------------------------------------
*
Flush
L1
and
L2
caches
to
PoC
.
*
---------------------------------------------
*/
flush_caches_to_poc
:
bl
dcsw_op_all
/
*
---------------------------------------------
*
TODO
:
Intra
-
cluster
coherency
should
be
*
turned
off
here
once
cpu
-
specific
*
abstractions
are
in
place
.
*
---------------------------------------------
*/
/
*
---------------------------------------------
*
Do
stack
maintenance
by
flushing
the
used
*
stack
to
the
main
memory
and
invalidating
the
*
remainder
.
*
---------------------------------------------
*/
do_stack_maintenance
:
mrs
x0
,
mpidr_el1
bl
platform_get_stack
/
*
---------------------------------------------
*
Calculate
and
store
the
size
of
the
used
*
stack
memory
in
x1
.
*
---------------------------------------------
*/
mov
x19
,
x0
mov
x1
,
sp
sub
x1
,
x0
,
x1
mov
x0
,
sp
bl
flush_dcache_range
/
*
---------------------------------------------
*
Calculate
and
store
the
size
of
the
unused
*
stack
memory
in
x1
.
Calculate
and
store
the
*
stack
base
address
in
x0
.
*
---------------------------------------------
*/
sub
x0
,
x19
,
#
PLATFORM_STACK_SIZE
sub
x1
,
sp
,
x0
bl
inv_dcache_range
ldp
x19
,
x20
,
[
sp
],
#
16
ldp
x29
,
x30
,
[
sp
],
#
16
ret
/*
-----------------------------------------------------------------------
*
void
psci_do_pwrup_cache_maintenance
(
void
)
;
*
*
This
function
performs
cache
maintenance
after
this
cpu
is
powered
up
.
*
Currently
,
this
involves
managing
the
used
stack
memory
before
turning
*
on
the
data
cache
.
*
-----------------------------------------------------------------------
*/
func
psci_do_pwrup_cache_maintenance
stp
x29
,
x30
,
[
sp
,#-
16
]!
/
*
---------------------------------------------
*
Ensure
any
inflight
stack
writes
have
made
it
*
to
main
memory
.
*
---------------------------------------------
*/
dmb
st
/
*
---------------------------------------------
*
Calculate
and
store
the
size
of
the
used
*
stack
memory
in
x1
.
Calculate
and
store
the
*
stack
base
address
in
x0
.
*
---------------------------------------------
*/
mrs
x0
,
mpidr_el1
bl
platform_get_stack
mov
x1
,
sp
sub
x1
,
x0
,
x1
mov
x0
,
sp
bl
inv_dcache_range
/
*
---------------------------------------------
*
Enable
the
data
cache
.
*
---------------------------------------------
*/
mrs
x0
,
sctlr_el3
orr
x0
,
x0
,
#
SCTLR_C_BIT
msr
sctlr_el3
,
x0
isb
ldp
x29
,
x30
,
[
sp
],
#
16
ret
services/std_svc/psci/psci_main.c
View file @
d9b1128b
...
...
@@ -230,10 +230,10 @@ uint64_t psci_smc_handler(uint32_t smc_fid,
SMC_RET1
(
handle
,
psci_version
());
case
PSCI_CPU_OFF
:
SMC_RET1
(
handle
,
__
psci_cpu_off
());
SMC_RET1
(
handle
,
psci_cpu_off
());
case
PSCI_CPU_SUSPEND_AARCH32
:
SMC_RET1
(
handle
,
__
psci_cpu_suspend
(
x1
,
x2
,
x3
));
SMC_RET1
(
handle
,
psci_cpu_suspend
(
x1
,
x2
,
x3
));
case
PSCI_CPU_ON_AARCH32
:
SMC_RET1
(
handle
,
psci_cpu_on
(
x1
,
x2
,
x3
));
...
...
@@ -258,7 +258,7 @@ uint64_t psci_smc_handler(uint32_t smc_fid,
switch
(
smc_fid
)
{
case
PSCI_CPU_SUSPEND_AARCH64
:
SMC_RET1
(
handle
,
__
psci_cpu_suspend
(
x1
,
x2
,
x3
));
SMC_RET1
(
handle
,
psci_cpu_suspend
(
x1
,
x2
,
x3
));
case
PSCI_CPU_ON_AARCH64
:
SMC_RET1
(
handle
,
psci_cpu_on
(
x1
,
x2
,
x3
));
...
...
services/std_svc/psci/psci_private.h
View file @
d9b1128b
...
...
@@ -128,5 +128,8 @@ int psci_afflvl_suspend(unsigned long,
int
);
unsigned
int
psci_afflvl_suspend_finish
(
int
,
int
);
/* Private exported functions from psci_helpers.S */
void
psci_do_pwrdown_cache_maintenance
(
uint32_t
affinity_level
);
void
psci_do_pwrup_cache_maintenance
(
void
);
#endif
/* __PSCI_PRIVATE_H__ */
Prev
1
2
Next
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