162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1994 - 2002 by Ralf Baechle 762306a36Sopenharmony_ci * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. 862306a36Sopenharmony_ci * Copyright (C) 2002 Maciej W. Rozycki 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci#ifndef _ASM_PGTABLE_BITS_H 1162306a36Sopenharmony_ci#define _ASM_PGTABLE_BITS_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * Note that we shift the lower 32bits of each EntryLo[01] entry 1662306a36Sopenharmony_ci * 6 bits to the left. That way we can convert the PFN into the 1762306a36Sopenharmony_ci * physical address by a single 'and' operation and gain 6 additional 1862306a36Sopenharmony_ci * bits for storing information which isn't present in a normal 1962306a36Sopenharmony_ci * MIPS page table. 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * Similar to the Alpha port, we need to keep track of the ref 2262306a36Sopenharmony_ci * and mod bits in software. We have a software "yeah you can read 2362306a36Sopenharmony_ci * from this page" bit, and a hardware one which actually lets the 2462306a36Sopenharmony_ci * process read from the page. On the same token we have a software 2562306a36Sopenharmony_ci * writable bit and the real hardware one which actually lets the 2662306a36Sopenharmony_ci * process write to the page, this keeps a mod bit via the hardware 2762306a36Sopenharmony_ci * dirty bit. 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * Certain revisions of the R4000 and R5000 have a bug where if a 3062306a36Sopenharmony_ci * certain sequence occurs in the last 3 instructions of an executable 3162306a36Sopenharmony_ci * page, and the following page is not mapped, the cpu can do 3262306a36Sopenharmony_ci * unpredictable things. The code (when it is written) to deal with 3362306a36Sopenharmony_ci * this problem will be in the update_mmu_cache() code for the r4k. 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci#if defined(CONFIG_XPA) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Page table bit offsets used for 64 bit physical addressing on 3962306a36Sopenharmony_ci * MIPS32r5 with XPA. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_cienum pgtable_bits { 4262306a36Sopenharmony_ci /* Used by TLB hardware (placed in EntryLo*) */ 4362306a36Sopenharmony_ci _PAGE_NO_EXEC_SHIFT, 4462306a36Sopenharmony_ci _PAGE_NO_READ_SHIFT, 4562306a36Sopenharmony_ci _PAGE_GLOBAL_SHIFT, 4662306a36Sopenharmony_ci _PAGE_VALID_SHIFT, 4762306a36Sopenharmony_ci _PAGE_DIRTY_SHIFT, 4862306a36Sopenharmony_ci _CACHE_SHIFT, 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* Used only by software (masked out before writing EntryLo*) */ 5162306a36Sopenharmony_ci _PAGE_PRESENT_SHIFT = 24, 5262306a36Sopenharmony_ci _PAGE_WRITE_SHIFT, 5362306a36Sopenharmony_ci _PAGE_ACCESSED_SHIFT, 5462306a36Sopenharmony_ci _PAGE_MODIFIED_SHIFT, 5562306a36Sopenharmony_ci#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 5662306a36Sopenharmony_ci _PAGE_SPECIAL_SHIFT, 5762306a36Sopenharmony_ci#endif 5862306a36Sopenharmony_ci#if defined(CONFIG_HAVE_ARCH_SOFT_DIRTY) 5962306a36Sopenharmony_ci _PAGE_SOFT_DIRTY_SHIFT, 6062306a36Sopenharmony_ci#endif 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* 6462306a36Sopenharmony_ci * Bits for extended EntryLo0/EntryLo1 registers 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci#define _PFNX_MASK 0xffffff 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * Page table bit offsets used for 36 bit physical addressing on MIPS32, 7262306a36Sopenharmony_ci * for example with Alchemy or Netlogic XLP/XLR. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cienum pgtable_bits { 7562306a36Sopenharmony_ci /* Used by TLB hardware (placed in EntryLo*) */ 7662306a36Sopenharmony_ci _PAGE_GLOBAL_SHIFT, 7762306a36Sopenharmony_ci _PAGE_VALID_SHIFT, 7862306a36Sopenharmony_ci _PAGE_DIRTY_SHIFT, 7962306a36Sopenharmony_ci _CACHE_SHIFT, 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci /* Used only by software (masked out before writing EntryLo*) */ 8262306a36Sopenharmony_ci _PAGE_PRESENT_SHIFT = _CACHE_SHIFT + 3, 8362306a36Sopenharmony_ci _PAGE_NO_READ_SHIFT, 8462306a36Sopenharmony_ci _PAGE_WRITE_SHIFT, 8562306a36Sopenharmony_ci _PAGE_ACCESSED_SHIFT, 8662306a36Sopenharmony_ci _PAGE_MODIFIED_SHIFT, 8762306a36Sopenharmony_ci#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 8862306a36Sopenharmony_ci _PAGE_SPECIAL_SHIFT, 8962306a36Sopenharmony_ci#endif 9062306a36Sopenharmony_ci#if defined(CONFIG_HAVE_ARCH_SOFT_DIRTY) 9162306a36Sopenharmony_ci _PAGE_SOFT_DIRTY_SHIFT, 9262306a36Sopenharmony_ci#endif 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#elif defined(CONFIG_CPU_R3K_TLB) 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* Page table bits used for r3k systems */ 9862306a36Sopenharmony_cienum pgtable_bits { 9962306a36Sopenharmony_ci /* Used only by software (writes to EntryLo ignored) */ 10062306a36Sopenharmony_ci _PAGE_PRESENT_SHIFT, 10162306a36Sopenharmony_ci _PAGE_NO_READ_SHIFT, 10262306a36Sopenharmony_ci _PAGE_WRITE_SHIFT, 10362306a36Sopenharmony_ci _PAGE_ACCESSED_SHIFT, 10462306a36Sopenharmony_ci _PAGE_MODIFIED_SHIFT, 10562306a36Sopenharmony_ci#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 10662306a36Sopenharmony_ci _PAGE_SPECIAL_SHIFT, 10762306a36Sopenharmony_ci#endif 10862306a36Sopenharmony_ci#if defined(CONFIG_HAVE_ARCH_SOFT_DIRTY) 10962306a36Sopenharmony_ci _PAGE_SOFT_DIRTY_SHIFT, 11062306a36Sopenharmony_ci#endif 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci /* Used by TLB hardware (placed in EntryLo) */ 11362306a36Sopenharmony_ci _PAGE_GLOBAL_SHIFT = 8, 11462306a36Sopenharmony_ci _PAGE_VALID_SHIFT, 11562306a36Sopenharmony_ci _PAGE_DIRTY_SHIFT, 11662306a36Sopenharmony_ci _CACHE_UNCACHED_SHIFT, 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#else 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* Page table bits used for r4k systems */ 12262306a36Sopenharmony_cienum pgtable_bits { 12362306a36Sopenharmony_ci /* Used only by software (masked out before writing EntryLo*) */ 12462306a36Sopenharmony_ci _PAGE_PRESENT_SHIFT, 12562306a36Sopenharmony_ci#if !defined(CONFIG_CPU_HAS_RIXI) 12662306a36Sopenharmony_ci _PAGE_NO_READ_SHIFT, 12762306a36Sopenharmony_ci#endif 12862306a36Sopenharmony_ci _PAGE_WRITE_SHIFT, 12962306a36Sopenharmony_ci _PAGE_ACCESSED_SHIFT, 13062306a36Sopenharmony_ci _PAGE_MODIFIED_SHIFT, 13162306a36Sopenharmony_ci#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 13262306a36Sopenharmony_ci _PAGE_HUGE_SHIFT, 13362306a36Sopenharmony_ci#endif 13462306a36Sopenharmony_ci#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 13562306a36Sopenharmony_ci _PAGE_SPECIAL_SHIFT, 13662306a36Sopenharmony_ci#endif 13762306a36Sopenharmony_ci#if defined(CONFIG_HAVE_ARCH_SOFT_DIRTY) 13862306a36Sopenharmony_ci _PAGE_SOFT_DIRTY_SHIFT, 13962306a36Sopenharmony_ci#endif 14062306a36Sopenharmony_ci /* Used by TLB hardware (placed in EntryLo*) */ 14162306a36Sopenharmony_ci#if defined(CONFIG_CPU_HAS_RIXI) 14262306a36Sopenharmony_ci _PAGE_NO_EXEC_SHIFT, 14362306a36Sopenharmony_ci _PAGE_NO_READ_SHIFT, 14462306a36Sopenharmony_ci#endif 14562306a36Sopenharmony_ci _PAGE_GLOBAL_SHIFT, 14662306a36Sopenharmony_ci _PAGE_VALID_SHIFT, 14762306a36Sopenharmony_ci _PAGE_DIRTY_SHIFT, 14862306a36Sopenharmony_ci _CACHE_SHIFT, 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* Used only by software */ 15462306a36Sopenharmony_ci#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) 15562306a36Sopenharmony_ci#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) 15662306a36Sopenharmony_ci#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) 15762306a36Sopenharmony_ci#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) 15862306a36Sopenharmony_ci#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 15962306a36Sopenharmony_ci# define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) 16062306a36Sopenharmony_ci#endif 16162306a36Sopenharmony_ci#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 16262306a36Sopenharmony_ci# define _PAGE_SPECIAL (1 << _PAGE_SPECIAL_SHIFT) 16362306a36Sopenharmony_ci#else 16462306a36Sopenharmony_ci# define _PAGE_SPECIAL 0 16562306a36Sopenharmony_ci#endif 16662306a36Sopenharmony_ci#if defined(CONFIG_HAVE_ARCH_SOFT_DIRTY) 16762306a36Sopenharmony_ci# define _PAGE_SOFT_DIRTY (1 << _PAGE_SOFT_DIRTY_SHIFT) 16862306a36Sopenharmony_ci#else 16962306a36Sopenharmony_ci# define _PAGE_SOFT_DIRTY 0 17062306a36Sopenharmony_ci#endif 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/* Used by TLB hardware (placed in EntryLo*) */ 17362306a36Sopenharmony_ci#if defined(CONFIG_XPA) 17462306a36Sopenharmony_ci# define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT) 17562306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_RIXI) 17662306a36Sopenharmony_ci# define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0) 17762306a36Sopenharmony_ci#endif 17862306a36Sopenharmony_ci#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT) 17962306a36Sopenharmony_ci#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) 18062306a36Sopenharmony_ci#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) 18162306a36Sopenharmony_ci#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) 18262306a36Sopenharmony_ci#if defined(CONFIG_CPU_R3K_TLB) 18362306a36Sopenharmony_ci# define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) 18462306a36Sopenharmony_ci# define _CACHE_MASK _CACHE_UNCACHED 18562306a36Sopenharmony_ci# define PFN_PTE_SHIFT PAGE_SHIFT 18662306a36Sopenharmony_ci#else 18762306a36Sopenharmony_ci# define _CACHE_MASK (7 << _CACHE_SHIFT) 18862306a36Sopenharmony_ci# define PFN_PTE_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) 18962306a36Sopenharmony_ci#endif 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#ifndef _PAGE_NO_EXEC 19262306a36Sopenharmony_ci#define _PAGE_NO_EXEC 0 19362306a36Sopenharmony_ci#endif 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci#define _PAGE_SILENT_READ _PAGE_VALID 19662306a36Sopenharmony_ci#define _PAGE_SILENT_WRITE _PAGE_DIRTY 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci#define _PFN_MASK (~((1 << (PFN_PTE_SHIFT)) - 1)) 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci/* 20162306a36Sopenharmony_ci * The final layouts of the PTE bits are: 20262306a36Sopenharmony_ci * 20362306a36Sopenharmony_ci * 64-bit, R1 or earlier: CCC D V G [S H] M A W R P 20462306a36Sopenharmony_ci * 32-bit, R1 or earler: CCC D V G M A W R P 20562306a36Sopenharmony_ci * 64-bit, R2 or later: CCC D V G RI/R XI [S H] M A W P 20662306a36Sopenharmony_ci * 32-bit, R2 or later: CCC D V G RI/R XI M A W P 20762306a36Sopenharmony_ci */ 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/* 21162306a36Sopenharmony_ci * pte_to_entrylo converts a page table entry (PTE) into a Mips 21262306a36Sopenharmony_ci * entrylo0/1 value. 21362306a36Sopenharmony_ci */ 21462306a36Sopenharmony_cistatic inline uint64_t pte_to_entrylo(unsigned long pte_val) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci#ifdef CONFIG_CPU_HAS_RIXI 21762306a36Sopenharmony_ci if (cpu_has_rixi) { 21862306a36Sopenharmony_ci int sa; 21962306a36Sopenharmony_ci#ifdef CONFIG_32BIT 22062306a36Sopenharmony_ci sa = 31 - _PAGE_NO_READ_SHIFT; 22162306a36Sopenharmony_ci#else 22262306a36Sopenharmony_ci sa = 63 - _PAGE_NO_READ_SHIFT; 22362306a36Sopenharmony_ci#endif 22462306a36Sopenharmony_ci /* 22562306a36Sopenharmony_ci * C has no way to express that this is a DSRL 22662306a36Sopenharmony_ci * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2. Luckily 22762306a36Sopenharmony_ci * in the fast path this is done in assembly 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_ci return (pte_val >> _PAGE_GLOBAL_SHIFT) | 23062306a36Sopenharmony_ci ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa); 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci#endif 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci return pte_val >> _PAGE_GLOBAL_SHIFT; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci/* 23862306a36Sopenharmony_ci * Cache attributes 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci#if defined(CONFIG_CPU_R3K_TLB) 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#define _CACHE_CACHABLE_NONCOHERENT 0 24362306a36Sopenharmony_ci#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci#elif defined(CONFIG_CPU_SB1) 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* No penalty for being coherent on the SB1, so just 24862306a36Sopenharmony_ci use it for "noncoherent" spaces, too. Shouldn't hurt. */ 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci#endif 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_NO_WA 25562306a36Sopenharmony_ci#define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT) 25662306a36Sopenharmony_ci#endif 25762306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_WA 25862306a36Sopenharmony_ci#define _CACHE_CACHABLE_WA (1<<_CACHE_SHIFT) 25962306a36Sopenharmony_ci#endif 26062306a36Sopenharmony_ci#ifndef _CACHE_UNCACHED 26162306a36Sopenharmony_ci#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) 26262306a36Sopenharmony_ci#endif 26362306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_NONCOHERENT 26462306a36Sopenharmony_ci#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) 26562306a36Sopenharmony_ci#endif 26662306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_CE 26762306a36Sopenharmony_ci#define _CACHE_CACHABLE_CE (4<<_CACHE_SHIFT) 26862306a36Sopenharmony_ci#endif 26962306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_COW 27062306a36Sopenharmony_ci#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT) 27162306a36Sopenharmony_ci#endif 27262306a36Sopenharmony_ci#ifndef _CACHE_CACHABLE_CUW 27362306a36Sopenharmony_ci#define _CACHE_CACHABLE_CUW (6<<_CACHE_SHIFT) 27462306a36Sopenharmony_ci#endif 27562306a36Sopenharmony_ci#ifndef _CACHE_UNCACHED_ACCELERATED 27662306a36Sopenharmony_ci#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) 27762306a36Sopenharmony_ci#endif 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED) 28062306a36Sopenharmony_ci#define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci#define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ 28362306a36Sopenharmony_ci _PAGE_SOFT_DIRTY | _PFN_MASK | \ 28462306a36Sopenharmony_ci _CACHE_MASK | _PAGE_SPECIAL) 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci#endif /* _ASM_PGTABLE_BITS_H */ 287