diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-15 23:37:43 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-15 23:37:43 +0000 |
commit | aa94d813ac15b199cd5c03e8d728522b43e8c562 (patch) | |
tree | 5f7cdc5a18b6e36db83a8235b250ec2e05a6420d /sys/arch/alpha | |
parent | aa6cdb54ee75d8ad2bb5b8ac2a496b546bee324f (diff) |
Implement TCB_{GET,SET} using PAL_{rd,wr}unique.
Inline asm from NetBSD
testing deraadt@
Diffstat (limited to 'sys/arch/alpha')
-rw-r--r-- | sys/arch/alpha/alpha/cpu.c | 4 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/vm_machdep.c | 20 | ||||
-rw-r--r-- | sys/arch/alpha/include/alpha_cpu.h | 25 | ||||
-rw-r--r-- | sys/arch/alpha/include/proc.h | 4 | ||||
-rw-r--r-- | sys/arch/alpha/include/tcb.h | 31 |
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_ */ |