PPC MD bits for KSE. Runs test cases OK. Crippled to 1:1 mode for

the time being.
This commit is contained in:
Peter Grehan 2004-07-19 12:19:04 +00:00
parent cc73b0f03d
commit 0f47890401
16 changed files with 1640 additions and 0 deletions

View File

@ -0,0 +1,8 @@
# $FreeBSD$
# XXX temporary
CFLAGS+=-DSYSTEM_SCOPE_ONLY
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
SRCS+= enter_uts.S context.S pthread_md.c

View File

@ -0,0 +1,62 @@
/*
* Copyright 2004 by Peter Grehan. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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$
*/
#ifndef _ATOMIC_OPS_H_
#define _ATOMIC_OPS_H_
/*
* Atomic swap:
* Atomic (tmp = *dst, *dst = val), then *res = tmp
*
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
*/
static inline void
atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res)
{
int tmp;
tmp = 0; /* should be a better way to quieten cc1... */
#ifdef __GNUC__
__asm __volatile(
"1: lwarx %0, 0, %4\n" /* load with reservation */
" stwcx. %3, 0, %4\n" /* attempt to store val */
" bne- 1b\n" /* interrupted? retry */
" stw %0, %1\n" /* else, *dst -> *res */
: "=&r" (tmp), "=m" (*res), "+m" (*dst)
: "r" (val), "r" (dst)
: "cc", "memory");
#endif
}
#define atomic_swap_ptr(d, v, r) \
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
#define atomic_swap_int(d, v, r) \
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
#endif

View File

@ -0,0 +1,257 @@
/*
* Copyright 2004 by Peter Grehan. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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>
extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t);
extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *);
extern int _ppc32_getcontext(mcontext_t *);
#define KSE_STACKSIZE 16384
#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext)
#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL)
#define PER_THREAD
struct kcb;
struct kse;
struct pthread;
struct tcb;
struct tdv;
/*
* %r2 points to a struct kcb.
*/
struct ppc32_tp {
struct tdv *tp_tdv; /* dynamic TLS */
uint32_t _reserved_;
long double tp_tls[0]; /* static TLS */
};
struct tcb {
struct kse_thr_mailbox tcb_tmbx;
struct pthread *tcb_thread;
struct kcb *tcb_curkcb;
long tcb_isfake;
struct ppc32_tp tcb_tp;
};
struct kcb {
struct kse_mailbox kcb_kmbx;
struct tcb kcb_faketcb;
struct tcb *kcb_curtcb;
struct kse *kcb_kse;
};
/*
* From the PowerPC32 TLS spec:
*
* "r2 is the thread pointer, and points 0x7000 past the end of the
* thread control block." Or, 0x7008 past the start of the 8-byte tcb
*/
#define TP_OFFSET 0x7008
register uint8_t *_tpr __asm("%r2");
#define _tcb ((struct tcb *)(_tpr - TP_OFFSET - 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. */
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
}
/*
* 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;
_tpr = (uint8_t *)&tcb->tcb_tp + TP_OFFSET;
}
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);
}
static __inline int
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
{
if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
/* Make the fake tcb the current thread. */
kcb->kcb_curtcb = &kcb->kcb_faketcb;
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
_ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
kcb->kcb_kmbx.km_stack.ss_sp,
kcb->kcb_kmbx.km_stack.ss_size - 32);
/* 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;
extern int _libkse_debug;
_tcb_set(kcb, tcb);
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
/*
* A full context needs a system call to restore, so use
* kse_switchin. Otherwise, the partial context can be
* restored with _ppc32_setcontext
*/
if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) {
if (setmbox)
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
else
kse_switchin(&tcb->tcb_tmbx, 0);
} else {
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
if (setmbox)
_ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
else
_ppc32_setcontext(mc, 0, NULL);
}
/* We should not reach here. */
return (-1);
}
#endif /* _PTHREAD_MD_H_ */

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$
*/
/* Used to generate mcontext_t offsets */
#include <sys/types.h>
#include <sys/assym.h>
#include <sys/ucontext.h>
#include <stddef.h>
ASSYM(_MC_VERSION, _MC_VERSION);
ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE);
ASSYM(_MC_FP_VALID, _MC_FP_VALID);
ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers));
ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags));
ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0]));
ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1]));
ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2]));
ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3]));
ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4]));
ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5]));
ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6]));
ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7]));
ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8]));
ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9]));
ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10]));
ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11]));
ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12]));
ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13]));
ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14]));
ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15]));
ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16]));
ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17]));
ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18]));
ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19]));
ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20]));
ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21]));
ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22]));
ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23]));
ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24]));
ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25]));
ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26]));
ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27]));
ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28]));
ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29]));
ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30]));
ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31]));
ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32]));
ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33]));
ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34]));
ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35]));
ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32]));
ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0]));
ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1]));
ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2]));
ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3]));
ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4]));
ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5]));
ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6]));
ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7]));
ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8]));
ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9]));
ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10]));
ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11]));
ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12]));
ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13]));
ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14]));
ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15]));
ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16]));
ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17]));
ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18]));
ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19]));
ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20]));
ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21]));
ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22]));
ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23]));
ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24]));
ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25]));
ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26]));
ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27]));
ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28]));
ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29]));
ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30]));
ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31]));

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$
*/
/*
* Struct offsets for version 0x1 of the mcontext struct.
* Generated with
* cc -c assym.c
* ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s
* hand-edit output
*/
#define _MC_VERSION 0x1
#define _MC_VERSION_KSE 0xee
#define _MC_FP_VALID 0x1
#define _MC_VERS 0x0
#define _MC_FLAGS 0x4
#define _MC_R0 0x298
#define _MC_R1 0x21c
#define _MC_R2 0x220
#define _MC_R3 0x224
#define _MC_R4 0x228
#define _MC_R5 0x22c
#define _MC_R6 0x230
#define _MC_R7 0x234
#define _MC_R8 0x238
#define _MC_R9 0x23c
#define _MC_R10 0x240
#define _MC_R11 0x244
#define _MC_R12 0x248
#define _MC_R13 0x24c
#define _MC_R14 0x250
#define _MC_R15 0x254
#define _MC_R16 0x258
#define _MC_R17 0x25c
#define _MC_R18 0x260
#define _MC_R19 0x264
#define _MC_R20 0x268
#define _MC_R21 0x26c
#define _MC_R22 0x270
#define _MC_R23 0x274
#define _MC_R24 0x278
#define _MC_R25 0x27c
#define _MC_R26 0x280
#define _MC_R27 0x284
#define _MC_R28 0x288
#define _MC_R29 0x28c
#define _MC_R30 0x290
#define _MC_R31 0x294
#define _MC_LR 0x298
#define _MC_CR 0x29c
#define _MC_XER 0x2a0
#define _MC_CTR 0x2a4
#define _MC_FPSCR 0x3c0
#define _MC_F0 0x2c0
#define _MC_F1 0x2c8
#define _MC_F2 0x2d0
#define _MC_F3 0x2d8
#define _MC_F4 0x2e0
#define _MC_F5 0x2e8
#define _MC_F6 0x2f0
#define _MC_F7 0x2f8
#define _MC_F8 0x300
#define _MC_F9 0x308
#define _MC_F10 0x310
#define _MC_F11 0x318
#define _MC_F12 0x320
#define _MC_F13 0x328
#define _MC_F14 0x330
#define _MC_F15 0x338
#define _MC_F16 0x340
#define _MC_F17 0x348
#define _MC_F18 0x350
#define _MC_F19 0x358
#define _MC_F20 0x360
#define _MC_F21 0x368
#define _MC_F22 0x370
#define _MC_F23 0x378
#define _MC_F24 0x380
#define _MC_F25 0x388
#define _MC_F26 0x390
#define _MC_F27 0x398
#define _MC_F28 0x3a0
#define _MC_F29 0x3a8
#define _MC_F30 0x3b0
#define _MC_F31 0x3b8

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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"
/*
* int _ppc32_getcontext(mcontext_t *mcp)
*
* Save register state from a voluntary context switch.
* Only volatile registers, and those needed to complete
* a setcontext call, need to be saved.
*
* r1
* r14-31
* f14-31 XXX
* lr
*
* Return 0 for this call, and set up the context so it will return
* 1 when restored with _ppc32_setcontext().
*
* XXX XXX
* Floating-point is a big issue. Since there's no way to determine
* if the caller has used FP, all volatile register need to be saved.
* If FP hasn't been used, this results in a lazy FP exception in
* the kernel and from that point on FP is always switched in/out
* for the thread, which may be a big performance drag for the system.
* An alternative is to use a system call to get the context, which
* will do the right thing for floating point, but will save all
* registers rather than the caller-saved subset, and has the overhead
* of a syscall.
* Maybe another option would be to give a light-weight way for a
* thread to determine if FP is in used: perhaps a syscall that
* returns in the asm traphandler, or an OSX-style read-only page
* with a flag to indicate FP state.
*
* For now, punt the issue ala Alpha 1:1 model and fix in the future.
*/
ENTRY(_ppc32_getcontext)
stw %r1, _MC_R1(%r3)
stw %r13, _MC_R13(%r3)
stw %r14, _MC_R14(%r3)
stw %r15, _MC_R15(%r3)
stw %r16, _MC_R16(%r3)
stw %r17, _MC_R17(%r3)
stw %r18, _MC_R18(%r3)
stw %r19, _MC_R19(%r3)
stw %r20, _MC_R20(%r3)
stw %r21, _MC_R21(%r3)
stw %r22, _MC_R22(%r3)
stw %r23, _MC_R23(%r3)
stw %r24, _MC_R24(%r3)
stw %r25, _MC_R25(%r3)
stw %r26, _MC_R26(%r3)
stw %r27, _MC_R27(%r3)
stw %r28, _MC_R28(%r3)
stw %r29, _MC_R28(%r3)
stw %r30, _MC_R30(%r3)
stw %r31, _MC_R31(%r3)
mflr %r4
stw %r4, _MC_LR(%r3)
mfcr %r4
stw %r4, _MC_CR(%r3)
/* XXX f14-31 ? */
li %r4, _MC_VERSION_KSE /* partial ucontext version */
stw %r4, _MC_VERS(%r3)
/* Return 0 */
li %r3, 0
blr
/*
* int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
* intptr_t *loc);
*
* Should only be called for partial KSE contexts. The full context
* case is handled by kse_switchin() in _thread_switch()
*
* Returns -1 on error and 1 for return from a saved context
*/
ENTRY(_ppc32_setcontext)
lwz %r6, _MC_VERS(%r3)
cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */
beq 1f
li %r3, -1 /* invalid context type, return -1 */
blr
1: /* partial format, callee-saved regs assumed */
lwz %r1, _MC_R1(%r3)
lwz %r13, _MC_R13(%r3)
lwz %r14, _MC_R14(%r3)
lwz %r15, _MC_R15(%r3)
lwz %r16, _MC_R16(%r3)
lwz %r17, _MC_R17(%r3)
lwz %r18, _MC_R18(%r3)
lwz %r19, _MC_R19(%r3)
lwz %r20, _MC_R20(%r3)
lwz %r21, _MC_R21(%r3)
lwz %r22, _MC_R22(%r3)
lwz %r23, _MC_R23(%r3)
lwz %r24, _MC_R24(%r3)
lwz %r25, _MC_R25(%r3)
lwz %r26, _MC_R26(%r3)
lwz %r27, _MC_R27(%r3)
lwz %r28, _MC_R28(%r3)
lwz %r29, _MC_R28(%r3)
lwz %r30, _MC_R30(%r3)
lwz %r31, _MC_R31(%r3)
lwz %r6, _MC_LR(%r3)
mtlr %r6
lwz %r6, _MC_CR(%r3)
mtcr %r6
/* XXX f14-31 ? */
/* if (loc != NULL) *loc = val */
cmpwi %r5, 0
beq 2f
stw %r4, 0(%r5)
/* Return 1 */
2: li %r3, 1
blr

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$");
/*
* _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
* long stacksz);
*
* Call (*uts)(km) on the requested stack. This function doesn't
* return. The km parameter stays in %r3.
*/
ENTRY(_ppc32_enter_uts)
add %r1,%r5,%r6 /* new stack = stack + stacksz */
mtlr %r4 /* link register = uts */
blrl /* (*uts)(km) */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 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 ``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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <strings.h>
#include "pthread_md.h"
/*
* The constructors.
*/
struct tcb *
_tcb_ctor(struct pthread *thread)
{
struct tcb *tcb;
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
bzero(tcb, sizeof(struct tcb));
tcb->tcb_thread = thread;
/* Allocate TDV */
}
return (tcb);
}
void
_tcb_dtor(struct tcb *tcb)
{
/* Free TDV */
free(tcb);
}
struct kcb *
_kcb_ctor(struct kse *kse)
{
struct kcb *kcb;
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
bzero(kcb, sizeof(struct kcb));
kcb->kcb_faketcb.tcb_isfake = 1;
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
kcb->kcb_curtcb = &kcb->kcb_faketcb;
kcb->kcb_kse = kse;
}
return (kcb);
}
void
_kcb_dtor(struct kcb *kcb)
{
free(kcb);
}

View File

@ -0,0 +1,8 @@
# $FreeBSD$
# XXX temporary
CFLAGS+=-DSYSTEM_SCOPE_ONLY
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
SRCS+= enter_uts.S context.S pthread_md.c

View File

@ -0,0 +1,62 @@
/*
* Copyright 2004 by Peter Grehan. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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$
*/
#ifndef _ATOMIC_OPS_H_
#define _ATOMIC_OPS_H_
/*
* Atomic swap:
* Atomic (tmp = *dst, *dst = val), then *res = tmp
*
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
*/
static inline void
atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res)
{
int tmp;
tmp = 0; /* should be a better way to quieten cc1... */
#ifdef __GNUC__
__asm __volatile(
"1: lwarx %0, 0, %4\n" /* load with reservation */
" stwcx. %3, 0, %4\n" /* attempt to store val */
" bne- 1b\n" /* interrupted? retry */
" stw %0, %1\n" /* else, *dst -> *res */
: "=&r" (tmp), "=m" (*res), "+m" (*dst)
: "r" (val), "r" (dst)
: "cc", "memory");
#endif
}
#define atomic_swap_ptr(d, v, r) \
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
#define atomic_swap_int(d, v, r) \
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
#endif

View File

@ -0,0 +1,257 @@
/*
* Copyright 2004 by Peter Grehan. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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>
extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t);
extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *);
extern int _ppc32_getcontext(mcontext_t *);
#define KSE_STACKSIZE 16384
#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext)
#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL)
#define PER_THREAD
struct kcb;
struct kse;
struct pthread;
struct tcb;
struct tdv;
/*
* %r2 points to a struct kcb.
*/
struct ppc32_tp {
struct tdv *tp_tdv; /* dynamic TLS */
uint32_t _reserved_;
long double tp_tls[0]; /* static TLS */
};
struct tcb {
struct kse_thr_mailbox tcb_tmbx;
struct pthread *tcb_thread;
struct kcb *tcb_curkcb;
long tcb_isfake;
struct ppc32_tp tcb_tp;
};
struct kcb {
struct kse_mailbox kcb_kmbx;
struct tcb kcb_faketcb;
struct tcb *kcb_curtcb;
struct kse *kcb_kse;
};
/*
* From the PowerPC32 TLS spec:
*
* "r2 is the thread pointer, and points 0x7000 past the end of the
* thread control block." Or, 0x7008 past the start of the 8-byte tcb
*/
#define TP_OFFSET 0x7008
register uint8_t *_tpr __asm("%r2");
#define _tcb ((struct tcb *)(_tpr - TP_OFFSET - 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. */
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
}
/*
* 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;
_tpr = (uint8_t *)&tcb->tcb_tp + TP_OFFSET;
}
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);
}
static __inline int
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
{
if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
/* Make the fake tcb the current thread. */
kcb->kcb_curtcb = &kcb->kcb_faketcb;
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
_ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
kcb->kcb_kmbx.km_stack.ss_sp,
kcb->kcb_kmbx.km_stack.ss_size - 32);
/* 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;
extern int _libkse_debug;
_tcb_set(kcb, tcb);
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
/*
* A full context needs a system call to restore, so use
* kse_switchin. Otherwise, the partial context can be
* restored with _ppc32_setcontext
*/
if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) {
if (setmbox)
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
else
kse_switchin(&tcb->tcb_tmbx, 0);
} else {
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
if (setmbox)
_ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
else
_ppc32_setcontext(mc, 0, NULL);
}
/* We should not reach here. */
return (-1);
}
#endif /* _PTHREAD_MD_H_ */

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$
*/
/* Used to generate mcontext_t offsets */
#include <sys/types.h>
#include <sys/assym.h>
#include <sys/ucontext.h>
#include <stddef.h>
ASSYM(_MC_VERSION, _MC_VERSION);
ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE);
ASSYM(_MC_FP_VALID, _MC_FP_VALID);
ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers));
ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags));
ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0]));
ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1]));
ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2]));
ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3]));
ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4]));
ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5]));
ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6]));
ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7]));
ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8]));
ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9]));
ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10]));
ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11]));
ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12]));
ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13]));
ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14]));
ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15]));
ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16]));
ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17]));
ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18]));
ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19]));
ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20]));
ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21]));
ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22]));
ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23]));
ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24]));
ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25]));
ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26]));
ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27]));
ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28]));
ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29]));
ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30]));
ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31]));
ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32]));
ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33]));
ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34]));
ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35]));
ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32]));
ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0]));
ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1]));
ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2]));
ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3]));
ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4]));
ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5]));
ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6]));
ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7]));
ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8]));
ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9]));
ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10]));
ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11]));
ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12]));
ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13]));
ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14]));
ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15]));
ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16]));
ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17]));
ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18]));
ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19]));
ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20]));
ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21]));
ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22]));
ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23]));
ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24]));
ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25]));
ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26]));
ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27]));
ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28]));
ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29]));
ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30]));
ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31]));

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$
*/
/*
* Struct offsets for version 0x1 of the mcontext struct.
* Generated with
* cc -c assym.c
* ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s
* hand-edit output
*/
#define _MC_VERSION 0x1
#define _MC_VERSION_KSE 0xee
#define _MC_FP_VALID 0x1
#define _MC_VERS 0x0
#define _MC_FLAGS 0x4
#define _MC_R0 0x298
#define _MC_R1 0x21c
#define _MC_R2 0x220
#define _MC_R3 0x224
#define _MC_R4 0x228
#define _MC_R5 0x22c
#define _MC_R6 0x230
#define _MC_R7 0x234
#define _MC_R8 0x238
#define _MC_R9 0x23c
#define _MC_R10 0x240
#define _MC_R11 0x244
#define _MC_R12 0x248
#define _MC_R13 0x24c
#define _MC_R14 0x250
#define _MC_R15 0x254
#define _MC_R16 0x258
#define _MC_R17 0x25c
#define _MC_R18 0x260
#define _MC_R19 0x264
#define _MC_R20 0x268
#define _MC_R21 0x26c
#define _MC_R22 0x270
#define _MC_R23 0x274
#define _MC_R24 0x278
#define _MC_R25 0x27c
#define _MC_R26 0x280
#define _MC_R27 0x284
#define _MC_R28 0x288
#define _MC_R29 0x28c
#define _MC_R30 0x290
#define _MC_R31 0x294
#define _MC_LR 0x298
#define _MC_CR 0x29c
#define _MC_XER 0x2a0
#define _MC_CTR 0x2a4
#define _MC_FPSCR 0x3c0
#define _MC_F0 0x2c0
#define _MC_F1 0x2c8
#define _MC_F2 0x2d0
#define _MC_F3 0x2d8
#define _MC_F4 0x2e0
#define _MC_F5 0x2e8
#define _MC_F6 0x2f0
#define _MC_F7 0x2f8
#define _MC_F8 0x300
#define _MC_F9 0x308
#define _MC_F10 0x310
#define _MC_F11 0x318
#define _MC_F12 0x320
#define _MC_F13 0x328
#define _MC_F14 0x330
#define _MC_F15 0x338
#define _MC_F16 0x340
#define _MC_F17 0x348
#define _MC_F18 0x350
#define _MC_F19 0x358
#define _MC_F20 0x360
#define _MC_F21 0x368
#define _MC_F22 0x370
#define _MC_F23 0x378
#define _MC_F24 0x380
#define _MC_F25 0x388
#define _MC_F26 0x390
#define _MC_F27 0x398
#define _MC_F28 0x3a0
#define _MC_F29 0x3a8
#define _MC_F30 0x3b0
#define _MC_F31 0x3b8

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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"
/*
* int _ppc32_getcontext(mcontext_t *mcp)
*
* Save register state from a voluntary context switch.
* Only volatile registers, and those needed to complete
* a setcontext call, need to be saved.
*
* r1
* r14-31
* f14-31 XXX
* lr
*
* Return 0 for this call, and set up the context so it will return
* 1 when restored with _ppc32_setcontext().
*
* XXX XXX
* Floating-point is a big issue. Since there's no way to determine
* if the caller has used FP, all volatile register need to be saved.
* If FP hasn't been used, this results in a lazy FP exception in
* the kernel and from that point on FP is always switched in/out
* for the thread, which may be a big performance drag for the system.
* An alternative is to use a system call to get the context, which
* will do the right thing for floating point, but will save all
* registers rather than the caller-saved subset, and has the overhead
* of a syscall.
* Maybe another option would be to give a light-weight way for a
* thread to determine if FP is in used: perhaps a syscall that
* returns in the asm traphandler, or an OSX-style read-only page
* with a flag to indicate FP state.
*
* For now, punt the issue ala Alpha 1:1 model and fix in the future.
*/
ENTRY(_ppc32_getcontext)
stw %r1, _MC_R1(%r3)
stw %r13, _MC_R13(%r3)
stw %r14, _MC_R14(%r3)
stw %r15, _MC_R15(%r3)
stw %r16, _MC_R16(%r3)
stw %r17, _MC_R17(%r3)
stw %r18, _MC_R18(%r3)
stw %r19, _MC_R19(%r3)
stw %r20, _MC_R20(%r3)
stw %r21, _MC_R21(%r3)
stw %r22, _MC_R22(%r3)
stw %r23, _MC_R23(%r3)
stw %r24, _MC_R24(%r3)
stw %r25, _MC_R25(%r3)
stw %r26, _MC_R26(%r3)
stw %r27, _MC_R27(%r3)
stw %r28, _MC_R28(%r3)
stw %r29, _MC_R28(%r3)
stw %r30, _MC_R30(%r3)
stw %r31, _MC_R31(%r3)
mflr %r4
stw %r4, _MC_LR(%r3)
mfcr %r4
stw %r4, _MC_CR(%r3)
/* XXX f14-31 ? */
li %r4, _MC_VERSION_KSE /* partial ucontext version */
stw %r4, _MC_VERS(%r3)
/* Return 0 */
li %r3, 0
blr
/*
* int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
* intptr_t *loc);
*
* Should only be called for partial KSE contexts. The full context
* case is handled by kse_switchin() in _thread_switch()
*
* Returns -1 on error and 1 for return from a saved context
*/
ENTRY(_ppc32_setcontext)
lwz %r6, _MC_VERS(%r3)
cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */
beq 1f
li %r3, -1 /* invalid context type, return -1 */
blr
1: /* partial format, callee-saved regs assumed */
lwz %r1, _MC_R1(%r3)
lwz %r13, _MC_R13(%r3)
lwz %r14, _MC_R14(%r3)
lwz %r15, _MC_R15(%r3)
lwz %r16, _MC_R16(%r3)
lwz %r17, _MC_R17(%r3)
lwz %r18, _MC_R18(%r3)
lwz %r19, _MC_R19(%r3)
lwz %r20, _MC_R20(%r3)
lwz %r21, _MC_R21(%r3)
lwz %r22, _MC_R22(%r3)
lwz %r23, _MC_R23(%r3)
lwz %r24, _MC_R24(%r3)
lwz %r25, _MC_R25(%r3)
lwz %r26, _MC_R26(%r3)
lwz %r27, _MC_R27(%r3)
lwz %r28, _MC_R28(%r3)
lwz %r29, _MC_R28(%r3)
lwz %r30, _MC_R30(%r3)
lwz %r31, _MC_R31(%r3)
lwz %r6, _MC_LR(%r3)
mtlr %r6
lwz %r6, _MC_CR(%r3)
mtcr %r6
/* XXX f14-31 ? */
/* if (loc != NULL) *loc = val */
cmpwi %r5, 0
beq 2f
stw %r4, 0(%r5)
/* Return 1 */
2: li %r3, 1
blr

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2004 Peter Grehan.
* 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 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$");
/*
* _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
* long stacksz);
*
* Call (*uts)(km) on the requested stack. This function doesn't
* return. The km parameter stays in %r3.
*/
ENTRY(_ppc32_enter_uts)
add %r1,%r5,%r6 /* new stack = stack + stacksz */
mtlr %r4 /* link register = uts */
blrl /* (*uts)(km) */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 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 ``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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <strings.h>
#include "pthread_md.h"
/*
* The constructors.
*/
struct tcb *
_tcb_ctor(struct pthread *thread)
{
struct tcb *tcb;
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
bzero(tcb, sizeof(struct tcb));
tcb->tcb_thread = thread;
/* Allocate TDV */
}
return (tcb);
}
void
_tcb_dtor(struct tcb *tcb)
{
/* Free TDV */
free(tcb);
}
struct kcb *
_kcb_ctor(struct kse *kse)
{
struct kcb *kcb;
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
bzero(kcb, sizeof(struct kcb));
kcb->kcb_faketcb.tcb_isfake = 1;
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
kcb->kcb_curtcb = &kcb->kcb_faketcb;
kcb->kcb_kse = kse;
}
return (kcb);
}
void
_kcb_dtor(struct kcb *kcb)
{
free(kcb);
}