18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_NOHASH_32_PTE_40x_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_NOHASH_32_PTE_40x_H
48c2ecf20Sopenharmony_ci#ifdef __KERNEL__
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci/*
78c2ecf20Sopenharmony_ci * At present, all PowerPC 400-class processors share a similar TLB
88c2ecf20Sopenharmony_ci * architecture. The instruction and data sides share a unified,
98c2ecf20Sopenharmony_ci * 64-entry, fully-associative TLB which is maintained totally under
108c2ecf20Sopenharmony_ci * software control. In addition, the instruction side has a
118c2ecf20Sopenharmony_ci * hardware-managed, 4-entry, fully-associative TLB which serves as a
128c2ecf20Sopenharmony_ci * first level to the shared TLB. These two TLBs are known as the UTLB
138c2ecf20Sopenharmony_ci * and ITLB, respectively (see "mmu.h" for definitions).
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * There are several potential gotchas here.  The 40x hardware TLBLO
168c2ecf20Sopenharmony_ci * field looks like this:
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * 0  1  2  3  4  ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
198c2ecf20Sopenharmony_ci * RPN.....................  0  0 EX WR ZSEL.......  W  I  M  G
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * Where possible we make the Linux PTE bits match up with this
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
248c2ecf20Sopenharmony_ci *   support down to 1k pages), this is done in the TLBMiss exception
258c2ecf20Sopenharmony_ci *   handler.
268c2ecf20Sopenharmony_ci * - We use only zones 0 (for kernel pages) and 1 (for user pages)
278c2ecf20Sopenharmony_ci *   of the 16 available.  Bit 24-26 of the TLB are cleared in the TLB
288c2ecf20Sopenharmony_ci *   miss handler.  Bit 27 is PAGE_USER, thus selecting the correct
298c2ecf20Sopenharmony_ci *   zone.
308c2ecf20Sopenharmony_ci * - PRESENT *must* be in the bottom two bits because swap cache
318c2ecf20Sopenharmony_ci *   entries use the top 30 bits.  Because 40x doesn't support SMP
328c2ecf20Sopenharmony_ci *   anyway, M is irrelevant so we borrow it for PAGE_PRESENT.  Bit 30
338c2ecf20Sopenharmony_ci *   is cleared in the TLB miss handler before the TLB entry is loaded.
348c2ecf20Sopenharmony_ci * - All other bits of the PTE are loaded into TLBLO without
358c2ecf20Sopenharmony_ci *   modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
368c2ecf20Sopenharmony_ci *   software PTE bits.  We actually use bits 21, 24, 25, and
378c2ecf20Sopenharmony_ci *   30 respectively for the software bits: ACCESSED, DIRTY, RW, and
388c2ecf20Sopenharmony_ci *   PRESENT.
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define	_PAGE_GUARDED	0x001	/* G: page is guarded from prefetch */
428c2ecf20Sopenharmony_ci#define _PAGE_PRESENT	0x002	/* software: PTE contains a translation */
438c2ecf20Sopenharmony_ci#define	_PAGE_NO_CACHE	0x004	/* I: caching is inhibited */
448c2ecf20Sopenharmony_ci#define	_PAGE_WRITETHRU	0x008	/* W: caching is write-through */
458c2ecf20Sopenharmony_ci#define	_PAGE_USER	0x010	/* matches one of the zone permission bits */
468c2ecf20Sopenharmony_ci#define	_PAGE_SPECIAL	0x020	/* software: Special page */
478c2ecf20Sopenharmony_ci#define	_PAGE_DIRTY	0x080	/* software: dirty page */
488c2ecf20Sopenharmony_ci#define _PAGE_RW	0x100	/* hardware: WR, anded with dirty in exception */
498c2ecf20Sopenharmony_ci#define _PAGE_EXEC	0x200	/* hardware: EX permission */
508c2ecf20Sopenharmony_ci#define _PAGE_ACCESSED	0x400	/* software: R: page referenced */
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/* No page size encoding in the linux PTE */
538c2ecf20Sopenharmony_ci#define _PAGE_PSIZE		0
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/* cache related flags non existing on 40x */
568c2ecf20Sopenharmony_ci#define _PAGE_COHERENT	0
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#define _PAGE_KERNEL_RO		0
598c2ecf20Sopenharmony_ci#define _PAGE_KERNEL_ROX	_PAGE_EXEC
608c2ecf20Sopenharmony_ci#define _PAGE_KERNEL_RW		(_PAGE_DIRTY | _PAGE_RW)
618c2ecf20Sopenharmony_ci#define _PAGE_KERNEL_RWX	(_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci#define _PMD_PRESENT	0x400	/* PMD points to page of PTEs */
648c2ecf20Sopenharmony_ci#define _PMD_PRESENT_MASK	_PMD_PRESENT
658c2ecf20Sopenharmony_ci#define _PMD_BAD	0x802
668c2ecf20Sopenharmony_ci#define _PMD_SIZE_4M	0x0c0
678c2ecf20Sopenharmony_ci#define _PMD_SIZE_16M	0x0e0
688c2ecf20Sopenharmony_ci#define _PMD_USER	0
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define _PTE_NONE_MASK	0
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED)
738c2ecf20Sopenharmony_ci#define _PAGE_BASE	(_PAGE_BASE_NC)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/* Permission masks used to generate the __P and __S table */
768c2ecf20Sopenharmony_ci#define PAGE_NONE	__pgprot(_PAGE_BASE)
778c2ecf20Sopenharmony_ci#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
788c2ecf20Sopenharmony_ci#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
798c2ecf20Sopenharmony_ci#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
808c2ecf20Sopenharmony_ci#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
818c2ecf20Sopenharmony_ci#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
828c2ecf20Sopenharmony_ci#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
858c2ecf20Sopenharmony_ci#endif /*  _ASM_POWERPC_NOHASH_32_PTE_40x_H */
86