Changeset ae3578a2 in rtems


Ignore:
Timestamp:
Jul 17, 2016, 4:21:48 PM (4 years ago)
Author:
Pavel Pisa <pisa@…>
Branches:
4.11
Children:
8c5c8b27
Parents:
0d77c4f2
git-author:
Pavel Pisa <pisa@…> (07/17/16 16:21:48)
git-committer:
Pavel Pisa <pisa@…> (10/02/16 08:40:34)
Message:

bsps/arm: do not disable MMU during translation table management operations.

Disabling MMU requires complex cache flushing and invalidation
operations. There is almost no way how to do that right
on SMP system without stopping all other CPUs. On the other hand,
there is documented sequence of operations which should be used
according to ARM manual and it guarantees even distribution
of maintenance operations to other cores for last generation
of Cortex-A cores with multiprocessor extension.

This change could require addition of appropriate entry
to arm_cp15_start_mmu_config_table for some BSPs to ensure
that MMU table stays accessible after MMU is enabled

{

.begin = (uint32_t) bsp_translation_table_base,
.end = (uint32_t) bsp_translation_table_base + 0x4000,
.flags = ARMV7_MMU_DATA_READ_WRITE_CACHED

}

Updates #2782
Updates #2783

Location:
c/src/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/shared/arm-cp15-set-ttb-entries.c

    r0d77c4f2 rae3578a2  
    1313 */
    1414
     15#include <rtems.h>
    1516#include <libcpu/arm-cp15.h>
     17
     18/*
     19 * Translation table modification requires to propagate
     20 * information to memory and other cores.
     21 *
     22 * Algorithm follows example found in the section
     23 *
     24 * B3.10.1 General TLB maintenance requirements
     25 * TLB maintenance operations and the memory order model
     26 *
     27 * of ARM Architecture Reference Manual
     28 * ARMv7-A and ARMv7-R edition
     29 * ARM DDI 0406C.b (ID072512)
     30 */
    1631
    1732static uint32_t set_translation_table_entries(
     
    2136)
    2237{
    23   uint32_t cl_size = arm_cp15_get_min_cache_line_size();
    2438  uint32_t *ttb = arm_cp15_get_translation_table_base();
    25   uint32_t i = ARM_MMU_SECT_GET_INDEX(begin);
     39  uint32_t istart = ARM_MMU_SECT_GET_INDEX(begin);
    2640  uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
    2741  uint32_t index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
    2842  uint32_t ctrl;
    2943  uint32_t section_flags_of_first_entry;
     44  uint32_t i;
     45  void *first_ttb_addr;
     46  void *last_ttb_end;
    3047
    31   ctrl = arm_cp15_mmu_disable(cl_size);
    32   arm_cp15_tlb_invalidate();
    33   section_flags_of_first_entry = ttb [i];
     48  ctrl = arm_cp15_get_control();
     49  section_flags_of_first_entry = ttb [istart];
     50  last_ttb_end = first_ttb_addr = ttb + istart;
    3451
    35   while (i != iend) {
     52  for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
    3653    uint32_t addr = i << ARM_MMU_SECT_BASE_SHIFT;
    3754
    3855    ttb [i] = addr | section_flags;
    39 
    40     i = (i + 1U) & index_mask;
     56    last_ttb_end = ttb + i + 1;
    4157  }
    4258
    43   arm_cp15_set_control(ctrl);
     59  if ( ctrl & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M ) ) {
     60    rtems_cache_flush_multiple_data_lines(first_ttb_addr,
     61                last_ttb_end - first_ttb_addr);
     62  }
     63
     64  _ARM_Data_synchronization_barrier();
     65
     66  for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
     67    void *mva = (void *) (i << ARM_MMU_SECT_BASE_SHIFT);
     68    #if defined(__ARM_ARCH_7A__)
     69    arm_cp15_tlb_invalidate_entry_all_asids(mva);
     70    #else
     71    arm_cp15_tlb_instruction_invalidate_entry(mva);
     72    arm_cp15_tlb_data_invalidate_entry(mva);
     73    #endif
     74  }
     75
     76  _ARM_Data_synchronization_barrier();
     77  _ARM_Instruction_synchronization_barrier();
    4478
    4579  return section_flags_of_first_entry;
  • c/src/lib/libcpu/arm/shared/include/arm-cp15.h

    r0d77c4f2 rae3578a2  
    561561
    562562ARM_CP15_TEXT_SECTION static inline void
     563arm_cp15_tlb_invalidate_entry_all_asids(const void *mva)
     564{
     565  ARM_SWITCH_REGISTERS;
     566
     567  mva = ARM_CP15_TLB_PREPARE_MVA(mva);
     568
     569  __asm__ volatile (
     570    ARM_SWITCH_TO_ARM
     571    "mcr p15, 0, %[mva], c8, c7, 3\n"
     572    ARM_SWITCH_BACK
     573    : ARM_SWITCH_OUTPUT
     574    : [mva] "r" (mva)
     575  );
     576}
     577
     578ARM_CP15_TEXT_SECTION static inline void
    563579arm_cp15_tlb_instruction_invalidate(void)
    564580{
Note: See TracChangeset for help on using the changeset viewer.