Ticket #3007: 0002-Fix-cache-invalidate-behavior.patch

File 0002-Fix-cache-invalidate-behavior.patch, 3.8 KB (added by munster, on May 11, 2017 at 2:25:54 PM)
  • c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h

    From efe5792ad833ff0cf0457fa3961ec76d70262300 Mon Sep 17 00:00:00 2001
    From: munster <something@my.door>
    Date: Thu, 11 May 2017 14:49:44 +0100
    Subject: [PATCH 2/2] Fix cache invalidate behavior.
    
    In cases where the buffer is not aligned to line boundary at the beginning or the end, the invalidate operation would lose modifications done on the adjacent data. This applies to both L1 and L2 caches.
    See #3007.
    ---
     c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h   | 23 +++++++++++-----
     c/src/lib/libbsp/arm/shared/include/arm-cache-l1.h | 31 +++++++++++++++-------
     2 files changed, 38 insertions(+), 16 deletions(-)
    
    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 81b34a62fa..e773cb5003 100644
    a b l2c_310_invalidate_1_line( const void *d_addr ) 
    932932static inline void
    933933l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
    934934{
    935   /* Back starting address up to start of a line and invalidate until ADDR_LAST */
    936   uint32_t       adx               = (uint32_t)d_addr
    937     & ~L2C_310_DATA_LINE_MASK;
    938   const uint32_t ADDR_LAST         =
    939     (uint32_t)( (size_t)d_addr + n_bytes - 1 );
     935  uint32_t       adx               = (uint32_t)d_addr;
     936  uint32_t       end               =
     937    (uint32_t)( (size_t)d_addr + n_bytes );
    940938  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
    941939
    942940  if ( n_bytes == 0 ) {
    943941    return;
    944942  }
    945943
    946   for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
     944  if ( adx & L2C_310_DATA_LINE_MASK ) {
     945    /* flush start line in case of misalignment */
     946    adx &= ~L2C_310_DATA_LINE_MASK;
     947    l2c_310_flush_1_line( l2cc, adx );
     948    adx += CPU_DATA_CACHE_ALIGNMENT;
     949  }
     950
     951  if ( end & L2C_310_DATA_LINE_MASK ) {
     952    /* flush end line in case of misalignment */
     953    end &= ~L2C_310_DATA_LINE_MASK;
     954    l2c_310_flush_1_line( l2cc, end );
     955  }
     956
     957  for (; adx < end; adx += CPU_DATA_CACHE_ALIGNMENT ) {
    947958    /* Invalidate L2 cache line */
    948959    l2cc->inv_pa = adx;
    949960  }
  • 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..f2927a2766 100644
    a b static inline void arm_cache_l1_invalidate_data_range( 
    268268)
    269269{
    270270  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);
     271    uint32_t       adx = (uint32_t) d_addr;
     272    uint32_t       end =
     273      (uint32_t)( (size_t)d_addr + n_bytes );
    275274
    276275    arm_cache_l1_errata_764369_handler();
    277276   
    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 );
     277    if (adx & ARM_CACHE_L1_DATA_LINE_MASK) {
     278      /* flush start line in case of misalignment */
     279      adx &= ~ARM_CACHE_L1_DATA_LINE_MASK;
     280      arm_cp15_data_cache_clean_and_invalidate_line( (void*)adx );
     281      adx += ARM_CACHE_L1_CPU_DATA_ALIGNMENT;
    284282    }
     283
     284    if (end & ARM_CACHE_L1_DATA_LINE_MASK) {
     285      /* flush end line in case of misalignment */
     286      end &= ~ARM_CACHE_L1_DATA_LINE_MASK;
     287      arm_cp15_data_cache_clean_and_invalidate_line( (void*)end );
     288    }
     289
     290    while (adx < end) {
     291      /* Invalidate the Data cache line */
     292      arm_cp15_data_cache_invalidate_line( (void*)adx );
     293      adx += ARM_CACHE_L1_CPU_DATA_ALIGNMENT;
     294    }
     295
    285296    /* Wait for L1 invalidate to complete */
    286297    _ARM_Data_synchronization_barrier();
    287298  }