Back to home page

LXR

 
 

    


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

0001 /**
0002  * @file
0003  *
0004  * @ingroup arm_start
0005  *
0006  * @brief Arm CP15 start.
0007  */
0008 
0009 
0010 /*
0011  * Copyright (c) 2013 Hesham AL-Matary.
0012  * Copyright (C) 2009, 2019 embedded brains GmbH & Co. KG
0013  *
0014  * The license and distribution terms for this file may be
0015  * found in the file LICENSE in this distribution or at
0016  * http://www.rtems.org/license/LICENSE.
0017  */
0018 
0019 #ifndef LIBBSP_ARM_SHARED_ARM_CP15_START_H
0020 #define LIBBSP_ARM_SHARED_ARM_CP15_START_H
0021 
0022 #include <libcpu/arm-cp15.h>
0023 #include <bsp/start.h>
0024 #include <bsp/linker-symbols.h>
0025 #include <bspopts.h>
0026 
0027 #ifdef __cplusplus
0028 extern "C" {
0029 #endif /* __cplusplus */
0030 
0031 typedef struct {
0032   uint32_t begin;
0033   uint32_t end;
0034   uint32_t flags;
0035 } arm_cp15_start_section_config;
0036 
0037 #define ARMV7_CP15_START_DEFAULT_SECTIONS \
0038   { \
0039     .begin = (uint32_t) bsp_section_fast_text_begin, \
0040     .end = (uint32_t) bsp_section_fast_text_end, \
0041     .flags = ARMV7_MMU_CODE_CACHED \
0042   }, { \
0043     .begin = (uint32_t) bsp_section_fast_data_begin, \
0044     .end = (uint32_t) bsp_section_fast_data_end, \
0045     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0046   }, { \
0047     .begin = (uint32_t) bsp_section_start_begin, \
0048     .end = (uint32_t) bsp_section_start_end, \
0049     .flags = ARMV7_MMU_CODE_CACHED \
0050   }, { \
0051     .begin = (uint32_t) bsp_section_vector_begin, \
0052     .end = (uint32_t) bsp_section_vector_end, \
0053     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0054   }, { \
0055     .begin = (uint32_t) bsp_section_text_begin, \
0056     .end = (uint32_t) bsp_section_text_end, \
0057     .flags = ARMV7_MMU_CODE_CACHED \
0058   }, { \
0059     .begin = (uint32_t) bsp_section_rodata_begin, \
0060     .end = (uint32_t) bsp_section_rodata_end, \
0061     .flags = ARMV7_MMU_DATA_READ_ONLY_CACHED \
0062   }, { \
0063     .begin = (uint32_t) bsp_section_data_begin, \
0064     .end = (uint32_t) bsp_section_data_end, \
0065     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0066   }, { \
0067     .begin = (uint32_t) bsp_section_bss_begin, \
0068     .end = (uint32_t) bsp_section_bss_end, \
0069     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0070   }, { \
0071     .begin = (uint32_t) bsp_section_rtemsstack_begin, \
0072     .end = (uint32_t) bsp_section_rtemsstack_end, \
0073     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0074   }, { \
0075     .begin = (uint32_t) bsp_section_noinit_begin, \
0076     .end = (uint32_t) bsp_section_noinit_end, \
0077     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0078   }, { \
0079     .begin = (uint32_t) bsp_section_work_begin, \
0080     .end = (uint32_t) bsp_section_work_end, \
0081     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0082   }, { \
0083     .begin = (uint32_t) bsp_section_stack_begin, \
0084     .end = (uint32_t) bsp_section_stack_end, \
0085     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0086   }, { \
0087     .begin = (uint32_t) bsp_section_nocache_begin, \
0088     .end = (uint32_t) bsp_section_nocache_end, \
0089     .flags = ARMV7_MMU_DEVICE \
0090   }, { \
0091     .begin = (uint32_t) bsp_section_nocachenoload_begin, \
0092     .end = (uint32_t) bsp_section_nocachenoload_end, \
0093     .flags = ARMV7_MMU_DEVICE \
0094   }, { \
0095     .begin = (uint32_t) bsp_translation_table_base, \
0096     .end = (uint32_t) bsp_translation_table_end, \
0097     .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED \
0098   }
0099 
0100 #define ARMV7_CP15_START_WORKSPACE_ENTRY_INDEX 10
0101 
0102 BSP_START_DATA_SECTION extern const arm_cp15_start_section_config
0103   arm_cp15_start_mmu_config_table[];
0104 
0105 BSP_START_DATA_SECTION extern const size_t
0106   arm_cp15_start_mmu_config_table_size;
0107 
0108 BSP_START_TEXT_SECTION static inline void
0109 arm_cp15_start_set_translation_table_entries(
0110   uint32_t *ttb,
0111   const arm_cp15_start_section_config *config
0112 )
0113 {
0114   if (config->begin != config->end) {
0115     uint32_t i;
0116     uint32_t iend;
0117     uint32_t index_mask;
0118     uint32_t flags;
0119 #ifdef ARM_MMU_USE_SMALL_PAGES
0120     uint32_t *pt;
0121 
0122     pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
0123     i = ARM_MMU_SMALL_PAGE_GET_INDEX(config->begin);
0124     iend = ARM_MMU_SMALL_PAGE_GET_INDEX(ARM_MMU_SMALL_PAGE_MVA_ALIGN_UP(config->end));
0125     index_mask = (1U << (32 - ARM_MMU_SMALL_PAGE_BASE_SHIFT)) - 1U;
0126     flags = ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(config->flags);
0127 
0128     while (i != iend) {
0129       pt[i] = (i << ARM_MMU_SMALL_PAGE_BASE_SHIFT) | flags;
0130       i = (i + 1U) & index_mask;
0131     }
0132 #else
0133     i = ARM_MMU_SECT_GET_INDEX(config->begin);
0134     iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
0135     index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
0136     flags = config->flags;
0137 
0138     while (i != iend) {
0139       ttb[i] = (i << ARM_MMU_SECT_BASE_SHIFT) | flags;
0140       i = (i + 1U) & index_mask;
0141     }
0142 #endif
0143   }
0144 }
0145 
0146 BSP_START_TEXT_SECTION static inline void
0147 arm_cp15_start_setup_translation_table(
0148   uint32_t *ttb,
0149   uint32_t client_domain,
0150   const arm_cp15_start_section_config *config_table,
0151   size_t config_count
0152 )
0153 {
0154 #ifdef ARM_MMU_USE_SMALL_PAGES
0155   uint32_t *pt;
0156 #endif
0157   uint32_t dac;
0158   size_t i;
0159 
0160   dac = ARM_CP15_DAC_DOMAIN(client_domain, ARM_CP15_DAC_CLIENT);
0161   arm_cp15_set_domain_access_control(dac);
0162   arm_cp15_set_translation_table_base(ttb);
0163 
0164   /* Initialize translation table with invalid entries */
0165 #ifdef ARM_MMU_USE_SMALL_PAGES
0166   pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
0167   for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
0168     size_t j;
0169 
0170     for (j = 0; j < ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT; ++j) {
0171       pt[j] = 0;
0172     }
0173 
0174     ttb[i] = (uint32_t) pt | (client_domain << ARM_MMU_SECT_DOMAIN_SHIFT)
0175       | ARM_MMU_PAGE_TABLE_DEFAULT;
0176     pt += ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT;
0177   }
0178 #else
0179   for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
0180     ttb[i] = 0;
0181   }
0182 #endif
0183 
0184   for (i = 0; i < config_count; ++i) {
0185     arm_cp15_start_set_translation_table_entries(ttb, &config_table [i]);
0186   }
0187 }
0188 
0189 BSP_START_TEXT_SECTION static inline void
0190 arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
0191   uint32_t ctrl,
0192   uint32_t *ttb,
0193   uint32_t client_domain,
0194   const arm_cp15_start_section_config *config_table,
0195   size_t config_count
0196 )
0197 {
0198   arm_cp15_start_setup_translation_table(
0199     ttb,
0200     client_domain,
0201     config_table,
0202     config_count
0203   );
0204 
0205   /* Enable MMU and cache */
0206   ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
0207 
0208   arm_cp15_set_control(ctrl);
0209 }
0210 
0211 BSP_START_TEXT_SECTION static inline uint32_t
0212 arm_cp15_start_setup_mmu_and_cache(uint32_t ctrl_clear, uint32_t ctrl_set)
0213 {
0214   uint32_t ctrl = arm_cp15_get_control();
0215 
0216   ctrl &= ~ctrl_clear;
0217   ctrl |= ctrl_set;
0218 
0219   arm_cp15_set_control(ctrl);
0220 
0221   arm_cp15_tlb_invalidate();
0222 
0223   return ctrl;
0224 }
0225 
0226 #ifdef __cplusplus
0227 }
0228 #endif /* __cplusplus */
0229 
0230 #endif /* LIBBSP_ARM_SHARED_ARM_CP15_START_H */