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