summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/ml/zulu_hat_asm.s
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sun4u/ml/zulu_hat_asm.s')
-rw-r--r--usr/src/uts/sun4u/ml/zulu_hat_asm.s314
1 files changed, 314 insertions, 0 deletions
diff --git a/usr/src/uts/sun4u/ml/zulu_hat_asm.s b/usr/src/uts/sun4u/ml/zulu_hat_asm.s
new file mode 100644
index 0000000000..eba64b9368
--- /dev/null
+++ b/usr/src/uts/sun4u/ml/zulu_hat_asm.s
@@ -0,0 +1,314 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(lint)
+#include <sys/types.h>
+#include <sys/thread.h>
+#else /* lint */
+#include "assym.h"
+#endif /* lint */
+
+#include <sys/asi.h>
+#include <sys/machasi.h>
+#include <sys/asm_linkage.h>
+#include <zuluvm_offsets.h>
+#include <sys/zulu_hat.h>
+#include <sys/zuluvm.h>
+
+/*
+ * function to look up ttes in zulu_hat TSB.
+ *
+ * zulu_hat_tsb_lookup_tl1 is called from the zuluvm dmv interrupt handler
+ * so we can only use the global registers.
+ *
+ * zulu_hat_tsb_lookup_tl0 is called from TL=0
+ */
+#ifdef lint
+
+/* ARGSUSED */
+uint64_t
+zulu_hat_tsb_lookup_tl1(caddr_t vaddr)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+uint64_t
+zulu_hat_tsb_lookup_tl0(struct zulu_hat *zhat, caddr_t vaddr)
+{
+ return (0);
+}
+
+#else /* lint */
+
+ /*
+ * %g1 - vaddr | ctx
+ * %g3 - return address
+ * Must preserve %g7 for caller
+ *
+ * returns:
+ * %g1 - pfn and flags
+ * %g2 - zuluvm error code if %g1 is null
+ */
+ ENTRY_NP(zulu_hat_tsb_lookup_tl1)
+ set ZULU_CTX_MASK, %g4
+ and %g1, %g4, %g4
+
+ ! we're at trap level 1, (TL=1)
+ ! if the context is already locked by another
+ ! thread, punt to the TL=0 code
+ ! it's not safe to spinloop now.
+
+ set zulu_ctx_tab, %g6
+ sllx %g4, 3, %g5
+#ifdef DEBUG
+ mov %g5, %g2 ! remember ctx * 8
+#endif
+ add %g5, %g6, %g6
+
+ ldx [%g6], %g4
+ andcc %g4, 1, %g0
+ bne,a,pn %icc, ctx_busy
+ mov ZULUVM_CTX_LOCKED, %g2
+
+ ! now do a compare and swap and make sure it's still not locked
+ or %g4, 1, %g5
+ casxa [%g6]ASI_N, %g4, %g5
+ cmp %g4, %g5
+ bne,a,pn %icc, ctx_busy
+ mov ZULUVM_CTX_LOCKED, %g2
+
+ brz,a,pn %g4, zulu_hat_tsb_exit
+ mov %g0, %g1
+
+ ! we have the lock now proceed
+
+ ! set lsb of g3 to indicate that we need to unlock the context
+ ! before returning
+ ba,pt %xcc, zulu_hat_tsb_lookup
+ or %g3, 1, %g3
+
+ctx_busy:
+ mov %g0, %g1
+ jmpl %g3+8, %g0
+ nop
+
+
+ /*
+ * zulu_hat_tsb_lookup_tl0 jumps here
+ *
+ * %g1 vaddr | ctx
+ * %g3 return address | unlock flag (bit zero)
+ * %g4 has the zulu hat ptr (locked)
+ */
+zulu_hat_tsb_lookup:
+ mov %g1, %g2
+ mov %g4, %g1
+
+ add %g1, ZULU_HAT_TSB_SZ, %g5
+ lduh [%g5], %g5 ! tsb size
+ sub %g5, 1, %g5
+
+ srlx %g2, 22, %g4 ! 4m page hash
+ and %g5, %g4, %g4 ! hash index
+ sllx %g4, 4, %g4
+ add %g1, ZULU_HAT_TSB, %g5
+ ldx [%g5], %g5
+ add %g5, %g4, %g4 ! ptr to struct zulu_tte
+ ldx [%g4], %g5 ! get the tag
+
+ set (0x1ff << 13), %g6
+ andn %g5, %g6, %g5
+ andn %g2, %g6, %g6
+ cmp %g5, %g6
+ bne,pn %xcc, zulu_hat_tsb_try_512k
+ nop
+
+ ldx [%g4 + 8], %g4 ! flags and pfn
+ brgez,pn %g4, zulu_hat_tsb_try_512k ! check if entry is valid
+ nop
+
+ sllx %g4, 2, %g5
+ srlx %g5, 61, %g5 ! tte size
+ cmp %g5, ZULU_TTE4M
+ be,pn %xcc, zulu_hat_tsb_found
+ nop
+
+zulu_hat_tsb_try_512k:
+ add %g1, ZULU_HAT_TSB_SZ, %g5
+ lduh [%g5], %g5 ! tsb size
+ sub %g5, 1, %g5
+
+ srlx %g2, 19, %g4 ! 4m page hash
+ and %g5, %g4, %g4 ! hash index
+ sllx %g4, 4, %g4
+ add %g1, ZULU_HAT_TSB, %g5
+ ldx [%g5], %g5
+ add %g5, %g4, %g4 ! ptr to struct zulu_tte
+ ldx [%g4], %g5 ! get the tag
+
+ set (0x3f << 13), %g6
+ andn %g5, %g6, %g5
+ andn %g2, %g6, %g6
+ cmp %g5, %g6
+ bne,pn %xcc, zulu_hat_tsb_try_64k
+ nop
+
+ ldx [%g4 + 8], %g4 ! flags and pfn
+ brgez,pn %g4, zulu_hat_tsb_try_64k ! check if entry is valid
+ nop
+
+ sllx %g4, 2, %g5
+ srlx %g5, 61, %g5 ! tte size
+ cmp %g5, ZULU_TTE512K
+ be,pn %xcc, zulu_hat_tsb_found
+ nop
+
+zulu_hat_tsb_try_64k:
+ add %g1, ZULU_HAT_TSB_SZ, %g5
+ lduh [%g5], %g5 ! tsb size
+ sub %g5, 1, %g5
+
+ srlx %g2, 16, %g4 ! 4m page hash
+ and %g5, %g4, %g4 ! hash index
+ sllx %g4, 4, %g4
+ add %g1, ZULU_HAT_TSB, %g5
+ ldx [%g5], %g5
+ add %g5, %g4, %g4 ! ptr to struct zulu_tte
+ ldx [%g4], %g5 ! get the tag
+
+ set (0x7 << 13), %g6
+ andn %g5, %g6, %g5
+ andn %g2, %g6, %g6
+ cmp %g5, %g6
+ bne,pn %xcc, zulu_hat_tsb_try_8k
+ nop
+
+ ldx [%g4 + 8], %g4 ! flags and pfn
+ brgez,pn %g4, zulu_hat_tsb_try_8k ! check if entry is valid
+ nop
+
+ sllx %g4, 2, %g5
+ srlx %g5, 61, %g5 ! tte size
+ cmp %g5, ZULU_TTE64K
+ be,pn %xcc, zulu_hat_tsb_found
+ nop
+
+zulu_hat_tsb_try_8k:
+ add %g1, ZULU_HAT_TSB_SZ, %g5
+ lduh [%g5], %g5 ! tsb size
+ sub %g5, 1, %g5
+
+ srlx %g2, 13, %g4 ! calc hash
+ and %g5, %g4, %g4 ! hash index
+ sllx %g4, 4, %g4
+ add %g1, ZULU_HAT_TSB, %g5
+ ldx [%g5], %g5 ! tsb ptr
+ add %g5, %g4, %g4 ! ptr to struct tte
+ ldx [%g4], %g5 ! get the tag
+ cmp %g5, %g2
+ bne,pn %xcc, zulu_hat_tsb_exit
+ mov %g0, %g1
+
+ ldx [%g4 + 8], %g4 ! flags and pfn
+ brgez,pn %g4, zulu_hat_tsb_exit ! check if entry is valid
+ mov %g0, %g1
+
+ sllx %g4, 2, %g5
+ srlx %g5, 61, %g5 ! tte size
+ brnz,pn %g5, zulu_hat_tsb_exit
+ mov %g0, %g1
+
+zulu_hat_tsb_found:
+ ! expect the tte size in %g5
+ mulx %g5, 3, %g5
+ mov 1, %g1
+ sllx %g1, %g5, %g1
+ sub %g1, 1, %g1
+ andn %g4, %g1, %g4
+ srlx %g2, 13, %g5
+ and %g1, %g5, %g5
+ or %g5, %g4, %g4
+ mov %g4, %g1
+
+ ! now fall through to exit
+
+zulu_hat_tsb_exit:
+ ! if bit zero of %g3 is set, we're at TL=1 and need to unlock
+ ! the context here
+ andcc %g3, 1, %g0
+ be,pn %xcc, after_unlock
+ nop
+
+ ! clear the context unlock flag
+ andn %g3, 1, %g3
+
+ set ZULU_CTX_MASK, %g6
+ and %g2, %g6, %g6 ! ctx num
+
+ sllx %g6, 3, %g6
+ set zulu_ctx_tab, %g5
+ add %g6, %g5, %g5 ! %g5 = &zulu_ctx_tab[ctx_num]
+ ldx [%g5], %g6
+ andn %g6, 1, %g6
+ stx %g6, [%g5]
+
+after_unlock:
+
+ ! set the status code to ZULUVM_NO_TTE in case we are running at TL=1
+ ! and no tte was found.
+ !
+ ! note: caller doesn't examine %g2 unless flags and pfn are null
+ jmpl %g3 + 0x8, %g0
+ mov ZULUVM_NO_TTE, %g2
+
+
+
+
+ SET_SIZE(zulu_hat_tsb_lookup_tl1)
+
+ /*
+ * %o0 - zulu hat ptr (already locked)
+ * %o1 - vaddr
+ */
+ ENTRY_NP(zulu_hat_tsb_lookup_tl0)
+ mov %o0, %g4
+
+ set zulu_hat_tsb_lookup, %g3
+
+ ! note bit zero of g3 is zero which tells zulu_hat_tsb_lookup
+ ! to not unlock tsb before returning
+
+ jmpl %g3, %g3
+ mov %o1, %g1
+
+ retl
+ mov %g1, %o0
+ SET_SIZE(zulu_hat_tsb_lookup_tl0)
+
+#endif /* lint */