diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2016-07-04 01:30:05 +0200 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2016-07-04 15:55:58 +0200 |
commit | 06165554b62e3ba5bf322a8c3cfc2879e344bb1a (patch) | |
tree | 5a494af384f593e189d2733e48352b52b0793d7d /c/src/lib/libcpu/arm/shared/include/arm-cp15.h | |
parent | libdl/rtl-obj.c: ensure that loaded code is synchronized through caches. (diff) | |
download | rtems-06165554b62e3ba5bf322a8c3cfc2879e344bb1a.tar.bz2 |
bsps/arm: basic on core cache support changed to use l1 functions.
The basic data and instruction rage functions should be compatible
for all ARMv4,5,6,7 functions. On the other hand, some functions
are not portable, for example arm_cp15_data_cache_test_and_clean()
and arm_cp15_data_cache_invalidate() for all versions and there
has to be specialized version for newer cores.
arm_cache_l1_properties_for_level uses CCSIDR which is not present
on older chips.
Actual version is only experimental, needs more changes
and problem has been found on RPi1 with dlopen so there seems
to be real problem.
Diffstat (limited to 'c/src/lib/libcpu/arm/shared/include/arm-cp15.h')
-rw-r--r-- | c/src/lib/libcpu/arm/shared/include/arm-cp15.h | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/c/src/lib/libcpu/arm/shared/include/arm-cp15.h b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h index 8357656bd8..ca7a11e673 100644 --- a/c/src/lib/libcpu/arm/shared/include/arm-cp15.h +++ b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h @@ -210,6 +210,18 @@ extern "C" { /** @} */ +/** + * @name CCSIDR, Cache Size ID Register Defines + * + * @{ + */ + +#define ARM_CP15_CACHE_CSS_ID_DATA 0 +#define ARM_CP15_CACHE_CSS_ID_INSTRUCTION 1 +#define ARM_CP15_CACHE_CSS_LEVEL(level) ((level) << 1) + +/** @} */ + ARM_CP15_TEXT_SECTION static inline uint32_t arm_cp15_get_id_code(void) { @@ -819,6 +831,21 @@ arm_cp15_set_cache_size_selection(uint32_t val) ); } +ARM_CP15_TEXT_SECTION static inline uint32_t +arm_cp15_get_cache_size_id_for_level(uint32_t level_and_inst_dat) +{ + rtems_interrupt_level irq_level; + uint32_t ccsidr; + + rtems_interrupt_local_disable(irq_level); + arm_cp15_set_cache_size_selection(level_and_inst_dat); + _ARM_Instruction_synchronization_barrier(); + ccsidr = arm_cp15_get_cache_size_id(); + rtems_interrupt_local_enable(irq_level); + + return ccsidr; +} + ARM_CP15_TEXT_SECTION static inline void arm_cp15_cache_invalidate(void) { @@ -1036,10 +1063,8 @@ arm_cp15_data_cache_invalidate_all_levels(void) uint32_t way; uint32_t way_shift; - arm_cp15_set_cache_size_selection(level << 1); - _ARM_Instruction_synchronization_barrier(); + ccsidr = arm_cp15_get_cache_size_id_for_level(level << 1); - ccsidr = arm_cp15_get_cache_size_id(); line_power = arm_ccsidr_get_line_power(ccsidr); associativity = arm_ccsidr_get_associativity(ccsidr); way_shift = __builtin_clz(associativity - 1); |