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
ef27980d
Commit
ef27980d
authored
May 16, 2014
by
Andrew Thoelke
Browse files
Merge pull request #69 from sandrine-bailleux:sb/split-mmu-fcts-per-el
parents
19ea62d3
b793e431
Changes
10
Show whitespace changes
Inline
Side-by-side
bl32/tsp/aarch64/tsp_entrypoint.S
View file @
ef27980d
...
...
@@ -203,7 +203,7 @@ func tsp_cpu_on_entry
*
Initialise
the
MMU
*
---------------------------------------------
*/
bl
enable_mmu
bl
enable_mmu
_el1
/
*
---------------------------------------------
*
Give
ourselves
a
stack
allocated
in
Normal
...
...
common/bl_common.c
View file @
ef27980d
...
...
@@ -106,9 +106,7 @@ void __dead2 raise_el(aapcs64_params_t *args)
*/
void
__dead2
change_el
(
el_change_info_t
*
info
)
{
unsigned
long
current_el
=
read_current_el
();
if
(
GET_EL
(
current_el
)
==
MODE_EL3
)
{
if
(
IS_IN_EL3
())
{
/*
* We can go anywhere from EL3. So find where.
* TODO: Lots to do if we are going non-secure.
...
...
@@ -551,7 +549,6 @@ void __dead2 run_image(unsigned long entrypoint,
void
*
second_arg
)
{
el_change_info_t
run_image_info
;
unsigned
long
current_el
=
read_current_el
();
/* Tell next EL what we want done */
run_image_info
.
args
.
arg0
=
RUN_IMAGE
;
...
...
@@ -565,7 +562,7 @@ void __dead2 run_image(unsigned long entrypoint,
* to jump to a higher EL and issue an SMC. Contents of argY
* will go into the general purpose register xY e.g. arg0->x0
*/
if
(
GET_EL
(
current_el
)
==
MODE_EL3
)
{
if
(
IS_IN_EL3
()
)
{
run_image_info
.
args
.
arg1
=
(
unsigned
long
)
first_arg
;
run_image_info
.
args
.
arg2
=
(
unsigned
long
)
second_arg
;
}
else
{
...
...
include/lib/aarch64/arch_helpers.h
View file @
ef27980d
...
...
@@ -264,5 +264,10 @@ extern void write_cpuectlr(unsigned long);
extern
void
write_cptr_el2
(
unsigned
long
);
extern
void
write_cptr_el3
(
unsigned
long
);
#define IS_IN_EL(x) \
(GET_EL(read_current_el()) == MODE_EL##x)
#define IS_IN_EL1() IS_IN_EL(1)
#define IS_IN_EL3() IS_IN_EL(3)
#endif
/* __ARCH_HELPERS_H__ */
plat/fvp/aarch64/plat_common.c
View file @
ef27980d
...
...
@@ -47,81 +47,68 @@
static
unsigned
long
platform_config
[
CONFIG_LIMIT
];
/*******************************************************************************
* Enable the MMU assuming that the pagetables have already been created
*******************************************************************************/
void
enable_mmu
()
{
unsigned
long
mair
,
tcr
,
ttbr
,
sctlr
;
unsigned
long
current_el
=
read_current_el
();
/* Set the attributes in the right indices of the MAIR */
mair
=
MAIR_ATTR_SET
(
ATTR_DEVICE
,
ATTR_DEVICE_INDEX
);
mair
|=
MAIR_ATTR_SET
(
ATTR_IWBWA_OWBWA_NTR
,
ATTR_IWBWA_OWBWA_NTR_INDEX
);
/*
* Set TCR bits as well. Inner & outer WBWA & shareable + T0SZ = 32
*/
tcr
=
TCR_SH_INNER_SHAREABLE
|
TCR_RGN_OUTER_WBA
|
TCR_RGN_INNER_WBA
|
TCR_T0SZ_4GB
;
/* Set TTBR bits as well */
ttbr
=
(
unsigned
long
)
l1_xlation_table
;
if
(
GET_EL
(
current_el
)
==
MODE_EL3
)
{
assert
((
read_sctlr_el3
()
&
SCTLR_M_BIT
)
==
0
);
write_mair_el3
(
mair
);
tcr
|=
TCR_EL3_RES1
;
/* Invalidate EL3 TLBs */
tlbialle3
();
write_tcr_el3
(
tcr
);
write_ttbr0_el3
(
ttbr
);
/* ensure all translation table writes have drained into memory,
* the TLB invalidation is complete, and translation register
* writes are committed before enabling the MMU
*/
dsb
();
isb
();
sctlr
=
read_sctlr_el3
();
sctlr
|=
SCTLR_WXN_BIT
|
SCTLR_M_BIT
|
SCTLR_I_BIT
;
sctlr
|=
SCTLR_A_BIT
|
SCTLR_C_BIT
;
write_sctlr_el3
(
sctlr
);
}
else
{
assert
((
read_sctlr_el1
()
&
SCTLR_M_BIT
)
==
0
);
write_mair_el1
(
mair
);
/* Invalidate EL1 TLBs */
tlbivmalle1
();
write_tcr_el1
(
tcr
);
write_ttbr0_el1
(
ttbr
);
/* ensure all translation table writes have drained into memory,
* the TLB invalidation is complete, and translation register
* writes are committed before enabling the MMU
*/
dsb
();
isb
();
sctlr
=
read_sctlr_el1
();
sctlr
|=
SCTLR_WXN_BIT
|
SCTLR_M_BIT
|
SCTLR_I_BIT
;
sctlr
|=
SCTLR_A_BIT
|
SCTLR_C_BIT
;
write_sctlr_el1
(
sctlr
);
* Macro generating the code for the function enabling the MMU in the given
* exception level, assuming that the pagetables have already been created.
*
* _el: Exception level at which the function will run
* _tcr_extra: Extra bits to set in the TCR register. This mask will
* be OR'ed with the default TCR value.
* _tlbi_fct: Function to invalidate the TLBs at the current
* exception level
******************************************************************************/
#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \
void enable_mmu_el##_el(void) \
{ \
uint64_t mair, tcr, ttbr; \
uint32_t sctlr; \
\
assert(IS_IN_EL(_el)); \
assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0); \
\
/* Set attributes in the right indices of the MAIR */
\
mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \
ATTR_IWBWA_OWBWA_NTR_INDEX); \
write_mair_el##_el(mair); \
\
/* Invalidate TLBs at the current exception level */
\
_tlbi_fct(); \
\
/* Set TCR bits as well. */
\
/* Inner & outer WBWA & shareable + T0SZ = 32 */
\
tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | \
TCR_RGN_INNER_WBA | TCR_T0SZ_4GB; \
tcr |= _tcr_extra; \
write_tcr_el##_el(tcr); \
\
/* Set TTBR bits as well */
\
ttbr = (uint64_t) l1_xlation_table; \
write_ttbr0_el##_el(ttbr); \
\
/* Ensure all translation table writes have drained */
\
/* into memory, the TLB invalidation is complete, */
\
/* and translation register writes are committed */
\
/* before enabling the MMU */
\
dsb(); \
isb(); \
\
sctlr = read_sctlr_el##_el(); \
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; \
sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; \
write_sctlr_el##_el(sctlr); \
\
/* Ensure the MMU enable takes effect immediately */
\
isb(); \
}
/* ensure the MMU enable takes effect immediately */
isb
();
return
;
}
/* Define EL1 and EL3 variants of the function enabling the MMU */
DEFINE_ENABLE_MMU_EL
(
1
,
0
,
tlbivmalle1
)
DEFINE_ENABLE_MMU_EL
(
3
,
TCR_EL3_RES1
,
tlbialle3
)
/*
* Table of regions to map using the MMU.
* This doesn't include TZRAM as the 'mem_layout' argument passed to
to
* configure_mmu() will give the available subset of that,
* This doesn't include TZRAM as the 'mem_layout' argument passed to
* configure_mmu
_elx
() will give the available subset of that,
*/
const
mmap_region_t
fvp_mmap
[]
=
{
{
TZROM_BASE
,
TZROM_SIZE
,
MT_MEMORY
|
MT_RO
|
MT_SECURE
},
...
...
@@ -139,28 +126,32 @@ const mmap_region_t fvp_mmap[] = {
};
/*******************************************************************************
* Setup the pagetables as per the platform memory map & initialize the mmu
*******************************************************************************/
void
configure_mmu
(
meminfo_t
*
mem_layout
,
unsigned
long
ro_start
,
unsigned
long
ro_limit
,
unsigned
long
coh_start
,
unsigned
long
coh_limit
)
{
mmap_add_region
(
mem_layout
->
total_base
,
mem_layout
->
total_size
,
MT_MEMORY
|
MT_RW
|
MT_SECURE
);
mmap_add_region
(
ro_start
,
ro_limit
-
ro_start
,
MT_MEMORY
|
MT_RO
|
MT_SECURE
);
mmap_add_region
(
coh_start
,
coh_limit
-
coh_start
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
);
mmap_add
(
fvp_mmap
);
init_xlat_tables
();
* Macro generating the code for the function setting up the pagetables as per
* the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void configure_mmu_el##_el(meminfo_t *mem_layout, \
unsigned long ro_start, \
unsigned long ro_limit, \
unsigned long coh_start, \
unsigned long coh_limit) \
{ \
mmap_add_region(mem_layout->total_base, \
mem_layout->total_size, \
MT_MEMORY | MT_RW | MT_SECURE); \
mmap_add_region(ro_start, ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
mmap_add_region(coh_start, coh_limit - coh_start, \
MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(fvp_mmap); \
init_xlat_tables(); \
\
enable_mmu_el##_el(); \
}
enable_mmu
();
return
;
}
/* Define EL1 and EL3 variants of the function initialising the MMU */
DEFINE_CONFIGURE_MMU_EL
(
1
)
DEFINE_CONFIGURE_MMU_EL
(
3
)
/* Simple routine which returns a configuration variable value */
unsigned
long
platform_get_cfgvar
(
unsigned
int
var_id
)
...
...
plat/fvp/bl1_plat_setup.c
View file @
ef27980d
...
...
@@ -138,7 +138,7 @@ void bl1_plat_arch_setup(void)
cci_enable_coherency
(
read_mpidr
());
}
configure_mmu
(
&
bl1_tzram_layout
,
configure_mmu
_el3
(
&
bl1_tzram_layout
,
TZROM_BASE
,
TZROM_BASE
+
TZROM_SIZE
,
BL1_COHERENT_RAM_BASE
,
...
...
plat/fvp/bl2_plat_setup.c
View file @
ef27980d
...
...
@@ -172,7 +172,7 @@ void bl2_platform_setup()
******************************************************************************/
void
bl2_plat_arch_setup
()
{
configure_mmu
(
&
bl2_tzram_layout
,
configure_mmu
_el1
(
&
bl2_tzram_layout
,
BL2_RO_BASE
,
BL2_RO_LIMIT
,
BL2_COHERENT_RAM_BASE
,
...
...
plat/fvp/bl31_plat_setup.c
View file @
ef27980d
...
...
@@ -172,7 +172,7 @@ void bl31_platform_setup()
******************************************************************************/
void
bl31_plat_arch_setup
()
{
configure_mmu
(
&
bl2_to_bl31_args
->
bl31_meminfo
,
configure_mmu
_el3
(
&
bl2_to_bl31_args
->
bl31_meminfo
,
BL31_RO_BASE
,
BL31_RO_LIMIT
,
BL31_COHERENT_RAM_BASE
,
...
...
plat/fvp/bl32_plat_setup.c
View file @
ef27980d
...
...
@@ -111,7 +111,7 @@ void bl32_platform_setup()
******************************************************************************/
void
bl32_plat_arch_setup
()
{
configure_mmu
(
&
bl32_tzdram_layout
,
configure_mmu
_el1
(
&
bl32_tzdram_layout
,
BL32_RO_BASE
,
BL32_RO_LIMIT
,
BL32_COHERENT_RAM_BASE
,
...
...
plat/fvp/platform.h
View file @
ef27980d
...
...
@@ -373,12 +373,18 @@ extern void bl2_plat_arch_setup(void);
extern
void
bl31_plat_arch_setup
(
void
);
extern
int
platform_setup_pm
(
const
struct
plat_pm_ops
**
);
extern
unsigned
int
platform_get_core_pos
(
unsigned
long
mpidr
);
extern
void
enable_mmu
(
void
);
extern
void
configure_mmu
(
struct
meminfo
*
,
unsigned
long
,
unsigned
long
,
unsigned
long
,
unsigned
long
);
extern
void
enable_mmu_el1
(
void
);
extern
void
enable_mmu_el3
(
void
);
extern
void
configure_mmu_el1
(
struct
meminfo
*
mem_layout
,
unsigned
long
ro_start
,
unsigned
long
ro_limit
,
unsigned
long
coh_start
,
unsigned
long
coh_limit
);
extern
void
configure_mmu_el3
(
struct
meminfo
*
mem_layout
,
unsigned
long
ro_start
,
unsigned
long
ro_limit
,
unsigned
long
coh_start
,
unsigned
long
coh_limit
);
extern
unsigned
long
platform_get_cfgvar
(
unsigned
int
);
extern
int
platform_config_setup
(
void
);
extern
void
plat_report_exception
(
unsigned
long
);
...
...
services/std_svc/psci/psci_afflvl_on.c
View file @
ef27980d
...
...
@@ -362,7 +362,7 @@ static unsigned int psci_afflvl0_on_finish(unsigned long mpidr,
/*
* Arch. management: Turn on mmu & restore architectural state
*/
enable_mmu
();
enable_mmu
_el3
();
/*
* All the platform specific actions for turning this cpu
...
...
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