Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / huron / src / instr_emul.s
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: instr_emul.s
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
47 */
48
49#pragma ident "@(#)instr_emul.s 1.2 07/07/17 SMI"
50
51/*
52 * Niagara II unimplemented instruction emulation
53 */
54#include <sys/asm_linkage.h>
55#include <sys/stack.h>
56#include <hypervisor.h>
57#include <hprivregs.h>
58#include <sparcv9/asi.h>
59#include <asi.h>
60#include <mmu.h>
61#include <traps.h>
62#include <sun4v/traps.h>
63#include <sun4v/mmu.h>
64#include <sun4v/asi.h>
65#include <sun4v/instr.h>
66#include <sparcv9/misc.h>
67
68#include <offsets.h>
69#include <traptable.h>
70#include <util.h>
71#include <guest.h>
72#include <segments.h>
73#include <debug.h>
74#include <abort.h>
75
76 /*
77 * Illegal access to non-cacheable page
78 *
79 * Emulate VIS LDBLOCKF instruction.
80 *
81 * %g1 TPC
82 * %g2 VA from D-SFAR (sign-extended)
83 * %g3 LSUCR
84 */
85 ENTRY(dae_nc_page)
86
87 /*
88 * Decode the instruction to determine whether it's a VIS block load
89 * instruction.
90 *
91 * Note: We know that we will never use these instructions in
92 * hyper-privileged mode so we could ignore that possibility and
93 * save a few instructions. Leave the test in for debug.
94 */
95#ifdef DEBUG
96 rdhpr %htstate, %g4
97 btst HTSTATE_HPRIV, %g4
98 bnz,a,pn %xcc, hvabort
99 rd %pc, %g1
100#endif
101
102 /*
103 * Ascertain what the MMU is doing for instruction translation by
104 * checking LSUCR.im
105 */
106 btst LSUCR_IM, %g3
107 bz,pn %xcc, .dae_nc_page_tpc_ra
108 nop
109
110 /*
111 * Check if we are in nucleus ctx or not. If we
112 * are (ie, we took the trap the trap at TL == 0),
113 * we need to zero the primary ctx regs
114 * before using ASI_ITLB_PROBE.
115 */
116 rdpr %tl, %g3
117 dec %g3
118 brz %g3, 1f
119 .empty
120
121 mov MMU_PCONTEXT0, %g5
122 ldxa [%g5]ASI_MMU, %g4
123 stxa %g0, [%g5]ASI_MMU
124 STRAND_PUSH(%g4, %g6, %g7)
125
126 mov MMU_PCONTEXT1, %g5
127 ldxa [%g5]ASI_MMU, %g4
128 stxa %g0, [%g5]ASI_MMU
129 STRAND_PUSH(%g4, %g6, %g7)
1301:
131 /*
132 * LSUCR.im == 1, virtual address translation is enabled
133 * %g1 contains VA of instruction, clear VA[12:0]
134 */
135 srlx %g1, 13, %g6
136 sllx %g6, 13, %g6
137
138 /*
139 * VA[39:5] for ASI_ITLB_PROBE is VA[47:13]
140 */
141 srlx %g6, 13 - 5, %g6
142 ldxa [%g6]ASI_ITLB_PROBE, %g7
143 brlz,a,pt %g7, 2f ! valid PA ? (bit 63 == 1 ?)
144 nop
145
146 ! not a valid PA, look for RA->PA translation
147 or %g6, (1 << 4), %g6
148 ldxa [%g6]ASI_ITLB_PROBE, %g7
1492:
150 ! if needed, restore MMU contexts
151 brz %g3, 3f
152 nop
153
154 STRAND_POP(%g4, %g5)
155 mov MMU_PCONTEXT0, %g5
156 stxa %g4, [%g5]ASI_MMU
157 STRAND_POP(%g4, %g5)
158 mov MMU_PCONTEXT1, %g5
159 stxa %g4, [%g5]ASI_MMU
160
1613:
162 ! valid PA ? (bit 63 is Valid bit)
163 brlz,a,pt %g7, .dae_nc_page_va
164 sllx %g7, 1, %g6 ! %g6 bit 62 after ITLB_PROBE,
165 ! multi-hit
166
167 /*
168 * nope, retry the instruction and hope for better luck next time
169 *
170 * Note: We are introducing a possible infinite retry/trap loop
171 * here. This needs to be carefully considered.
172 */
173 retry
174
175.dae_nc_page_va:
176 /*
177 * valid instruction address found with ASI_ITLB_PROBE
178 * better avoid multi-hits and parity errors
179 *
180 * %g1 instruction VA
181 * %g7 Valid PA[39:13], (need to clear bit 63)
182 */
183 brlz,pn %g6, .dae_nc_page_dmmu_err ! %g6 bit 62 << 1
184 sllx %g6, 1, %g6 ! %g6 bit 61 after ITLB_PROBE,
185 ! parity
186 brlz,pn %g6, .dae_nc_page_dmmu_err ! %g6 bit 61 << 1
187
188 sllx %g7, 1, %g7
189 srlx %g7, 1, %g7
190
191 ! VA[12:0] -> PA[12:0]
192 set 0x1fff, %g6
193 and %g1, %g6, %g5 ! %g5 VA[12:0]
194 or %g7, %g5, %g7 ! %g7 PA of instruction
195 ba .dae_nc_page_decode_instr
196 ld [%g7], %g5 ! %g5 instruction
197
198.dae_nc_page_tpc_ra:
199
200 /*
201 * TPC contains RA
202 * %g1 contains RA of instruction
203 */
204 GUEST_STRUCT(%g4)
205 RA2PA_CONV(%g4, %g1, %g5, %g6) ! %g5 PA
206 ld [%g5], %g5 ! %g5 instruction
207
208.dae_nc_page_decode_instr:
209 /*
210 * %g1 TPC
211 * %g2 VA from D-SFAR (sign-extended)
212 * %g5 instruction to decode
213 */
214 srlx %g5, LDBLOCKF_OP_SHIFT, %g7 ! op
215 cmp %g7, LDBLOCKF_OP
216 bne,pn %xcc, .dae_nc_page_dmmu_err
217 set LDBLOCKF_OP3_MASK, %g7
218 and %g5, %g7, %g7
219 srlx %g7, LDBLOCKF_OP3_SHIFT, %g7
220 cmp %g7, LDBLOCKF_OP3 ! block load
221 bne,pn %xcc, .dae_nc_page_dmmu_err
222
223 /*
224 * Block load/store, check the ASI from the instruction if instr.i = 0,
225 * from TSTATE.ASI if instr.i = 1.
226 *
227 * %g5 instruction
228 */
229 srlx %g5, LDBLOCKF_I_SHIFT, %g4
230 btst 1, %g4
231 bnz,pn %xcc, 1f ! i = 1
232 nop
233
234 set LDBLOCKF_ASI_MASK, %g4
235 and %g4, %g5, %g4
236 ba,pt %xcc, 2f
237 srlx %g4, LDBLOCKF_ASI_SHIFT, %g4 ! %g4 instr.imm_asi
2381:
239 rdpr %tstate, %g4
240 srlx %g4, TSTATE_ASI_SHIFT, %g4
241 and %g4, TSTATE_ASI_MASK, %g4
2422:
243
244 /*
245 * If the ASI is not for a block load/store, no emulation
246 * The following ASIs are for use with LDDFA and STDFA instructions
247 * as Block Load (LDBLOCKF) and Block Store (STBLOCKF) operations.
248 *
249 * The block load ASI is mapped as :-
250 *
251 * ASI_BLK_AIUP -> ASI_AIUP
252 * ASI_BLK_AIUS -> ASI_AIUS
253 * ASI_BLK_AIUP_LE -> ASI_AIUP_LE
254 * ASI_BLK_AIUS_LE -> ASI_AIUS_LE
255 * ASI_BLK_P -> ASI_AIUP
256 * ASI_BLK_S -> ASI_AIUS
257 * ASI_BLK_PL -> ASI_AIUP_LE
258 * ASI_BLK_SL -> ASI_AIUS_LE
259 *
260 * Note: Is there a possible TLB/TSB miss here which would cause
261 * a guest trap at TL > 1 but with a user VA ? We are entering
262 * dangerous territor here.
263 *
264 * %g4 ASI
265 */
266 cmp %g4, ASI_BLK_P
267 be,pn %xcc, .dae_nc_page_asi_ok
268 mov ASI_AIUP, %g7
269 cmp %g4, ASI_BLK_S
270 be,pn %xcc, .dae_nc_page_asi_ok
271 mov ASI_AIUS, %g7
272 cmp %g4, ASI_BLK_PL
273 be,pn %xcc, .dae_nc_page_asi_ok
274 mov ASI_AIUP_LE, %g7
275 cmp %g4, ASI_BLK_SL
276 be,pn %xcc, .dae_nc_page_asi_ok
277 mov ASI_AIUS_LE, %g7
278 cmp %g4, ASI_BLK_AIUP
279 be,pn %xcc, .dae_nc_page_asi_ok
280 mov ASI_AIUP, %g7
281 cmp %g4, ASI_BLK_AIUS
282 be,pn %xcc, .dae_nc_page_asi_ok
283 mov ASI_AIUS, %g7
284 cmp %g4, ASI_BLK_AIUP_LE
285 be,pn %xcc, .dae_nc_page_asi_ok
286 mov ASI_AIUP_LE, %g7
287 cmp %g4, ASI_BLK_AIUS_LE
288 be,pn %xcc, .dae_nc_page_asi_ok
289 mov ASI_AIUS_LE, %g7
290
291 /*
292 * Not a block load/store ASI, so treat this as any other
293 * MMU DAE_nc_page error
294 */
295 ba,a,pt %xcc, .dae_nc_page_dmmu_err
296 .empty
297
298.dae_nc_page_asi_ok:
299 /*
300 * Valid LDBLOCKF VIS instruction, emulate
301 *
302 * %g2 VA from D-SFAR (sign-extended)
303 * %g5 instruction
304 * %g7 ASI
305 */
306
307 /*
308 * Get the target register, verify that it is a double-precision
309 * FP register aligned on an eight-double-precision register boundary.
310 */
311 set LDBLOCKF_RD_MASK, %g3
312 and %g5, %g3, %g3
313 srlx %g3, LDBLOCKF_RD_SHIFT, %g3 ! %g3 target FP register
314 btst 1, %g3 ! if odd-numbered fp reg, it
315 ! is for fp32 and up
316
317 bnz,a,pt %xcc, 0f ! it is for fp32 and up
318 add %g3, 31, %g3 ! only 5 bits available for
319 ! dest reg in instr
3200:
321#if 0
322 /*
323 * illegal_inst trap has priority, no need to check for aligned fp reg
324 * save a couple of instructions here
325 */
326 btst 0xf, %g3
327 bnz,pn %xcc, .dae_nc_page_dmmu_err
328 nop
329#endif
330
331 wr %g7, %asi ! set target ASI
332
333 /*
334 * we know this was a valid FP block load operation,
335 * as the fp_disabled trap has priority, so FPRS.fef
336 * must have been set. Set it again now for the hypervisor
337 * without checking/storing FPRS, save a few instructions.
338 * The DAE_nc_page trap will have enabled PSTATE.PEF.
339 */
340 wr %g0, FPRS_FEF, %fprs
341
342.dae_nc_page_ldblockf:
343
344#define LD_FP_SIZE (SZ_INSTR * 9)
345
346 /*
347 * get address of 'load table' below
348 *
349 * %g2 PA
350 * %g3 target register
351 */
352 ba 1f
353 rd %pc, %g5
354
355.dae_nc_page_load_fp0:
356 ldda [%g2 + 0]%asi, %f0
357 ldda [%g2 + 8]%asi, %f2
358 ldda [%g2 + 16]%asi, %f4
359 ldda [%g2 + 24]%asi, %f6
360 ldda [%g2 + 32]%asi, %f8
361 ldda [%g2 + 40]%asi, %f10
362 ldda [%g2 + 48]%asi, %f12
363 ldda [%g2 + 56]%asi, %f14
364 done
365
366.dae_nc_page_load_fp16:
367 ldda [%g2 + 0]%asi, %f16
368 ldda [%g2 + 8]%asi, %f18
369 ldda [%g2 + 16]%asi, %f20
370 ldda [%g2 + 24]%asi, %f22
371 ldda [%g2 + 32]%asi, %f24
372 ldda [%g2 + 40]%asi, %f26
373 ldda [%g2 + 48]%asi, %f28
374 ldda [%g2 + 56]%asi, %f30
375 done
376
377.dae_nc_page_load_fp32:
378 ldda [%g2 + 0]%asi, %f32
379 ldda [%g2 + 8]%asi, %f34
380 ldda [%g2 + 16]%asi, %f36
381 ldda [%g2 + 24]%asi, %f38
382 ldda [%g2 + 32]%asi, %f40
383 ldda [%g2 + 40]%asi, %f42
384 ldda [%g2 + 48]%asi, %f44
385 ldda [%g2 + 56]%asi, %f46
386 done
387
388.dae_nc_page_load_fp48:
389 ldda [%g2 + 0]%asi, %f48
390 ldda [%g2 + 8]%asi, %f50
391 ldda [%g2 + 16]%asi, %f52
392 ldda [%g2 + 24]%asi, %f54
393 ldda [%g2 + 32]%asi, %f56
394 ldda [%g2 + 40]%asi, %f58
395 ldda [%g2 + 48]%asi, %f60
396 ldda [%g2 + 56]%asi, %f62
397 done
398
3991:
400
401 /*
402 * Jump into the load table, load the FP registers from the
403 * source address and return to TNPC.
404 *
405 * target register must be 8 double-aligned, (% 16 == 0)
406 *
407 * %g2 PA for load
408 * %g3 target register
409 * %g5 &.dae_nc_page_load_fp0
410 */
411 srlx %g3, 4, %g3 ! fpreg / 16
412 mulx %g3, LD_FP_SIZE, %g3
413 add %g3, %g5, %g3
414 jmp %g3 + SZ_INSTR
415 nop
416
417.dae_nc_page_dmmu_err:
418 /*
419 * Emulation not supported for this instruction, treat as
420 * DMMU DAE_nc_page error
421 */
422 DMMU_ERR_RV(MMU_FT_NCATOMIC)
423
424 /* NOTREACHED */
425
426 SET_SIZE(dae_nc_page)