Hardware Libraries  20.1
Stratix 10 SoC Hardware Manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
alt_mmu.h
1 /*****************************************************************************
2 *
3 * Copyright 2014-2017 Altera Corporation. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *****************************************************************************/
32 
33 
34 #ifndef __ALT_MMU_H__
35 #define __ALT_MMU_H__
36 
37 #include "hwlib.h"
38 
39 #ifdef __cplusplus
40 extern "C"
41 {
42 #endif /* __cplusplus */
43 
65 typedef enum ALT_MMU_TTB_SH_e
66 {
72 
80 typedef enum ALT_MMU_TTB_NS_e
81 {
86 
92 typedef enum ALT_MMU_TTB_XN_e
93 {
108 
135 typedef enum ALT_MMU_AP_e
136 {
142 } ALT_MMU_AP_t;
143 
201 typedef uint8_t ALT_MMU_ATTR_t;
202 
214 typedef struct ALT_MMU_MAIR_s
215 {
216  ALT_MMU_ATTR_t mair[8];
219 
220 #if __arm__
221 
228 typedef struct ALT_MMU_TTBCR_s
229 {
230  bool eae;
231  unsigned t0sz;
235 } ALT_MMU_TTBCR_t;
236 
237 #elif __aarch64__
238 
243 typedef enum ALT_MMU_TCR_PS_e
244 {
245  ALT_MMU_TCR_PS_4GiB = 0,
246  ALT_MMU_TCR_PS_64GiB = 1,
247  ALT_MMU_TCR_PS_1TiB = 2,
248  ALT_MMU_TCR_PS_4TiB = 3,
249  ALT_MMU_TCR_PS_16TiB = 4,
250  ALT_MMU_TCR_PS_256TiB = 5
252 } ALT_MMU_TCR_PS_t;
253 
258 typedef enum ALT_MMU_TCR_TG0_e
259 {
260  ALT_MMU_TCR_TG0_4KiB = 0,
261  ALT_MMU_TCR_TG0_16KiB = 2,
262  ALT_MMU_TCR_TG0_64KiB = 1
264 } ALT_MMU_TCR_TG0_t;
265 
270 typedef struct ALT_MMU_TCR_s
271 {
272  bool tbi;
273  ALT_MMU_TCR_PS_t ps;
274  ALT_MMU_TCR_TG0_t tg0;
275  unsigned t0sz;
279 } ALT_MMU_TCR_t;
280 
281 #endif
282 
283 #define FALSE 0
284 #define TRUE 1
285 
286 #if __arm__
287  /* Short Descriptor Format */
288  /* Long Descriptor Format */
289  #define ALT_MMU_VMSAV8_32_LONG_TTB_TYPE_E_FAULT (0x0) /* Fault Entry */
290  #define ALT_MMU_VMSAV8_32_LONG_TTB_TYPE_E_BLOCK (0x1) /* Block Entry */
291  #define ALT_MMU_VMSAV8_32_LONG_TTB_TYPE_E_TABLE (0x3) /* Table Entry */
292  #define ALT_MMU_VMSAV8_32_LONG_TTB_TYPE_E_PAGE (0x3) /* Page Entry */
293  #define ALT_MMU_VMSAV8_32_LONG_TTB_TYPE_SET(value) (((uint64_t)(value) & 0x3) << 0)
294 
295  /* Upper Attributes for Table Descriptors */
296  #define ALT_MMU_VMSAV8_32_LONG_TABLE_PXNTABLE_SET(value) (((uint64_t)(value) & 0x1) << 59)
297  #define ALT_MMU_VMSAV8_32_LONG_TABLE_XNTABLE_SET(value) (((uint64_t)(value) & 0x1) << 60)
298  #define ALT_MMU_VMSAV8_32_LONG_TABLE_APTABLE_SET(value) (((uint64_t)(value) & 0x3) << 61)
299  #define ALT_MMU_VMSAV8_32_LONG_TABLE_NSTABLE_SET(value) (((uint64_t)(value) & 0x1) << 63)
300 
301  /* Upper Attributes for Block and Page Descriptors */
302  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_XN_SET(value) (((uint64_t)(value) & 0x1) << 54)
303  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_PXN_SET(value) (((uint64_t)(value) & 0x1) << 53)
304  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_CONT_SET(value) (((uint64_t)(value) & 0x1) << 52)
305 
306  /* Lower Attributes for Block and Page Descriptors */
307  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_NG_SET(value) (((uint64_t)(value) & 0x3) << 9)
308  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_AF_SET(value) (((uint64_t)(value) & 0x3) << 9)
309  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_SH_SET(value) (((uint64_t)(value) & 0x3) << 9)
310  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_AP_SET(value) (((uint64_t)(value) & 0x6) << 5) /* AP is a bit different. The block only has AP[2:1]. */
311  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_NS_SET(value) (((uint64_t)(value) & 0x1) << 5)
312  #define ALT_MMU_VMSAV8_32_LONG_BLOCK_ATTR_INDEX_SET(value) (((uint64_t)(value) & 0x7) << 2)
313 
314 #elif __aarch64__
315 
316  #define ALT_MMU_VMSAV8_64_TTB_TYPE_E_FAULT (0x0) /* Fault Entry */
317  #define ALT_MMU_VMSAV8_64_TTB_TYPE_E_BLOCK (0x1) /* Block Entry */
318  #define ALT_MMU_VMSAV8_64_TTB_TYPE_E_TABLE (0x3) /* Table Entry */
319  #define ALT_MMU_VMSAV8_64_TTB_TYPE_E_PAGE (0x3) /* Page Entry */
320  #define ALT_MMU_VMSAV8_64_TTB_TYPE_SET(value) (((uint64_t)(value) & 0x3) << 0)
321 
322  /* Upper Attributes for Table Descriptors */
323  #define ALT_MMU_VMSAV8_64_TABLE_PXNTABLE_SET(value) (((uint64_t)(value) & 0x1) << 59)
324  #define ALT_MMU_VMSAV8_64_TABLE_XNTABLE_SET(value) (((uint64_t)(value) & 0x1) << 60)
325  #define ALT_MMU_VMSAV8_64_TABLE_APTABLE_SET(value) (((uint64_t)(value) & 0x3) << 61)
326  #define ALT_MMU_VMSAV8_64_TABLE_NSTABLE_SET(value) (((uint64_t)(value) & 0x1) << 63)
327 
328  /* Upper Attributes for Block and Page Descriptors */
329  #define ALT_MMU_VMSAV8_64_BLOCK_XN_SET(value) (((uint64_t)(value) & 0x1) << 54)
330  #define ALT_MMU_VMSAV8_64_BLOCK_PXN_SET(value) (((uint64_t)(value) & 0x1) << 53)
331  #define ALT_MMU_VMSAV8_64_BLOCK_CONT_SET(value) (((uint64_t)(value) & 0x1) << 52)
332 
333  /* Lower Attributes for Block and Page Descriptors */
334  #define ALT_MMU_VMSAV8_64_BLOCK_NG_SET(value) (((uint64_t)(value) & 0x1) << 11)
335  #define ALT_MMU_VMSAV8_64_BLOCK_AF_SET(value) (((uint64_t)(value) & 0x1) << 10)
336  #define ALT_MMU_VMSAV8_64_BLOCK_SH_SET(value) (((uint64_t)(value) & 0x3) << 8)
337  #define ALT_MMU_VMSAV8_64_BLOCK_AP_SET(value) (((uint64_t)(value) & 0x3) << 6) /* AP is a bit different. The block only has AP[2:1]. */
338  #define ALT_MMU_VMSAV8_64_BLOCK_NS_SET(value) (((uint64_t)(value) & 0x1) << 5)
339  #define ALT_MMU_VMSAV8_64_BLOCK_ATTR_INDEX_SET(value) (((uint64_t)(value) & 0x7) << 2)
340 
341  #define GEN_MAIR_INDEX(index, value) (((value) & 0xff) << (8 * index))
342 
343  /* Strongly ordered memory:
344  - no Gather, no Reorder, no Early write acknowledgements. */
345  #define MAIR_ATTR_DEVICE_nGnRnE (0x00)
346 
347  /* Device memory:
348  - no Gather, no Reorder, Early write acknowledgements. This is suitable for performant device memory. */
349  #define MAIR_ATTR_DEVICE_nGnRE (0x04)
350 
351  /* Cacheable memory, most performant options:
352  - Inner and Outer are: Write Back Allocate for Reads and Writes. */
353  #define OUTER_WB (1 << 6) /* Write back */
354  #define OUTER_NONTRANS (1 << 7) /* non-transient (hint to the cache, ignored on Cortex-A53) */
355  #define OUTER_WALLOC (1 << 4) /* Write allocate */
356  #define OUTER_RALLOC (1 << 5) /* Read allocate */
357  #define INNER_WB (1 << 2)
358  #define INNER_NONTRANS (1 << 3)
359  #define INNER_WALLOC (1 << 0)
360  #define INNER_RALLOC (1 << 1)
361 
362  #define MAIR_ATTR_MEMORY_IO_WBRWA (OUTER_WB | OUTER_NONTRANS | OUTER_WALLOC | OUTER_RALLOC | INNER_WB | INNER_NONTRANS | INNER_WALLOC | INNER_RALLOC)
363 
364  /* Default MAIR attribute */
365  #define MAIR_ATTR_DEFAULT MAIR_ATTR_DEVICE_nGnRnE
366 
367  #define ALT_MMU_VMSAV8_64_TTB_ADDR_4KB(value) ( ((uint64_t)(value) & 0x00007FFFFFFFFF000) )
368  #define ALT_MMU_VMSAV8_64_TTB_ADDR_16KB(value) ( ((uint64_t)(value) & 0x00007FFFFFFFFC000) )
369  #define ALT_MMU_VMSAV8_64_TTB_ADDR_64KB(value) ( ((uint64_t)(value) & 0x00007FFFFFFFF0000) )
370 #endif
371 
378 ALT_STATUS_CODE alt_mmu_tlb_invalidate(void);
379 
389 ALT_STATUS_CODE alt_mmu_tlb_invalidate_is(void);
390 
409 ALT_STATUS_CODE alt_mmu_enable(void);
410 
417 ALT_STATUS_CODE alt_mmu_disable(void);
418 
426 typedef struct ALT_MMU_MEM_REGION_s
427 {
428  void * va;
432  uint64_t pa;
438  size_t size;
442  bool fault;
444  unsigned attrindex;
458 
459 /* Holds Information about the Translation Table Format that are dependent on
460  Desired Page Size, and the desired span of the Input Address (Virtual Address)
461  that is configured for Address Translation */
462 typedef struct
463 {
464  unsigned descriptor_count; /* Number of Translation Table Descriptors in Table */
465  uintptr_t block_size[4]; /* Block size per Level. */
466  uintptr_t table_span[4]; /* Table entry spans per Level. */
467  unsigned level; /* Starting Level of a Translation Table Walk (based on T0sZ) */
468  unsigned entries; /* Number of Translation Table Entries Required to Span entire Virtual Address Range (based on T0sZ*/
469 } ALT_MMU_GRANULE_INFO_t;
470 
471 extern ALT_MMU_GRANULE_INFO_t granule_4KiB;
472 extern ALT_MMU_GRANULE_INFO_t granule_16KiB;
473 extern ALT_MMU_GRANULE_INFO_t granule_64KiB;
474 
506 typedef void* (*alt_mmu_ttb_alloc_t)(size_t size, size_t align, void * context);
507 
512 #if __arm__
513 typedef ALT_MMU_TTBCR_t ALT_MMU_TCR_INFO_t;
514 #elif __aarch64__
515 typedef ALT_MMU_TCR_t ALT_MMU_TCR_INFO_t;
516 #endif
517 
518 ALT_STATUS_CODE alt_mmu_configure_granule(const ALT_MMU_TCR_INFO_t * ttbconfig);
519 
551  size_t regions_count,
552  const ALT_MMU_GRANULE_INFO_t * granule_info,
553  const ALT_MMU_TCR_INFO_t * ttbconfig);
554 
555 
604 ALT_STATUS_CODE alt_mmu_va_space_create(const ALT_MMU_MEM_REGION_t * regions, /* Pointer to Base Memory Region */
605  size_t regions_count, /* Number of Memory Regions */
606  const ALT_MMU_GRANULE_INFO_t * granule_info, /* Pointer to Granule Information */
607  const ALT_MMU_TCR_INFO_t * ttbconfig, /* Pointer to Translation Control Register Config */
608  alt_mmu_ttb_alloc_t ttb_alloc,
609  void * memPool); /* Pointer to Memory Pool */
610 
611 /*
612  * Enables the virtual address space described by the MMU translation table \e
613  * ttb1.
614  *
615  * This function actualizes the virtual address space rooted a the MMU first level
616  * translation table \e ttb1. The function performs the following steps to enable
617  * the virtual address space:
618  * * Configure the Translation Table Base Control Register (TTBCR) (AArch32)
619  * or Translation Control Register (TCR) (AArch64) to use a single table.
620  * * Configure the Memory Attribute Indirection Register (MAIR) 0 and 1
621  * (MAIR0, MAIR1) (AArch32) or MAIR (AArch64).
622  * * Set Translation Table Base Register (TTBR0) to \e ttb1.
623  * * Invalidate TLB.
624  * * Enable MMU.
625  *
626  * \param ttb1
627  * The base address of a initial translation table.
628  *
629  * \param ttbcr_info
630  * Pagetable configuration information conveyed in the Translation
631  * Table Base Control Register. (AArch32 only)
632  *
633  * \param tcr_info
634  * Pagetable configuration information conveyed in the Translation
635  * Control Register. (AArch64 only)
636  *
637  * \param mair_info
638  * Memory Attribute Indirection Register information.
639  *
640  * \retval ALT_E_SUCCESS Successful status.
641  * \retval ALT_E_ERROR Details about error status code
642  */
643 ALT_STATUS_CODE alt_mmu_va_space_enable(const uint64_t* translation_table_base,
644  const ALT_MMU_TCR_INFO_t *tcrconfig,
645  const ALT_MMU_MAIR_t* mair_info);
646 
678 uint64_t alt_mmu_va_to_pa(const void * va, ALT_MMU_ATTR_t * attr, uint32_t * dfsc);
679 
684 #ifdef __cplusplus
685 }
686 #endif /* __cplusplus */
687 #endif /* __ALT_MMU_H__ */