/* * E2K ISET V2-V5 MMU structure and common definitions. * * Copyright 2018 (c) MCST, Salavat S. Guiliazov (atic@mcst.ru) */ #ifndef _ASM_E2K_MMU_REGS_TYPES_V2_H #define _ASM_E2K_MMU_REGS_TYPES_V2_H /* Avoid header dependency loop of probe_entry_t and DTLB_ENTRY_PH_BOUND_V2 */ #ifndef _E2K_TLB_REGS_TYPES_H_ # error Do not include directly, use instead #endif /* * This file contains the functions and defines necessary to modify and * use the E2K ISET V2-V5 page tables. * NOTE: E2K has four levels of page tables. */ #ifndef __ASSEMBLY__ #include #include #include /* * DTLB entry probe format */ #define DTLB_ENTRY_ERROR_MASK_V2 0xbe00000000000000ULL #define DTLB_ENTRY_PH_BOUND_V2 0x8000000000000000ULL #define DTLB_ENTRY_ILLEGAL_PAGE_V2 0x4000000000000000ULL #define DTLB_ENTRY_PAGE_MISS_V2 0x2000000000000000ULL #define DTLB_ENTRY_PROBE_DISABLED_V2 0x0400000000000000ULL #define DTLB_ENTRY_RES_BITS_V2 0x0200000000000000ULL #define DTLB_ENTRY_MISS_LEVEL_MASK_V2 0x1800000000000000ULL #define DTLB_ENTRY_WR_V2 0x0000000000000002ULL #define DTLB_ENTRY_NON_EX_U_S_V2 0x0000000000000004ULL #define DTLB_ENTRY_PWT_V2 0x0000000000000008ULL #define DTLB_ENTRY_PCD1_V2 0x0000000000000010ULL #define DTLB_ENTRY_D_V2 0x0000000000000040ULL #define DTLB_ENTRY_G_V2 0x0000000000000100ULL #define DTLB_ENTRY_PCD2_V2 0x0000000000000200ULL #define DTLB_ENTRY_NWA_V2 0x0000000000000400ULL #define DTLB_ENTRY_PHA_V2 0x000000fffffff000ULL /* phys address */ #define DTLB_ENTRY_VVA_V2 0x0000010000000000ULL /* VVA bit */ #define DTLB_ENTRY_PV_V2 0x0000020000000000ULL #define DTLB_ENTRY_INT_PR_NON_EX_V2 0x0000040000000000ULL #define DTLB_ENTRY_INTL_RD_V2 0x0000200000000000ULL #define DTLB_ENTRY_INTL_WR_V2 0x0000400000000000ULL #define DTLB_ENTRY_WP_V2 0x0000800000000000ULL #define DTLB_ENTRY_UC_V2 0x0001000000000000ULL /* MPT flags for 2/4Mb & 1Gb pages [46:45] */ #define DTLB_ENTRY_MPT_FLAGS_V2 0x0000600000000000ULL #define DTLB_EP_RES_V2 0x0001ffffffffffffULL #define DTLB_EP_FAULT_RES_V2 (~DTLB_EP_RES_V2) /* * DTLB address probe result format */ #define PH_ADDR_AP_RES_V2 0x000000ffffffffffULL /* Physical address */ /* normal result of */ /* AP [39: 0] */ #define DISABLE_AP_RES_V2 DISABLE_EP_RES_V2 /* AP diasble result */ /* [62] */ #define ILLEGAL_PAGE_AP_RES_V2 ILLEGAL_PAGE_EP_RES_V2 /* illegal page */ /* [58] */ /* convert physical address to page frame number for DTLB */ #define PA_TO_DTLB_ENTRY_PHA_V2(phys_addr) \ (((e2k_addr_t)phys_addr) & DTLB_ENTRY_PHA_V2) /* convert the page frame number from DTLB entry to physical address */ #define DTLB_ENTRY_PHA_TO_PA_V2(dtlb_entry) \ ((e2k_addr_t)(dtlb_entry) & DTLB_ENTRY_PHA_V2) static inline probe_entry_t covert_uni_dtlb_flags_to_dtlb_val_v2(const uni_dtlb_t uni_flags) { probe_entry_t dtlb_flags = 0; if (uni_flags & UNI_PAGE_WRITE) dtlb_flags |= (DTLB_ENTRY_WR_V2); if (uni_flags & UNI_PAGE_PRIV) dtlb_flags |= (DTLB_ENTRY_PV_V2); if (uni_flags & UNI_PAGE_VALID) dtlb_flags |= (DTLB_ENTRY_VVA_V2); if (uni_flags & UNI_PAGE_PROTECT) dtlb_flags |= (DTLB_ENTRY_INT_PR_NON_EX_V2); if (uni_flags & UNI_PAGE_GLOBAL) dtlb_flags |= (DTLB_ENTRY_G_V2); if (uni_flags & UNI_PAGE_DIRTY) dtlb_flags |= (DTLB_ENTRY_D_V2); if (uni_flags & UNI_PAGE_NWA) dtlb_flags |= (DTLB_ENTRY_NWA_V2); if (uni_flags & UNI_PAGE_MEM_TYPE) dtlb_flags |= (DTLB_ENTRY_PCD1_V2 | DTLB_ENTRY_PCD2_V2 | DTLB_ENTRY_PWT_V2); if (uni_flags & UNI_PAGE_NON_EX) dtlb_flags |= (DTLB_ENTRY_NON_EX_U_S_V2); if (uni_flags & UNI_PAGE_PFN) dtlb_flags |= (DTLB_ENTRY_PHA_V2); if (uni_flags & UNI_PAGE_MEM_TYPE_MA) dtlb_flags |= (DTLB_ENTRY_PCD1_V2 | DTLB_ENTRY_PCD2_V2 | DTLB_ENTRY_PWT_V2); if (uni_flags & UNI_PAGE_WRITE_INT) dtlb_flags |= (DTLB_ENTRY_WP_V2); if (uni_flags & UNI_PAGE_INTL_RD) dtlb_flags |= (DTLB_ENTRY_INTL_RD_V2); if (uni_flags & UNI_PAGE_INTL_WR) dtlb_flags |= (DTLB_ENTRY_INTL_WR_V2); if (uni_flags & UNI_DTLB_EP_RES) dtlb_flags |= (DTLB_EP_RES_V2); if (uni_flags & UNI_DTLB_PH_ADDR_AP_RES) dtlb_flags |= (PH_ADDR_AP_RES_V2); if (uni_flags & UNI_DTLB_ERROR_MASK) dtlb_flags |= (DTLB_ENTRY_ERROR_MASK_V2); if (uni_flags & UNI_DTLB_MISS_LEVEL) dtlb_flags |= (DTLB_ENTRY_MISS_LEVEL_MASK_V2); if (uni_flags & UNI_DTLB_SUCCESSFUL) dtlb_flags |= (DTLB_ENTRY_PROBE_DISABLED_V2); if (uni_flags & UNI_DTLB_RES_BITS) dtlb_flags |= (DTLB_ENTRY_RES_BITS_V2); BUILD_BUG_ON(dtlb_flags == 0); return dtlb_flags; } static inline probe_entry_t fill_dtlb_val_v2_flags(const uni_dtlb_t uni_flags) { return covert_uni_dtlb_flags_to_dtlb_val_v2(uni_flags); } static inline probe_entry_t get_dtlb_val_v2_flags(probe_entry_t dtlb_val, const uni_dtlb_t uni_flags) { return dtlb_val & covert_uni_dtlb_flags_to_dtlb_val_v2(uni_flags); } static inline bool test_dtlb_val_v2_flags(probe_entry_t dtlb_val, const uni_dtlb_t uni_flags) { return get_dtlb_val_v2_flags(dtlb_val, uni_flags) != 0; } static inline probe_entry_t set_dtlb_val_v2_flags(probe_entry_t dtlb_val, const uni_dtlb_t uni_flags) { return dtlb_val | covert_uni_dtlb_flags_to_dtlb_val_v2(uni_flags); } static inline probe_entry_t clear_dtlb_val_v2_flags(probe_entry_t dtlb_val, const uni_dtlb_t uni_flags) { return dtlb_val & ~covert_uni_dtlb_flags_to_dtlb_val_v2(uni_flags); } #endif /* ! __ASSEMBLY__ */ #endif /* ! _ASM_E2K_MMU_REGS_TYPES_V2_H */