Add preliminary sparc64 support to libpthread. This does not
yet work, but hopefully someone familiar with the sparc64 port can pick up the reins. Submitted by: jake With mods by: deischen
This commit is contained in:
parent
981152552a
commit
203a51090b
5
lib/libkse/arch/sparc64/Makefile.inc
Normal file
5
lib/libkse/arch/sparc64/Makefile.inc
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= pthread_md.c thr_getcontext.S
|
75
lib/libkse/arch/sparc64/include/atomic_ops.h
Normal file
75
lib/libkse/arch/sparc64/include/atomic_ops.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
#include <machine/atomic.h>
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap_long(long *dst, long val, long *res);
|
||||
*/
|
||||
static __inline void
|
||||
atomic_swap_long(long *dst, long val, long *res)
|
||||
{
|
||||
long tmp;
|
||||
long r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_64(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_swap_int(int *dst, int val, int *res)
|
||||
{
|
||||
int tmp;
|
||||
int r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_32(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(dst, val, res) \
|
||||
atomic_swap_long((long *)dst, (long)val, (long *)res)
|
||||
|
||||
#endif
|
243
lib/libkse/arch/sparc64/include/pthread_md.h
Normal file
243
lib/libkse/arch/sparc64/include/pthread_md.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>.
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
|
||||
/*
|
||||
* %g6 points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory.
|
||||
*
|
||||
* XXX - Both static and dynamic allocation of any of these structures
|
||||
* will result in a valid, well-aligned thread pointer???
|
||||
*/
|
||||
struct sparc64_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint64_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
struct kcb *tcb_curkcb;
|
||||
uint64_t tcb_isfake;
|
||||
uint64_t tcb_spare[4];
|
||||
struct kse_thr_mailbox tcb_tmbx; /* needs 64-byte alignment */
|
||||
struct sparc64_tp tcb_tp;
|
||||
} __aligned(64);
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
register struct sparc64_tp *_tp __asm("%g6");
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tp = &tcb->tcb_tp;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _sparc64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
_sparc64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (setmbox)
|
||||
_thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(mc, 0, NULL);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
13
lib/libkse/arch/sparc64/sparc64/assym.s
Normal file
13
lib/libkse/arch/sparc64/sparc64/assym.s
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Offsets into structures used from asm. Must be kept in sync with
|
||||
* appropriate headers.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define UC_MCONTEXT 0x40
|
||||
|
||||
#define MC_GLOBAL 0x0
|
||||
#define MC_OUT 0x40
|
||||
#define MC_TPC 0xc8
|
||||
#define MC_TNPC 0xc0
|
88
lib/libkse/arch/sparc64/sparc64/pthread_md.c
Normal file
88
lib/libkse/arch/sparc64/sparc64/pthread_md.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 63);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 63) & ~63);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
85
lib/libkse/arch/sparc64/sparc64/thr_getcontext.S
Normal file
85
lib/libkse/arch/sparc64/sparc64/thr_getcontext.S
Normal file
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
.weak CNAME(_thr_getcontext)
|
||||
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
add %o7, 8, %o1
|
||||
add %o1, 4, %o2
|
||||
stx %sp, [%o0 + MC_OUT + (6 * 8)]
|
||||
stx %o1, [%o0 + MC_TPC]
|
||||
stx %o2, [%o0 + MC_TNPC]
|
||||
mov 1, %l0 # Validate the context.
|
||||
stx %l0, [%o0 + MC_GLOBAL]
|
||||
retl
|
||||
nop
|
||||
END(__thr_getcontext)
|
||||
|
||||
.weak CNAME(_thr_setcontext)
|
||||
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
mov %i0, %l0
|
||||
mov %i1, %l1
|
||||
mov %i2, %l2
|
||||
ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1
|
||||
ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2
|
||||
ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3
|
||||
ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4
|
||||
ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5
|
||||
ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6
|
||||
ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7
|
||||
ldx [%l0 + MC_OUT + (0 * 8)], %i0
|
||||
ldx [%l0 + MC_OUT + (1 * 8)], %i1
|
||||
ldx [%l0 + MC_OUT + (2 * 8)], %i2
|
||||
ldx [%l0 + MC_OUT + (3 * 8)], %i3
|
||||
ldx [%l0 + MC_OUT + (4 * 8)], %i4
|
||||
ldx [%l0 + MC_OUT + (5 * 8)], %i5
|
||||
ldx [%l0 + MC_OUT + (6 * 8)], %i6
|
||||
ldx [%l0 + MC_OUT + (7 * 8)], %i7
|
||||
ldx [%l0 + MC_TPC], %l4
|
||||
ldx [%l0 + MC_TNPC], %l3
|
||||
brz %l2, 1f
|
||||
nop
|
||||
stx %l1, [%l2]
|
||||
1: jmpl %l3, %g0
|
||||
return %l4
|
||||
END(__thr_setcontext)
|
||||
|
||||
ENTRY(_sparc64_enter_uts)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
add %i2, %i3, %i2
|
||||
sub %i2, SPOFF + CCFSZ, %sp
|
||||
jmpl %i1, %g0
|
||||
mov %i0, %o0
|
||||
END(_sparc64_enter_uts)
|
5
lib/libpthread/arch/sparc64/Makefile.inc
Normal file
5
lib/libpthread/arch/sparc64/Makefile.inc
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= pthread_md.c thr_getcontext.S
|
75
lib/libpthread/arch/sparc64/include/atomic_ops.h
Normal file
75
lib/libpthread/arch/sparc64/include/atomic_ops.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
#include <machine/atomic.h>
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap_long(long *dst, long val, long *res);
|
||||
*/
|
||||
static __inline void
|
||||
atomic_swap_long(long *dst, long val, long *res)
|
||||
{
|
||||
long tmp;
|
||||
long r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_64(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_swap_int(int *dst, int val, int *res)
|
||||
{
|
||||
int tmp;
|
||||
int r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_32(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(dst, val, res) \
|
||||
atomic_swap_long((long *)dst, (long)val, (long *)res)
|
||||
|
||||
#endif
|
243
lib/libpthread/arch/sparc64/include/pthread_md.h
Normal file
243
lib/libpthread/arch/sparc64/include/pthread_md.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>.
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
|
||||
/*
|
||||
* %g6 points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory.
|
||||
*
|
||||
* XXX - Both static and dynamic allocation of any of these structures
|
||||
* will result in a valid, well-aligned thread pointer???
|
||||
*/
|
||||
struct sparc64_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint64_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
struct kcb *tcb_curkcb;
|
||||
uint64_t tcb_isfake;
|
||||
uint64_t tcb_spare[4];
|
||||
struct kse_thr_mailbox tcb_tmbx; /* needs 64-byte alignment */
|
||||
struct sparc64_tp tcb_tp;
|
||||
} __aligned(64);
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
register struct sparc64_tp *_tp __asm("%g6");
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tp = &tcb->tcb_tp;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _sparc64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
_sparc64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (setmbox)
|
||||
_thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(mc, 0, NULL);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
13
lib/libpthread/arch/sparc64/sparc64/assym.s
Normal file
13
lib/libpthread/arch/sparc64/sparc64/assym.s
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Offsets into structures used from asm. Must be kept in sync with
|
||||
* appropriate headers.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define UC_MCONTEXT 0x40
|
||||
|
||||
#define MC_GLOBAL 0x0
|
||||
#define MC_OUT 0x40
|
||||
#define MC_TPC 0xc8
|
||||
#define MC_TNPC 0xc0
|
88
lib/libpthread/arch/sparc64/sparc64/pthread_md.c
Normal file
88
lib/libpthread/arch/sparc64/sparc64/pthread_md.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 63);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 63) & ~63);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
85
lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S
Normal file
85
lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S
Normal file
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
.weak CNAME(_thr_getcontext)
|
||||
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
add %o7, 8, %o1
|
||||
add %o1, 4, %o2
|
||||
stx %sp, [%o0 + MC_OUT + (6 * 8)]
|
||||
stx %o1, [%o0 + MC_TPC]
|
||||
stx %o2, [%o0 + MC_TNPC]
|
||||
mov 1, %l0 # Validate the context.
|
||||
stx %l0, [%o0 + MC_GLOBAL]
|
||||
retl
|
||||
nop
|
||||
END(__thr_getcontext)
|
||||
|
||||
.weak CNAME(_thr_setcontext)
|
||||
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
mov %i0, %l0
|
||||
mov %i1, %l1
|
||||
mov %i2, %l2
|
||||
ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1
|
||||
ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2
|
||||
ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3
|
||||
ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4
|
||||
ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5
|
||||
ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6
|
||||
ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7
|
||||
ldx [%l0 + MC_OUT + (0 * 8)], %i0
|
||||
ldx [%l0 + MC_OUT + (1 * 8)], %i1
|
||||
ldx [%l0 + MC_OUT + (2 * 8)], %i2
|
||||
ldx [%l0 + MC_OUT + (3 * 8)], %i3
|
||||
ldx [%l0 + MC_OUT + (4 * 8)], %i4
|
||||
ldx [%l0 + MC_OUT + (5 * 8)], %i5
|
||||
ldx [%l0 + MC_OUT + (6 * 8)], %i6
|
||||
ldx [%l0 + MC_OUT + (7 * 8)], %i7
|
||||
ldx [%l0 + MC_TPC], %l4
|
||||
ldx [%l0 + MC_TNPC], %l3
|
||||
brz %l2, 1f
|
||||
nop
|
||||
stx %l1, [%l2]
|
||||
1: jmpl %l3, %g0
|
||||
return %l4
|
||||
END(__thr_setcontext)
|
||||
|
||||
ENTRY(_sparc64_enter_uts)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
add %i2, %i3, %i2
|
||||
sub %i2, SPOFF + CCFSZ, %sp
|
||||
jmpl %i1, %g0
|
||||
mov %i0, %o0
|
||||
END(_sparc64_enter_uts)
|
Loading…
x
Reference in New Issue
Block a user