xref: /openbmc/linux/arch/sparc/include/asm/mmu_64.h (revision 04a7279f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __MMU_H
3 #define __MMU_H
4 
5 #include <linux/const.h>
6 #include <asm/page.h>
7 #include <asm/hypervisor.h>
8 
9 #define CTX_NR_BITS		13
10 
11 #define TAG_CONTEXT_BITS	((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL))
12 
13 /* UltraSPARC-III+ and later have a feature whereby you can
14  * select what page size the various Data-TLB instances in the
15  * chip.  In order to gracefully support this, we put the version
16  * field in a spot outside of the areas of the context register
17  * where this parameter is specified.
18  */
19 #define CTX_VERSION_SHIFT	22
20 #define CTX_VERSION_MASK	((~0UL) << CTX_VERSION_SHIFT)
21 
22 #define CTX_PGSZ_8KB		_AC(0x0,UL)
23 #define CTX_PGSZ_64KB		_AC(0x1,UL)
24 #define CTX_PGSZ_512KB		_AC(0x2,UL)
25 #define CTX_PGSZ_4MB		_AC(0x3,UL)
26 #define CTX_PGSZ_BITS		_AC(0x7,UL)
27 #define CTX_PGSZ0_NUC_SHIFT	61
28 #define CTX_PGSZ1_NUC_SHIFT	58
29 #define CTX_PGSZ0_SHIFT		16
30 #define CTX_PGSZ1_SHIFT		19
31 #define CTX_PGSZ_MASK		((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
32 				 (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
33 
34 #define CTX_PGSZ_BASE	CTX_PGSZ_8KB
35 #define CTX_PGSZ_HUGE	CTX_PGSZ_4MB
36 #define CTX_PGSZ_KERN	CTX_PGSZ_4MB
37 
38 /* Thus, when running on UltraSPARC-III+ and later, we use the following
39  * PRIMARY_CONTEXT register values for the kernel context.
40  */
41 #define CTX_CHEETAH_PLUS_NUC \
42 	((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \
43 	 (CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT))
44 
45 #define CTX_CHEETAH_PLUS_CTX0 \
46 	((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \
47 	 (CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT))
48 
49 /* If you want "the TLB context number" use CTX_NR_MASK.  If you
50  * want "the bits I program into the context registers" use
51  * CTX_HW_MASK.
52  */
53 #define CTX_NR_MASK		TAG_CONTEXT_BITS
54 #define CTX_HW_MASK		(CTX_NR_MASK | CTX_PGSZ_MASK)
55 
56 #define CTX_FIRST_VERSION	BIT(CTX_VERSION_SHIFT)
57 #define CTX_VALID(__ctx)	\
58 	 (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
59 #define CTX_HWBITS(__ctx)	((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
60 #define CTX_NRBITS(__ctx)	((__ctx.sparc64_ctx_val) & CTX_NR_MASK)
61 
62 #ifndef __ASSEMBLY__
63 
64 #define TSB_ENTRY_ALIGNMENT	16
65 
66 struct tsb {
67 	unsigned long tag;
68 	unsigned long pte;
69 } __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
70 
71 void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
72 void tsb_flush(unsigned long ent, unsigned long tag);
73 void tsb_init(struct tsb *tsb, unsigned long size);
74 
75 struct tsb_config {
76 	struct tsb		*tsb;
77 	unsigned long		tsb_rss_limit;
78 	unsigned long		tsb_nentries;
79 	unsigned long		tsb_reg_val;
80 	unsigned long		tsb_map_vaddr;
81 	unsigned long		tsb_map_pte;
82 };
83 
84 #define MM_TSB_BASE	0
85 
86 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
87 #define MM_TSB_HUGE	1
88 #define MM_NUM_TSBS	2
89 #else
90 #define MM_NUM_TSBS	1
91 #endif
92 
93 typedef struct {
94 	spinlock_t		lock;
95 	unsigned long		sparc64_ctx_val;
96 	unsigned long		hugetlb_pte_count;
97 	unsigned long		thp_pte_count;
98 	struct tsb_config	tsb_block[MM_NUM_TSBS];
99 	struct hv_tsb_descr	tsb_descr[MM_NUM_TSBS];
100 	void			*vdso;
101 } mm_context_t;
102 
103 #endif /* !__ASSEMBLY__ */
104 
105 #define TSB_CONFIG_TSB		0x00
106 #define TSB_CONFIG_RSS_LIMIT	0x08
107 #define TSB_CONFIG_NENTRIES	0x10
108 #define TSB_CONFIG_REG_VAL	0x18
109 #define TSB_CONFIG_MAP_VADDR	0x20
110 #define TSB_CONFIG_MAP_PTE	0x28
111 
112 #endif /* __MMU_H */
113