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