Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:05

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMShared
0007  *
0008  * @brief This source file contains the implementation of
0009  *   arm_cp15_set_translation_table_entries().
0010  */
0011 
0012 /*
0013  * Copyright (C) 2010, 2019 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #include <rtems.h>
0038 #include <libcpu/arm-cp15.h>
0039 #include <bspopts.h>
0040 
0041 /*
0042  * Translation table modification requires to propagate
0043  * information to memory and other cores.
0044  *
0045  * Algorithm follows example found in the section
0046  *
0047  * B3.10.1 General TLB maintenance requirements
0048  * TLB maintenance operations and the memory order model
0049  *
0050  * of ARM Architecture Reference Manual
0051  * ARMv7-A and ARMv7-R edition
0052  * ARM DDI 0406C.b (ID072512)
0053  */
0054 
0055 static uint32_t set_translation_table_entries(
0056   const void *begin,
0057   const void *end,
0058   uint32_t section_flags
0059 )
0060 {
0061   uint32_t *ttb;
0062 #ifdef ARM_MMU_USE_SMALL_PAGES
0063   uint32_t *pt;
0064   uint32_t flags;
0065 #endif
0066   uint32_t istart;
0067   uint32_t iend;
0068   uint32_t index_mask;
0069   uint32_t section_flags_of_first_entry;
0070   uint32_t i;
0071   uint32_t *modified_begin;
0072   size_t modified_size;
0073 
0074   ttb = arm_cp15_get_translation_table_base();
0075 #ifdef ARM_MMU_USE_SMALL_PAGES
0076   pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
0077   istart = ARM_MMU_SMALL_PAGE_GET_INDEX(begin);
0078   iend = ARM_MMU_SMALL_PAGE_GET_INDEX(ARM_MMU_SMALL_PAGE_MVA_ALIGN_UP(end));
0079   index_mask = (1U << (32 - ARM_MMU_SMALL_PAGE_BASE_SHIFT)) - 1U;
0080   section_flags_of_first_entry = ARM_MMU_SMALL_PAGE_FLAGS_TO_SECT(pt[istart])
0081     | ARM_MMU_PAGE_TABLE_FLAGS_TO_SECT(ttb[ARM_MMU_SECT_GET_INDEX(begin)]);
0082   modified_begin = &pt[istart];
0083   flags = ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(section_flags);
0084 #else
0085   istart = ARM_MMU_SECT_GET_INDEX(begin);
0086   iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
0087   index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
0088   section_flags_of_first_entry = ttb[istart];
0089   modified_begin = &ttb[istart];
0090 #endif
0091   modified_size = 0;
0092 
0093   for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
0094     uint32_t pa;
0095 
0096 #ifdef ARM_MMU_USE_SMALL_PAGES
0097     pa = i << ARM_MMU_SMALL_PAGE_BASE_SHIFT;
0098     pt[i] = pa | flags;
0099     modified_size += ARM_MMU_SMALL_PAGE_TABLE_ENTRY_SIZE;
0100 #else
0101     pa = i << ARM_MMU_SECT_BASE_SHIFT;
0102     ttb[i] = pa | section_flags;
0103     modified_size += ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE;
0104 #endif
0105   }
0106 
0107   if ((arm_cp15_get_control() & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M)) != 0) {
0108     rtems_cache_flush_multiple_data_lines(modified_begin, modified_size);
0109   }
0110 
0111   _ARM_Data_synchronization_barrier();
0112 
0113   for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
0114     void *mva;
0115 
0116 #ifdef ARM_MMU_USE_SMALL_PAGES
0117     mva = (void *) (i << ARM_MMU_SMALL_PAGE_BASE_SHIFT);
0118 #else
0119     mva = (void *) (i << ARM_MMU_SECT_BASE_SHIFT);
0120 #endif
0121 
0122 #if defined(__ARM_ARCH_7A__)
0123     /*
0124      * Bit 31 needs to be 1 to indicate the register implements the
0125      * Multiprocessing Extensions register format and the U (bit 30)
0126      * is 0.
0127      */
0128     #define MPIDR_MX_FMT (1 << 31)
0129     #define MPIDR_UP     (1 << 30)
0130     const uint32_t mpidr = arm_cp15_get_multiprocessor_affinity();
0131     if ((mpidr & (MPIDR_MX_FMT | MPIDR_UP)) == MPIDR_MX_FMT) {
0132       arm_cp15_tlb_invalidate_entry_all_asids_inner_shareable(mva);
0133     }
0134     else
0135 #endif
0136     {
0137       arm_cp15_tlb_instruction_invalidate_entry(mva);
0138       arm_cp15_tlb_data_invalidate_entry(mva);
0139     }
0140   }
0141 
0142   _ARM_Data_synchronization_barrier();
0143   _ARM_Instruction_synchronization_barrier();
0144 
0145   return section_flags_of_first_entry;
0146 }
0147 
0148 uint32_t arm_cp15_set_translation_table_entries(
0149   const void *begin,
0150   const void *end,
0151   uint32_t section_flags
0152 )
0153 {
0154   return set_translation_table_entries(begin, end, section_flags);
0155 }