summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2016-05-15 23:37:43 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2016-05-15 23:37:43 +0000
commitaa94d813ac15b199cd5c03e8d728522b43e8c562 (patch)
tree5f7cdc5a18b6e36db83a8235b250ec2e05a6420d
parentaa6cdb54ee75d8ad2bb5b8ac2a496b546bee324f (diff)
Implement TCB_{GET,SET} using PAL_{rd,wr}unique.
Inline asm from NetBSD testing deraadt@
-rw-r--r--sys/arch/alpha/alpha/cpu.c4
-rw-r--r--sys/arch/alpha/alpha/vm_machdep.c20
-rw-r--r--sys/arch/alpha/include/alpha_cpu.h25
-rw-r--r--sys/arch/alpha/include/proc.h4
-rw-r--r--sys/arch/alpha/include/tcb.h31
5 files changed, 76 insertions, 8 deletions
diff --git a/sys/arch/alpha/alpha/cpu.c b/sys/arch/alpha/alpha/cpu.c
index e10b7400257..3b872d0d820 100644
--- a/sys/arch/alpha/alpha/cpu.c
+++ b/sys/arch/alpha/alpha/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.39 2015/08/15 19:04:31 miod Exp $ */
+/* $OpenBSD: cpu.c,v 1.40 2016/05/15 23:37:42 guenther Exp $ */
/* $NetBSD: cpu.c,v 1.44 2000/05/23 05:12:53 thorpej Exp $ */
/*-
@@ -347,7 +347,7 @@ recognized:
* Initialize the idle stack pointer, reserving space for an
* (empty) trapframe (XXX is the trapframe really necessary?)
*/
- pcb->pcb_hw.apcb_ksp = pcb->pcb_hw.apcb_backup_ksp =
+ pcb->pcb_hw.apcb_ksp =
(u_int64_t)pcb + USPACE - sizeof(struct trapframe);
/*
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c
index 26385a93044..0c37b609e60 100644
--- a/sys/arch/alpha/alpha/vm_machdep.c
+++ b/sys/arch/alpha/alpha/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.43 2015/05/05 02:13:46 guenther Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.44 2016/05/15 23:37:42 guenther Exp $ */
/* $NetBSD: vm_machdep.c,v 1.55 2000/03/29 03:49:48 simonb Exp $ */
/*
@@ -242,3 +242,21 @@ vunmapbuf(bp, len)
bp->b_data = bp->b_saveaddr;
bp->b_saveaddr = NULL;
}
+
+void *
+tcb_get(struct proc *p)
+{
+ if (p == curproc)
+ return (void *)alpha_pal_rdunique();
+ else
+ return (void *)p->p_addr->u_pcb.pcb_hw.apcb_unique;
+}
+
+void
+tcb_set(struct proc *p, void *newtcb)
+{
+ KASSERT(p == curproc);
+
+ p->p_addr->u_pcb.pcb_hw.apcb_unique = (unsigned long)newtcb;
+ alpha_pal_wrunique((unsigned long)newtcb);
+}
diff --git a/sys/arch/alpha/include/alpha_cpu.h b/sys/arch/alpha/include/alpha_cpu.h
index f56c74ccfa1..2b2efd0d03c 100644
--- a/sys/arch/alpha/include/alpha_cpu.h
+++ b/sys/arch/alpha/include/alpha_cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: alpha_cpu.h,v 1.12 2014/03/29 18:09:28 guenther Exp $ */
+/* $OpenBSD: alpha_cpu.h,v 1.13 2016/05/15 23:37:42 guenther Exp $ */
/* $NetBSD: alpha_cpu.h,v 1.43 2001/12/18 04:18:22 thorpej Exp $ */
/*
@@ -62,7 +62,6 @@ struct alpha_pcb {
unsigned int apcb_cpc; /* charged process cycles */
unsigned int apcb_asn; /* address space number */
unsigned long apcb_unique; /* process unique value */
-#define apcb_backup_ksp apcb_unique /* backup kernel stack ptr */
unsigned long apcb_flags; /* flags; see below */
unsigned long apcb_decrsv0; /* DEC reserved */
unsigned long apcb_decrsv1; /* DEC reserved */
@@ -390,6 +389,18 @@ alpha_pal_rdps(void)
}
static __inline unsigned long
+alpha_pal_rdunique(void)
+{
+ register unsigned long v0 __asm("$0");
+
+ __asm volatile("call_pal %1 # PAL_rdunique"
+ : "=r" (v0)
+ : "i" (PAL_rdunique));
+
+ return (v0);
+}
+
+static __inline unsigned long
alpha_pal_rdusp(void)
{
register unsigned long v0 __asm("$0");
@@ -499,6 +510,16 @@ alpha_pal_wripir(unsigned long cpu_id)
}
static __inline void
+alpha_pal_wrunique(unsigned long unique)
+{
+ register unsigned long a0 __asm("$16") = unique;
+
+ __asm volatile("call_pal %1 # PAL_wrunique"
+ : "=r" (a0)
+ : "i" (PAL_wrunique), "0" (a0));
+}
+
+static __inline void
alpha_pal_wrusp(unsigned long usp)
{
register unsigned long a0 __asm("$16") = usp;
diff --git a/sys/arch/alpha/include/proc.h b/sys/arch/alpha/include/proc.h
index b75d3bbe9e4..1e4a41939f3 100644
--- a/sys/arch/alpha/include/proc.h
+++ b/sys/arch/alpha/include/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.11 2012/11/01 21:09:17 miod Exp $ */
+/* $OpenBSD: proc.h,v 1.12 2016/05/15 23:37:42 guenther Exp $ */
/* $NetBSD: proc.h,v 1.2 1995/03/24 15:01:36 cgd Exp $ */
/*
@@ -46,6 +46,8 @@ struct mdproc {
struct mdbpt md_sstep[2]; /* two breakpoints for sstep */
};
+#define __HAVE_MD_TCB
+
/*
* md_flags usage
* --------------
diff --git a/sys/arch/alpha/include/tcb.h b/sys/arch/alpha/include/tcb.h
index 1305f9fb96d..278d63133df 100644
--- a/sys/arch/alpha/include/tcb.h
+++ b/sys/arch/alpha/include/tcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcb.h,v 1.1 2011/10/27 04:01:17 guenther Exp $ */
+/* $OpenBSD: tcb.h,v 1.2 2016/05/15 23:37:42 guenther Exp $ */
/*
* Copyright (c) 2011 Philip Guenther <guenther@openbsd.org>
@@ -21,13 +21,40 @@
#ifdef _KERNEL
-#error "not yet"
+void *tcb_get(struct proc *_p);
+void tcb_set(struct proc *_p, void *_newtcb);
+
+#define TCB_GET(p) tcb_get(p)
+#define TCB_SET(p, addr) tcb_set(p, addr)
#else /* _KERNEL */
/* ELF TLS ABI calls for small TCB, with static TLS data after it */
#define TLS_VARIANT 1
+static inline void *
+__alpha_get_tcb(void)
+{
+ register void *__tmp __asm__("$0");
+
+ __asm__ ("call_pal %1 # PAL_rdunique"
+ : "=r" (__tmp)
+ : "i" (0x009e /* PAL_rdunique */));
+ return __tmp;
+}
+#define TCB_GET() __alpha_get_tcb()
+
+static inline void
+__alpha_set_tcb(void *__val)
+{
+ register void *__tmp __asm__("$16") = __val;
+
+ __asm__ volatile ("call_pal %1 # PAL_wrunique"
+ : "=r" (__tmp)
+ : "i" (0x009f /* PAL_wrunique */), "0" (__tmp));
+}
+#define TCB_SET(addr) __alpha_set_tcb(addr)
+
#endif /* _KERNEL */
#endif /* _MACHINE_TCB_H_ */