This patch rearranges the PTE bits into fixed positions for R2 and later cores. In the past, the TLB handling code did runtime checking of RI/XI and adjusted the shifts and rotates in order to fit the largest PFN value into the PTE. The checking now occurs when building the TLB handler, thus eliminating those checks. These new arrangements also define the largest possible PFN value that can fit in the PTE. HUGE page support is only available on 64-bit platforms. The new layouts of the PTE bits are the following: 64-bit, R1 or earlier: CCC D V G [S H] M A W R P 32-bit, R1 or earler: CCC D V G M A W R P 64-bit, R2 or later: CCC D V G RI XI [S H] M A W R P 32-bit, R2 or later: CCC D V G RI XI M A W R P In the case of cores that support the RI/XI bits, the value of the R bit is ignored. Signed-off-by: Steven J. Hill <Steven.Hill@xxxxxxxxxx> --- arch/mips/include/asm/pgtable-bits.h | 79 ++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 068ac7d..dc39ea5 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -95,50 +95,73 @@ #else /* - * When using the RI/XI bit support, we have 13 bits of flags below - * the physical address. The RI/XI bits are placed such that a SRL 5 - * can strip off the software bits, then a ROTR 2 can move the RI/XI - * into bits [63:62]. This also limits physical address to 56 bits, - * which is more than we need right now. + * Below are the "Normal" R4K cases */ - +#if defined(CONFIG_64BIT) || !defined(CONFIG_CPU_MIPSR2) /* * The following bits are implemented in software */ #define _PAGE_PRESENT_SHIFT (0) #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) -#define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1) -#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; }) +#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) +#define _PAGE_READ (1 << _PAGE_READ_SHIFT) #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) +#else +#define _PAGE_PRESENT_SHIFT (0) +#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) +#define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1) +#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) +#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) +#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) +#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) +#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) +#endif -#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT +#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) /* huge tlb page */ #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1) #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1) #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) -#else -#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT) -#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */ -#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT) -#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */ -#endif +#ifdef CONFIG_CPU_MIPSR2 /* Page cannot be executed */ -#define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT) -#define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; }) +#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1) + +#else /* !CONFIG_CPU_MIPSR2 */ +#define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1) +#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) +/* not supported */ +#define _PAGE_NO_EXEC (0) +#define _PAGE_NO_READ (0) +#endif /* CONFIG_CPU_MIPSR2 */ + +#endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */ + +#ifdef CONFIG_CPU_MIPSR2 +/* if not defined, we are 32BIT */ +#ifndef _PAGE_NO_EXEC_SHIFT +#define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1) +#endif +#define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT) /* Page cannot be read */ -#define _PAGE_NO_READ_SHIFT (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT) -#define _PAGE_NO_READ ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; }) +#define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1) +#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT) + +/* unused if cpu_has_rixi */ +#define _PAGE_READ_SHIFT _PAGE_NO_READ_SHIFT +#define _PAGE_READ (1 << _PAGE_READ_SHIFT) #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) +#endif + #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) @@ -148,6 +171,14 @@ #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) +/* + * Below are the different layouts of the PTE bits: + * + * 64-bit, R1 or earlier: CCC D V G [S H] M A W R P + * 32-bit, R1 or earler: CCC D V G M A W R P + * 64-bit, R2 or later: CCC D V G RI XI [S H] M A W R P + * 32-bit, R2 or later: CCC D V G RI XI M A W R P + */ #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ /* @@ -159,14 +190,6 @@ #define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1)) -#ifndef _PAGE_NO_READ -#define _PAGE_NO_READ ({BUG(); 0; }) -#define _PAGE_NO_READ_SHIFT ({BUG(); 0; }) -#endif -#ifndef _PAGE_NO_EXEC -#define _PAGE_NO_EXEC ({BUG(); 0; }) -#endif - #ifndef __ASSEMBLY__ /* @@ -249,7 +272,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) #endif -#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ)) +#define __READABLE (_PAGE_SILENT_READ | _PAGE_READ | _PAGE_ACCESSED) #define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ -- 1.7.10.4