diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-08 04:21:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-08 04:21:35 +0000 |
commit | 7b642cd94bb96385cbdbb36a1952f129af6b1bbb (patch) | |
tree | e7c4209372da8a2fa745aaa3e99d062e54d0f556 /arch/powerpc/include/asm/nohash | |
parent | Adding debian version 4.19.289-2. (diff) | |
download | linux-7b642cd94bb96385cbdbb36a1952f129af6b1bbb.tar.xz linux-7b642cd94bb96385cbdbb36a1952f129af6b1bbb.zip |
Merging upstream version 4.19.304.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/powerpc/include/asm/nohash')
-rw-r--r-- | arch/powerpc/include/asm/nohash/32/mmu-40x.h | 68 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/32/mmu-44x.h | 153 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/32/mmu-8xx.h | 244 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/32/mmu.h | 23 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/64/mmu.h | 12 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/64/pgtable.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/mmu-book3e.h | 313 | ||||
-rw-r--r-- | arch/powerpc/include/asm/nohash/mmu.h | 11 |
8 files changed, 825 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/nohash/32/mmu-40x.h b/arch/powerpc/include/asm/nohash/32/mmu-40x.h new file mode 100644 index 000000000..74f4edb59 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/32/mmu-40x.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_MMU_40X_H_ +#define _ASM_POWERPC_MMU_40X_H_ + +/* + * PPC40x support + */ + +#define PPC40X_TLB_SIZE 64 + +/* + * TLB entries are defined by a "high" tag portion and a "low" data + * portion. On all architectures, the data portion is 32-bits. + * + * TLB entries are managed entirely under software control by reading, + * writing, and searchoing using the 4xx-specific tlbre, tlbwr, and tlbsx + * instructions. + */ + +#define TLB_LO 1 +#define TLB_HI 0 + +#define TLB_DATA TLB_LO +#define TLB_TAG TLB_HI + +/* Tag portion */ + +#define TLB_EPN_MASK 0xFFFFFC00 /* Effective Page Number */ +#define TLB_PAGESZ_MASK 0x00000380 +#define TLB_PAGESZ(x) (((x) & 0x7) << 7) +#define PAGESZ_1K 0 +#define PAGESZ_4K 1 +#define PAGESZ_16K 2 +#define PAGESZ_64K 3 +#define PAGESZ_256K 4 +#define PAGESZ_1M 5 +#define PAGESZ_4M 6 +#define PAGESZ_16M 7 +#define TLB_VALID 0x00000040 /* Entry is valid */ + +/* Data portion */ + +#define TLB_RPN_MASK 0xFFFFFC00 /* Real Page Number */ +#define TLB_PERM_MASK 0x00000300 +#define TLB_EX 0x00000200 /* Instruction execution allowed */ +#define TLB_WR 0x00000100 /* Writes permitted */ +#define TLB_ZSEL_MASK 0x000000F0 +#define TLB_ZSEL(x) (((x) & 0xF) << 4) +#define TLB_ATTR_MASK 0x0000000F +#define TLB_W 0x00000008 /* Caching is write-through */ +#define TLB_I 0x00000004 /* Caching is inhibited */ +#define TLB_M 0x00000002 /* Memory is coherent */ +#define TLB_G 0x00000001 /* Memory is guarded from prefetch */ + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned int id; + unsigned int active; + unsigned long vdso_base; +} mm_context_t; + +#endif /* !__ASSEMBLY__ */ + +#define mmu_virtual_psize MMU_PAGE_4K +#define mmu_linear_psize MMU_PAGE_256M + +#endif /* _ASM_POWERPC_MMU_40X_H_ */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu-44x.h b/arch/powerpc/include/asm/nohash/32/mmu-44x.h new file mode 100644 index 000000000..295b3dbb2 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/32/mmu-44x.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_MMU_44X_H_ +#define _ASM_POWERPC_MMU_44X_H_ +/* + * PPC440 support + */ + +#include <asm/asm-const.h> + +#define PPC44x_MMUCR_TID 0x000000ff +#define PPC44x_MMUCR_STS 0x00010000 + +#define PPC44x_TLB_PAGEID 0 +#define PPC44x_TLB_XLAT 1 +#define PPC44x_TLB_ATTRIB 2 + +/* Page identification fields */ +#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */ +#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */ +#define PPC44x_TLB_TS 0x00000100 /* Translation address space */ +#define PPC44x_TLB_1K 0x00000000 /* Page sizes */ +#define PPC44x_TLB_4K 0x00000010 +#define PPC44x_TLB_16K 0x00000020 +#define PPC44x_TLB_64K 0x00000030 +#define PPC44x_TLB_256K 0x00000040 +#define PPC44x_TLB_1M 0x00000050 +#define PPC44x_TLB_16M 0x00000070 +#define PPC44x_TLB_256M 0x00000090 + +/* Translation fields */ +#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */ +#define PPC44x_TLB_ERPN_MASK 0x0000000f + +/* Storage attribute and access control fields */ +#define PPC44x_TLB_ATTR_MASK 0x0000ff80 +#define PPC44x_TLB_U0 0x00008000 /* User 0 */ +#define PPC44x_TLB_U1 0x00004000 /* User 1 */ +#define PPC44x_TLB_U2 0x00002000 /* User 2 */ +#define PPC44x_TLB_U3 0x00001000 /* User 3 */ +#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */ +#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */ +#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */ +#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */ +#define PPC44x_TLB_E 0x00000080 /* Memory is little endian */ + +#define PPC44x_TLB_PERM_MASK 0x0000003f +#define PPC44x_TLB_UX 0x00000020 /* User execution */ +#define PPC44x_TLB_UW 0x00000010 /* User write */ +#define PPC44x_TLB_UR 0x00000008 /* User read */ +#define PPC44x_TLB_SX 0x00000004 /* Super execution */ +#define PPC44x_TLB_SW 0x00000002 /* Super write */ +#define PPC44x_TLB_SR 0x00000001 /* Super read */ + +/* Number of TLB entries */ +#define PPC44x_TLB_SIZE 64 + +/* 47x bits */ +#define PPC47x_MMUCR_TID 0x0000ffff +#define PPC47x_MMUCR_STS 0x00010000 + +/* Page identification fields */ +#define PPC47x_TLB0_EPN_MASK 0xfffff000 /* Effective Page Number */ +#define PPC47x_TLB0_VALID 0x00000800 /* Valid flag */ +#define PPC47x_TLB0_TS 0x00000400 /* Translation address space */ +#define PPC47x_TLB0_4K 0x00000000 +#define PPC47x_TLB0_16K 0x00000010 +#define PPC47x_TLB0_64K 0x00000030 +#define PPC47x_TLB0_1M 0x00000070 +#define PPC47x_TLB0_16M 0x000000f0 +#define PPC47x_TLB0_256M 0x000001f0 +#define PPC47x_TLB0_1G 0x000003f0 +#define PPC47x_TLB0_BOLTED_R 0x00000008 /* tlbre only */ + +/* Translation fields */ +#define PPC47x_TLB1_RPN_MASK 0xfffff000 /* Real Page Number */ +#define PPC47x_TLB1_ERPN_MASK 0x000003ff + +/* Storage attribute and access control fields */ +#define PPC47x_TLB2_ATTR_MASK 0x0003ff80 +#define PPC47x_TLB2_IL1I 0x00020000 /* Memory is guarded */ +#define PPC47x_TLB2_IL1D 0x00010000 /* Memory is guarded */ +#define PPC47x_TLB2_U0 0x00008000 /* User 0 */ +#define PPC47x_TLB2_U1 0x00004000 /* User 1 */ +#define PPC47x_TLB2_U2 0x00002000 /* User 2 */ +#define PPC47x_TLB2_U3 0x00001000 /* User 3 */ +#define PPC47x_TLB2_W 0x00000800 /* Caching is write-through */ +#define PPC47x_TLB2_I 0x00000400 /* Caching is inhibited */ +#define PPC47x_TLB2_M 0x00000200 /* Memory is coherent */ +#define PPC47x_TLB2_G 0x00000100 /* Memory is guarded */ +#define PPC47x_TLB2_E 0x00000080 /* Memory is little endian */ +#define PPC47x_TLB2_PERM_MASK 0x0000003f +#define PPC47x_TLB2_UX 0x00000020 /* User execution */ +#define PPC47x_TLB2_UW 0x00000010 /* User write */ +#define PPC47x_TLB2_UR 0x00000008 /* User read */ +#define PPC47x_TLB2_SX 0x00000004 /* Super execution */ +#define PPC47x_TLB2_SW 0x00000002 /* Super write */ +#define PPC47x_TLB2_SR 0x00000001 /* Super read */ +#define PPC47x_TLB2_U_RWX (PPC47x_TLB2_UX|PPC47x_TLB2_UW|PPC47x_TLB2_UR) +#define PPC47x_TLB2_S_RWX (PPC47x_TLB2_SX|PPC47x_TLB2_SW|PPC47x_TLB2_SR) +#define PPC47x_TLB2_S_RW (PPC47x_TLB2_SW | PPC47x_TLB2_SR) +#define PPC47x_TLB2_IMG (PPC47x_TLB2_I | PPC47x_TLB2_M | PPC47x_TLB2_G) + +#ifndef __ASSEMBLY__ + +extern unsigned int tlb_44x_hwater; +extern unsigned int tlb_44x_index; + +typedef struct { + unsigned int id; + unsigned int active; + unsigned long vdso_base; +} mm_context_t; + +#endif /* !__ASSEMBLY__ */ + +#ifndef CONFIG_PPC_EARLY_DEBUG_44x +#define PPC44x_EARLY_TLBS 1 +#else +#define PPC44x_EARLY_TLBS 2 +#define PPC44x_EARLY_DEBUG_VIRTADDR (ASM_CONST(0xf0000000) \ + | (ASM_CONST(CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW) & 0xffff)) +#endif + +/* Size of the TLBs used for pinning in lowmem */ +#define PPC_PIN_SIZE (1 << 28) /* 256M */ + +#if defined(CONFIG_PPC_4K_PAGES) +#define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_4K +#define mmu_virtual_psize MMU_PAGE_4K +#elif defined(CONFIG_PPC_16K_PAGES) +#define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_16K +#define mmu_virtual_psize MMU_PAGE_16K +#elif defined(CONFIG_PPC_64K_PAGES) +#define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_64K +#define mmu_virtual_psize MMU_PAGE_64K +#elif defined(CONFIG_PPC_256K_PAGES) +#define PPC44x_TLBE_SIZE PPC44x_TLB_256K +#define mmu_virtual_psize MMU_PAGE_256K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define mmu_linear_psize MMU_PAGE_256M + +#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) +#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2) +#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) +#define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT) + +#endif /* _ASM_POWERPC_MMU_44X_H_ */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h new file mode 100644 index 000000000..193f53116 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_MMU_8XX_H_ +#define _ASM_POWERPC_MMU_8XX_H_ +/* + * PPC8xx support + */ + +/* Control/status registers for the MPC8xx. + * A write operation to these registers causes serialized access. + * During software tablewalk, the registers used perform mask/shift-add + * operations when written/read. A TLB entry is created when the Mx_RPN + * is written, and the contents of several registers are used to + * create the entry. + */ +#define SPRN_MI_CTR 784 /* Instruction TLB control register */ +#define MI_GPM 0x80000000 /* Set domain manager mode */ +#define MI_PPM 0x40000000 /* Set subpage protection */ +#define MI_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ +#define MI_RSV4I 0x08000000 /* Reserve 4 TLB entries */ +#define MI_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ +#define MI_IDXMASK 0x00001f00 /* TLB index to be loaded */ +#define MI_RESETVAL 0x00000000 /* Value of register at reset */ + +/* These are the Ks and Kp from the PowerPC books. For proper operation, + * Ks = 0, Kp = 1. + */ +#define SPRN_MI_AP 786 +#define MI_Ks 0x80000000 /* Should not be set */ +#define MI_Kp 0x40000000 /* Should always be set */ + +/* + * All pages' PP data bits are set to either 001 or 011 by copying _PAGE_EXEC + * into bit 21 in the ITLBmiss handler (bit 21 is the middle bit), which means + * respectively NA for All or X for Supervisor and no access for User. + * Then we use the APG to say whether accesses are according to Page rules or + * "all Supervisor" rules (Access to all) + * Therefore, we define 2 APG groups. lsb is _PMD_USER + * 0 => No user => 01 (all accesses performed according to page definition) + * 1 => User => 00 (all accesses performed as supervisor iaw page definition) + * We define all 16 groups so that all other bits of APG can take any value + */ +#define MI_APG_INIT 0x44444444 + +/* The effective page number register. When read, contains the information + * about the last instruction TLB miss. When MI_RPN is written, bits in + * this register are used to create the TLB entry. + */ +#define SPRN_MI_EPN 787 +#define MI_EPNMASK 0xfffff000 /* Effective page number for entry */ +#define MI_EVALID 0x00000200 /* Entry is valid */ +#define MI_ASIDMASK 0x0000000f /* ASID match value */ + /* Reset value is undefined */ + +/* A "level 1" or "segment" or whatever you want to call it register. + * For the instruction TLB, it contains bits that get loaded into the + * TLB entry when the MI_RPN is written. + */ +#define SPRN_MI_TWC 789 +#define MI_APG 0x000001e0 /* Access protection group (0) */ +#define MI_GUARDED 0x00000010 /* Guarded storage */ +#define MI_PSMASK 0x0000000c /* Mask of page size bits */ +#define MI_PS8MEG 0x0000000c /* 8M page size */ +#define MI_PS512K 0x00000004 /* 512K page size */ +#define MI_PS4K_16K 0x00000000 /* 4K or 16K page size */ +#define MI_SVALID 0x00000001 /* Segment entry is valid */ + /* Reset value is undefined */ + +/* Real page number. Defined by the pte. Writing this register + * causes a TLB entry to be created for the instruction TLB, using + * additional information from the MI_EPN, and MI_TWC registers. + */ +#define SPRN_MI_RPN 790 +#define MI_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ + +/* Define an RPN value for mapping kernel memory to large virtual + * pages for boot initialization. This has real page number of 0, + * large page size, shared page, cache enabled, and valid. + * Also mark all subpages valid and write access. + */ +#define MI_BOOTINIT 0x000001fd + +#define SPRN_MD_CTR 792 /* Data TLB control register */ +#define MD_GPM 0x80000000 /* Set domain manager mode */ +#define MD_PPM 0x40000000 /* Set subpage protection */ +#define MD_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ +#define MD_WTDEF 0x10000000 /* Set writethrough when MMU dis */ +#define MD_RSV4I 0x08000000 /* Reserve 4 TLB entries */ +#define MD_TWAM 0x04000000 /* Use 4K page hardware assist */ +#define MD_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ +#define MD_IDXMASK 0x00001f00 /* TLB index to be loaded */ +#define MD_RESETVAL 0x04000000 /* Value of register at reset */ + +#define SPRN_M_CASID 793 /* Address space ID (context) to match */ +#define MC_ASIDMASK 0x0000000f /* Bits used for ASID value */ + + +/* These are the Ks and Kp from the PowerPC books. For proper operation, + * Ks = 0, Kp = 1. + */ +#define SPRN_MD_AP 794 +#define MD_Ks 0x80000000 /* Should not be set */ +#define MD_Kp 0x40000000 /* Should always be set */ + +/* + * All pages' PP data bits are set to either 000 or 011 or 001, which means + * respectively RW for Supervisor and no access for User, or RO for + * Supervisor and no access for user and NA for ALL. + * Then we use the APG to say whether accesses are according to Page rules or + * "all Supervisor" rules (Access to all) + * Therefore, we define 2 APG groups. lsb is _PMD_USER + * 0 => No user => 01 (all accesses performed according to page definition) + * 1 => User => 00 (all accesses performed as supervisor iaw page definition) + * We define all 16 groups so that all other bits of APG can take any value + */ +#define MD_APG_INIT 0x44444444 + +/* The effective page number register. When read, contains the information + * about the last instruction TLB miss. When MD_RPN is written, bits in + * this register are used to create the TLB entry. + */ +#define SPRN_MD_EPN 795 +#define MD_EPNMASK 0xfffff000 /* Effective page number for entry */ +#define MD_EVALID 0x00000200 /* Entry is valid */ +#define MD_ASIDMASK 0x0000000f /* ASID match value */ + /* Reset value is undefined */ + +/* The pointer to the base address of the first level page table. + * During a software tablewalk, reading this register provides the address + * of the entry associated with MD_EPN. + */ +#define SPRN_M_TWB 796 +#define M_L1TB 0xfffff000 /* Level 1 table base address */ +#define M_L1INDX 0x00000ffc /* Level 1 index, when read */ + /* Reset value is undefined */ + +/* A "level 1" or "segment" or whatever you want to call it register. + * For the data TLB, it contains bits that get loaded into the TLB entry + * when the MD_RPN is written. It is also provides the hardware assist + * for finding the PTE address during software tablewalk. + */ +#define SPRN_MD_TWC 797 +#define MD_L2TB 0xfffff000 /* Level 2 table base address */ +#define MD_L2INDX 0xfffffe00 /* Level 2 index (*pte), when read */ +#define MD_APG 0x000001e0 /* Access protection group (0) */ +#define MD_GUARDED 0x00000010 /* Guarded storage */ +#define MD_PSMASK 0x0000000c /* Mask of page size bits */ +#define MD_PS8MEG 0x0000000c /* 8M page size */ +#define MD_PS512K 0x00000004 /* 512K page size */ +#define MD_PS4K_16K 0x00000000 /* 4K or 16K page size */ +#define MD_WT 0x00000002 /* Use writethrough page attribute */ +#define MD_SVALID 0x00000001 /* Segment entry is valid */ + /* Reset value is undefined */ + + +/* Real page number. Defined by the pte. Writing this register + * causes a TLB entry to be created for the data TLB, using + * additional information from the MD_EPN, and MD_TWC registers. + */ +#define SPRN_MD_RPN 798 +#define MD_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ + +/* This is a temporary storage register that could be used to save + * a processor working register during a tablewalk. + */ +#define SPRN_M_TW 799 + +#ifdef CONFIG_PPC_MM_SLICES +#include <asm/nohash/32/slice.h> +#define SLICE_ARRAY_SIZE (1 << (32 - SLICE_LOW_SHIFT - 1)) +#endif + +#ifndef __ASSEMBLY__ +struct slice_mask { + u64 low_slices; + DECLARE_BITMAP(high_slices, 0); +}; + +typedef struct { + unsigned int id; + unsigned int active; + unsigned long vdso_base; +#ifdef CONFIG_PPC_MM_SLICES + u16 user_psize; /* page size index */ + unsigned char low_slices_psize[SLICE_ARRAY_SIZE]; + unsigned char high_slices_psize[0]; + unsigned long slb_addr_limit; + struct slice_mask mask_base_psize; /* 4k or 16k */ +# ifdef CONFIG_HUGETLB_PAGE + struct slice_mask mask_512k; + struct slice_mask mask_8m; +# endif +#endif +} mm_context_t; + +#define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000) +#define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE)) + +/* Page size definitions, common between 32 and 64-bit + * + * shift : is the "PAGE_SHIFT" value for that page size + * penc : is the pte encoding mask + * + */ +struct mmu_psize_def { + unsigned int shift; /* number of bits */ + unsigned int enc; /* PTE encoding */ + unsigned int ind; /* Corresponding indirect page size shift */ + unsigned int flags; +#define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */ +#define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */ +}; + +extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; + +static inline int shift_to_mmu_psize(unsigned int shift) +{ + int psize; + + for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) + if (mmu_psize_defs[psize].shift == shift) + return psize; + return -1; +} + +static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) +{ + if (mmu_psize_defs[mmu_psize].shift) + return mmu_psize_defs[mmu_psize].shift; + BUG(); +} + +#endif /* !__ASSEMBLY__ */ + +#if defined(CONFIG_PPC_4K_PAGES) +#define mmu_virtual_psize MMU_PAGE_4K +#elif defined(CONFIG_PPC_16K_PAGES) +#define mmu_virtual_psize MMU_PAGE_16K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define mmu_linear_psize MMU_PAGE_8M + +#endif /* _ASM_POWERPC_MMU_8XX_H_ */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h new file mode 100644 index 000000000..f61f933a4 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/32/mmu.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_NOHASH_32_MMU_H_ +#define _ASM_POWERPC_NOHASH_32_MMU_H_ + +#if defined(CONFIG_40x) +/* 40x-style software loaded TLB */ +#include <asm/nohash/32/mmu-40x.h> +#elif defined(CONFIG_44x) +/* 44x-style software loaded TLB */ +#include <asm/nohash/32/mmu-44x.h> +#elif defined(CONFIG_PPC_BOOK3E_MMU) +/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ +#include <asm/nohash/mmu-book3e.h> +#elif defined (CONFIG_PPC_8xx) +/* Motorola/Freescale 8xx software loaded TLB */ +#include <asm/nohash/32/mmu-8xx.h> +#endif + +#ifndef __ASSEMBLY__ +typedef struct page *pgtable_t; +#endif + +#endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */ diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h new file mode 100644 index 000000000..e6585480d --- /dev/null +++ b/arch/powerpc/include/asm/nohash/64/mmu.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_NOHASH_64_MMU_H_ +#define _ASM_POWERPC_NOHASH_64_MMU_H_ + +/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ +#include <asm/nohash/mmu-book3e.h> + +#ifndef __ASSEMBLY__ +typedef struct page *pgtable_t; +#endif + +#endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */ diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index 7cd6809f4..30fcffc02 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -215,7 +215,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, { unsigned long old; - if (pte_young(*ptep)) + if (!pte_young(*ptep)) return 0; old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); return (old & _PAGE_ACCESSED) != 0; diff --git a/arch/powerpc/include/asm/nohash/mmu-book3e.h b/arch/powerpc/include/asm/nohash/mmu-book3e.h new file mode 100644 index 000000000..e20072972 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/mmu-book3e.h @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_MMU_BOOK3E_H_ +#define _ASM_POWERPC_MMU_BOOK3E_H_ +/* + * Freescale Book-E/Book-3e (ISA 2.06+) MMU support + */ + +/* Book-3e defined page sizes */ +#define BOOK3E_PAGESZ_1K 0 +#define BOOK3E_PAGESZ_2K 1 +#define BOOK3E_PAGESZ_4K 2 +#define BOOK3E_PAGESZ_8K 3 +#define BOOK3E_PAGESZ_16K 4 +#define BOOK3E_PAGESZ_32K 5 +#define BOOK3E_PAGESZ_64K 6 +#define BOOK3E_PAGESZ_128K 7 +#define BOOK3E_PAGESZ_256K 8 +#define BOOK3E_PAGESZ_512K 9 +#define BOOK3E_PAGESZ_1M 10 +#define BOOK3E_PAGESZ_2M 11 +#define BOOK3E_PAGESZ_4M 12 +#define BOOK3E_PAGESZ_8M 13 +#define BOOK3E_PAGESZ_16M 14 +#define BOOK3E_PAGESZ_32M 15 +#define BOOK3E_PAGESZ_64M 16 +#define BOOK3E_PAGESZ_128M 17 +#define BOOK3E_PAGESZ_256M 18 +#define BOOK3E_PAGESZ_512M 19 +#define BOOK3E_PAGESZ_1GB 20 +#define BOOK3E_PAGESZ_2GB 21 +#define BOOK3E_PAGESZ_4GB 22 +#define BOOK3E_PAGESZ_8GB 23 +#define BOOK3E_PAGESZ_16GB 24 +#define BOOK3E_PAGESZ_32GB 25 +#define BOOK3E_PAGESZ_64GB 26 +#define BOOK3E_PAGESZ_128GB 27 +#define BOOK3E_PAGESZ_256GB 28 +#define BOOK3E_PAGESZ_512GB 29 +#define BOOK3E_PAGESZ_1TB 30 +#define BOOK3E_PAGESZ_2TB 31 + +/* MAS registers bit definitions */ + +#define MAS0_TLBSEL_MASK 0x30000000 +#define MAS0_TLBSEL_SHIFT 28 +#define MAS0_TLBSEL(x) (((x) << MAS0_TLBSEL_SHIFT) & MAS0_TLBSEL_MASK) +#define MAS0_GET_TLBSEL(mas0) (((mas0) & MAS0_TLBSEL_MASK) >> \ + MAS0_TLBSEL_SHIFT) +#define MAS0_ESEL_MASK 0x0FFF0000 +#define MAS0_ESEL_SHIFT 16 +#define MAS0_ESEL(x) (((x) << MAS0_ESEL_SHIFT) & MAS0_ESEL_MASK) +#define MAS0_NV(x) ((x) & 0x00000FFF) +#define MAS0_HES 0x00004000 +#define MAS0_WQ_ALLWAYS 0x00000000 +#define MAS0_WQ_COND 0x00001000 +#define MAS0_WQ_CLR_RSRV 0x00002000 + +#define MAS1_VALID 0x80000000 +#define MAS1_IPROT 0x40000000 +#define MAS1_TID(x) (((x) << 16) & 0x3FFF0000) +#define MAS1_IND 0x00002000 +#define MAS1_TS 0x00001000 +#define MAS1_TSIZE_MASK 0x00000f80 +#define MAS1_TSIZE_SHIFT 7 +#define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) +#define MAS1_GET_TSIZE(mas1) (((mas1) & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT) + +#define MAS2_EPN (~0xFFFUL) +#define MAS2_X0 0x00000040 +#define MAS2_X1 0x00000020 +#define MAS2_W 0x00000010 +#define MAS2_I 0x00000008 +#define MAS2_M 0x00000004 +#define MAS2_G 0x00000002 +#define MAS2_E 0x00000001 +#define MAS2_WIMGE_MASK 0x0000001f +#define MAS2_EPN_MASK(size) (~0 << (size + 10)) +#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags)) + +#define MAS3_RPN 0xFFFFF000 +#define MAS3_U0 0x00000200 +#define MAS3_U1 0x00000100 +#define MAS3_U2 0x00000080 +#define MAS3_U3 0x00000040 +#define MAS3_UX 0x00000020 +#define MAS3_SX 0x00000010 +#define MAS3_UW 0x00000008 +#define MAS3_SW 0x00000004 +#define MAS3_UR 0x00000002 +#define MAS3_SR 0x00000001 +#define MAS3_BAP_MASK 0x0000003f +#define MAS3_SPSIZE 0x0000003e +#define MAS3_SPSIZE_SHIFT 1 + +#define MAS4_TLBSEL_MASK MAS0_TLBSEL_MASK +#define MAS4_TLBSELD(x) MAS0_TLBSEL(x) +#define MAS4_INDD 0x00008000 /* Default IND */ +#define MAS4_TSIZED(x) MAS1_TSIZE(x) +#define MAS4_X0D 0x00000040 +#define MAS4_X1D 0x00000020 +#define MAS4_WD 0x00000010 +#define MAS4_ID 0x00000008 +#define MAS4_MD 0x00000004 +#define MAS4_GD 0x00000002 +#define MAS4_ED 0x00000001 +#define MAS4_WIMGED_MASK 0x0000001f /* Default WIMGE */ +#define MAS4_WIMGED_SHIFT 0 +#define MAS4_VLED MAS4_X1D /* Default VLE */ +#define MAS4_ACMD 0x000000c0 /* Default ACM */ +#define MAS4_ACMD_SHIFT 6 +#define MAS4_TSIZED_MASK 0x00000f80 /* Default TSIZE */ +#define MAS4_TSIZED_SHIFT 7 + +#define MAS5_SGS 0x80000000 + +#define MAS6_SPID0 0x3FFF0000 +#define MAS6_SPID1 0x00007FFE +#define MAS6_ISIZE(x) MAS1_TSIZE(x) +#define MAS6_SAS 0x00000001 +#define MAS6_SPID MAS6_SPID0 +#define MAS6_SIND 0x00000002 /* Indirect page */ +#define MAS6_SIND_SHIFT 1 +#define MAS6_SPID_MASK 0x3fff0000 +#define MAS6_SPID_SHIFT 16 +#define MAS6_ISIZE_MASK 0x00000f80 +#define MAS6_ISIZE_SHIFT 7 + +#define MAS7_RPN 0xFFFFFFFF + +#define MAS8_TGS 0x80000000 /* Guest space */ +#define MAS8_VF 0x40000000 /* Virtualization Fault */ +#define MAS8_TLPID 0x000000ff + +/* Bit definitions for MMUCFG */ +#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */ +#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */ +#define MMUCFG_MAVN_V2 0x00000001 /* v2.0 */ +#define MMUCFG_NTLBS 0x0000000c /* Number of TLBs */ +#define MMUCFG_PIDSIZE 0x000007c0 /* PID Reg Size */ +#define MMUCFG_TWC 0x00008000 /* TLB Write Conditional (v2.0) */ +#define MMUCFG_LRAT 0x00010000 /* LRAT Supported (v2.0) */ +#define MMUCFG_RASIZE 0x00fe0000 /* Real Addr Size */ +#define MMUCFG_LPIDSIZE 0x0f000000 /* LPID Reg Size */ + +/* Bit definitions for MMUCSR0 */ +#define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */ +#define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */ +#define MMUCSR0_TLB2FI 0x00000040 /* TLB2 Flash invalidate */ +#define MMUCSR0_TLB3FI 0x00000020 /* TLB3 Flash invalidate */ +#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ + MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) +#define MMUCSR0_TLB0PS 0x00000780 /* TLB0 Page Size */ +#define MMUCSR0_TLB1PS 0x00007800 /* TLB1 Page Size */ +#define MMUCSR0_TLB2PS 0x00078000 /* TLB2 Page Size */ +#define MMUCSR0_TLB3PS 0x00780000 /* TLB3 Page Size */ + +/* MMUCFG bits */ +#define MMUCFG_MAVN_NASK 0x00000003 +#define MMUCFG_MAVN_V1_0 0x00000000 +#define MMUCFG_MAVN_V2_0 0x00000001 +#define MMUCFG_NTLB_MASK 0x0000000c +#define MMUCFG_NTLB_SHIFT 2 +#define MMUCFG_PIDSIZE_MASK 0x000007c0 +#define MMUCFG_PIDSIZE_SHIFT 6 +#define MMUCFG_TWC 0x00008000 +#define MMUCFG_LRAT 0x00010000 +#define MMUCFG_RASIZE_MASK 0x00fe0000 +#define MMUCFG_RASIZE_SHIFT 17 +#define MMUCFG_LPIDSIZE_MASK 0x0f000000 +#define MMUCFG_LPIDSIZE_SHIFT 24 + +/* TLBnCFG encoding */ +#define TLBnCFG_N_ENTRY 0x00000fff /* number of entries */ +#define TLBnCFG_HES 0x00002000 /* HW select supported */ +#define TLBnCFG_IPROT 0x00008000 /* IPROT supported */ +#define TLBnCFG_GTWE 0x00010000 /* Guest can write */ +#define TLBnCFG_IND 0x00020000 /* IND entries supported */ +#define TLBnCFG_PT 0x00040000 /* Can load from page table */ +#define TLBnCFG_MINSIZE 0x00f00000 /* Minimum Page Size (v1.0) */ +#define TLBnCFG_MINSIZE_SHIFT 20 +#define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */ +#define TLBnCFG_MAXSIZE_SHIFT 16 +#define TLBnCFG_ASSOC 0xff000000 /* Associativity */ +#define TLBnCFG_ASSOC_SHIFT 24 + +/* TLBnPS encoding */ +#define TLBnPS_4K 0x00000004 +#define TLBnPS_8K 0x00000008 +#define TLBnPS_16K 0x00000010 +#define TLBnPS_32K 0x00000020 +#define TLBnPS_64K 0x00000040 +#define TLBnPS_128K 0x00000080 +#define TLBnPS_256K 0x00000100 +#define TLBnPS_512K 0x00000200 +#define TLBnPS_1M 0x00000400 +#define TLBnPS_2M 0x00000800 +#define TLBnPS_4M 0x00001000 +#define TLBnPS_8M 0x00002000 +#define TLBnPS_16M 0x00004000 +#define TLBnPS_32M 0x00008000 +#define TLBnPS_64M 0x00010000 +#define TLBnPS_128M 0x00020000 +#define TLBnPS_256M 0x00040000 +#define TLBnPS_512M 0x00080000 +#define TLBnPS_1G 0x00100000 +#define TLBnPS_2G 0x00200000 +#define TLBnPS_4G 0x00400000 +#define TLBnPS_8G 0x00800000 +#define TLBnPS_16G 0x01000000 +#define TLBnPS_32G 0x02000000 +#define TLBnPS_64G 0x04000000 +#define TLBnPS_128G 0x08000000 +#define TLBnPS_256G 0x10000000 + +/* tlbilx action encoding */ +#define TLBILX_T_ALL 0 +#define TLBILX_T_TID 1 +#define TLBILX_T_FULLMATCH 3 +#define TLBILX_T_CLASS0 4 +#define TLBILX_T_CLASS1 5 +#define TLBILX_T_CLASS2 6 +#define TLBILX_T_CLASS3 7 + +#ifndef __ASSEMBLY__ +#include <asm/bug.h> + +extern unsigned int tlbcam_index; + +typedef struct { + unsigned int id; + unsigned int active; + unsigned long vdso_base; +} mm_context_t; + +/* Page size definitions, common between 32 and 64-bit + * + * shift : is the "PAGE_SHIFT" value for that page size + * penc : is the pte encoding mask + * + */ +struct mmu_psize_def +{ + unsigned int shift; /* number of bits */ + unsigned int enc; /* PTE encoding */ + unsigned int ind; /* Corresponding indirect page size shift */ + unsigned int flags; +#define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */ +#define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */ +}; +extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; + +static inline int shift_to_mmu_psize(unsigned int shift) +{ + int psize; + + for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) + if (mmu_psize_defs[psize].shift == shift) + return psize; + return -1; +} + +static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) +{ + if (mmu_psize_defs[mmu_psize].shift) + return mmu_psize_defs[mmu_psize].shift; + BUG(); +} + +/* The page sizes use the same names as 64-bit hash but are + * constants + */ +#if defined(CONFIG_PPC_4K_PAGES) +#define mmu_virtual_psize MMU_PAGE_4K +#else +#error Unsupported page size +#endif + +extern int mmu_linear_psize; +extern int mmu_vmemmap_psize; + +struct tlb_core_data { + /* + * Per-core spinlock for e6500 TLB handlers (no tlbsrx.) + * Must be the first struct element. + */ + u8 lock; + + /* For software way selection, as on Freescale TLB1 */ + u8 esel_next, esel_max, esel_first; +}; + +#ifdef CONFIG_PPC64 +extern unsigned long linear_map_top; +extern int book3e_htw_mode; + +#define PPC_HTW_NONE 0 +#define PPC_HTW_IBM 1 +#define PPC_HTW_E6500 2 + +/* + * 64-bit booke platforms don't load the tlb in the tlb miss handler code. + * HUGETLB_NEED_PRELOAD handles this - it causes huge_ptep_set_access_flags to + * return 1, indicating that the tlb requires preloading. + */ +#define HUGETLB_NEED_PRELOAD + +#define mmu_cleanup_all NULL + +#endif + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */ diff --git a/arch/powerpc/include/asm/nohash/mmu.h b/arch/powerpc/include/asm/nohash/mmu.h new file mode 100644 index 000000000..a037cb1ef --- /dev/null +++ b/arch/powerpc/include/asm/nohash/mmu.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_NOHASH_MMU_H_ +#define _ASM_POWERPC_NOHASH_MMU_H_ + +#ifdef CONFIG_PPC64 +#include <asm/nohash/64/mmu.h> +#else +#include <asm/nohash/32/mmu.h> +#endif + +#endif /* _ASM_POWERPC_NOHASH_MMU_H_ */ |