blob: 5bc663d330d210aa97f0f882c55ef84c57033fcf [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 2002 by Ralf Baechle
7 * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
8 * Copyright (C) 2002 Maciej W. Rozycki
9 */
10#ifndef _ASM_PGTABLE_BITS_H
11#define _ASM_PGTABLE_BITS_H
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14/*
15 * Note that we shift the lower 32bits of each EntryLo[01] entry
16 * 6 bits to the left. That way we can convert the PFN into the
17 * physical address by a single 'and' operation and gain 6 additional
18 * bits for storing information which isn't present in a normal
19 * MIPS page table.
20 *
21 * Similar to the Alpha port, we need to keep track of the ref
22 * and mod bits in software. We have a software "yeah you can read
23 * from this page" bit, and a hardware one which actually lets the
Ralf Baechle70342282013-01-22 12:59:30 +010024 * process read from the page. On the same token we have a software
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 * writable bit and the real hardware one which actually lets the
26 * process write to the page, this keeps a mod bit via the hardware
27 * dirty bit.
28 *
29 * Certain revisions of the R4000 and R5000 have a bug where if a
30 * certain sequence occurs in the last 3 instructions of an executable
31 * page, and the following page is not mapped, the cpu can do
32 * unpredictable things. The code (when it is written) to deal with
33 * this problem will be in the update_mmu_cache() code for the r4k.
34 */
Ralf Baechle34adb282014-11-22 00:16:48 +010035#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Ralf Baechlea2c763e2012-10-16 22:20:26 +020037/*
Paul Burton69497702016-04-19 09:25:02 +010038 * Page table bit offsets used for 64 bit physical addressing on MIPS32,
39 * for example with Alchemy, Netlogic XLP/XLR or XPA.
Ralf Baechlea2c763e2012-10-16 22:20:26 +020040 */
Paul Burton69497702016-04-19 09:25:02 +010041enum pgtable_bits {
42 /* Used by TLB hardware (placed in EntryLo*) */
43 _PAGE_NO_EXEC_SHIFT,
44 _PAGE_NO_READ_SHIFT,
45 _PAGE_GLOBAL_SHIFT,
46 _PAGE_VALID_SHIFT,
47 _PAGE_DIRTY_SHIFT,
48 _CACHE_SHIFT,
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Paul Burton69497702016-04-19 09:25:02 +010050 /* Used only by software (masked out before writing EntryLo*) */
51 _PAGE_PRESENT_SHIFT = 24,
Paul Burton69497702016-04-19 09:25:02 +010052 _PAGE_WRITE_SHIFT,
53 _PAGE_ACCESSED_SHIFT,
54 _PAGE_MODIFIED_SHIFT,
55};
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Steven J. Hillc5b36782015-02-26 18:16:38 -060057/*
58 * Bits for extended EntryLo0/EntryLo1 registers
59 */
60#define _PFNX_MASK 0xffffff
61
David Daney6dd93442010-02-10 15:12:47 -080062#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Paul Burton69497702016-04-19 09:25:02 +010064/* Page table bits used for r3k systems */
65enum pgtable_bits {
66 /* Used only by software (writes to EntryLo ignored) */
67 _PAGE_PRESENT_SHIFT,
Paul Burton780602d2016-04-19 09:25:03 +010068 _PAGE_NO_READ_SHIFT,
Paul Burton69497702016-04-19 09:25:02 +010069 _PAGE_WRITE_SHIFT,
70 _PAGE_ACCESSED_SHIFT,
71 _PAGE_MODIFIED_SHIFT,
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Paul Burton69497702016-04-19 09:25:02 +010073 /* Used by TLB hardware (placed in EntryLo) */
74 _PAGE_GLOBAL_SHIFT = 8,
75 _PAGE_VALID_SHIFT,
76 _PAGE_DIRTY_SHIFT,
77 _CACHE_UNCACHED_SHIFT,
78};
Steven J. Hill05f98832015-02-19 10:18:50 -060079
80#else
David Daney6dd93442010-02-10 15:12:47 -080081
Paul Burton69497702016-04-19 09:25:02 +010082/* Page table bits used for r4k systems */
83enum pgtable_bits {
84 /* Used only by software (masked out before writing EntryLo*) */
85 _PAGE_PRESENT_SHIFT,
86#if !defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_MIPSR6)
Paul Burton780602d2016-04-19 09:25:03 +010087 _PAGE_NO_READ_SHIFT,
Steven J. Hillbe0c37c2015-02-26 18:16:37 -060088#endif
Paul Burton69497702016-04-19 09:25:02 +010089 _PAGE_WRITE_SHIFT,
90 _PAGE_ACCESSED_SHIFT,
91 _PAGE_MODIFIED_SHIFT,
Steven J. Hillbe0c37c2015-02-26 18:16:37 -060092#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
Paul Burton69497702016-04-19 09:25:02 +010093 _PAGE_HUGE_SHIFT,
94#endif
Steven J. Hillbe0c37c2015-02-26 18:16:37 -060095
Paul Burton69497702016-04-19 09:25:02 +010096 /* Used by TLB hardware (placed in EntryLo*) */
Markos Chandrasd7b63142015-05-29 14:43:52 +010097#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
Paul Burton69497702016-04-19 09:25:02 +010098 _PAGE_NO_EXEC_SHIFT,
99 _PAGE_NO_READ_SHIFT,
Ralf Baechle970d0322012-10-18 13:54:15 +0200100#endif
Paul Burton69497702016-04-19 09:25:02 +0100101 _PAGE_GLOBAL_SHIFT,
102 _PAGE_VALID_SHIFT,
103 _PAGE_DIRTY_SHIFT,
104 _CACHE_SHIFT,
105};
David Daney6dd93442010-02-10 15:12:47 -0800106
Ralf Baechle34adb282014-11-22 00:16:48 +0100107#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */
Chris Dearmanbec50522007-09-19 00:51:57 +0100108
Paul Burton69497702016-04-19 09:25:02 +0100109/* Used only by software */
110#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
Paul Burton69497702016-04-19 09:25:02 +0100111#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
112#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
113#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
114#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
115# define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
116#endif
117
118/* Used by TLB hardware (placed in EntryLo*) */
119#if (defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32))
120# define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT)
Paul Burton69497702016-04-19 09:25:02 +0100121#elif defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
122# define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0)
Paul Burton69497702016-04-19 09:25:02 +0100123#endif
Paul Burton780602d2016-04-19 09:25:03 +0100124#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT)
Paul Burton69497702016-04-19 09:25:02 +0100125#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
126#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
127#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
128#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
129# define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT)
130# define _CACHE_MASK _CACHE_UNCACHED
131# define _PFN_SHIFT PAGE_SHIFT
132#else
133# define _CACHE_MASK (7 << _CACHE_SHIFT)
134# define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
135#endif
136
Steven J. Hillbe0c37c2015-02-26 18:16:37 -0600137#ifndef _PAGE_NO_EXEC
138#define _PAGE_NO_EXEC 0
139#endif
Steven J. Hillbe0c37c2015-02-26 18:16:37 -0600140
Steven J. Hill05f98832015-02-19 10:18:50 -0600141#define _PAGE_SILENT_READ _PAGE_VALID
142#define _PAGE_SILENT_WRITE _PAGE_DIRTY
143
David Daney6dd93442010-02-10 15:12:47 -0800144#define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1))
145
Steven J. Hillbe0c37c2015-02-26 18:16:37 -0600146/*
147 * The final layouts of the PTE bits are:
148 *
149 * 64-bit, R1 or earlier: CCC D V G [S H] M A W R P
150 * 32-bit, R1 or earler: CCC D V G M A W R P
151 * 64-bit, R2 or later: CCC D V G RI/R XI [S H] M A W P
152 * 32-bit, R2 or later: CCC D V G RI/R XI M A W P
153 */
David Daney6dd93442010-02-10 15:12:47 -0800154
155
David Daney6dd93442010-02-10 15:12:47 -0800156/*
157 * pte_to_entrylo converts a page table entry (PTE) into a Mips
158 * entrylo0/1 value.
159 */
160static inline uint64_t pte_to_entrylo(unsigned long pte_val)
161{
Markos Chandrasd7b63142015-05-29 14:43:52 +0100162#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
Steven J. Hill05857c62012-09-13 16:51:46 -0500163 if (cpu_has_rixi) {
David Daney6dd93442010-02-10 15:12:47 -0800164 int sa;
165#ifdef CONFIG_32BIT
166 sa = 31 - _PAGE_NO_READ_SHIFT;
167#else
168 sa = 63 - _PAGE_NO_READ_SHIFT;
169#endif
170 /*
171 * C has no way to express that this is a DSRL
172 * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2. Luckily
173 * in the fast path this is done in assembly
174 */
175 return (pte_val >> _PAGE_GLOBAL_SHIFT) |
176 ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
177 }
Steven J. Hillbe0c37c2015-02-26 18:16:37 -0600178#endif
David Daney6dd93442010-02-10 15:12:47 -0800179
180 return pte_val >> _PAGE_GLOBAL_SHIFT;
181}
Chris Dearmanbec50522007-09-19 00:51:57 +0100182
183/*
184 * Cache attributes
185 */
186#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
187
188#define _CACHE_CACHABLE_NONCOHERENT 0
Markos Chandrasfb020352014-07-18 10:51:30 +0100189#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED
Chris Dearmanbec50522007-09-19 00:51:57 +0100190
191#elif defined(CONFIG_CPU_SB1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
193/* No penalty for being coherent on the SB1, so just
194 use it for "noncoherent" spaces, too. Shouldn't hurt. */
195
Chris Dearmanbec50522007-09-19 00:51:57 +0100196#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Huacai Chen152ebb42014-03-21 18:43:59 +0800198#elif defined(CONFIG_CPU_LOONGSON3)
199
200/* Using COHERENT flag for NONCOHERENT doesn't hurt. */
201
Huacai Chen152ebb42014-03-21 18:43:59 +0800202#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */
203#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */
Huacai Chen152ebb42014-03-21 18:43:59 +0800204
Alex Smithf1f5e412015-07-24 16:16:12 +0100205#elif defined(CONFIG_MACH_INGENIC)
Markos Chandras80bc94d12014-07-18 10:51:31 +0100206
207/* Ingenic uses the WA bit to achieve write-combine memory writes */
208#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT)
209
Markos Chandrasfb020352014-07-18 10:51:30 +0100210#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Markos Chandrasfb020352014-07-18 10:51:30 +0100212#ifndef _CACHE_CACHABLE_NO_WA
213#define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT)
214#endif
215#ifndef _CACHE_CACHABLE_WA
216#define _CACHE_CACHABLE_WA (1<<_CACHE_SHIFT)
217#endif
218#ifndef _CACHE_UNCACHED
219#define _CACHE_UNCACHED (2<<_CACHE_SHIFT)
220#endif
221#ifndef _CACHE_CACHABLE_NONCOHERENT
222#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT)
223#endif
224#ifndef _CACHE_CACHABLE_CE
225#define _CACHE_CACHABLE_CE (4<<_CACHE_SHIFT)
226#endif
227#ifndef _CACHE_CACHABLE_COW
228#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT)
229#endif
230#ifndef _CACHE_CACHABLE_CUW
231#define _CACHE_CACHABLE_CUW (6<<_CACHE_SHIFT)
232#endif
233#ifndef _CACHE_UNCACHED_ACCELERATED
234#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
Paul Burton780602d2016-04-19 09:25:03 +0100237#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED)
Steven J. Hill05f98832015-02-19 10:18:50 -0600238#define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
Steven J. Hill05f98832015-02-19 10:18:50 -0600240#define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \
241 _PFN_MASK | _CACHE_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243#endif /* _ASM_PGTABLE_BITS_H */