1994da93dSChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */ 2994da93dSChristophe Leroy #ifndef _ASM_POWERPC_MMU_8XX_H_ 3994da93dSChristophe Leroy #define _ASM_POWERPC_MMU_8XX_H_ 4994da93dSChristophe Leroy /* 5994da93dSChristophe Leroy * PPC8xx support 6994da93dSChristophe Leroy */ 7994da93dSChristophe Leroy 8994da93dSChristophe Leroy /* Control/status registers for the MPC8xx. 9994da93dSChristophe Leroy * A write operation to these registers causes serialized access. 10994da93dSChristophe Leroy * During software tablewalk, the registers used perform mask/shift-add 11994da93dSChristophe Leroy * operations when written/read. A TLB entry is created when the Mx_RPN 12994da93dSChristophe Leroy * is written, and the contents of several registers are used to 13994da93dSChristophe Leroy * create the entry. 14994da93dSChristophe Leroy */ 15994da93dSChristophe Leroy #define SPRN_MI_CTR 784 /* Instruction TLB control register */ 16994da93dSChristophe Leroy #define MI_GPM 0x80000000 /* Set domain manager mode */ 17994da93dSChristophe Leroy #define MI_PPM 0x40000000 /* Set subpage protection */ 18994da93dSChristophe Leroy #define MI_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ 19994da93dSChristophe Leroy #define MI_RSV4I 0x08000000 /* Reserve 4 TLB entries */ 20994da93dSChristophe Leroy #define MI_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ 21994da93dSChristophe Leroy #define MI_IDXMASK 0x00001f00 /* TLB index to be loaded */ 22994da93dSChristophe Leroy 23994da93dSChristophe Leroy /* These are the Ks and Kp from the PowerPC books. For proper operation, 24994da93dSChristophe Leroy * Ks = 0, Kp = 1. 25994da93dSChristophe Leroy */ 26994da93dSChristophe Leroy #define SPRN_MI_AP 786 27994da93dSChristophe Leroy #define MI_Ks 0x80000000 /* Should not be set */ 28994da93dSChristophe Leroy #define MI_Kp 0x40000000 /* Should always be set */ 29994da93dSChristophe Leroy 30994da93dSChristophe Leroy /* 31994da93dSChristophe Leroy * All pages' PP data bits are set to either 001 or 011 by copying _PAGE_EXEC 32994da93dSChristophe Leroy * into bit 21 in the ITLBmiss handler (bit 21 is the middle bit), which means 33994da93dSChristophe Leroy * respectively NA for All or X for Supervisor and no access for User. 34994da93dSChristophe Leroy * Then we use the APG to say whether accesses are according to Page rules or 35994da93dSChristophe Leroy * "all Supervisor" rules (Access to all) 3633fe43cfSChristophe Leroy * _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say 3733fe43cfSChristophe Leroy * "all User" rules, that will lead to NA for all. 3833fe43cfSChristophe Leroy * Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED 3933fe43cfSChristophe Leroy * 0 => Kernel => 11 (all accesses performed according as user iaw page definition) 4033fe43cfSChristophe Leroy * 1 => Kernel+Accessed => 01 (all accesses performed according to page definition) 4133fe43cfSChristophe Leroy * 2 => User => 11 (all accesses performed according as user iaw page definition) 4213dac4e3SChristophe Leroy * 3 => User+Accessed => 10 (all accesses performed according to swaped page definition) for KUEP 4333fe43cfSChristophe Leroy * 4-15 => Not Used 44994da93dSChristophe Leroy */ 4513dac4e3SChristophe Leroy #define MI_APG_INIT 0xde000000 4606fbe81bSChristophe Leroy 47994da93dSChristophe Leroy /* The effective page number register. When read, contains the information 48994da93dSChristophe Leroy * about the last instruction TLB miss. When MI_RPN is written, bits in 49994da93dSChristophe Leroy * this register are used to create the TLB entry. 50994da93dSChristophe Leroy */ 51994da93dSChristophe Leroy #define SPRN_MI_EPN 787 52994da93dSChristophe Leroy #define MI_EPNMASK 0xfffff000 /* Effective page number for entry */ 53994da93dSChristophe Leroy #define MI_EVALID 0x00000200 /* Entry is valid */ 54994da93dSChristophe Leroy #define MI_ASIDMASK 0x0000000f /* ASID match value */ 55994da93dSChristophe Leroy /* Reset value is undefined */ 56994da93dSChristophe Leroy 57994da93dSChristophe Leroy /* A "level 1" or "segment" or whatever you want to call it register. 58994da93dSChristophe Leroy * For the instruction TLB, it contains bits that get loaded into the 59994da93dSChristophe Leroy * TLB entry when the MI_RPN is written. 60994da93dSChristophe Leroy */ 61994da93dSChristophe Leroy #define SPRN_MI_TWC 789 62994da93dSChristophe Leroy #define MI_APG 0x000001e0 /* Access protection group (0) */ 63994da93dSChristophe Leroy #define MI_GUARDED 0x00000010 /* Guarded storage */ 64994da93dSChristophe Leroy #define MI_PSMASK 0x0000000c /* Mask of page size bits */ 65994da93dSChristophe Leroy #define MI_PS8MEG 0x0000000c /* 8M page size */ 66994da93dSChristophe Leroy #define MI_PS512K 0x00000004 /* 512K page size */ 67994da93dSChristophe Leroy #define MI_PS4K_16K 0x00000000 /* 4K or 16K page size */ 68994da93dSChristophe Leroy #define MI_SVALID 0x00000001 /* Segment entry is valid */ 69994da93dSChristophe Leroy /* Reset value is undefined */ 70994da93dSChristophe Leroy 71994da93dSChristophe Leroy /* Real page number. Defined by the pte. Writing this register 72994da93dSChristophe Leroy * causes a TLB entry to be created for the instruction TLB, using 73994da93dSChristophe Leroy * additional information from the MI_EPN, and MI_TWC registers. 74994da93dSChristophe Leroy */ 75994da93dSChristophe Leroy #define SPRN_MI_RPN 790 76994da93dSChristophe Leroy #define MI_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ 77994da93dSChristophe Leroy 78994da93dSChristophe Leroy /* Define an RPN value for mapping kernel memory to large virtual 79994da93dSChristophe Leroy * pages for boot initialization. This has real page number of 0, 80994da93dSChristophe Leroy * large page size, shared page, cache enabled, and valid. 81994da93dSChristophe Leroy * Also mark all subpages valid and write access. 82994da93dSChristophe Leroy */ 83994da93dSChristophe Leroy #define MI_BOOTINIT 0x000001fd 84994da93dSChristophe Leroy 85994da93dSChristophe Leroy #define SPRN_MD_CTR 792 /* Data TLB control register */ 86994da93dSChristophe Leroy #define MD_GPM 0x80000000 /* Set domain manager mode */ 87994da93dSChristophe Leroy #define MD_PPM 0x40000000 /* Set subpage protection */ 88994da93dSChristophe Leroy #define MD_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ 89994da93dSChristophe Leroy #define MD_WTDEF 0x10000000 /* Set writethrough when MMU dis */ 90994da93dSChristophe Leroy #define MD_RSV4I 0x08000000 /* Reserve 4 TLB entries */ 91994da93dSChristophe Leroy #define MD_TWAM 0x04000000 /* Use 4K page hardware assist */ 92994da93dSChristophe Leroy #define MD_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ 93994da93dSChristophe Leroy #define MD_IDXMASK 0x00001f00 /* TLB index to be loaded */ 94994da93dSChristophe Leroy 95994da93dSChristophe Leroy #define SPRN_M_CASID 793 /* Address space ID (context) to match */ 96994da93dSChristophe Leroy #define MC_ASIDMASK 0x0000000f /* Bits used for ASID value */ 97994da93dSChristophe Leroy 98994da93dSChristophe Leroy 99994da93dSChristophe Leroy /* These are the Ks and Kp from the PowerPC books. For proper operation, 100994da93dSChristophe Leroy * Ks = 0, Kp = 1. 101994da93dSChristophe Leroy */ 102994da93dSChristophe Leroy #define SPRN_MD_AP 794 103994da93dSChristophe Leroy #define MD_Ks 0x80000000 /* Should not be set */ 104994da93dSChristophe Leroy #define MD_Kp 0x40000000 /* Should always be set */ 105994da93dSChristophe Leroy 10633fe43cfSChristophe Leroy /* See explanation above at the definition of MI_APG_INIT */ 10733fe43cfSChristophe Leroy #define MD_APG_INIT 0xdc000000 10833fe43cfSChristophe Leroy #define MD_APG_KUAP 0xde000000 1092679f9bdSChristophe Leroy 110994da93dSChristophe Leroy /* The effective page number register. When read, contains the information 111994da93dSChristophe Leroy * about the last instruction TLB miss. When MD_RPN is written, bits in 112994da93dSChristophe Leroy * this register are used to create the TLB entry. 113994da93dSChristophe Leroy */ 114994da93dSChristophe Leroy #define SPRN_MD_EPN 795 115994da93dSChristophe Leroy #define MD_EPNMASK 0xfffff000 /* Effective page number for entry */ 116994da93dSChristophe Leroy #define MD_EVALID 0x00000200 /* Entry is valid */ 117994da93dSChristophe Leroy #define MD_ASIDMASK 0x0000000f /* ASID match value */ 118994da93dSChristophe Leroy /* Reset value is undefined */ 119994da93dSChristophe Leroy 120994da93dSChristophe Leroy /* The pointer to the base address of the first level page table. 121994da93dSChristophe Leroy * During a software tablewalk, reading this register provides the address 122994da93dSChristophe Leroy * of the entry associated with MD_EPN. 123994da93dSChristophe Leroy */ 124994da93dSChristophe Leroy #define SPRN_M_TWB 796 125994da93dSChristophe Leroy #define M_L1TB 0xfffff000 /* Level 1 table base address */ 126994da93dSChristophe Leroy #define M_L1INDX 0x00000ffc /* Level 1 index, when read */ 127994da93dSChristophe Leroy /* Reset value is undefined */ 128994da93dSChristophe Leroy 129994da93dSChristophe Leroy /* A "level 1" or "segment" or whatever you want to call it register. 130994da93dSChristophe Leroy * For the data TLB, it contains bits that get loaded into the TLB entry 131994da93dSChristophe Leroy * when the MD_RPN is written. It is also provides the hardware assist 132994da93dSChristophe Leroy * for finding the PTE address during software tablewalk. 133994da93dSChristophe Leroy */ 134994da93dSChristophe Leroy #define SPRN_MD_TWC 797 135994da93dSChristophe Leroy #define MD_L2TB 0xfffff000 /* Level 2 table base address */ 136994da93dSChristophe Leroy #define MD_L2INDX 0xfffffe00 /* Level 2 index (*pte), when read */ 137994da93dSChristophe Leroy #define MD_APG 0x000001e0 /* Access protection group (0) */ 138994da93dSChristophe Leroy #define MD_GUARDED 0x00000010 /* Guarded storage */ 139994da93dSChristophe Leroy #define MD_PSMASK 0x0000000c /* Mask of page size bits */ 140994da93dSChristophe Leroy #define MD_PS8MEG 0x0000000c /* 8M page size */ 141994da93dSChristophe Leroy #define MD_PS512K 0x00000004 /* 512K page size */ 142994da93dSChristophe Leroy #define MD_PS4K_16K 0x00000000 /* 4K or 16K page size */ 143994da93dSChristophe Leroy #define MD_WT 0x00000002 /* Use writethrough page attribute */ 144994da93dSChristophe Leroy #define MD_SVALID 0x00000001 /* Segment entry is valid */ 145994da93dSChristophe Leroy /* Reset value is undefined */ 146994da93dSChristophe Leroy 147994da93dSChristophe Leroy 148994da93dSChristophe Leroy /* Real page number. Defined by the pte. Writing this register 149994da93dSChristophe Leroy * causes a TLB entry to be created for the data TLB, using 150994da93dSChristophe Leroy * additional information from the MD_EPN, and MD_TWC registers. 151994da93dSChristophe Leroy */ 152994da93dSChristophe Leroy #define SPRN_MD_RPN 798 153994da93dSChristophe Leroy #define MD_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ 154994da93dSChristophe Leroy 155994da93dSChristophe Leroy /* This is a temporary storage register that could be used to save 156994da93dSChristophe Leroy * a processor working register during a tablewalk. 157994da93dSChristophe Leroy */ 158994da93dSChristophe Leroy #define SPRN_M_TW 799 159994da93dSChristophe Leroy 160fca5c1e9SChristophe Leroy #if defined(CONFIG_PPC_4K_PAGES) 161fca5c1e9SChristophe Leroy #define mmu_virtual_psize MMU_PAGE_4K 162fca5c1e9SChristophe Leroy #elif defined(CONFIG_PPC_16K_PAGES) 163fca5c1e9SChristophe Leroy #define mmu_virtual_psize MMU_PAGE_16K 164fca5c1e9SChristophe Leroy #define PTE_FRAG_NR 4 165fca5c1e9SChristophe Leroy #define PTE_FRAG_SIZE_SHIFT 12 166fca5c1e9SChristophe Leroy #define PTE_FRAG_SIZE (1UL << 12) 167fca5c1e9SChristophe Leroy #else 168fca5c1e9SChristophe Leroy #error "Unsupported PAGE_SIZE" 169fca5c1e9SChristophe Leroy #endif 170fca5c1e9SChristophe Leroy 171fca5c1e9SChristophe Leroy #define mmu_linear_psize MMU_PAGE_8M 172fca5c1e9SChristophe Leroy 1739132a2e8SChristophe Leroy #define MODULES_VADDR (PAGE_OFFSET - SZ_256M) 1749132a2e8SChristophe Leroy #define MODULES_END PAGE_OFFSET 1759132a2e8SChristophe Leroy 176994da93dSChristophe Leroy #ifndef __ASSEMBLY__ 177fca5c1e9SChristophe Leroy 178fca5c1e9SChristophe Leroy #include <linux/mmdebug.h> 179a6a8f7c4SChristophe Leroy #include <linux/sizes.h> 180fca5c1e9SChristophe Leroy 181f76c8f6dSChristophe Leroy void mmu_pin_tlb(unsigned long top, bool readonly); 182f76c8f6dSChristophe Leroy 183994da93dSChristophe Leroy typedef struct { 184994da93dSChristophe Leroy unsigned int id; 185994da93dSChristophe Leroy unsigned int active; 186c102f076SChristophe Leroy void __user *vdso; 18755c8fc3fSChristophe Leroy void *pte_frag; 188994da93dSChristophe Leroy } mm_context_t; 189994da93dSChristophe Leroy 190994da93dSChristophe Leroy #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000) 191994da93dSChristophe Leroy 192*b04c2da4SChristophe Leroy /* 193*b04c2da4SChristophe Leroy * Page size definitions for 8xx 194994da93dSChristophe Leroy * 195994da93dSChristophe Leroy * shift : is the "PAGE_SHIFT" value for that page size 196994da93dSChristophe Leroy * 197994da93dSChristophe Leroy */ 198994da93dSChristophe Leroy struct mmu_psize_def { 199994da93dSChristophe Leroy unsigned int shift; /* number of bits */ 200994da93dSChristophe Leroy }; 201994da93dSChristophe Leroy 202994da93dSChristophe Leroy extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; 203994da93dSChristophe Leroy 204994da93dSChristophe Leroy static inline int shift_to_mmu_psize(unsigned int shift) 205994da93dSChristophe Leroy { 206994da93dSChristophe Leroy int psize; 207994da93dSChristophe Leroy 208994da93dSChristophe Leroy for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) 209994da93dSChristophe Leroy if (mmu_psize_defs[psize].shift == shift) 210994da93dSChristophe Leroy return psize; 211994da93dSChristophe Leroy return -1; 212994da93dSChristophe Leroy } 213994da93dSChristophe Leroy 214994da93dSChristophe Leroy static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) 215994da93dSChristophe Leroy { 216994da93dSChristophe Leroy if (mmu_psize_defs[mmu_psize].shift) 217994da93dSChristophe Leroy return mmu_psize_defs[mmu_psize].shift; 218994da93dSChristophe Leroy BUG(); 219994da93dSChristophe Leroy } 220994da93dSChristophe Leroy 221a6a8f7c4SChristophe Leroy static inline bool arch_vmap_try_size(unsigned long addr, unsigned long end, u64 pfn, 222a6a8f7c4SChristophe Leroy unsigned int max_page_shift, unsigned long size) 223a6a8f7c4SChristophe Leroy { 224a6a8f7c4SChristophe Leroy if (end - addr < size) 225a6a8f7c4SChristophe Leroy return false; 226a6a8f7c4SChristophe Leroy 227a6a8f7c4SChristophe Leroy if ((1UL << max_page_shift) < size) 228a6a8f7c4SChristophe Leroy return false; 229a6a8f7c4SChristophe Leroy 230a6a8f7c4SChristophe Leroy if (!IS_ALIGNED(addr, size)) 231a6a8f7c4SChristophe Leroy return false; 232a6a8f7c4SChristophe Leroy 233a6a8f7c4SChristophe Leroy if (!IS_ALIGNED(PFN_PHYS(pfn), size)) 234a6a8f7c4SChristophe Leroy return false; 235a6a8f7c4SChristophe Leroy 236a6a8f7c4SChristophe Leroy return true; 237a6a8f7c4SChristophe Leroy } 238a6a8f7c4SChristophe Leroy 239a6a8f7c4SChristophe Leroy static inline unsigned long arch_vmap_pte_range_map_size(unsigned long addr, unsigned long end, 240a6a8f7c4SChristophe Leroy u64 pfn, unsigned int max_page_shift) 241a6a8f7c4SChristophe Leroy { 242a6a8f7c4SChristophe Leroy if (arch_vmap_try_size(addr, end, pfn, max_page_shift, SZ_512K)) 243a6a8f7c4SChristophe Leroy return SZ_512K; 244a6a8f7c4SChristophe Leroy if (PAGE_SIZE == SZ_16K) 245a6a8f7c4SChristophe Leroy return SZ_16K; 246a6a8f7c4SChristophe Leroy if (arch_vmap_try_size(addr, end, pfn, max_page_shift, SZ_16K)) 247a6a8f7c4SChristophe Leroy return SZ_16K; 248a6a8f7c4SChristophe Leroy return PAGE_SIZE; 249a6a8f7c4SChristophe Leroy } 250a6a8f7c4SChristophe Leroy #define arch_vmap_pte_range_map_size arch_vmap_pte_range_map_size 251a6a8f7c4SChristophe Leroy 252a6a8f7c4SChristophe Leroy static inline int arch_vmap_pte_supported_shift(unsigned long size) 253a6a8f7c4SChristophe Leroy { 254a6a8f7c4SChristophe Leroy if (size >= SZ_512K) 255a6a8f7c4SChristophe Leroy return 19; 256a6a8f7c4SChristophe Leroy else if (size >= SZ_16K) 257a6a8f7c4SChristophe Leroy return 14; 258a6a8f7c4SChristophe Leroy else 259a6a8f7c4SChristophe Leroy return PAGE_SHIFT; 260a6a8f7c4SChristophe Leroy } 261a6a8f7c4SChristophe Leroy #define arch_vmap_pte_supported_shift arch_vmap_pte_supported_shift 262a6a8f7c4SChristophe Leroy 263994da93dSChristophe Leroy /* patch sites */ 2641251288eSChristophe Leroy extern s32 patch__itlbmiss_exit_1, patch__dtlbmiss_exit_1; 265994da93dSChristophe Leroy extern s32 patch__itlbmiss_perf, patch__dtlbmiss_perf; 266994da93dSChristophe Leroy 267994da93dSChristophe Leroy #endif /* !__ASSEMBLY__ */ 268994da93dSChristophe Leroy 269994da93dSChristophe Leroy #endif /* _ASM_POWERPC_MMU_8XX_H_ */ 270