37#ifndef LIBBSP_AARCH64_SHARED_AARCH64_MMU_H
38#define LIBBSP_AARCH64_SHARED_AARCH64_MMU_H
41#include <bsp/linker-symbols.h>
53#define MMU_MAX_SUBTABLE_PAGE_BITS ( 3 * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS )
61#define AARCH64_MMU_DEFAULT_SECTIONS \
63 .begin = (uintptr_t) bsp_section_fast_text_begin, \
64 .end = (uintptr_t) bsp_section_fast_text_end, \
65 .flags = AARCH64_MMU_CODE_CACHED \
67 .begin = (uintptr_t) bsp_section_fast_data_begin, \
68 .end = (uintptr_t) bsp_section_fast_data_end, \
69 .flags = AARCH64_MMU_DATA_RW_CACHED \
71 .begin = (uintptr_t) bsp_section_start_begin, \
72 .end = (uintptr_t) bsp_section_start_end, \
73 .flags = AARCH64_MMU_CODE_CACHED \
75 .begin = (uintptr_t) bsp_section_vector_begin, \
76 .end = (uintptr_t) bsp_section_vector_end, \
77 .flags = AARCH64_MMU_DATA_RW_CACHED \
79 .begin = (uintptr_t) bsp_section_text_begin, \
80 .end = (uintptr_t) bsp_section_text_end, \
81 .flags = AARCH64_MMU_CODE_CACHED \
83 .begin = (uintptr_t) bsp_section_rodata_begin, \
84 .end = (uintptr_t) bsp_section_rodata_end, \
85 .flags = AARCH64_MMU_DATA_RO_CACHED \
87 .begin = (uintptr_t) bsp_section_data_begin, \
88 .end = (uintptr_t) bsp_section_data_end, \
89 .flags = AARCH64_MMU_DATA_RW_CACHED \
91 .begin = (uintptr_t) bsp_section_bss_begin, \
92 .end = (uintptr_t) bsp_section_bss_end, \
93 .flags = AARCH64_MMU_DATA_RW_CACHED \
95 .begin = (uintptr_t) bsp_section_rtemsstack_begin, \
96 .end = (uintptr_t) bsp_section_rtemsstack_end, \
97 .flags = AARCH64_MMU_DATA_RW_CACHED \
99 .begin = (uintptr_t) bsp_section_noinit_begin, \
100 .end = (uintptr_t) bsp_section_noinit_end, \
101 .flags = AARCH64_MMU_DATA_RW_CACHED \
103 .begin = (uintptr_t) bsp_section_work_begin, \
104 .end = (uintptr_t) bsp_section_work_end, \
105 .flags = AARCH64_MMU_DATA_RW_CACHED \
107 .begin = (uintptr_t) bsp_section_stack_begin, \
108 .end = (uintptr_t) bsp_section_stack_end, \
109 .flags = AARCH64_MMU_DATA_RW_CACHED \
111 .begin = (uintptr_t) bsp_section_nocache_begin, \
112 .end = (uintptr_t) bsp_section_nocache_end, \
113 .flags = AARCH64_MMU_DEVICE \
115 .begin = (uintptr_t) bsp_section_nocachenoload_begin, \
116 .end = (uintptr_t) bsp_section_nocachenoload_end, \
117 .flags = AARCH64_MMU_DEVICE \
119 .begin = (uintptr_t) bsp_translation_table_base, \
120 .end = (uintptr_t) bsp_translation_table_end, \
121 .flags = AARCH64_MMU_DATA_RW_CACHED \
127 .begin = (uintptr_t) bsp_start_vector_table_begin, \
128 .end = (uintptr_t) bsp_start_vector_table_end, \
129 .flags = AARCH64_MMU_CODE_RW_CACHED \
133BSP_START_TEXT_SECTION
static inline void aarch64_mmu_page_table_set_blocks(
136 uint32_t bits_offset,
137 uint64_t default_attr
140 uint64_t page_flag = 0;
142 if ( bits_offset == MMU_PAGE_BITS ) {
143 page_flag = MMU_DESC_TYPE_PAGE;
146 for ( uint64_t i = 0; i < ( 1 << MMU_BITS_PER_LEVEL ); i++ ) {
153aarch64_mmu_page_table_alloc( uint64_t **
page_table )
156 static uintptr_t current_page_table =
157 (uintptr_t) bsp_translation_table_base;
159 current_page_table += MMU_PAGE_SIZE;
160 *
page_table = (uint64_t *) current_page_table;
163 uintptr_t consumed_pages = (uintptr_t) current_page_table;
164 consumed_pages -= (uintptr_t) bsp_translation_table_base;
165 consumed_pages /= MMU_PAGE_SIZE;
167 if ( consumed_pages > AARCH64_MMU_TRANSLATION_TABLE_PAGES ) {
175BSP_START_TEXT_SECTION
static inline uintptr_t aarch64_mmu_get_index(
176 uintptr_t root_address,
181 uintptr_t mask = ( 1 << ( MMU_BITS_PER_LEVEL + 1 ) ) - 1;
183 return ( ( vaddr - root_address ) >> shift ) & mask;
187aarch64_mmu_get_sub_table(
189 uint64_t **sub_table,
190 uintptr_t physical_root_address,
199 *sub_table = (uint64_t *) (uintptr_t) table_pointer;
208 aarch64_mmu_page_table_set_blocks(
210 physical_root_address,
211 shift - MMU_BITS_PER_LEVEL,
223 uint64_t root_address,
230 uint32_t shift = ( 2 - level ) * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS;
231 uint64_t granularity = 1LLU << shift;
232 uint64_t page_flag = 0;
235 page_flag = MMU_DESC_TYPE_PAGE;
239 uintptr_t index = aarch64_mmu_get_index( root_address, addr, shift );
241 uint64_t chunk_size = granularity;
244 if ( block_bottom == addr ) {
245 if (
size >= chunk_size ) {
249 if ( page_flag || (
page_table[index] & MMU_DESC_TYPE_TABLE ) != MMU_DESC_TYPE_TABLE ) {
272 chunk_size = block_top - addr;
274 if ( chunk_size >
size ) {
280 uint64_t new_root_address = root_address + index * granularity;
281 uint64_t *sub_table =
NULL;
284 sc = aarch64_mmu_get_sub_table(
295 sc = aarch64_mmu_map_block(
316 aarch64_mmu_config_table[];
318BSP_START_DATA_SECTION
extern const size_t
319 aarch64_mmu_config_table_size;
322BSP_START_TEXT_SECTION
static inline uint64_t
323aarch64_mmu_get_cpu_pa_bits(
void )
325 uint64_t id_reg = _AArch64_Read_id_aa64mmfr0_el1();
327 switch ( AARCH64_ID_AA64MMFR0_EL1_PARANGE_GET( id_reg ) ) {
348BSP_START_TEXT_SECTION
static inline void
349aarch64_mmu_set_translation_table_entries(
357 uint64_t max_mappable = 1LLU << aarch64_mmu_get_cpu_pa_bits();
360 if ( begin >= max_mappable || end > max_mappable ) {
361 bsp_fatal( BSP_FATAL_MMU_ADDRESS_INVALID );
364 sc = aarch64_mmu_map_block(
378BSP_START_TEXT_SECTION
static inline void aarch64_mmu_setup_translation_table(
384 uint64_t *ttb = (uint64_t *) bsp_translation_table_base;
386 aarch64_mmu_page_table_set_blocks(
389 MMU_MAX_SUBTABLE_PAGE_BITS,
393 _AArch64_Write_ttbr0_el1( (uintptr_t) ttb );
396 for ( i = 0; i < config_count; ++i ) {
397 aarch64_mmu_set_translation_table_entries( ttb, &config_table[i] );
401BSP_START_TEXT_SECTION
static inline void
402aarch64_mmu_enable(
void )
413 sctlr = _AArch64_Read_sctlr_el1();
414 sctlr |= AARCH64_SCTLR_EL1_I | AARCH64_SCTLR_EL1_C | AARCH64_SCTLR_EL1_M;
415 _AArch64_Write_sctlr_el1( sctlr );
418BSP_START_TEXT_SECTION
static inline void
419aarch64_mmu_disable(
void )
430 sctlr = _AArch64_Read_sctlr_el1();
431 sctlr &= ~(AARCH64_SCTLR_EL1_M);
432 _AArch64_Write_sctlr_el1( sctlr );
435BSP_START_TEXT_SECTION
static inline void aarch64_mmu_setup(
void )
439 _AArch64_Write_tcr_el1(
440 AARCH64_TCR_EL1_T0SZ( 0x10 ) | AARCH64_TCR_EL1_IRGN0( 0x1 ) |
441 AARCH64_TCR_EL1_ORGN0( 0x1 ) | AARCH64_TCR_EL1_SH0( 0x3 ) |
442 AARCH64_TCR_EL1_TG0( 0x0 ) | AARCH64_TCR_EL1_IPS( 0x5ULL ) |
447 _AArch64_Write_mair_el1(
448 AARCH64_MAIR_EL1_ATTR0( 0x0 ) | AARCH64_MAIR_EL1_ATTR1( 0x4 ) |
449 AARCH64_MAIR_EL1_ATTR2( 0x44 ) | AARCH64_MAIR_EL1_ATTR3( 0xFF )
This header file provides the API to read and write the AArch64 system registers.
This header file provides fatal codes for RTEMS_FATAL_SOURCE_BSP.
#define RTEMS_ALIGN_UP(_value, _alignment)
Aligns up the value to the alignment.
Definition: basedefs.h:141
#define RTEMS_ALIGN_DOWN(_value, _alignment)
Aligns down the value to the alignment.
Definition: basedefs.h:123
void rtems_cache_invalidate_entire_data(void)
Invalidates the entire data cache.
Definition: cacheimpl.h:228
void rtems_cache_flush_entire_data(void)
Flushes the entire data cache.
Definition: cacheimpl.h:213
RTEMS_NO_RETURN void rtems_fatal_error_occurred(uint32_t fatal_code)
Invokes the fatal error handler.
Definition: fatal.c:47
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:85
@ RTEMS_SUCCESSFUL
This status code indicates successful completion of a requested operation.
Definition: status.h:90
@ RTEMS_NO_MEMORY
This status code indicates that the directive attempted to allocate memory but was unable to do so.
Definition: status.h:236
#define NULL
Requests a GPIO pin group configuration.
Definition: xil_types.h:54
This header file provides utility macros for BSPs.
Definitions used in MMU setup.
Definition: aarch64-mmu.h:55
Definition: deflate.c:114
unsigned size
Definition: tte.h:1