xref: /titanic_41/usr/src/uts/sun4u/ml/zulu_asm.s (revision d73ae94e59c019f5cc3221ee0a0012d02091b40e)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#if defined(lint)
29#include <sys/types.h>
30#include <sys/thread.h>
31#else	/* lint */
32#include "assym.h"
33#endif	/* lint */
34
35#include <sys/asi.h>
36#include <sys/sun4asi.h>
37#include <sys/machasi.h>
38#include <sys/asm_linkage.h>
39#include <sys/pte.h>
40#include <sys/mmu.h>
41#include <sys/intreg.h>
42#include <sys/zulumod.h>
43#include <vm/hat_sfmmu.h>
44#include <sys/zulu_hat.h>
45#include <zuluvm_offsets.h>
46
47#ifdef lint
48void
49zuluvm_dmv_tlbmiss_tl1()
50{}
51
52#else	/* lint */
53
54	DGDEF(zuluvm_base_pgsize)
55        .word   0
56
57	ENTRY_NP(zuluvm_dmv_tlbmiss_tl1)
58
59	! g1 - zuluvm_state_t pointer
60	! g2 - IRDR_0
61	mov	UIII_IRDR_1, %g3
62	ldxa	[%g3]ASI_INTR_RECEIVE, %g5
63	stx	%g5, [%g1 + ZULUVM_ASM_TLB_ADDR]
64	mov	UIII_IRDR_6, %g3
65	ldxa	[%g3]ASI_INTR_RECEIVE, %g5
66	stx	%g5, [%g1 + ZULUVM_ASM_TLB_TYPE]
67
68	stxa	%g0, [%g0]ASI_INTR_RECEIVE_STATUS       ! clear the BUSY bit
69	membar	#Sync
70
71	mov	%g1, %g7
72
73	! check the fast tlb miss flag
74	sethi	%hi(zuluvm_fast_tlb), %g6
75	lduw	[%g6 + %lo(zuluvm_fast_tlb)], %g6
76	brz,pn	%g6, send_intr1
77	  mov	ZULUVM_TTE_DELAY, %g1
78#if 1
79	add	%g7, ZULUVM_STATE, %g4
80	mov	ZULUVM_STATE_IDLE, %g1
81	mov	ZULUVM_STATE_TLB_PENDING, %g6
82	casa	[%g4]ASI_N, %g1, %g6
83	cmp 	%g6, %g1
84	be,pt	%icc, 2f
85	  nop
86
87	mov	ZULUVM_STATE_CANCELED, %g1
88	cmp 	%g6, %g1
89	be,pt	%icc, 1f
90	  mov	ZULUVM_STATE_STOPPED, %g1
91	retry
921:
93	st	%g1, [%g4]
94#ifdef ZULUVM_STATS
95	lduw	[%g7 + ZULUVM_ST_TLBCANCEL], %g3
96	add	%g3, 1, %g3
97	stuw	%g3, [%g7 + ZULUVM_ST_TLBCANCEL]
98#endif
99	retry
100
1012:
102	ldx	[%g7 + ZULUVM_ASM_TLB_TYPE], %g4
103	and	%g4, ZULUVM_DMA_MASK, %g4
104#ifdef ZULUVM_STATS
105	cmp	%g4, ZULUVM_DMA2
106	be,a,pn	%icc, 1f
107	  add	%g7, ZULUVM_ST_DTLB2MISS, %g1
108	cmp     %g4, ZULUVM_ITLB1
109	be,a,pn %icc, 1f
110          add   %g7, ZULUVM_ST_ITLB1MISS, %g1
111	cmp     %g4, ZULUVM_ITLB2
112	be,a,pn %icc, 1f
113          add   %g7, ZULUVM_ST_ITLB2MISS, %g1
114	add	%g7, ZULUVM_ST_DTLB1MISS, %g1
1151:
116	lduw	[%g1], %g3
117	add	%g3, 1, %g3
118	stuw 	%g3, [%g1]
119#endif
120	/*
121	 * lookup the tte in the tsb
122	 * %g1 - vaddr[63:13], ctx[12:0]
123	 * %g2 - our trap level
124	 * %g3 - return address
125	 * %g7 - zulu data pointer (needs to be preserved)
126	 * return:
127	 * %g1 - flags [63..58] and pfn [31..0]
128	 * %g2 - status code if %g1 is null
129	 * %g7 - zulu data pointer
130	 */
131	mov	1, %g2
132	set	zulu_hat_tsb_lookup_tl1, %g3
133	jmpl	%g3, %g3
134	  ldx	[%g7 + ZULUVM_ASM_TLB_ADDR], %g1	! vaddr(tag)
135
136	/*
137	 * did we find a tte ??
138	 * If not, %g2 has the error code
139	 */
140	brgez,a,pt %g1, send_intr
141	mov	%g2, %g1
142
143	set	zulu_tsb_hit, %g6
144	ldx	[%g6], %g3
145	add	%g3, 1, %g3
146	stx	%g3, [%g6]
147
148	/*
149	 * get flags and pfn
150	 */
151	sllx    %g1, 32, %g6
152	srlx	%g6, 32, %g6			! %g6 pfn
153	srlx    %g1, 59, %g3
154	and 	%g3, 0x7, %g2			! %g2 page size
155	srlx    %g3, 3, %g4
156	and	%g4, 1, %g4			! %g4 write perm
157	mov     %g6, %g1
158
159	/*
160	 * check if this is a dtlb2 miss(no itlb, pgsz != 8k)
161	 * and if the current dtlb2 pgsz != tte pgsz
162	 */
163	ldx	[%g7 + ZULUVM_ASM_TLB_TYPE], %g3
164	and	%g3, 0x1, %g3
165	brnz,pt %g3, 3f				! not 0 => itlb => handles
166	  nop
167
168	! check page size, base page size is always handled by dtlb1, so we
169	! only need to check against dtlb2
170	sethi   %hi(zuluvm_base_pgsize), %g3
171        lduw    [%g3 + %lo(zuluvm_base_pgsize)], %g3
172	cmp	%g2, %g3
173	be,pt	%icc, 2f
174	cmp	%g2, ZULU_TTE4M
175	be,pt 	%icc, 2f			! TTE4M => dtlb2 => ok!
176	  nop
177
178#ifdef ZULUVM_STATS
179	lduw	[%g7 + ZULUVM_ST_PAGESIZE], %g3
180	add	%g3, 1, %g3
181	stuw	%g3, [%g7 + ZULUVM_ST_PAGESIZE]
182	add	%g7, ZULUVM_ST_MISS, %g3
183	sll	%g2, 2, %g5
184	add	%g5, %g3, %g5
185	lduw	[%g5], %g3
186	add	%g3, 1, %g3
187	stuw	%g3, [%g5]
188#endif
189	! set tte size to ZULUVM_BASE_PGSZ
190	sethi   %hi(zuluvm_base_pgsize), %g3
191        lduw    [%g3 + %lo(zuluvm_base_pgsize)], %g3
192	ba,pt	%icc, 3f
193	  mov	%g3, %g2
1942:
195
196#ifdef ZULUVM_STATS
197	add	%g7, ZULUVM_ST_MISS, %g3
198	sll	%g2, 2, %g5
199	add	%g3, %g5, %g5
200	lduw	[%g5], %g3
201	add	%g3, 1, %g3
202	stuw	%g3, [%g5]
203#endif
204
205	! we maintain data on the last pfns for the last 12 pfns that we
206	! processed
2073:
208        lduw    [%g7 + ZULUVM_PFNCNT], %g5
209        add     %g5, 4, %g3
210        cmp     %g3, 48
211        be,a,pn %icc, 1f
212          mov   %g0, %g3
213
2141:
215        stuw    %g3, [%g7 + ZULUVM_PFNCNT]
216        sllx    %g5, 3, %g5
217        add     %g7, ZULUVM_PFNBUF, %g3
218        add     %g3, %g5, %g3
219        stx     %g1, [%g3]
220        stx     %g2, [%g3 + 8]
221        stx     %g4, [%g3 + 16]
222	ldx     [%g7 + ZULUVM_ASM_TLB_TYPE], %g5
223	stx     %g5, [%g3 + 24]
224
225	ldx	[%g7 + ZULUVM_ASM_TLB_TYPE], %g3
226	and	%g3, 0x3, %g3			! tlbtype
227	ldx	[%g7 + ZULUVM_ARG], %g6
228
229	! write tte to zulu mmu
230	! %g1 pfn
231	! %g2 tte size
232	! %g3 tlbtype
233	! %g4 tte wrperm
234	! %g6 zulu device driver arg
235	! %g7 devtab pointer
236
237	sllx	%g1, ZULUVM_ZFB_MMU_TLB_D_PA_SHIFT, %g1
238	mov	0x1, %g5
239	sllx	%g5, 63, %g5			! ZFB_MMU_TLB_D_V_MASK
240	or	%g1, %g5, %g1
241	or	%g1, ZULUVM_ZFB_MMU_TLB_D_C_MASK, %g1
242	sllx	%g2, ZULUVM_ZFB_MMU_TLB_D_SZ_SHIFT, %g2
243
244	brz,pt	%g4, 3f				! write perm ??
245	  or	%g2, %g1, %g1
246
247	or	%g1, ZULUVM_ZFB_MMU_TLB_D_W_MASK, %g1
2483:
249	! at this point %g1 is ready to be written to the corresponding
250	! data_in register, let's see which if it was itlb or dtlb...
251	and	%g3, ZULUVM_ITLB_FLAG, %g3
252						! assumption is that data miss
253	brz,pt	%g3, 4f				! is more likely than instr miss
254	  ldx	[%g7 + ZULUVM_PAMMU], %g2	! physical addr of zulu mmu regs
255
256	! instruction miss
257	mov     ZULUVM_ZFB_MMU_TLB_CR_IMISS_MASK, %g5
258        add     %g2, ZULUVM_ITLB_DATA_IN, %g4
259	!stxa  %g1, [%g4]ASI_IO
260	ba,pt	%xcc, 5f
261	  stxa  %g1, [%g4]ASI_IO
262	  !ldxa    [%g4]ASI_IO, %g4
2634:
264	! data miss
265	mov     ZULUVM_ZFB_MMU_TLB_CR_DMISS_MASK, %g5
266	add     %g2, ZULUVM_DTLB_DATA_IN, %g4
267	stxa    %g1, [%g4]ASI_IO
268	!ldxa    [%g4]ASI_IO, %g4
2695:
270	add     %g7, ZULUVM_STATE, %g4
271        mov     ZULUVM_STATE_TLB_PENDING, %g6
272        mov     ZULUVM_STATE_IDLE, %g1
273        casa	[%g4]ASI_N, %g6, %g1
274        cmp     %g6, %g1
275        bne,a,pn %icc, stopped
276          mov	ZULUVM_STATE_STOPPED, %g3
277
278	ldx	[%g7 + ZULUVM_PAMMU], %g2
279	add     %g2, ZULUVM_TLB_CONTROL, %g2
280	stxa    %g5, [%g2]ASI_IO
281	!ldxa	[%g2]ASI_IO, %g3
282	retry
283
284send_intr:
285	add     %g7, ZULUVM_STATE, %g4
286	mov     ZULUVM_STATE_INTR_QUEUED, %g5
287	mov     ZULUVM_STATE_TLB_PENDING, %g3
288	casa    [%g4]ASI_N, %g3, %g5
289	cmp     %g3, %g5
290        be,pt  %icc, deliver_intr
291        mov     ZULUVM_STATE_STOPPED, %g3
292	ba,pt	%icc, stopped
293	  nop
294#endif
295
296send_intr1:
297	add	%g7, ZULUVM_STATE, %g4
298	mov     ZULUVM_STATE_IDLE, %g3
299	mov 	ZULUVM_STATE_INTR_QUEUED, %g5
300	casa	[%g4]ASI_N, %g3, %g5
301        cmp     %g3, %g5
302        be,pt  %icc, deliver_intr
303        mov	ZULUVM_STATE_STOPPED, %g3
304stopped:
305	st	%g3, [%g4]
306#ifdef ZULUVM_STATS
307	lduw	[%g7 + ZULUVM_ST_TLBCANCEL], %g3
308	add	%g3, 1, %g3
309	stuw	%g3, [%g7 + ZULUVM_ST_TLBCANCEL]
310#endif
311	retry
312
313deliver_intr:
314	stx     %g1, [%g7 + ZULUVM_ASM_TLB_ERRCODE]     ! set the error field
315        stx     %g6, [%g7 + ZULUVM_ASM_TLB_TTE] ! deliver tte in data_0
316                                                ! %g6 is invalid if error != SUCCESS
317	! setsoftint_tl1(uint64_t inum, uint64_t dummy)
318	set     setsoftint_tl1, %g5
319        jmp     %g5
320        ldx     [%g7 + ZULUVM_INTRNUM], %g1
321
322	SET_SIZE(zuluvm_dmv_tlbmiss_tl1)
323
324#endif	/* lint */
325
326