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,7 +136,8 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
* 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) \
#if USE_COHERENT_MEM
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void fvp_configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
......@@ -158,6 +159,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
\
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_CONFIGURE_MMU_EL(1)
......
......@@ -40,6 +40,7 @@
#include "fvp_def.h"
#include "fvp_private.h"
#if USE_COHERENT_MEM
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
......@@ -56,6 +57,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo_t bl1_tzram_layout;
......@@ -116,9 +118,12 @@ void bl1_plat_arch_setup(void)
fvp_configure_mmu_el3(bl1_tzram_layout.total_base,
bl1_tzram_layout.total_size,
BL1_RO_BASE,
BL1_RO_LIMIT,
BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT);
BL1_RO_LIMIT
#if USE_COHERENT_MEM
, BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT
#endif
);
}
......
......@@ -45,8 +45,10 @@
extern unsigned long __RO_START__;
extern unsigned long __RO_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
......@@ -57,6 +59,7 @@ extern unsigned long __COHERENT_RAM_END__;
#define BL2_RO_BASE (unsigned long)(&__RO_START__)
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
#if USE_COHERENT_MEM
/*
* 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
......@@ -66,11 +69,11 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem")));
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE)));
/* Assert that BL3-1 parameters fit in shared memory */
CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) <
......@@ -209,9 +212,12 @@ void bl2_plat_arch_setup(void)
fvp_configure_mmu_el1(bl2_tzram_layout.total_base,
bl2_tzram_layout.total_size,
BL2_RO_BASE,
BL2_RO_LIMIT,
BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT);
BL2_RO_LIMIT
#if USE_COHERENT_MEM
, BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT
#endif
);
}
/*******************************************************************************
......
......@@ -48,19 +48,25 @@
******************************************************************************/
extern unsigned long __RO_START__;
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_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
* The next 3 constants identify the extents of the code, RO data region and the
* limit of the BL3-1 image. These addresses are used by the MMU setup code and
* therefore they must be page-aligned. It is the responsibility of the linker
* 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_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.
* These addresses are used by the MMU setup code and therefore they must be
......@@ -70,7 +76,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
#if RESET_TO_BL31
static entry_point_info_t bl32_image_ep_info;
......@@ -235,9 +241,12 @@ void bl31_plat_arch_setup(void)
fvp_cci_enable();
#endif
fvp_configure_mmu_el3(BL31_RO_BASE,
(BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE),
(BL31_END - BL31_RO_BASE),
BL31_RO_BASE,
BL31_RO_LIMIT,
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
BL31_RO_LIMIT
#if USE_COHERENT_MEM
, BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT
#endif
);
}
......@@ -31,13 +31,19 @@
#include <bakery_lock.h>
#include <mmio.h>
#include "../../fvp_def.h"
#include "../../fvp_private.h"
#include "fvp_pwrc.h"
/*
* 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.
*/
#if USE_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)
{
......@@ -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 rc;
bakery_lock_get(&pwrc_lock);
fvp_lock_get(LOCK_ARG);
mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
return rc;
}
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);
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
}
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);
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
}
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,
(unsigned int) (PWKUPR_WEN | mpidr));
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
}
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,
(unsigned int) mpidr);
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
}
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);
bakery_lock_release(&pwrc_lock);
fvp_lock_release(LOCK_ARG);
}
/* Nothing else to do here apart from initializing the lock */
int fvp_pwrc_setup(void)
{
bakery_lock_init(&pwrc_lock);
fvp_lock_init(LOCK_ARG);
return 0;
}
......
......@@ -31,7 +31,9 @@
#ifndef __FVP_PRIVATE_H__
#define __FVP_PRIVATE_H__
#include <bakery_lock.h>
#include <bl_common.h>
#include <cpu_data.h>
#include <platform_def.h>
......@@ -55,10 +57,60 @@ typedef struct bl2_to_bl31_params_mem {
entry_point_info_t bl31_ep_info;
} 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
......@@ -66,15 +118,22 @@ struct meminfo;
void fvp_configure_mmu_el1(unsigned long total_base,
unsigned long total_size,
unsigned long,
unsigned long,
unsigned long,
unsigned long);
unsigned long
#if USE_COHERENT_MEM
, unsigned long,
unsigned long
#endif
);
void fvp_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long,
unsigned long,
unsigned long,
unsigned long);
unsigned long
#if USE_COHERENT_MEM
, unsigned long,
unsigned long
#endif
);
int fvp_config_setup(void);
void fvp_cci_init(void);
......
......@@ -169,5 +169,12 @@
#define CACHE_WRITEBACK_SHIFT 6
#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__ */
......@@ -40,19 +40,25 @@
******************************************************************************/
extern unsigned long __RO_START__;
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_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
* The next 3 constants identify the extents of the code & RO data region and
* the limit of the BL3-2 image. These addresses are used by the MMU setup code
* and therefore they must be page-aligned. It is the responsibility of the
* 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_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.
* These addresses are used by the MMU setup code and therefore they must be
......@@ -62,6 +68,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/*******************************************************************************
* Initialize the UART
......@@ -93,9 +100,12 @@ void tsp_platform_setup(void)
void tsp_plat_arch_setup(void)
{
fvp_configure_mmu_el1(BL32_RO_BASE,
(BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE),
(BL32_END - BL32_RO_BASE),
BL32_RO_BASE,
BL32_RO_LIMIT,
BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT);
BL32_RO_LIMIT
#if USE_COHERENT_MEM
, BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT
#endif
);
}
......@@ -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
* the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/
#if USE_COHERENT_MEM
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void configure_mmu_el##_el(unsigned long total_base, \
unsigned long total_size, \
......@@ -162,7 +163,25 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
\
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_CONFIGURE_MMU_EL(1)
DEFINE_CONFIGURE_MMU_EL(3)
......
......@@ -41,6 +41,7 @@
#include "juno_def.h"
#include "juno_private.h"
#if USE_COHERENT_MEM
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted RAM
......@@ -57,6 +58,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
......@@ -189,9 +191,12 @@ void bl1_plat_arch_setup(void)
configure_mmu_el3(bl1_tzram_layout.total_base,
bl1_tzram_layout.total_size,
TZROM_BASE,
TZROM_BASE + TZROM_SIZE,
BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT);
TZROM_BASE + TZROM_SIZE
#if USE_COHERENT_MEM
, BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT
#endif
);
}
/*******************************************************************************
......
......@@ -47,8 +47,10 @@
extern unsigned long __RO_START__;
extern unsigned long __RO_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
......@@ -59,6 +61,7 @@ extern unsigned long __COHERENT_RAM_END__;
#define BL2_RO_BASE (unsigned long)(&__RO_START__)
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
#if USE_COHERENT_MEM
/*
* 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
......@@ -68,11 +71,11 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/* Data structure which holds the extents of the trusted RAM for BL2 */
static meminfo_t bl2_tzram_layout
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem")));
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE)));
/*******************************************************************************
* Structure which holds the arguments which need to be passed to BL3-1
......@@ -194,9 +197,12 @@ void bl2_plat_arch_setup(void)
configure_mmu_el1(bl2_tzram_layout.total_base,
bl2_tzram_layout.total_size,
BL2_RO_BASE,
BL2_RO_LIMIT,
BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT);
BL2_RO_LIMIT
#if USE_COHERENT_MEM
, BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT
#endif
);
}
/*******************************************************************************
......
......@@ -48,19 +48,25 @@
******************************************************************************/
extern unsigned long __RO_START__;
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_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
* The next 3 constants identify the extents of the code, RO data region and the
* limit of the BL3-1 image. These addresses are used by the MMU setup code and
* therefore they must be page-aligned. It is the responsibility of the linker
* 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_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.
* These addresses are used by the MMU setup code and therefore they must be
......@@ -70,6 +76,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/******************************************************************************
* Placeholder variables for copying the arguments that have been passed to
......@@ -178,9 +185,13 @@ void bl31_platform_setup(void)
void bl31_plat_arch_setup()
{
configure_mmu_el3(BL31_RO_BASE,
BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE,
(BL31_END - BL31_RO_BASE),
BL31_RO_BASE,
BL31_RO_LIMIT,
BL31_RO_LIMIT
#if USE_COHERENT_MEM
,
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
BL31_COHERENT_RAM_LIMIT
#endif
);
}
......@@ -174,4 +174,12 @@
#define CACHE_WRITEBACK_SHIFT 6
#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__ */
......@@ -31,7 +31,9 @@
#ifndef __JUNO_PRIVATE_H__
#define __JUNO_PRIVATE_H__
#include <bakery_lock.h>
#include <bl_common.h>
#include <cpu_data.h>
#include <platform_def.h>
#include <stdint.h>
......@@ -59,6 +61,68 @@ typedef struct bl2_to_bl31_params_mem {
struct entry_point_info bl31_ep_info;
} 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
******************************************************************************/
......@@ -70,15 +134,21 @@ unsigned int platform_get_core_pos(unsigned long mpidr);
void configure_mmu_el1(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit);
unsigned long ro_limit
#if USE_COHERENT_MEM
, unsigned long coh_start,
unsigned long coh_limit
#endif
);
void configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit);
unsigned long ro_limit
#if USE_COHERENT_MEM
, unsigned long coh_start,
unsigned long coh_limit
#endif
);
void plat_report_exception(unsigned long type);
unsigned long plat_get_ns_image_entrypoint(void);
unsigned long platform_get_stack(unsigned long mpidr);
......
......@@ -32,6 +32,7 @@
#include <bakery_lock.h>
#include <mmio.h>
#include "juno_def.h"
#include "juno_private.h"
#include "mhu.h"
/* SCP MHU secure channel registers */
......@@ -44,13 +45,20 @@
#define CPU_INTR_S_SET 0x308
#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")));
#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)
{
bakery_lock_get(&mhu_secure_lock);
juno_lock_get(LOCK_ARG);
/* Make sure any previous command has finished */
while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
......@@ -80,12 +88,12 @@ void mhu_secure_message_end(void)
/* Clear any response we got by writing all ones to the CLEAR register */
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)
{
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
......
......@@ -66,7 +66,6 @@ BL1_SOURCES += drivers/arm/cci400/cci400.c \
plat/juno/aarch64/juno_common.c
BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
lib/locks/bakery/bakery_lock.c \
plat/common/aarch64/platform_up_stack.S \
plat/juno/bl2_plat_setup.c \
plat/juno/mhu.c \
......
......@@ -40,19 +40,25 @@
******************************************************************************/
extern unsigned long __RO_START__;
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_END__;
#endif
/*
* The next 2 constants identify the extents of the code & RO data region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
* The next 3 constants identify the extents of the code, RO data region and the
* limit of the BL3-2 image. These addresses are used by the MMU setup code and
* therefore they must be page-aligned. It is the responsibility of the 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_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.
* These addresses are used by the MMU setup code and therefore they must be
......@@ -62,6 +68,7 @@ extern unsigned long __COHERENT_RAM_END__;
*/
#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/*******************************************************************************
* Initialize the UART
......@@ -90,9 +97,12 @@ void tsp_platform_setup(void)
void tsp_plat_arch_setup(void)
{
configure_mmu_el1(BL32_RO_BASE,
BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE,
(BL32_END - BL32_RO_BASE),
BL32_RO_BASE,
BL32_RO_LIMIT,
BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT);
BL32_RO_LIMIT
#if USE_COHERENT_MEM
, BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT
#endif
);
}
......@@ -51,7 +51,10 @@ const spd_pm_ops_t *psci_spd_pm;
* corresponds to an affinity instance e.g. cluster, cpu within an mpidr
******************************************************************************/
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
......@@ -246,7 +249,8 @@ void psci_acquire_afflvl_locks(int start_afflvl,
for (level = start_afflvl; level <= end_afflvl; level++) {
if (mpidr_nodes[level] == NULL)
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,
for (level = end_afflvl; level >= start_afflvl; level--) {
if (mpidr_nodes[level] == NULL)
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,
******************************************************************************/
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);
/* 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)
node->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 @@
#include <arch.h>
#include <bakery_lock.h>
#include <platform_def.h> /* for PLATFORM_NUM_AFFS */
#include <psci.h>
/* Number of affinity instances whose state this psci imp. can track */
#ifdef PLATFORM_NUM_AFFS
#define PSCI_NUM_AFFS PLATFORM_NUM_AFFS
/*
* The following helper macros abstract the interface to the Bakery
* 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
#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
/*******************************************************************************
......@@ -49,10 +57,15 @@
******************************************************************************/
typedef struct aff_map_node {
unsigned long mpidr;
unsigned short ref_count;
unsigned char ref_count;
unsigned char state;
unsigned char level;
#if USE_COHERENT_MEM
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;
typedef struct aff_limits_node {
......
......@@ -181,7 +181,7 @@ static void psci_init_aff_map_node(unsigned long mpidr,
uint32_t linear_id;
psci_aff_map[idx].mpidr = mpidr;
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.
......@@ -331,13 +331,20 @@ int32_t psci_setup(void)
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
* flush out the entire array so that it's visible to subsequent power
* management operations. The 'psci_aff_map' array is allocated in
* coherent memory so does not need flushing. The 'psci_aff_limits'
* array is allocated in normal memory. It will be accessed when the mmu
* is off e.g. after reset. Hence it needs to be flushed.
* management operations. The 'psci_aff_limits' array is allocated in
* normal memory. It will be accessed when the mmu is off e.g. after
* reset. Hence it needs to be flushed.
*/
for (afflvl = MPIDR_AFFLVL0; afflvl < max_afflvl; afflvl++) {
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