X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/85100692f959515729499ce1088d5b35532c7d51..38787eefffeaf458d09931320eab5597b7f4e64a:/sys/platform/pc32/isa/ipl_funcs.c diff --git a/sys/platform/pc32/isa/ipl_funcs.c b/sys/platform/pc32/isa/ipl_funcs.c index 2b75b073e3..0ee2ebd55f 100644 --- a/sys/platform/pc32/isa/ipl_funcs.c +++ b/sys/platform/pc32/isa/ipl_funcs.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/isa/ipl_funcs.c,v 1.32.2.5 2002/12/17 18:04:02 sam Exp $ - * $DragonFly: src/sys/platform/pc32/isa/ipl_funcs.c,v 1.5 2003/06/28 04:16:04 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/isa/ipl_funcs.c,v 1.10 2005/06/16 21:12:47 dillon Exp $ */ #include @@ -44,239 +44,36 @@ * * Note: setbits uses a locked or, making simple cases MP safe. */ -#define DO_SETBITS(name, var, bits) \ -void name(void) \ -{ \ - atomic_set_int(var, bits); \ - mycpu->gd_reqpri = TDPRI_CRIT; \ -} - -DO_SETBITS(setdelayed, &ipending, loadandclear(&idelayed)) - -DO_SETBITS(setsoftcamnet,&ipending, SWI_CAMNET_PENDING) -DO_SETBITS(setsoftcambio,&ipending, SWI_CAMBIO_PENDING) -DO_SETBITS(setsoftclock, &ipending, SWI_CLOCK_PENDING) -DO_SETBITS(setsoftnet, &ipending, SWI_NET_PENDING) -DO_SETBITS(setsofttty, &ipending, SWI_TTY_PENDING) -DO_SETBITS(setsoftvm, &ipending, SWI_VM_PENDING) -DO_SETBITS(setsofttq, &ipending, SWI_TQ_PENDING) -DO_SETBITS(setsoftcrypto,&ipending, SWI_CRYPTO_PENDING) - -DO_SETBITS(schedsoftcamnet, &idelayed, SWI_CAMNET_PENDING) -DO_SETBITS(schedsoftcambio, &idelayed, SWI_CAMBIO_PENDING) -DO_SETBITS(schedsoftnet, &idelayed, SWI_NET_PENDING) -DO_SETBITS(schedsofttty, &idelayed, SWI_TTY_PENDING) -DO_SETBITS(schedsoftvm, &idelayed, SWI_VM_PENDING) -DO_SETBITS(schedsofttq, &idelayed, SWI_TQ_PENDING) +#define DO_SETBITS(name, var, bits) \ +void name(void) \ +{ \ + struct mdglobaldata *gd = mdcpu; \ + atomic_set_int_nonlocked(var, bits); \ + atomic_set_int_nonlocked(&gd->mi.gd_reqflags, RQF_INTPEND); \ +} \ + +DO_SETBITS(setdelayed, &gd->gd_ipending, loadandclear(&gd->gd_idelayed)) + +DO_SETBITS(setsoftcamnet,&gd->gd_ipending, SWI_CAMNET_PENDING) +DO_SETBITS(setsoftcambio,&gd->gd_ipending, SWI_CAMBIO_PENDING) +DO_SETBITS(setsoftclock, &gd->gd_ipending, SWI_CLOCK_PENDING) +DO_SETBITS(setsoftnet, &gd->gd_ipending, SWI_NET_PENDING) +DO_SETBITS(setsofttty, &gd->gd_ipending, SWI_TTY_PENDING) +DO_SETBITS(setsoftvm, &gd->gd_ipending, SWI_VM_PENDING) +DO_SETBITS(setsofttq, &gd->gd_ipending, SWI_TQ_PENDING) +DO_SETBITS(setsoftcrypto,&gd->gd_ipending, SWI_CRYPTO_PENDING) + +DO_SETBITS(schedsoftcamnet, &gd->gd_idelayed, SWI_CAMNET_PENDING) +DO_SETBITS(schedsoftcambio, &gd->gd_idelayed, SWI_CAMBIO_PENDING) +DO_SETBITS(schedsoftnet, &gd->gd_idelayed, SWI_NET_PENDING) +DO_SETBITS(schedsofttty, &gd->gd_idelayed, SWI_TTY_PENDING) +DO_SETBITS(schedsoftvm, &gd->gd_idelayed, SWI_VM_PENDING) +DO_SETBITS(schedsofttq, &gd->gd_idelayed, SWI_TQ_PENDING) +/* YYY schedsoft what? */ unsigned softclockpending(void) { - return (ipending & SWI_CLOCK_PENDING); -} - -/* - * Support for SPL assertions. - */ - -#ifdef INVARIANT_SUPPORT - -#define SPLASSERT_IGNORE 0 -#define SPLASSERT_LOG 1 -#define SPLASSERT_PANIC 2 - -static int splassertmode = SPLASSERT_LOG; -SYSCTL_INT(_kern, OID_AUTO, splassertmode, CTLFLAG_RW, - &splassertmode, 0, "Set the mode of SPLASSERT"); -TUNABLE_INT("kern.splassertmode", &splassertmode); - -static void -splassertfail(char *str, const char *msg, char *name, int level) -{ - switch (splassertmode) { - case SPLASSERT_IGNORE: - break; - case SPLASSERT_LOG: - printf(str, msg, name, level); - printf("\n"); - break; - case SPLASSERT_PANIC: - panic(str, msg, name, level); - break; - } -} - -#define GENSPLASSERT(NAME, MODIFIER) \ -void \ -NAME##assert(const char *msg) \ -{ \ - if ((curthread->td_cpl & (MODIFIER)) != (MODIFIER)) \ - splassertfail("%s: not %s, curthread->td_cpl == %#x", \ - msg, __XSTRING(NAME) + 3, curthread->td_cpl); \ -} -#else -#define GENSPLASSERT(NAME, MODIFIER) -#endif - -/************************************************************************ - * GENERAL SPL CODE * - ************************************************************************ - * - * Implement splXXX(), spl0(), splx(), and splq(). splXXX() disables a - * set of interrupts (e.g. splbio() disables interrupts relating to - * device I/O) and returns the previous interrupt mask. splx() restores - * the previous interrupt mask, spl0() is a special case which enables - * all interrupts and is typically used inside i386/i386 swtch.s and - * fork_trampoline. splq() is a generic version of splXXX(). - * - * The SPL routines mess around with the 'cpl' global, which masks - * interrupts. Interrupts are not *actually* masked. What happens is - * that if an interrupt masked by the cpl occurs, the appropriate bit - * in 'ipending' is set and the interrupt is defered. When we clear - * bits in the cpl we must check to see if any ipending interrupts have - * been unmasked and issue the synchronously, which is what the splz() - * call does. - * - * Because the cpl is often saved and restored in a nested fashion, cpl - * modifications are only allowed in the SMP case when the MP lock is held - * to prevent multiple processes from tripping over each other's masks. - * The cpl is saved when you do a context switch (mi_switch()) and restored - * when your process gets cpu again. - * - * An interrupt routine is allowed to modify the cpl as long as it restores - * it prior to returning (thus the interrupted mainline code doesn't notice - * anything amiss). For the SMP case, the interrupt routine must hold - * the MP lock for any cpl manipulation. - * - * Likewise, due to the deterministic nature of cpl modifications, we do - * NOT need to use locked instructions to modify it. - */ - -#ifndef SMP - -#define GENSPL(NAME, OP, MODIFIER, PC) \ -GENSPLASSERT(NAME, MODIFIER) \ -unsigned NAME(void) \ -{ \ - unsigned x; \ - \ - x = curthread->td_cpl; \ - curthread->td_cpl OP MODIFIER; \ - return (x); \ -} - -void -spl0(void) -{ - curthread->td_cpl = 0; - if (ipending && curthread->td_pri < TDPRI_CRIT) - splz(); -} - -void -splx(unsigned ipl) -{ - curthread->td_cpl = ipl; - if ((ipending & ~ipl) && curthread->td_pri < TDPRI_CRIT) - splz(); + return ((mdcpu->gd_ipending | mdcpu->gd_fpending) & SWI_CLOCK_PENDING); } -intrmask_t -splq(intrmask_t mask) -{ - intrmask_t tmp = curthread->td_cpl; - curthread->td_cpl |= mask; - return (tmp); -} - -#else /* !SMP */ - -#include -#include - -/* - * SMP CASE - * - * Mostly the same as the non-SMP case now, but it didn't used to be - * this clean. - */ - -#define GENSPL(NAME, OP, MODIFIER, PC) \ -GENSPLASSERT(NAME, MODIFIER) \ -unsigned NAME(void) \ -{ \ - unsigned x; \ - \ - x = curthread->td_cpl; \ - curthread->td_cpl OP MODIFIER; \ - \ - return (x); \ -} - -/* - * spl0() - unmask all interrupts - * - * The MP lock must be held on entry - * This routine may only be called from mainline code. - */ -void -spl0(void) -{ - KASSERT(inside_intr == 0, ("spl0: called from interrupt")); - curthread->td_cpl = 0; - if (ipending && curthread->td_pri < TDPRI_CRIT) - splz(); -} - -/* - * splx() - restore previous interrupt mask - * - * The MP lock must be held on entry - */ - -void -splx(unsigned ipl) -{ - curthread->td_cpl = ipl; - if (inside_intr == 0 && (ipending & ~curthread->td_cpl) != 0 && - curthread->td_pri < TDPRI_CRIT) { - splz(); - } -} - - -/* - * splq() - blocks specified interrupts - * - * The MP lock must be held on entry - */ -intrmask_t -splq(intrmask_t mask) -{ - intrmask_t tmp = curthread->td_cpl; - curthread->td_cpl |= mask; - return (tmp); -} - -#endif /* !SMP */ - -/* Finally, generate the actual spl*() functions */ - -/* NAME: OP: MODIFIER: PC: */ -GENSPL(splbio, |=, bio_imask, 2) -GENSPL(splcam, |=, cam_imask, 7) -GENSPL(splclock, =, HWI_MASK | SWI_MASK, 3) -GENSPL(splhigh, =, HWI_MASK | SWI_MASK, 4) -GENSPL(splimp, |=, net_imask, 5) -GENSPL(splnet, |=, SWI_NET_MASK, 6) -GENSPL(splsoftcam, |=, SWI_CAMBIO_MASK | SWI_CAMNET_MASK, 8) -GENSPL(splsoftcambio, |=, SWI_CAMBIO_MASK, 9) -GENSPL(splsoftcamnet, |=, SWI_CAMNET_MASK, 10) -GENSPL(splsoftclock, =, SWI_CLOCK_MASK, 11) -GENSPL(splsofttty, |=, SWI_TTY_MASK, 12) -GENSPL(splsoftvm, |=, SWI_VM_MASK, 16) -GENSPL(splsofttq, |=, SWI_TQ_MASK, 17) -GENSPL(splstatclock, |=, stat_imask, 13) -GENSPL(spltty, |=, tty_imask, 14) -GENSPL(splvm, |=, net_imask | bio_imask | cam_imask, 15) -GENSPL(splcrypto, |=, net_imask | SWI_NET_MASK | SWI_CRYPTO_MASK,16)