1 /* 2 * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $ 35 */ 36 37 #ifndef _MACHINE_LOCK_H_ 38 #define _MACHINE_LOCK_H_ 39 40 #ifndef _CPU_PSL_H_ 41 #include <machine/psl.h> 42 #endif 43 44 #ifdef LOCORE 45 46 /* 47 * Spinlock assembly support. Note: rax and rcx can be tromped. No 48 * other register will be. Note that these routines are sometimes 49 * called with (%edx) as the mem argument. 50 * 51 * Under UP the spinlock routines still serve to disable/restore 52 * interrupts. 53 */ 54 55 #define SPIN_INIT(mem) \ 56 movq $0,mem ; \ 57 58 #define SPIN_INIT_NOREG(mem) \ 59 SPIN_INIT(mem) ; \ 60 61 #define SPIN_LOCK(mem) \ 62 pushfq ; \ 63 popq %rcx ; /* flags */ \ 64 cli ; \ 65 orq $PSL_C,%rcx ; /* make sure non-zero */ \ 66 7: ; \ 67 movq $0,%rax ; /* expected contents of lock */ \ 68 lock cmpxchgq %rcx,mem ; /* Z=1 (jz) on success */ \ 69 pause ; \ 70 jnz 7b ; \ 71 72 #define SPIN_LOCK_PUSH_REGS \ 73 subq $16,%rsp ; \ 74 movq %rcx,(%rsp) ; \ 75 movq %rax,8(%rsp) ; \ 76 77 #define SPIN_LOCK_POP_REGS \ 78 movq (%rsp),%rcx ; \ 79 movq 8(%rsp),%rax ; \ 80 addq $16,%rsp ; \ 81 82 #define SPIN_LOCK_FRAME_SIZE 16 83 84 #define SPIN_LOCK_NOREG(mem) \ 85 SPIN_LOCK_PUSH_REGS ; \ 86 SPIN_LOCK(mem) ; \ 87 SPIN_LOCK_POP_REGS ; \ 88 89 #define SPIN_UNLOCK(mem) \ 90 pushq mem ; \ 91 movq $0,mem ; \ 92 popfq ; \ 93 94 #define SPIN_UNLOCK_PUSH_REGS 95 #define SPIN_UNLOCK_POP_REGS 96 #define SPIN_UNLOCK_FRAME_SIZE 0 97 98 #define SPIN_UNLOCK_NOREG(mem) \ 99 SPIN_UNLOCK(mem) ; \ 100 101 #else /* !LOCORE */ 102 103 #ifdef _KERNEL 104 105 /* 106 * Spinlock functions (UP and SMP). Under UP a spinlock still serves 107 * to disable/restore interrupts even if it doesn't spin. 108 */ 109 struct spinlock_deprecated { 110 volatile long opaque; 111 }; 112 113 void com_lock(void); /* disables int / spinlock combo */ 114 void com_unlock(void); 115 void imen_lock(void); /* disables int / spinlock combo */ 116 void imen_unlock(void); 117 void clock_lock(void); /* disables int / spinlock combo */ 118 void clock_unlock(void); 119 120 void spin_lock_deprecated(struct spinlock_deprecated *lock); 121 void spin_unlock_deprecated(struct spinlock_deprecated *lock); 122 123 /* 124 * Inline version of spinlock routines -- overrides assembly. Only unlock 125 * and init here please. 126 */ 127 static __inline void 128 spin_init_deprecated(struct spinlock_deprecated *lock) 129 { 130 lock->opaque = 0; 131 } 132 133 #endif /* _KERNEL */ 134 135 #endif /* LOCORE */ 136 #endif /* !_MACHINE_LOCK_H_ */ 137