xref: /openbmc/linux/arch/sparc/include/asm/mmu_64.h (revision bef7a78d)
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 /* ADI tags are stored when a page is swapped out and the storage for
94  * tags is allocated dynamically. There is a tag storage descriptor
95  * associated with each set of tag storage pages. Tag storage descriptors
96  * are allocated dynamically. Since kernel will allocate a full page for
97  * each tag storage descriptor, we can store up to
98  * PAGE_SIZE/sizeof(tag storage descriptor) descriptors on that page.
99  */
100 typedef struct {
101 	unsigned long	start;		/* Start address for this tag storage */
102 	unsigned long	end;		/* Last address for tag storage */
103 	unsigned char	*tags;		/* Where the tags are */
104 	unsigned long	tag_users;	/* number of references to descriptor */
105 } tag_storage_desc_t;
106 
107 typedef struct {
108 	spinlock_t		lock;
109 	unsigned long		sparc64_ctx_val;
110 	unsigned long		hugetlb_pte_count;
111 	unsigned long		thp_pte_count;
112 	struct tsb_config	tsb_block[MM_NUM_TSBS];
113 	struct hv_tsb_descr	tsb_descr[MM_NUM_TSBS];
114 	void			*vdso;
115 	bool			adi;
116 	tag_storage_desc_t	*tag_store;
117 	spinlock_t		tag_lock;
118 } mm_context_t;
119 
120 #endif /* !__ASSEMBLY__ */
121 
122 #define TSB_CONFIG_TSB		0x00
123 #define TSB_CONFIG_RSS_LIMIT	0x08
124 #define TSB_CONFIG_NENTRIES	0x10
125 #define TSB_CONFIG_REG_VAL	0x18
126 #define TSB_CONFIG_MAP_VADDR	0x20
127 #define TSB_CONFIG_MAP_PTE	0x28
128 
129 #endif /* __MMU_H */
130