Ticket #3007: cache.diff

File cache.diff, 10.2 KB (added by munster, on Apr 27, 2017 at 2:24:20 PM)
  • c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h

    diff --git a/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h b/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h
    index f7017b7688..38726b6322 100644
    a b typedef struct { 
    455455#define L2C_310_DEBUG_DWB_MASK 0x00000002
    456456
    457457/** @brief Debug DCL bit, disables cache line fill */
    458 #define L2C_310_DEBUG_DCL_MASK 0x00000002
     458#define L2C_310_DEBUG_DCL_MASK 0x00000001
    459459
    460460  uint8_t reserved_f44[0xf60 - 0xf44];
    461461
    l2c_310_flush_1_line( volatile L2CC *l2cc, uint32_t d_addr ) 
    875875}
    876876
    877877static inline void
    878 l2c_310_flush_range( const void* d_addr, const size_t n_bytes )
     878l2c_310_flush_range( uint32_t start, uint32_t end )
    879879{
    880   /* Back starting address up to start of a line and invalidate until ADDR_LAST */
    881   uint32_t       adx               = (uint32_t)d_addr
    882     & ~L2C_310_DATA_LINE_MASK;
    883   const uint32_t ADDR_LAST         =
    884     (uint32_t)( (size_t)d_addr + n_bytes - 1 );
    885   uint32_t       block_end         =
    886     L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES );
    887880  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
    888881
    889   if ( n_bytes == 0 ) {
    890     return;
    891   }
    892 
    893   for (;
    894        adx      <= ADDR_LAST;
    895        adx       = block_end + 1,
    896        block_end = L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES )) {
    897     rtems_interrupt_lock_context lock_context;
    898 
    899     rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
     882  /* back starting address up to start of a line */
     883  start &= ~L2C_310_DATA_LINE_MASK;
    900884
    901     for (; adx <= block_end; adx += CPU_DATA_CACHE_ALIGNMENT ) {
    902       l2c_310_flush_1_line( l2cc, adx );
    903     }
    904 
    905     l2c_310_sync( l2cc );
    906 
    907     rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
     885  while (start < end) {
     886    l2c_310_flush_1_line( l2cc, start );
     887    start += CPU_DATA_CACHE_ALIGNMENT;
    908888  }
     889
     890  l2c_310_sync( l2cc );
    909891}
    910892
    911893static inline void
    l2c_310_invalidate_1_line( const void *d_addr ) 
    937919{
    938920  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
    939921
    940 
    941922  l2cc->inv_pa = (uint32_t) d_addr;
    942923  l2c_310_sync( l2cc );
    943924}
    944925
    945926static inline void
    946 l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
     927l2c_310_invalidate_range( uint32_t start, uint32_t end )
    947928{
    948   /* Back starting address up to start of a line and invalidate until ADDR_LAST */
    949   uint32_t       adx               = (uint32_t)d_addr
    950     & ~L2C_310_DATA_LINE_MASK;
    951   const uint32_t ADDR_LAST         =
    952     (uint32_t)( (size_t)d_addr + n_bytes - 1 );
    953   uint32_t       block_end         =
    954     L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES );
    955929  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
    956930
    957   if ( n_bytes == 0 ) {
    958     return;
     931  /* flush start line in case of misalignment */
     932  if (start & L2C_310_DATA_LINE_MASK) {
     933    start &= ~L2C_310_DATA_LINE_MASK;
     934    l2c_310_flush_1_line( l2cc, start );
     935    start += CPU_DATA_CACHE_ALIGNMENT;
    959936  }
    960937
    961   for (;
    962        adx      <= ADDR_LAST;
    963        adx       = block_end + 1,
    964        block_end = L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES )) {
    965     rtems_interrupt_lock_context lock_context;
    966 
    967     rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
    968 
    969     for (; adx <= block_end; adx += CPU_DATA_CACHE_ALIGNMENT ) {
    970       /* Invalidate L2 cache line */
    971       l2cc->inv_pa = adx;
    972     }
    973 
    974     l2c_310_sync( l2cc );
     938  /* flush end line in case of misalignment */
     939  if (end & L2C_310_DATA_LINE_MASK) {
     940    end &= ~L2C_310_DATA_LINE_MASK;
     941    l2c_310_flush_1_line( l2cc, end );
     942  }
    975943
    976     rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
     944  while (start < end) {
     945    /* invalidate L2 cache line */
     946    l2cc->inv_pa = start;
     947    start += CPU_DATA_CACHE_ALIGNMENT;
    977948  }
     949
     950  l2c_310_sync( l2cc );
    978951}
    979952
    980953
    _CPU_cache_flush_data_range( 
    12361209  size_t      n_bytes
    12371210)
    12381211{
    1239   arm_cache_l1_flush_data_range(
    1240     d_addr,
    1241     n_bytes
    1242   );
    1243   l2c_310_flush_range(
    1244     d_addr,
    1245     n_bytes
    1246   );
     1212  if ( n_bytes ) {
     1213    arm_cache_l1_flush_data_range(
     1214      (uint32_t)d_addr,
     1215      (uint32_t)d_addr + n_bytes
     1216    );
     1217    l2c_310_flush_range(
     1218      (uint32_t)d_addr,
     1219      (uint32_t)d_addr + n_bytes
     1220    );
     1221  }
    12471222}
    12481223
    12491224static inline void
    _CPU_cache_flush_entire_data( void ) 
    12551230
    12561231static inline void
    12571232_CPU_cache_invalidate_data_range(
    1258   const void *addr_first,
    1259   size_t     n_bytes
     1233  const void *d_addr,
     1234  size_t      n_bytes
    12601235)
    12611236{
    1262   l2c_310_invalidate_range(
    1263     addr_first,
    1264     n_bytes
    1265   );
    1266   arm_cache_l1_invalidate_data_range(
    1267     addr_first,
    1268     n_bytes
    1269   );
     1237  if ( n_bytes ) {
     1238    l2c_310_invalidate_range(
     1239      (uint32_t)d_addr,
     1240      (uint32_t)d_addr + n_bytes
     1241    );
     1242    arm_cache_l1_invalidate_data_range(
     1243      (uint32_t)d_addr,
     1244      (uint32_t)d_addr + n_bytes
     1245    );
     1246  }
    12701247}
    12711248
    12721249static inline void
  • c/src/lib/libbsp/arm/shared/armv467ar-basic-cache/cache_.h

    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 2ff1ae1f03..c394c8d997 100644
    a b _CPU_cache_flush_data_range( 
    4848  size_t      n_bytes
    4949)
    5050{
    51   _ARM_Data_synchronization_barrier();
    52   arm_cache_l1_flush_data_range(
    53     d_addr,
    54     n_bytes
    55   );
    56   #if !defined(__ARM_ARCH_7A__)
    57   arm_cp15_drain_write_buffer();
    58   #endif
    59  _ARM_Data_synchronization_barrier();
     51  if ( n_bytes ) {
     52    _ARM_Data_synchronization_barrier();
     53    arm_cache_l1_flush_data_range(
     54      (uint32_t)d_addr,
     55      (uint32_t)d_addr + n_bytes
     56    );
     57    #if !defined(__ARM_ARCH_7A__)
     58    arm_cp15_drain_write_buffer();
     59    #endif
     60    _ARM_Data_synchronization_barrier();
     61  }
    6062}
    6163
    6264static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr)
    static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr) 
    6668
    6769static inline void
    6870_CPU_cache_invalidate_data_range(
    69   const void *addr_first,
    70   size_t     n_bytes
     71  const void *d_addr,
     72  size_t      n_bytes
    7173)
    7274{
    73   arm_cache_l1_invalidate_data_range(
    74     addr_first,
    75     n_bytes
    76   );
     75  if ( n_bytes ) {
     76    arm_cache_l1_invalidate_data_range(
     77      (uint32_t)d_addr,
     78      (uint32_t)d_addr + n_bytes
     79    );
     80  }
    7781}
    7882
    7983static inline void _CPU_cache_freeze_data(void)
  • c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h

    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 9caa2685bc..7d6fe65886 100644
    a b  
    44 * @ingroup arm_shared
    55 *
    66 * @brief Level 1 Cache definitions and functions.
    7  * 
     7 *
    88 * This file implements handling for the ARM Level 1 cache controller
    99 */
    1010
    static void arm_cache_l1_errata_764369_handler( void ) 
    5555}
    5656
    5757/*
    58  * @param l1LineSize      Number of bytes in cache line expressed as power of 
     58 * @param l1LineSize      Number of bytes in cache line expressed as power of
    5959 *                        2 value
    60  * @param l1Associativity Associativity of cache. The associativity does not 
     60 * @param l1Associativity Associativity of cache. The associativity does not
    6161 *                        have to be a power of 2.
    6262 * qparam liNumSets       Number of sets in cache
    6363 * */
    static inline void arm_cache_l1_clean_and_invalidate_entire_data( void ) 
    209209  _ARM_Data_synchronization_barrier();
    210210}
    211211
    212 static inline void arm_cache_l1_flush_data_range( 
    213   const void *d_addr,
    214   size_t      n_bytes
     212static inline void arm_cache_l1_flush_data_range(
     213  uint32_t start,
     214  uint32_t end
    215215)
    216216{
    217   if ( n_bytes != 0 ) {
    218     uint32_t       adx       = (uint32_t) d_addr
    219                                & ~ARM_CACHE_L1_DATA_LINE_MASK;
    220     const uint32_t ADDR_LAST =
    221       (uint32_t)( (size_t) d_addr + n_bytes - 1 );
     217  /* back starting address up to start of a line */
     218  start &= ~ARM_CACHE_L1_DATA_LINE_MASK;
    222219
    223     arm_cache_l1_errata_764369_handler();
     220  arm_cache_l1_errata_764369_handler();
    224221
    225     for (; adx <= ADDR_LAST; adx += ARM_CACHE_L1_CPU_DATA_ALIGNMENT ) {
    226       /* Store and invalidate the Data cache line */
    227       arm_cp15_data_cache_clean_and_invalidate_line( (void*)adx );
    228     }
    229     /* Wait for L1 store to complete */
    230     _ARM_Data_synchronization_barrier();
     222  while (start < end) {
     223    /* Store and invalidate the Data cache line */
     224    arm_cp15_data_cache_clean_and_invalidate_line( (void*)start );
     225    start += ARM_CACHE_L1_CPU_DATA_ALIGNMENT;
    231226  }
     227  /* Wait for L1 store to complete */
     228  _ARM_Data_synchronization_barrier();
    232229}
    233230
    234231
    static inline void arm_cache_l1_invalidate_1_instruction_line( 
    263260}
    264261
    265262static inline void arm_cache_l1_invalidate_data_range(
    266   const void *d_addr,
    267   size_t      n_bytes
     263  uint32_t start,
     264  uint32_t end
    268265)
    269266{
    270   if ( n_bytes != 0 ) {
    271     uint32_t       adx = (uint32_t) d_addr
    272                          & ~ARM_CACHE_L1_DATA_LINE_MASK;
    273     const uint32_t end =
    274       (uint32_t)( (size_t)d_addr + n_bytes -1);
     267  arm_cache_l1_errata_764369_handler();
    275268
    276     arm_cache_l1_errata_764369_handler();
    277    
    278     /* Back starting address up to start of a line and invalidate until end */
    279     for (;
    280          adx <= end;
    281          adx += ARM_CACHE_L1_CPU_DATA_ALIGNMENT ) {
    282         /* Invalidate the Instruction cache line */
    283         arm_cp15_data_cache_invalidate_line( (void*)adx );
    284     }
    285     /* Wait for L1 invalidate to complete */
    286     _ARM_Data_synchronization_barrier();
     269  /* flush start line in case of misalignment */
     270  if (start & ARM_CACHE_L1_DATA_LINE_MASK) {
     271    start &= ~ARM_CACHE_L1_DATA_LINE_MASK;
     272    arm_cp15_data_cache_clean_and_invalidate_line( (void*)start );
     273    start += ARM_CACHE_L1_CPU_DATA_ALIGNMENT;
     274  }
     275
     276  /* flush end line in case of misalignment */
     277  if (end & ARM_CACHE_L1_DATA_LINE_MASK) {
     278    end &= ~ARM_CACHE_L1_DATA_LINE_MASK;
     279    arm_cp15_data_cache_clean_and_invalidate_line( (void*)end );
     280  }
     281
     282  while (start < end) {
     283    /* Invalidate the Data cache line */
     284    arm_cp15_data_cache_invalidate_line( (void*)start );
     285    start += ARM_CACHE_L1_CPU_DATA_ALIGNMENT;
    287286  }
     287
     288  /* Wait for L1 invalidate to complete */
     289  _ARM_Data_synchronization_barrier();
    288290}
    289291
    290292static inline void arm_cache_l1_invalidate_instruction_range(