1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef __MMU_H 3*4882a593Smuzhiyun #define __MMU_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/const.h> 6*4882a593Smuzhiyun #include <asm/page.h> 7*4882a593Smuzhiyun #include <asm/hypervisor.h> 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #define CTX_NR_BITS 13 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #define TAG_CONTEXT_BITS ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL)) 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun /* UltraSPARC-III+ and later have a feature whereby you can 14*4882a593Smuzhiyun * select what page size the various Data-TLB instances in the 15*4882a593Smuzhiyun * chip. In order to gracefully support this, we put the version 16*4882a593Smuzhiyun * field in a spot outside of the areas of the context register 17*4882a593Smuzhiyun * where this parameter is specified. 18*4882a593Smuzhiyun */ 19*4882a593Smuzhiyun #define CTX_VERSION_SHIFT 22 20*4882a593Smuzhiyun #define CTX_VERSION_MASK ((~0UL) << CTX_VERSION_SHIFT) 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #define CTX_PGSZ_8KB _AC(0x0,UL) 23*4882a593Smuzhiyun #define CTX_PGSZ_64KB _AC(0x1,UL) 24*4882a593Smuzhiyun #define CTX_PGSZ_512KB _AC(0x2,UL) 25*4882a593Smuzhiyun #define CTX_PGSZ_4MB _AC(0x3,UL) 26*4882a593Smuzhiyun #define CTX_PGSZ_BITS _AC(0x7,UL) 27*4882a593Smuzhiyun #define CTX_PGSZ0_NUC_SHIFT 61 28*4882a593Smuzhiyun #define CTX_PGSZ1_NUC_SHIFT 58 29*4882a593Smuzhiyun #define CTX_PGSZ0_SHIFT 16 30*4882a593Smuzhiyun #define CTX_PGSZ1_SHIFT 19 31*4882a593Smuzhiyun #define CTX_PGSZ_MASK ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \ 32*4882a593Smuzhiyun (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT)) 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun #define CTX_PGSZ_BASE CTX_PGSZ_8KB 35*4882a593Smuzhiyun #define CTX_PGSZ_HUGE CTX_PGSZ_4MB 36*4882a593Smuzhiyun #define CTX_PGSZ_KERN CTX_PGSZ_4MB 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* Thus, when running on UltraSPARC-III+ and later, we use the following 39*4882a593Smuzhiyun * PRIMARY_CONTEXT register values for the kernel context. 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun #define CTX_CHEETAH_PLUS_NUC \ 42*4882a593Smuzhiyun ((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \ 43*4882a593Smuzhiyun (CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT)) 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun #define CTX_CHEETAH_PLUS_CTX0 \ 46*4882a593Smuzhiyun ((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \ 47*4882a593Smuzhiyun (CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT)) 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* If you want "the TLB context number" use CTX_NR_MASK. If you 50*4882a593Smuzhiyun * want "the bits I program into the context registers" use 51*4882a593Smuzhiyun * CTX_HW_MASK. 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun #define CTX_NR_MASK TAG_CONTEXT_BITS 54*4882a593Smuzhiyun #define CTX_HW_MASK (CTX_NR_MASK | CTX_PGSZ_MASK) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun #define CTX_FIRST_VERSION BIT(CTX_VERSION_SHIFT) 57*4882a593Smuzhiyun #define CTX_VALID(__ctx) \ 58*4882a593Smuzhiyun (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK)) 59*4882a593Smuzhiyun #define CTX_HWBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_HW_MASK) 60*4882a593Smuzhiyun #define CTX_NRBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_NR_MASK) 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define TSB_ENTRY_ALIGNMENT 16 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun struct tsb { 67*4882a593Smuzhiyun unsigned long tag; 68*4882a593Smuzhiyun unsigned long pte; 69*4882a593Smuzhiyun } __attribute__((aligned(TSB_ENTRY_ALIGNMENT))); 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte); 72*4882a593Smuzhiyun void tsb_flush(unsigned long ent, unsigned long tag); 73*4882a593Smuzhiyun void tsb_init(struct tsb *tsb, unsigned long size); 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun struct tsb_config { 76*4882a593Smuzhiyun struct tsb *tsb; 77*4882a593Smuzhiyun unsigned long tsb_rss_limit; 78*4882a593Smuzhiyun unsigned long tsb_nentries; 79*4882a593Smuzhiyun unsigned long tsb_reg_val; 80*4882a593Smuzhiyun unsigned long tsb_map_vaddr; 81*4882a593Smuzhiyun unsigned long tsb_map_pte; 82*4882a593Smuzhiyun }; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun #define MM_TSB_BASE 0 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) 87*4882a593Smuzhiyun #define MM_TSB_HUGE 1 88*4882a593Smuzhiyun #define MM_NUM_TSBS 2 89*4882a593Smuzhiyun #else 90*4882a593Smuzhiyun #define MM_NUM_TSBS 1 91*4882a593Smuzhiyun #endif 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun /* ADI tags are stored when a page is swapped out and the storage for 94*4882a593Smuzhiyun * tags is allocated dynamically. There is a tag storage descriptor 95*4882a593Smuzhiyun * associated with each set of tag storage pages. Tag storage descriptors 96*4882a593Smuzhiyun * are allocated dynamically. Since kernel will allocate a full page for 97*4882a593Smuzhiyun * each tag storage descriptor, we can store up to 98*4882a593Smuzhiyun * PAGE_SIZE/sizeof(tag storage descriptor) descriptors on that page. 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun typedef struct { 101*4882a593Smuzhiyun unsigned long start; /* Start address for this tag storage */ 102*4882a593Smuzhiyun unsigned long end; /* Last address for tag storage */ 103*4882a593Smuzhiyun unsigned char *tags; /* Where the tags are */ 104*4882a593Smuzhiyun unsigned long tag_users; /* number of references to descriptor */ 105*4882a593Smuzhiyun } tag_storage_desc_t; 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun typedef struct { 108*4882a593Smuzhiyun spinlock_t lock; 109*4882a593Smuzhiyun unsigned long sparc64_ctx_val; 110*4882a593Smuzhiyun unsigned long hugetlb_pte_count; 111*4882a593Smuzhiyun unsigned long thp_pte_count; 112*4882a593Smuzhiyun struct tsb_config tsb_block[MM_NUM_TSBS]; 113*4882a593Smuzhiyun struct hv_tsb_descr tsb_descr[MM_NUM_TSBS]; 114*4882a593Smuzhiyun void *vdso; 115*4882a593Smuzhiyun bool adi; 116*4882a593Smuzhiyun tag_storage_desc_t *tag_store; 117*4882a593Smuzhiyun spinlock_t tag_lock; 118*4882a593Smuzhiyun } mm_context_t; 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */ 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun #define TSB_CONFIG_TSB 0x00 123*4882a593Smuzhiyun #define TSB_CONFIG_RSS_LIMIT 0x08 124*4882a593Smuzhiyun #define TSB_CONFIG_NENTRIES 0x10 125*4882a593Smuzhiyun #define TSB_CONFIG_REG_VAL 0x18 126*4882a593Smuzhiyun #define TSB_CONFIG_MAP_VADDR 0x20 127*4882a593Smuzhiyun #define TSB_CONFIG_MAP_PTE 0x28 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun #endif /* __MMU_H */ 130