summaryrefslogtreecommitdiffstats
path: root/c/src/lib
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
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 'c/src/lib')
-rw-r--r--c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h43
-rw-r--r--c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h71
-rw-r--r--c/src/lib/libcpu/arm/shared/include/arm-cp15.h31
3 files changed, 97 insertions, 48 deletions
diff --git a/c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h b/c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h
index bc19cb7cad..de5fddb5aa 100644
--- a/c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h
+++ b/c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h
@@ -24,6 +24,7 @@
#define LIBBSP_ARM_ARMV467AR_BASIC_CACHE_H
#include <libcpu/arm-cp15.h>
+#include "../include/arm-cache-l1.h"
#define CPU_DATA_CACHE_ALIGNMENT 32
#define CPU_INSTRUCTION_CACHE_ALIGNMENT 32
@@ -32,14 +33,44 @@
#define CPU_MAXIMAL_CACHE_ALIGNMENT 64
#endif
+#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS \
+ ARM_CACHE_L1_CPU_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+
+
static inline void _CPU_cache_flush_1_data_line(const void *d_addr)
{
- arm_cp15_data_cache_clean_line(d_addr);
+ arm_cache_l1_flush_1_data_line(d_addr);
+}
+
+static inline void
+_CPU_cache_flush_data_range(
+ const void *d_addr,
+ size_t n_bytes
+)
+{
+ _ARM_Data_synchronization_barrier();
+ arm_cp15_drain_write_buffer();
+ arm_cache_l1_flush_data_range(
+ d_addr,
+ n_bytes
+ );
}
static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr)
{
- arm_cp15_data_cache_invalidate_line(d_addr);
+ arm_cache_l1_invalidate_1_data_line(d_addr);
+}
+
+static inline void
+_CPU_cache_invalidate_data_range(
+ const void *addr_first,
+ size_t n_bytes
+)
+{
+ arm_cache_l1_invalidate_data_range(
+ addr_first,
+ n_bytes
+ );
}
static inline void _CPU_cache_freeze_data(void)
@@ -54,7 +85,13 @@ static inline void _CPU_cache_unfreeze_data(void)
static inline void _CPU_cache_invalidate_1_instruction_line(const void *d_addr)
{
- arm_cp15_instruction_cache_invalidate_line(d_addr);
+ arm_cache_l1_invalidate_1_instruction_line(d_addr);
+}
+
+static inline void
+_CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
+{
+ arm_cache_l1_invalidate_instruction_range( i_addr, n_bytes );
}
static inline void _CPU_cache_freeze_instruction(void)
diff --git a/c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h b/c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h
index 1c3d9cfee9..74a65c5ac7 100644
--- a/c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h
+++ b/c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h
@@ -37,8 +37,10 @@ extern "C" {
#define ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT 32
#define ARM_CACHE_L1_CPU_SUPPORT_PROVIDES_RANGE_FUNCTIONS
-#define ARM_CACHE_L1_CSS_ID_DATA 0
-#define ARM_CACHE_L1_CSS_ID_INSTRUCTION 1
+#define ARM_CACHE_L1_CSS_ID_DATA \
+ (ARM_CP15_CACHE_CSS_ID_DATA | ARM_CP15_CACHE_CSS_LEVEL(0))
+#define ARM_CACHE_L1_CSS_ID_INSTRUCTION \
+ (ARM_CP15_CACHE_CSS_ID_INSTRUCTION | ARM_CP15_CACHE_CSS_LEVEL(0))
#define ARM_CACHE_L1_DATA_LINE_MASK ( ARM_CACHE_L1_CPU_DATA_ALIGNMENT - 1 )
#define ARM_CACHE_L1_INSTRUCTION_LINE_MASK \
( ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT \
@@ -52,15 +54,6 @@ static void arm_cache_l1_errata_764369_handler( void )
#endif
}
-static void arm_cache_l1_select( const uint32_t selection )
-{
- /* select current cache level in cssr */
- arm_cp15_set_cache_size_selection( selection );
-
- /* isb to sych the new cssr&csidr */
- _ARM_Instruction_synchronization_barrier();
-}
-
/*
* @param l1LineSize Number of bytes in cache line expressed as power of
* 2 value
@@ -69,22 +62,23 @@ static void arm_cache_l1_select( const uint32_t selection )
* qparam liNumSets Number of sets in cache
* */
-static inline void arm_cache_l1_properties(
+static inline void arm_cache_l1_properties_for_level(
uint32_t *l1LineSize,
uint32_t *l1Associativity,
- uint32_t *l1NumSets )
+ uint32_t *l1NumSets,
+ uint32_t level_and_inst_dat
+)
{
- uint32_t id;
+ uint32_t ccsidr;
- _ARM_Instruction_synchronization_barrier();
- id = arm_cp15_get_cache_size_id();
+ ccsidr = arm_cp15_get_cache_size_id_for_level(level_and_inst_dat);
/* Cache line size in words + 2 -> bytes) */
- *l1LineSize = ( id & 0x0007U ) + 2 + 2;
+ *l1LineSize = arm_ccsidr_get_line_power(ccsidr);
/* Number of Ways */
- *l1Associativity = ( ( id >> 3 ) & 0x03ffU ) + 1;
+ *l1Associativity = arm_ccsidr_get_associativity(ccsidr);
/* Number of Sets */
- *l1NumSets = ( ( id >> 13 ) & 0x7fffU ) + 1;
+ *l1NumSets = arm_ccsidr_get_num_sets(ccsidr);
}
/*
@@ -130,8 +124,9 @@ static inline void arm_cache_l1_flush_entire_data( void )
_ARM_Data_memory_barrier();
/* Get the L1 cache properties */
- arm_cache_l1_properties( &l1LineSize, &l1Associativity,
- &l1NumSets );
+ arm_cache_l1_properties_for_level( &l1LineSize,
+ &l1Associativity, &l1NumSets,
+ ARM_CACHE_L1_CSS_ID_DATA);
for ( w = 0; w < l1Associativity; ++w ) {
for ( s = 0; s < l1NumSets; ++s ) {
@@ -160,8 +155,9 @@ static inline void arm_cache_l1_invalidate_entire_data( void )
_ARM_Data_memory_barrier();
/* Get the L1 cache properties */
- arm_cache_l1_properties( &l1LineSize, &l1Associativity,
- &l1NumSets );
+ arm_cache_l1_properties_for_level( &l1LineSize,
+ &l1Associativity, &l1NumSets,
+ ARM_CACHE_L1_CSS_ID_DATA);
for ( w = 0; w < l1Associativity; ++w ) {
for ( s = 0; s < l1NumSets; ++s ) {
@@ -191,8 +187,9 @@ static inline void arm_cache_l1_clean_and_invalidate_entire_data( void )
/* Get the L1 cache properties */
- arm_cache_l1_properties( &l1LineSize, &l1Associativity,
- &l1NumSets );
+ arm_cache_l1_properties_for_level( &l1LineSize,
+ &l1Associativity, &l1NumSets,
+ ARM_CACHE_L1_CSS_ID_DATA);
for ( w = 0; w < l1Associativity; ++w ) {
for ( s = 0; s < l1NumSets; ++s ) {
@@ -371,19 +368,14 @@ static inline void arm_cache_l1_disable_instruction( void )
static inline size_t arm_cache_l1_get_data_cache_size( void )
{
- rtems_interrupt_level level;
size_t size;
uint32_t line_size = 0;
uint32_t associativity = 0;
uint32_t num_sets = 0;
- rtems_interrupt_local_disable(level);
-
- arm_cache_l1_select( ARM_CACHE_L1_CSS_ID_DATA );
- arm_cache_l1_properties( &line_size, &associativity,
- &num_sets );
-
- rtems_interrupt_local_enable(level);
+ arm_cache_l1_properties_for_level( &line_size,
+ &associativity, &num_sets,
+ ARM_CACHE_L1_CSS_ID_DATA);
size = (1 << line_size) * associativity * num_sets;
@@ -392,22 +384,17 @@ static inline size_t arm_cache_l1_get_data_cache_size( void )
static inline size_t arm_cache_l1_get_instruction_cache_size( void )
{
- rtems_interrupt_level level;
size_t size;
uint32_t line_size = 0;
uint32_t associativity = 0;
uint32_t num_sets = 0;
- rtems_interrupt_local_disable(level);
-
- arm_cache_l1_select( ARM_CACHE_L1_CSS_ID_INSTRUCTION );
- arm_cache_l1_properties( &line_size, &associativity,
- &num_sets );
-
- rtems_interrupt_local_enable(level);
+ arm_cache_l1_properties_for_level( &line_size,
+ &associativity, &num_sets,
+ ARM_CACHE_L1_CSS_ID_INSTRUCTION);
size = (1 << line_size) * associativity * num_sets;
-
+
return size;
}
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);