source: rtems/c/src/lib/libbsp/arm/shared/arm-cp15-set-ttb-entries.c @ 577e7fb

5
Last change on this file since 577e7fb was 33381218, checked in by Pavel Pisa <pisa@…>, on 07/17/16 at 16:21:48

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

}

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/*
2 * Copyright (c) 2010-2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems.h>
16#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 */
31
32static uint32_t set_translation_table_entries(
33  const void *begin,
34  const void *end,
35  uint32_t section_flags
36)
37{
38  uint32_t *ttb = arm_cp15_get_translation_table_base();
39  uint32_t istart = ARM_MMU_SECT_GET_INDEX(begin);
40  uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
41  uint32_t index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
42  uint32_t ctrl;
43  uint32_t section_flags_of_first_entry;
44  uint32_t i;
45  void *first_ttb_addr;
46  void *last_ttb_end;
47
48  ctrl = arm_cp15_get_control();
49  section_flags_of_first_entry = ttb [istart];
50  last_ttb_end = first_ttb_addr = ttb + istart;
51
52  for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
53    uint32_t addr = i << ARM_MMU_SECT_BASE_SHIFT;
54
55    ttb [i] = addr | section_flags;
56    last_ttb_end = ttb + i + 1;
57  }
58
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();
78
79  return section_flags_of_first_entry;
80}
81
82uint32_t arm_cp15_set_translation_table_entries(
83  const void *begin,
84  const void *end,
85  uint32_t section_flags
86)
87{
88  rtems_interrupt_level level;
89  uint32_t section_flags_of_first_entry;
90
91  rtems_interrupt_disable(level);
92  section_flags_of_first_entry =
93    set_translation_table_entries(begin, end, section_flags);
94  rtems_interrupt_enable(level);
95
96  return section_flags_of_first_entry;
97}
Note: See TracBrowser for help on using the repository browser.