xref: /titanic_44/usr/src/uts/sun4u/sys/zulu_hat.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	__ZULU_HAT_INCL__
28*7c478bd9Sstevel@tonic-gate #define	__ZULU_HAT_INCL__
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
33*7c478bd9Sstevel@tonic-gate extern "C" {
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #define	ZULU_TTE8K		0
37*7c478bd9Sstevel@tonic-gate #define	ZULU_TTE64K		1
38*7c478bd9Sstevel@tonic-gate #define	ZULU_TTE512K		2
39*7c478bd9Sstevel@tonic-gate #define	ZULU_TTE4M		3
40*7c478bd9Sstevel@tonic-gate #define	ZULUM_MAX_PG_SIZES	4
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_MASK		0x1fff
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #ifndef _ASM
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/atomic.h>
48*7c478bd9Sstevel@tonic-gate #include <vm/xhat.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/avl.h>
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_BP_SHIFT		13
53*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_SZ_SHIFT(sz)		((sz) * 3)
54*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_NUM_PGS(sz)		(1<<ZULU_HAT_SZ_SHIFT(sz))
55*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGSHIFT(s)		(ZULU_HAT_BP_SHIFT + \
56*7c478bd9Sstevel@tonic-gate 					ZULU_HAT_SZ_SHIFT(s))
57*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGSZ(s)		((uint64_t)1<<ZULU_HAT_PGSHIFT(s))
58*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGOFFSET(s)		(ZULU_HAT_PGSZ(s) - 1)
59*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGMASK(s)		(~ZULU_HAT_PGOFFSET((uint64_t)s))
60*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGADDR(a, s)		((uintptr_t)(a) & ZULU_HAT_PGMASK(s))
61*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGADDROFF(a, s)	((uintptr_t)(a) & ZULU_HAT_PGOFFSET(s))
62*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PGDIFF(a, s)		(ZULU_HAT_PGSZ(s) - \
63*7c478bd9Sstevel@tonic-gate 					ZULU_HAT_PGADDROFF(a, s))
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_PFN_MASK(sz)		((1 << ZULU_HAT_SZ_SHIFT(sz)) - 1)
66*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT_ADJ_PFN(ttep, vaddr) \
67*7c478bd9Sstevel@tonic-gate 	((ttep->zulu_tte_pfn & ~ZULU_HAT_PFN_MASK(ttep->zulu_tte_size)) | \
68*7c478bd9Sstevel@tonic-gate 	(((uintptr_t)vaddr >> ZULU_HAT_BP_SHIFT) & \
69*7c478bd9Sstevel@tonic-gate 	ZULU_HAT_PFN_MASK(ttep->zulu_tte_size)))
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * zulu_ctx_tab is an array of pointers to zulu hat structures.
73*7c478bd9Sstevel@tonic-gate  * since the addresses are 8 byte aligned we use bit 0 as a lock flag.
74*7c478bd9Sstevel@tonic-gate  * This will synchronize TL1 access to the tsb and the mappings.
75*7c478bd9Sstevel@tonic-gate  */
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_LOCK	0x1
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_LOCK_INIT(c)		zulu_ctx_tab[c] = NULL
80*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_IS_FREE(c)		(zulu_ctx_tab[c] == NULL)
81*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_SET_HAT(c, h) 		zulu_ctx_tab[c] = h
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate #define	ZULU_CTX_GET_HAT(c)	(struct zulu_hat *)((uint64_t) \
84*7c478bd9Sstevel@tonic-gate 				    zulu_ctx_tab[c] & ~ZULU_CTX_LOCK)
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate struct zulu_tag {
87*7c478bd9Sstevel@tonic-gate 	uint64_t	zulu_tag_page:51;	/* [63:13] vpage */
88*7c478bd9Sstevel@tonic-gate };
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate struct zulu_tte {
91*7c478bd9Sstevel@tonic-gate 	union {
92*7c478bd9Sstevel@tonic-gate 		struct zulu_tag zulu_tte_tag;
93*7c478bd9Sstevel@tonic-gate 		uint64_t 	zulu_tte_addr;
94*7c478bd9Sstevel@tonic-gate 	} un;
95*7c478bd9Sstevel@tonic-gate 	uint_t	zulu_tte_valid  :1;
96*7c478bd9Sstevel@tonic-gate 	uint_t	zulu_tte_perm   :1;
97*7c478bd9Sstevel@tonic-gate 	uint_t	zulu_tte_size   :3;
98*7c478bd9Sstevel@tonic-gate 	uint_t	zulu_tte_locked :1;
99*7c478bd9Sstevel@tonic-gate 	uint_t	zulu_tte_pfn;
100*7c478bd9Sstevel@tonic-gate };
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate /*
103*7c478bd9Sstevel@tonic-gate  * zulu hat stores its list of translation in a hash table.
104*7c478bd9Sstevel@tonic-gate  * TODO: size this table. 256 buckets may be too small.
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate #define	ZULU_HASH_TBL_NUM  0x100
107*7c478bd9Sstevel@tonic-gate #define	ZULU_HASH_TBL_MASK (ZULU_HASH_TBL_NUM - 1)
108*7c478bd9Sstevel@tonic-gate #define	ZULU_HASH_TBL_SHIFT(_s) (ZULU_HAT_BP_SHIFT + (3 * _s))
109*7c478bd9Sstevel@tonic-gate #define	ZULU_HASH_TBL_SZ  (ZULU_HASH_TBL_NUM * sizeof (struct zulu_hat_blk *))
110*7c478bd9Sstevel@tonic-gate #define	ZULU_MAP_HASH_VAL(_v, _s) (((_v) >> ZULU_HASH_TBL_SHIFT(_s)) & \
111*7c478bd9Sstevel@tonic-gate 							ZULU_HASH_TBL_MASK)
112*7c478bd9Sstevel@tonic-gate #define	ZULU_MAP_HASH_HEAD(_zh, _v, _s) \
113*7c478bd9Sstevel@tonic-gate 		(_zh->hash_tbl[ZULU_MAP_HASH_VAL(_v, _s)])
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate /*
116*7c478bd9Sstevel@tonic-gate  *
117*7c478bd9Sstevel@tonic-gate  * TODO: need finalize the number of entries in the TSB
118*7c478bd9Sstevel@tonic-gate  * 32K tsb entries caused us to never get a tsb miss that didn't cause
119*7c478bd9Sstevel@tonic-gate  * a page fault.
120*7c478bd9Sstevel@tonic-gate  *
121*7c478bd9Sstevel@tonic-gate  * Reducing TSB_NUM to 512 entries caused tsb_miss > tsb_hit
122*7c478bd9Sstevel@tonic-gate  * in a yoyo run.
123*7c478bd9Sstevel@tonic-gate  */
124*7c478bd9Sstevel@tonic-gate #define	ZULU_TSB_NUM		4096
125*7c478bd9Sstevel@tonic-gate #define	ZULU_TSB_SZ		(ZULU_TSB_NUM * sizeof (struct zulu_tte))
126*7c478bd9Sstevel@tonic-gate #define	ZULU_TSB_HASH(a, ts, s)	(((uintptr_t)(a) >> ZULU_HAT_PGSHIFT(ts)) & \
127*7c478bd9Sstevel@tonic-gate 					(s-1))
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate #define	ZULU_VADDR(tag)		(tag & ~ZULU_CTX_MASK)
130*7c478bd9Sstevel@tonic-gate #define	ZULU_TTE_TO_PAGE(a)	a.un.zulu_tte_tag.zulu_tag_page
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate struct zulu_hat_blk {
134*7c478bd9Sstevel@tonic-gate 	struct zulu_hat_blk	*zulu_hash_next;
135*7c478bd9Sstevel@tonic-gate 	struct zulu_hat_blk	*zulu_hash_prev;
136*7c478bd9Sstevel@tonic-gate 	struct zulu_shadow_blk  *zulu_shadow_blk;
137*7c478bd9Sstevel@tonic-gate 	struct zulu_tte		zulu_hat_blk_tte;
138*7c478bd9Sstevel@tonic-gate };
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_vaddr	zulu_hat_blk_tte.un.zulu_tte_addr
141*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_pfn	zulu_hat_blk_tte.zulu_tte_pfn
142*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_page	ZULU_TTE_TO_PAGE(zulu_hat_blk_tte)
143*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_perm	zulu_hat_blk_tte.zulu_tte_perm
144*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_size	zulu_hat_blk_tte.zulu_tte_size
145*7c478bd9Sstevel@tonic-gate #define	zulu_hat_blk_valid	zulu_hat_blk_tte.zulu_tte_valid
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate /*
148*7c478bd9Sstevel@tonic-gate  * for fast lookups by address, len we use an avl list to shadow occupied
149*7c478bd9Sstevel@tonic-gate  * 4Mb regions that have mappings.
150*7c478bd9Sstevel@tonic-gate  */
151*7c478bd9Sstevel@tonic-gate #define	ZULU_SHADOW_BLK_RANGE 0x400000
152*7c478bd9Sstevel@tonic-gate #define	ZULU_SHADOW_BLK_MASK (~(ZULU_SHADOW_BLK_RANGE - 1))
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate struct zulu_shadow_blk {
155*7c478bd9Sstevel@tonic-gate 	avl_node_t	link;		/* must be at beginning of struct */
156*7c478bd9Sstevel@tonic-gate 	uint64_t	ivaddr;		/* base address of this node */
157*7c478bd9Sstevel@tonic-gate 	uint64_t	ref_count;
158*7c478bd9Sstevel@tonic-gate 	uint64_t	min_addr;
159*7c478bd9Sstevel@tonic-gate 	uint64_t	max_addr;
160*7c478bd9Sstevel@tonic-gate };
161*7c478bd9Sstevel@tonic-gate #define	ZULU_SHADOW_BLK_LINK_OFFSET (0)
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate struct zulu_hat {
164*7c478bd9Sstevel@tonic-gate 	struct xhat		zulu_xhat;
165*7c478bd9Sstevel@tonic-gate 	kmutex_t		lock;
166*7c478bd9Sstevel@tonic-gate 	avl_tree_t		shadow_tree;
167*7c478bd9Sstevel@tonic-gate 	char			magic;	    /* =42 to mark our data for mdb */
168*7c478bd9Sstevel@tonic-gate 	unsigned		in_fault  : 1;
169*7c478bd9Sstevel@tonic-gate 	unsigned		freed	  : 1;
170*7c478bd9Sstevel@tonic-gate 	unsigned		map8k	  : 1;
171*7c478bd9Sstevel@tonic-gate 	unsigned		map64k	  : 1;
172*7c478bd9Sstevel@tonic-gate 	unsigned		map512k	  : 1;
173*7c478bd9Sstevel@tonic-gate 	unsigned		map4m	  : 1;
174*7c478bd9Sstevel@tonic-gate 	short			zulu_ctx;
175*7c478bd9Sstevel@tonic-gate 	unsigned short		zulu_tsb_size;	/* TODO why not a constant? */
176*7c478bd9Sstevel@tonic-gate 	struct zulu_hat_blk	**hash_tbl;
177*7c478bd9Sstevel@tonic-gate 	struct zulu_tte 	*zulu_tsb;
178*7c478bd9Sstevel@tonic-gate 	struct zulu_shadow_blk	*sblk_last;	/* last sblk looked up */
179*7c478bd9Sstevel@tonic-gate 	uint64_t		fault_ivaddr_last; /* last translation loaded */
180*7c478bd9Sstevel@tonic-gate 	caddr_t			vaddr_max;
181*7c478bd9Sstevel@tonic-gate 	hrtime_t		last_used;
182*7c478bd9Sstevel@tonic-gate 	void			*zdev;
183*7c478bd9Sstevel@tonic-gate };
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate #define	ZULU_HAT2AS(h)	((h)->zulu_xhat.xhat_as)
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate /*
188*7c478bd9Sstevel@tonic-gate  * Assembly language function for TSB lookups
189*7c478bd9Sstevel@tonic-gate  */
190*7c478bd9Sstevel@tonic-gate uint64_t zulu_hat_tsb_lookup_tl0(struct zulu_hat *zhat, caddr_t vaddr);
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate /*
193*7c478bd9Sstevel@tonic-gate  * zuluvm's interface to zulu_hat
194*7c478bd9Sstevel@tonic-gate  */
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate int zulu_hat_load(struct zulu_hat *zhat, caddr_t vaddr, enum seg_rw rw, int *);
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate int zulu_hat_init();
199*7c478bd9Sstevel@tonic-gate int zulu_hat_destroy();
200*7c478bd9Sstevel@tonic-gate int zulu_hat_attach(void *arg);
201*7c478bd9Sstevel@tonic-gate int zulu_hat_detach(void *arg);
202*7c478bd9Sstevel@tonic-gate struct zulu_hat *zulu_hat_proc_attach(struct as *as, void *zdev);
203*7c478bd9Sstevel@tonic-gate void zulu_hat_proc_detach(struct zulu_hat *zhat);
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate void zulu_hat_validate_ctx(struct zulu_hat *zhat);
206*7c478bd9Sstevel@tonic-gate void zulu_hat_terminate(struct zulu_hat *zhat);
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate #endif /* _ASM */
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate #endif
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate #endif	/* __ZULU_HAT_INCL__ */
215