summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/arm/shared/include/arm-cp15.h
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2016-07-04 01:30:05 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2016-10-02 10:40:33 +0200
commitfd6cd36b09607cd79d87fddc902500f888f3f8b2 (patch)
treeab2f5d9b1e15a1fca9c803390ccb493deb6a6afb /c/src/lib/libcpu/arm/shared/include/arm-cp15.h
parentbsps/arm: Change code to explicit selection of cache implementation for ARM B... (diff)
downloadrtems-fd6cd36b09607cd79d87fddc902500f888f3f8b2.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. Updates #2783 Updates #2782
Diffstat (limited to '')
-rw-r--r--c/src/lib/libcpu/arm/shared/include/arm-cp15.h31
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);