Commit eadd7a1b authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #240 from danh-arm/sm/rem_coh_mem

Remove coherent memory v2
parents 1c73ffbd ab8707e6
...@@ -136,6 +136,7 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) / ...@@ -136,6 +136,7 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
* Macro generating the code for the function setting up the pagetables as per * 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 * the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/ ******************************************************************************/
#if USE_COHERENT_MEM
#define DEFINE_CONFIGURE_MMU_EL(_el) \ #define DEFINE_CONFIGURE_MMU_EL(_el) \
void fvp_configure_mmu_el##_el(unsigned long total_base, \ void fvp_configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \ unsigned long total_size, \
...@@ -158,6 +159,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) / ...@@ -158,6 +159,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
\ \
enable_mmu_el##_el(0); \ enable_mmu_el##_el(0); \
} }
#else
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void fvp_configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
unsigned long ro_limit) \
{ \
mmap_add_region(total_base, total_base, \
total_size, \
MT_MEMORY | MT_RW | MT_SECURE); \
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
mmap_add(fvp_mmap); \
init_xlat_tables(); \
\
enable_mmu_el##_el(0); \
}
#endif
/* Define EL1 and EL3 variants of the function initialising the MMU */ /* Define EL1 and EL3 variants of the function initialising the MMU */
DEFINE_CONFIGURE_MMU_EL(1) DEFINE_CONFIGURE_MMU_EL(1)
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "fvp_def.h" #include "fvp_def.h"
#include "fvp_private.h" #include "fvp_private.h"
#if USE_COHERENT_MEM
/******************************************************************************* /*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout * Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM * of trusted SRAM
...@@ -56,6 +57,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -56,6 +57,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/ */
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted SRAM for BL1*/ /* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo_t bl1_tzram_layout; static meminfo_t bl1_tzram_layout;
...@@ -116,9 +118,12 @@ void bl1_plat_arch_setup(void) ...@@ -116,9 +118,12 @@ void bl1_plat_arch_setup(void)
fvp_configure_mmu_el3(bl1_tzram_layout.total_base, fvp_configure_mmu_el3(bl1_tzram_layout.total_base,
bl1_tzram_layout.total_size, bl1_tzram_layout.total_size,
BL1_RO_BASE, BL1_RO_BASE,
BL1_RO_LIMIT, BL1_RO_LIMIT
BL1_COHERENT_RAM_BASE, #if USE_COHERENT_MEM
BL1_COHERENT_RAM_LIMIT); , BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT
#endif
);
} }
......
...@@ -45,8 +45,10 @@ ...@@ -45,8 +45,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.
...@@ -57,6 +59,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -57,6 +59,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
...@@ -66,11 +69,11 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -66,11 +69,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 SRAM for BL2 */ /* Data structure which holds the extents of the trusted SRAM 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")));
/* Assert that BL3-1 parameters fit in shared memory */ /* Assert that BL3-1 parameters fit in shared memory */
CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) < CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) <
...@@ -209,9 +212,12 @@ void bl2_plat_arch_setup(void) ...@@ -209,9 +212,12 @@ void bl2_plat_arch_setup(void)
fvp_configure_mmu_el1(bl2_tzram_layout.total_base, fvp_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,7 +76,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -70,7 +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
#if RESET_TO_BL31 #if RESET_TO_BL31
static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl32_image_ep_info;
...@@ -235,9 +241,12 @@ void bl31_plat_arch_setup(void) ...@@ -235,9 +241,12 @@ void bl31_plat_arch_setup(void)
fvp_cci_enable(); fvp_cci_enable();
#endif #endif
fvp_configure_mmu_el3(BL31_RO_BASE, fvp_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
BL31_COHERENT_RAM_BASE, #if USE_COHERENT_MEM
BL31_COHERENT_RAM_LIMIT); , BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT
#endif
);
} }
...@@ -31,13 +31,19 @@ ...@@ -31,13 +31,19 @@
#include <bakery_lock.h> #include <bakery_lock.h>
#include <mmio.h> #include <mmio.h>
#include "../../fvp_def.h" #include "../../fvp_def.h"
#include "../../fvp_private.h"
#include "fvp_pwrc.h" #include "fvp_pwrc.h"
/* /*
* TODO: Someday there will be a generic power controller api. At the moment * TODO: Someday there will be a generic power controller api. At the moment
* each platform has its own pwrc so just exporting functions is fine. * each platform has its own pwrc so just exporting functions is fine.
*/ */
#if USE_COHERENT_MEM
static bakery_lock_t pwrc_lock __attribute__ ((section("tzfw_coherent_mem"))); static bakery_lock_t pwrc_lock __attribute__ ((section("tzfw_coherent_mem")));
#define LOCK_ARG &pwrc_lock
#else
#define LOCK_ARG FVP_PWRC_BAKERY_ID
#endif
unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr) unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr)
{ {
...@@ -47,54 +53,55 @@ unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr) ...@@ -47,54 +53,55 @@ unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr)
unsigned int fvp_pwrc_read_psysr(unsigned long mpidr) unsigned int fvp_pwrc_read_psysr(unsigned long mpidr)
{ {
unsigned int rc; unsigned int rc;
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
rc = mmio_read_32(PWRC_BASE + PSYSR_OFF); rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
return rc; return rc;
} }
void fvp_pwrc_write_pponr(unsigned long mpidr) void fvp_pwrc_write_pponr(unsigned long mpidr)
{ {
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr); mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr);
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
} }
void fvp_pwrc_write_ppoffr(unsigned long mpidr) void fvp_pwrc_write_ppoffr(unsigned long mpidr)
{ {
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr); mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr);
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
} }
void fvp_pwrc_set_wen(unsigned long mpidr) void fvp_pwrc_set_wen(unsigned long mpidr)
{ {
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PWKUPR_OFF, mmio_write_32(PWRC_BASE + PWKUPR_OFF,
(unsigned int) (PWKUPR_WEN | mpidr)); (unsigned int) (PWKUPR_WEN | mpidr));
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
} }
void fvp_pwrc_clr_wen(unsigned long mpidr) void fvp_pwrc_clr_wen(unsigned long mpidr)
{ {
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PWKUPR_OFF, mmio_write_32(PWRC_BASE + PWKUPR_OFF,
(unsigned int) mpidr); (unsigned int) mpidr);
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
} }
void fvp_pwrc_write_pcoffr(unsigned long mpidr) void fvp_pwrc_write_pcoffr(unsigned long mpidr)
{ {
bakery_lock_get(&pwrc_lock); fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr); mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr);
bakery_lock_release(&pwrc_lock); fvp_lock_release(LOCK_ARG);
} }
/* Nothing else to do here apart from initializing the lock */ /* Nothing else to do here apart from initializing the lock */
int fvp_pwrc_setup(void) int fvp_pwrc_setup(void)
{ {
bakery_lock_init(&pwrc_lock); fvp_lock_init(LOCK_ARG);
return 0; return 0;
} }
......
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
#ifndef __FVP_PRIVATE_H__ #ifndef __FVP_PRIVATE_H__
#define __FVP_PRIVATE_H__ #define __FVP_PRIVATE_H__
#include <bakery_lock.h>
#include <bl_common.h> #include <bl_common.h>
#include <cpu_data.h>
#include <platform_def.h> #include <platform_def.h>
...@@ -55,10 +57,60 @@ typedef struct bl2_to_bl31_params_mem { ...@@ -55,10 +57,60 @@ typedef struct bl2_to_bl31_params_mem {
entry_point_info_t bl31_ep_info; entry_point_info_t bl31_ep_info;
} bl2_to_bl31_params_mem_t; } bl2_to_bl31_params_mem_t;
#if USE_COHERENT_MEM
/*
* These are wrapper macros to the Coherent Memory Bakery Lock API.
*/
#define fvp_lock_init(_lock_arg) bakery_lock_init(_lock_arg)
#define fvp_lock_get(_lock_arg) bakery_lock_get(_lock_arg)
#define fvp_lock_release(_lock_arg) bakery_lock_release(_lock_arg)
#else
/******************************************************************************* /*******************************************************************************
* Forward declarations * Constants to specify how many bakery locks this platform implements. These
* are used if the platform chooses not to use coherent memory for bakery lock
* data structures.
******************************************************************************/ ******************************************************************************/
struct meminfo; #define FVP_MAX_BAKERIES 1
#define FVP_PWRC_BAKERY_ID 0
/*******************************************************************************
* Definition of structure which holds platform specific per-cpu data. Currently
* it holds only the bakery lock information for each cpu. Constants to
* specify how many bakeries this platform implements and bakery ids are
* specified in fvp_def.h
******************************************************************************/
typedef struct fvp_cpu_data {
bakery_info_t pcpu_bakery_info[FVP_MAX_BAKERIES];
} fvp_cpu_data_t;
/* Macro to define the offset of bakery_info_t in fvp_cpu_data_t */
#define FVP_CPU_DATA_LOCK_OFFSET __builtin_offsetof\
(fvp_cpu_data_t, pcpu_bakery_info)
/*******************************************************************************
* Helper macros for bakery lock api when using the above fvp_cpu_data_t for
* bakery lock data structures. It assumes that the bakery_info is at the
* beginning of the platform specific per-cpu data.
******************************************************************************/
#define fvp_lock_init(_lock_arg) /* No init required */
#define fvp_lock_get(_lock_arg) bakery_lock_get(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + \
FVP_CPU_DATA_LOCK_OFFSET)
#define fvp_lock_release(_lock_arg) bakery_lock_release(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + \
FVP_CPU_DATA_LOCK_OFFSET)
/*
* Ensure that the size of the FVP specific per-cpu data structure and the size
* of the memory allocated in generic per-cpu data for the platform are the same.
*/
CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(fvp_cpu_data_t), \
fvp_pcpu_data_size_mismatch);
#endif /* __USE_COHERENT_MEM__ */
/******************************************************************************* /*******************************************************************************
* Function and variable prototypes * Function and variable prototypes
...@@ -66,15 +118,22 @@ struct meminfo; ...@@ -66,15 +118,22 @@ struct meminfo;
void fvp_configure_mmu_el1(unsigned long total_base, void fvp_configure_mmu_el1(unsigned long total_base,
unsigned long total_size, unsigned long total_size,
unsigned long, unsigned long,
unsigned long, unsigned long
unsigned long, #if USE_COHERENT_MEM
unsigned long); , unsigned long,
unsigned long
#endif
);
void fvp_configure_mmu_el3(unsigned long total_base, void fvp_configure_mmu_el3(unsigned long total_base,
unsigned long total_size, unsigned long total_size,
unsigned long, unsigned long,
unsigned long, unsigned long
unsigned long, #if USE_COHERENT_MEM
unsigned long); , unsigned long,
unsigned long
#endif
);
int fvp_config_setup(void); int fvp_config_setup(void);
void fvp_cci_init(void); void fvp_cci_init(void);
......
...@@ -169,5 +169,12 @@ ...@@ -169,5 +169,12 @@
#define CACHE_WRITEBACK_SHIFT 6 #define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) #define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
#if !USE_COHERENT_MEM
/*******************************************************************************
* Size of the per-cpu data in bytes that should be reserved in the generic
* per-cpu data structure for the FVP port.
******************************************************************************/
#define PLAT_PCPU_DATA_SIZE 2
#endif
#endif /* __PLATFORM_DEF_H__ */ #endif /* __PLATFORM_DEF_H__ */
...@@ -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
* These addresses are used by the MMU setup code and therefore they must be * the limit of the BL3-2 image. These addresses are used by the MMU setup code
* page-aligned. It is the responsibility of the linker script to ensure that * and therefore they must be page-aligned. It is the responsibility of the
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. * linker 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
...@@ -93,9 +100,12 @@ void tsp_platform_setup(void) ...@@ -93,9 +100,12 @@ void tsp_platform_setup(void)
void tsp_plat_arch_setup(void) void tsp_plat_arch_setup(void)
{ {
fvp_configure_mmu_el1(BL32_RO_BASE, fvp_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
);
} }
...@@ -140,6 +140,7 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) / ...@@ -140,6 +140,7 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
* Macro generating the code for the function setting up the pagetables as per * 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 * the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/ ******************************************************************************/
#if USE_COHERENT_MEM
#define DEFINE_CONFIGURE_MMU_EL(_el) \ #define DEFINE_CONFIGURE_MMU_EL(_el) \
void configure_mmu_el##_el(unsigned long total_base, \ void configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \ unsigned long total_size, \
...@@ -162,7 +163,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) / ...@@ -162,7 +163,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
\ \
enable_mmu_el##_el(0); \ enable_mmu_el##_el(0); \
} }
#else
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
unsigned long ro_limit) \
{ \
mmap_add_region(total_base, total_base, \
total_size, \
MT_MEMORY | MT_RW | MT_SECURE); \
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
mmap_add(juno_mmap); \
init_xlat_tables(); \
\
enable_mmu_el##_el(0); \
}
#endif
/* Define EL1 and EL3 variants of the function initialising the MMU */ /* Define EL1 and EL3 variants of the function initialising the MMU */
DEFINE_CONFIGURE_MMU_EL(1) DEFINE_CONFIGURE_MMU_EL(1)
DEFINE_CONFIGURE_MMU_EL(3) DEFINE_CONFIGURE_MMU_EL(3)
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "juno_def.h" #include "juno_def.h"
#include "juno_private.h" #include "juno_private.h"
#if USE_COHERENT_MEM
/******************************************************************************* /*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout * Declarations of linker defined symbols which will help us find the layout
* of trusted RAM * of trusted RAM
...@@ -57,6 +58,7 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -57,6 +58,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/ */
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted RAM for BL1 */ /* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout; static meminfo_t bl1_tzram_layout;
...@@ -189,9 +191,12 @@ void bl1_plat_arch_setup(void) ...@@ -189,9 +191,12 @@ void bl1_plat_arch_setup(void)
configure_mmu_el3(bl1_tzram_layout.total_base, configure_mmu_el3(bl1_tzram_layout.total_base,
bl1_tzram_layout.total_size, bl1_tzram_layout.total_size,
TZROM_BASE, TZROM_BASE,
TZROM_BASE + TZROM_SIZE, TZROM_BASE + TZROM_SIZE
BL1_COHERENT_RAM_BASE, #if USE_COHERENT_MEM
BL1_COHERENT_RAM_LIMIT); , BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT
#endif
);
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -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
);
} }
...@@ -174,4 +174,12 @@ ...@@ -174,4 +174,12 @@
#define CACHE_WRITEBACK_SHIFT 6 #define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) #define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
#if !USE_COHERENT_MEM
/*******************************************************************************
* Size of the per-cpu data in bytes that should be reserved in the generic
* per-cpu data structure for the Juno port.
******************************************************************************/
#define PLAT_PCPU_DATA_SIZE 2
#endif
#endif /* __PLATFORM_DEF_H__ */ #endif /* __PLATFORM_DEF_H__ */
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
#ifndef __JUNO_PRIVATE_H__ #ifndef __JUNO_PRIVATE_H__
#define __JUNO_PRIVATE_H__ #define __JUNO_PRIVATE_H__
#include <bakery_lock.h>
#include <bl_common.h> #include <bl_common.h>
#include <cpu_data.h>
#include <platform_def.h> #include <platform_def.h>
#include <stdint.h> #include <stdint.h>
...@@ -59,6 +61,68 @@ typedef struct bl2_to_bl31_params_mem { ...@@ -59,6 +61,68 @@ typedef struct bl2_to_bl31_params_mem {
struct entry_point_info bl31_ep_info; struct entry_point_info bl31_ep_info;
} bl2_to_bl31_params_mem_t; } bl2_to_bl31_params_mem_t;
#if IMAGE_BL31
#if USE_COHERENT_MEM
/*
* These are wrapper macros to the Coherent Memory Bakery Lock API.
*/
#define juno_lock_init(_lock_arg) bakery_lock_init(_lock_arg)
#define juno_lock_get(_lock_arg) bakery_lock_get(_lock_arg)
#define juno_lock_release(_lock_arg) bakery_lock_release(_lock_arg)
#else
/*******************************************************************************
* Constants that specify how many bakeries this platform implements and bakery
* ids.
******************************************************************************/
#define JUNO_MAX_BAKERIES 1
#define JUNO_MHU_BAKERY_ID 0
/*******************************************************************************
* Definition of structure which holds platform specific per-cpu data. Currently
* it holds only the bakery lock information for each cpu. Constants to specify
* how many bakeries this platform implements and bakery ids are specified in
* juno_def.h
******************************************************************************/
typedef struct juno_cpu_data {
bakery_info_t pcpu_bakery_info[JUNO_MAX_BAKERIES];
} juno_cpu_data_t;
/* Macro to define the offset of bakery_info_t in juno_cpu_data_t */
#define JUNO_CPU_DATA_LOCK_OFFSET __builtin_offsetof\
(juno_cpu_data_t, pcpu_bakery_info)
/*******************************************************************************
* Helper macros for bakery lock api when using the above juno_cpu_data_t for
* bakery lock data structures. It assumes that the bakery_info is at the
* beginning of the platform specific per-cpu data.
******************************************************************************/
#define juno_lock_init(_lock_arg) /* No init required */
#define juno_lock_get(_lock_arg) bakery_lock_get(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + \
JUNO_CPU_DATA_LOCK_OFFSET)
#define juno_lock_release(_lock_arg) bakery_lock_release(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + \
JUNO_CPU_DATA_LOCK_OFFSET)
/*
* Ensure that the size of the Juno specific per-cpu data structure and the size
* of the memory allocated in generic per-cpu data for the platform are the same.
*/
CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(juno_cpu_data_t), \
juno_pcpu_data_size_mismatch);
#endif /* __USE_COHERENT_MEM__ */
#else
/*
* Dummy wrapper macros for all other BL stages other than BL3-1
*/
#define juno_lock_init(_lock_arg)
#define juno_lock_get(_lock_arg)
#define juno_lock_release(_lock_arg)
#endif /* __IMAGE_BL31__ */
/******************************************************************************* /*******************************************************************************
* Function and variable prototypes * Function and variable prototypes
******************************************************************************/ ******************************************************************************/
...@@ -70,15 +134,21 @@ unsigned int platform_get_core_pos(unsigned long mpidr); ...@@ -70,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);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <bakery_lock.h> #include <bakery_lock.h>
#include <mmio.h> #include <mmio.h>
#include "juno_def.h" #include "juno_def.h"
#include "juno_private.h"
#include "mhu.h" #include "mhu.h"
/* SCP MHU secure channel registers */ /* SCP MHU secure channel registers */
...@@ -44,13 +45,20 @@ ...@@ -44,13 +45,20 @@
#define CPU_INTR_S_SET 0x308 #define CPU_INTR_S_SET 0x308
#define CPU_INTR_S_CLEAR 0x310 #define CPU_INTR_S_CLEAR 0x310
#if IMAGE_BL31
#if USE_COHERENT_MEM
static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem"))); static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem")));
#define LOCK_ARG &mhu_secure_lock
#else
#define LOCK_ARG JUNO_MHU_BAKERY_ID
#endif /*__USE_COHERENT_MEM__ */
#else
#define LOCK_ARG /* Locks required only for BL3-1 images */
#endif /* __IMAGE_BL31__ */
void mhu_secure_message_start(void) void mhu_secure_message_start(void)
{ {
bakery_lock_get(&mhu_secure_lock); juno_lock_get(LOCK_ARG);
/* Make sure any previous command has finished */ /* Make sure any previous command has finished */
while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0) while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
...@@ -80,12 +88,12 @@ void mhu_secure_message_end(void) ...@@ -80,12 +88,12 @@ void mhu_secure_message_end(void)
/* Clear any response we got by writing all ones to the CLEAR register */ /* Clear any response we got by writing all ones to the CLEAR register */
mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu); mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
bakery_lock_release(&mhu_secure_lock); juno_lock_release(LOCK_ARG);
} }
void mhu_secure_init(void) void mhu_secure_init(void)
{ {
bakery_lock_init(&mhu_secure_lock); juno_lock_init(LOCK_ARG);
/* /*
* Clear the CPU's INTR register to make sure we don't see a stale * Clear the CPU's INTR register to make sure we don't see a stale
......
...@@ -66,7 +66,6 @@ BL1_SOURCES += drivers/arm/cci400/cci400.c \ ...@@ -66,7 +66,6 @@ BL1_SOURCES += drivers/arm/cci400/cci400.c \
plat/juno/aarch64/juno_common.c plat/juno/aarch64/juno_common.c
BL2_SOURCES += drivers/arm/tzc400/tzc400.c \ BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
lib/locks/bakery/bakery_lock.c \
plat/common/aarch64/platform_up_stack.S \ plat/common/aarch64/platform_up_stack.S \
plat/juno/bl2_plat_setup.c \ plat/juno/bl2_plat_setup.c \
plat/juno/mhu.c \ plat/juno/mhu.c \
......
...@@ -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
...@@ -246,7 +249,8 @@ void psci_acquire_afflvl_locks(int start_afflvl, ...@@ -246,7 +249,8 @@ void psci_acquire_afflvl_locks(int start_afflvl,
for (level = start_afflvl; level <= end_afflvl; level++) { for (level = start_afflvl; level <= end_afflvl; level++) {
if (mpidr_nodes[level] == NULL) if (mpidr_nodes[level] == NULL)
continue; continue;
bakery_lock_get(&mpidr_nodes[level]->lock);
psci_lock_get(mpidr_nodes[level]);
} }
} }
...@@ -264,7 +268,8 @@ void psci_release_afflvl_locks(int start_afflvl, ...@@ -264,7 +268,8 @@ void psci_release_afflvl_locks(int start_afflvl,
for (level = end_afflvl; level >= start_afflvl; level--) { for (level = end_afflvl; level >= start_afflvl; level--) {
if (mpidr_nodes[level] == NULL) if (mpidr_nodes[level] == NULL)
continue; continue;
bakery_lock_release(&mpidr_nodes[level]->lock);
psci_lock_release(mpidr_nodes[level]);
} }
} }
...@@ -350,6 +355,10 @@ int psci_save_ns_entry(uint64_t mpidr, ...@@ -350,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 */
...@@ -407,6 +416,10 @@ void psci_set_state(aff_map_node_t *node, unsigned short state) ...@@ -407,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
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -33,14 +33,22 @@ ...@@ -33,14 +33,22 @@
#include <arch.h> #include <arch.h>
#include <bakery_lock.h> #include <bakery_lock.h>
#include <platform_def.h> /* for PLATFORM_NUM_AFFS */
#include <psci.h> #include <psci.h>
/* Number of affinity instances whose state this psci imp. can track */ /*
#ifdef PLATFORM_NUM_AFFS * The following helper macros abstract the interface to the Bakery
#define PSCI_NUM_AFFS PLATFORM_NUM_AFFS * Lock API.
*/
#if USE_COHERENT_MEM
#define psci_lock_init(aff_map, idx) bakery_lock_init(&(aff_map)[(idx)].lock)
#define psci_lock_get(node) bakery_lock_get(&((node)->lock))
#define psci_lock_release(node) bakery_lock_release(&((node)->lock))
#else #else
#define PSCI_NUM_AFFS (2 * PLATFORM_CORE_COUNT) #define psci_lock_init(aff_map, idx) ((aff_map)[(idx)].aff_map_index = (idx))
#define psci_lock_get(node) bakery_lock_get((node)->aff_map_index, \
CPU_DATA_PSCI_LOCK_OFFSET)
#define psci_lock_release(node) bakery_lock_release((node)->aff_map_index,\
CPU_DATA_PSCI_LOCK_OFFSET)
#endif #endif
/******************************************************************************* /*******************************************************************************
...@@ -49,10 +57,15 @@ ...@@ -49,10 +57,15 @@
******************************************************************************/ ******************************************************************************/
typedef struct aff_map_node { typedef struct aff_map_node {
unsigned long mpidr; unsigned long mpidr;
unsigned short ref_count; unsigned char ref_count;
unsigned char state; unsigned char state;
unsigned char level; unsigned char level;
#if USE_COHERENT_MEM
bakery_lock_t lock; bakery_lock_t lock;
#else
/* For indexing the bakery_info array in per CPU data */
unsigned char aff_map_index;
#endif
} aff_map_node_t; } aff_map_node_t;
typedef struct aff_limits_node { typedef struct aff_limits_node {
......
...@@ -181,7 +181,7 @@ static void psci_init_aff_map_node(unsigned long mpidr, ...@@ -181,7 +181,7 @@ static void psci_init_aff_map_node(unsigned long mpidr,
uint32_t linear_id; uint32_t linear_id;
psci_aff_map[idx].mpidr = mpidr; psci_aff_map[idx].mpidr = mpidr;
psci_aff_map[idx].level = level; psci_aff_map[idx].level = level;
bakery_lock_init(&psci_aff_map[idx].lock); psci_lock_init(psci_aff_map, idx);
/* /*
* If an affinity instance is present then mark it as OFF to begin with. * If an affinity instance is present then mark it as OFF to begin with.
...@@ -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