Commit ab8707e6 authored by Soby Mathew's avatar Soby Mathew Committed by Dan Handley
Browse files

Remove coherent memory from the BL memory maps

This patch extends the build option `USE_COHERENT_MEMORY` to
conditionally remove coherent memory from the memory maps of
all boot loader stages. The patch also adds necessary
documentation for coherent memory removal in firmware-design,
porting and user guides.

Fixes ARM-Software/tf-issues#106

Change-Id: I260e8768c6a5c2efc402f5804a80657d8ce38773
parent 8c5fe0b5
...@@ -47,8 +47,10 @@ ...@@ -47,8 +47,10 @@
extern unsigned long __RO_START__; extern unsigned long __RO_START__;
extern unsigned long __RO_END__; extern unsigned long __RO_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__; extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__; extern unsigned long __COHERENT_RAM_END__;
#endif
/* /*
* The next 2 constants identify the extents of the code & RO data region. * The next 2 constants identify the extents of the code & RO data region.
...@@ -59,6 +61,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -59,6 +61,7 @@ extern unsigned long __COHERENT_RAM_END__;
#define BL2_RO_BASE (unsigned long)(&__RO_START__) #define BL2_RO_BASE (unsigned long)(&__RO_START__)
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__) #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
#if USE_COHERENT_MEM
/* /*
* The next 2 constants identify the extents of the coherent memory region. * The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be * These addresses are used by the MMU setup code and therefore they must be
...@@ -68,11 +71,11 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -68,11 +71,11 @@ extern unsigned long __COHERENT_RAM_END__;
*/ */
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted RAM for BL2 */ /* Data structure which holds the extents of the trusted RAM for BL2 */
static meminfo_t bl2_tzram_layout static meminfo_t bl2_tzram_layout
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE)));
section("tzfw_coherent_mem")));
/******************************************************************************* /*******************************************************************************
* Structure which holds the arguments which need to be passed to BL3-1 * Structure which holds the arguments which need to be passed to BL3-1
...@@ -194,9 +197,12 @@ void bl2_plat_arch_setup(void) ...@@ -194,9 +197,12 @@ void bl2_plat_arch_setup(void)
configure_mmu_el1(bl2_tzram_layout.total_base, configure_mmu_el1(bl2_tzram_layout.total_base,
bl2_tzram_layout.total_size, bl2_tzram_layout.total_size,
BL2_RO_BASE, BL2_RO_BASE,
BL2_RO_LIMIT, BL2_RO_LIMIT
BL2_COHERENT_RAM_BASE, #if USE_COHERENT_MEM
BL2_COHERENT_RAM_LIMIT); , BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT
#endif
);
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -48,19 +48,25 @@ ...@@ -48,19 +48,25 @@
******************************************************************************/ ******************************************************************************/
extern unsigned long __RO_START__; extern unsigned long __RO_START__;
extern unsigned long __RO_END__; extern unsigned long __RO_END__;
extern unsigned long __BL31_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__; extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__; extern unsigned long __COHERENT_RAM_END__;
#endif
/* /*
* The next 2 constants identify the extents of the code & RO data region. * The next 3 constants identify the extents of the code, RO data region and the
* These addresses are used by the MMU setup code and therefore they must be * limit of the BL3-1 image. These addresses are used by the MMU setup code and
* page-aligned. It is the responsibility of the linker script to ensure that * therefore they must be page-aligned. It is the responsibility of the linker
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
* refer to page-aligned addresses.
*/ */
#define BL31_RO_BASE (unsigned long)(&__RO_START__) #define BL31_RO_BASE (unsigned long)(&__RO_START__)
#define BL31_RO_LIMIT (unsigned long)(&__RO_END__) #define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
#define BL31_END (unsigned long)(&__BL31_END__)
#if USE_COHERENT_MEM
/* /*
* The next 2 constants identify the extents of the coherent memory region. * The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be * These addresses are used by the MMU setup code and therefore they must be
...@@ -70,6 +76,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -70,6 +76,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/ */
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/****************************************************************************** /******************************************************************************
* Placeholder variables for copying the arguments that have been passed to * Placeholder variables for copying the arguments that have been passed to
...@@ -178,9 +185,13 @@ void bl31_platform_setup(void) ...@@ -178,9 +185,13 @@ void bl31_platform_setup(void)
void bl31_plat_arch_setup() void bl31_plat_arch_setup()
{ {
configure_mmu_el3(BL31_RO_BASE, configure_mmu_el3(BL31_RO_BASE,
BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE, (BL31_END - BL31_RO_BASE),
BL31_RO_BASE, BL31_RO_BASE,
BL31_RO_LIMIT, BL31_RO_LIMIT
#if USE_COHERENT_MEM
,
BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT); BL31_COHERENT_RAM_LIMIT
#endif
);
} }
...@@ -134,15 +134,21 @@ unsigned int platform_get_core_pos(unsigned long mpidr); ...@@ -134,15 +134,21 @@ unsigned int platform_get_core_pos(unsigned long mpidr);
void configure_mmu_el1(unsigned long total_base, void configure_mmu_el1(unsigned long total_base,
unsigned long total_size, unsigned long total_size,
unsigned long ro_start, unsigned long ro_start,
unsigned long ro_limit, unsigned long ro_limit
unsigned long coh_start, #if USE_COHERENT_MEM
unsigned long coh_limit); , unsigned long coh_start,
unsigned long coh_limit
#endif
);
void configure_mmu_el3(unsigned long total_base, void configure_mmu_el3(unsigned long total_base,
unsigned long total_size, unsigned long total_size,
unsigned long ro_start, unsigned long ro_start,
unsigned long ro_limit, unsigned long ro_limit
unsigned long coh_start, #if USE_COHERENT_MEM
unsigned long coh_limit); , unsigned long coh_start,
unsigned long coh_limit
#endif
);
void plat_report_exception(unsigned long type); void plat_report_exception(unsigned long type);
unsigned long plat_get_ns_image_entrypoint(void); unsigned long plat_get_ns_image_entrypoint(void);
unsigned long platform_get_stack(unsigned long mpidr); unsigned long platform_get_stack(unsigned long mpidr);
......
...@@ -40,19 +40,25 @@ ...@@ -40,19 +40,25 @@
******************************************************************************/ ******************************************************************************/
extern unsigned long __RO_START__; extern unsigned long __RO_START__;
extern unsigned long __RO_END__; extern unsigned long __RO_END__;
extern unsigned long __BL32_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__; extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__; extern unsigned long __COHERENT_RAM_END__;
#endif
/* /*
* The next 2 constants identify the extents of the code & RO data region. * The next 3 constants identify the extents of the code, RO data region and the
* These addresses are used by the MMU setup code and therefore they must be * limit of the BL3-2 image. These addresses are used by the MMU setup code and
* page-aligned. It is the responsibility of the linker script to ensure that * therefore they must be page-aligned. It is the responsibility of the linker
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. * script to ensure that __RO_START__, __RO_END__ & __BL32_END__ linker symbols
* refer to page-aligned addresses.
*/ */
#define BL32_RO_BASE (unsigned long)(&__RO_START__) #define BL32_RO_BASE (unsigned long)(&__RO_START__)
#define BL32_RO_LIMIT (unsigned long)(&__RO_END__) #define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
#define BL32_END (unsigned long)(&__BL32_END__)
#if USE_COHERENT_MEM
/* /*
* The next 2 constants identify the extents of the coherent memory region. * The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be * These addresses are used by the MMU setup code and therefore they must be
...@@ -62,6 +68,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -62,6 +68,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/ */
#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/******************************************************************************* /*******************************************************************************
* Initialize the UART * Initialize the UART
...@@ -90,9 +97,12 @@ void tsp_platform_setup(void) ...@@ -90,9 +97,12 @@ void tsp_platform_setup(void)
void tsp_plat_arch_setup(void) void tsp_plat_arch_setup(void)
{ {
configure_mmu_el1(BL32_RO_BASE, configure_mmu_el1(BL32_RO_BASE,
BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE, (BL32_END - BL32_RO_BASE),
BL32_RO_BASE, BL32_RO_BASE,
BL32_RO_LIMIT, BL32_RO_LIMIT
BL32_COHERENT_RAM_BASE, #if USE_COHERENT_MEM
BL32_COHERENT_RAM_LIMIT); , BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT
#endif
);
} }
...@@ -51,7 +51,10 @@ const spd_pm_ops_t *psci_spd_pm; ...@@ -51,7 +51,10 @@ const spd_pm_ops_t *psci_spd_pm;
* corresponds to an affinity instance e.g. cluster, cpu within an mpidr * corresponds to an affinity instance e.g. cluster, cpu within an mpidr
******************************************************************************/ ******************************************************************************/
aff_map_node_t psci_aff_map[PSCI_NUM_AFFS] aff_map_node_t psci_aff_map[PSCI_NUM_AFFS]
__attribute__ ((section("tzfw_coherent_mem"))); #if USE_COHERENT_MEM
__attribute__ ((section("tzfw_coherent_mem")))
#endif
;
/******************************************************************************* /*******************************************************************************
* Pointer to functions exported by the platform to complete power mgmt. ops * Pointer to functions exported by the platform to complete power mgmt. ops
...@@ -352,6 +355,10 @@ int psci_save_ns_entry(uint64_t mpidr, ...@@ -352,6 +355,10 @@ int psci_save_ns_entry(uint64_t mpidr,
******************************************************************************/ ******************************************************************************/
unsigned short psci_get_state(aff_map_node_t *node) unsigned short psci_get_state(aff_map_node_t *node)
{ {
#if !USE_COHERENT_MEM
flush_dcache_range((uint64_t) node, sizeof(*node));
#endif
assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL); assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL);
/* A cpu node just contains the state which can be directly returned */ /* A cpu node just contains the state which can be directly returned */
...@@ -409,6 +416,10 @@ void psci_set_state(aff_map_node_t *node, unsigned short state) ...@@ -409,6 +416,10 @@ void psci_set_state(aff_map_node_t *node, unsigned short state)
node->state &= ~(PSCI_STATE_MASK << PSCI_STATE_SHIFT); node->state &= ~(PSCI_STATE_MASK << PSCI_STATE_SHIFT);
node->state |= (state & PSCI_STATE_MASK) << PSCI_STATE_SHIFT; node->state |= (state & PSCI_STATE_MASK) << PSCI_STATE_SHIFT;
} }
#if !USE_COHERENT_MEM
flush_dcache_range((uint64_t) node, sizeof(*node));
#endif
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -331,13 +331,20 @@ int32_t psci_setup(void) ...@@ -331,13 +331,20 @@ int32_t psci_setup(void)
afflvl); afflvl);
} }
#if !USE_COHERENT_MEM
/*
* The psci_aff_map only needs flushing when it's not allocated in
* coherent memory.
*/
flush_dcache_range((uint64_t) &psci_aff_map, sizeof(psci_aff_map));
#endif
/* /*
* Set the bounds for the affinity counts of each level in the map. Also * Set the bounds for the affinity counts of each level in the map. Also
* flush out the entire array so that it's visible to subsequent power * flush out the entire array so that it's visible to subsequent power
* management operations. The 'psci_aff_map' array is allocated in * management operations. The 'psci_aff_limits' array is allocated in
* coherent memory so does not need flushing. The 'psci_aff_limits' * normal memory. It will be accessed when the mmu is off e.g. after
* array is allocated in normal memory. It will be accessed when the mmu * reset. Hence it needs to be flushed.
* is off e.g. after reset. Hence it needs to be flushed.
*/ */
for (afflvl = MPIDR_AFFLVL0; afflvl < max_afflvl; afflvl++) { for (afflvl = MPIDR_AFFLVL0; afflvl < max_afflvl; afflvl++) {
psci_aff_limits[afflvl].min = psci_aff_limits[afflvl].min =
......
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