#include "opt_lockdebug.h"
#include <machine/asm.h>
#include <machine/param.h>
#include <sparc/sparc/vaddrs.h>
#include <sparc/psl.h>
#include "assym.h"
curlwp = CPUINFO_VA + CPUINFO_CURLWP
.section .bss
.align 1024
.globl _C_LABEL(_lock_hash)
OTYPE(_C_LABEL(_lock_hash))
_C_LABEL(_lock_hash):
.space 1024
.text
#ifndef LOCKDEBUG
ENTRY(mutex_enter)
sethi %hi(curlwp), %o3
ld [%o3 + %lo(curlwp)], %o3 ! current thread
ldstub [%o0], %o1 ! try to acquire lock
mutex_enter_crit_start: .globl mutex_enter_crit_start
tst %o1
bnz _C_LABEL(mutex_vector_enter) ! nope, hard case
sra %o3, 5, %o1 ! curlwp >> 5
sethi %hi(0xff000000), %o2 ! finish constructing
or %o1, %o2, %o1 ! lock word
st %o1, [%o0]
mutex_enter_crit_end: .globl mutex_enter_crit_end
retl
nop
ENTRY(mutex_exit)
sethi %hi(curlwp), %o3
ld [%o3 + %lo(curlwp)], %o3 ! current thread
sra %o3, 5, %o1 ! curlwp >> 5
sethi %hi(0xff000000), %o2 ! finish constructing
or %o1, %o2, %o1 ! lock word
ld [%o0], %o2 ! get lock word
cmp %o1, %o2 ! -> 0 if we own lock
bne _C_LABEL(mutex_vector_exit) ! no, hard case
nop
ldub [%o0 + MTX_LOCK], %o3 ! get has-waiters indicator
tst %o3 ! has waiters?
bnz _C_LABEL(mutex_wakeup) ! yes, hard case
st %g0, [%o0] ! and release lock
retl
nop
#if 0
ENTRY(mutex_spin_enter)
sethi %hi(CPUINFO_VA+CPUINFO_MTX_COUNT), %o4
ld [ %o4 + %lo(CPUINFO_VA+CPUINFO_MTX_COUNT) ], %o5
sub %o5, 1, %o1
st %o1, [ %o4 + %lo(CPUINFO_VA+CPUINFO_MTX_COUNT) ]
ldub [ %o0 + MTX_IPL ], %o2
rd %psr, %o1
sll %o2, 8, %o2
and %o1, PSR_PIL, %o3
cmp %o3, %o2
bge 1f
tst %o5
andn %o1, PSR_PIL, %o1
wr %o2, %o1, %psr
nop
nop
nop
tst %o5
1:
sethi %hi(CPUINFO_VA+CPUINFO_MTX_OLDSPL), %o4
bz,a 2f
st %o3, [ %o4 + %lo(CPUINFO_VA+CPUINFO_MTX_OLDSPL) ]
2:
#if defined(MULTIPROCESSOR) || defined(DIAGNOSTIC)
ldstub [ %o0 + MTX_LOCK ], %o2
tst %o2
bnz _C_LABEL(mutex_spin_retry)
nop
#endif
retl
nop
ENTRY(mutex_spin_exit)
#if defined(DIAGNOSTIC)
ldub [ %o0 + MTX_LOCK ], %o1
tst %o1
bz _C_LABEL(mutex_vector_exit)
nop
clrb [ %o0 + MTX_LOCK ]
#elif defined(MULTIPROCESSOR)
clrb [ %o0 + MTX_LOCK ]
#endif
sethi %hi(CPUINFO_VA+CPUINFO_MTX_OLDSPL), %o2
ld [ %o2 + %lo(CPUINFO_VA+CPUINFO_MTX_OLDSPL) ], %o3
sethi %hi(CPUINFO_VA+CPUINFO_MTX_COUNT), %o2
ld [ %o2 + %lo(CPUINFO_VA+CPUINFO_MTX_COUNT) ], %o1
addcc %o1, 1, %o4
bnz 1f
st %o4, [ %o2 + %lo(CPUINFO_VA+CPUINFO_MTX_COUNT) ]
rd %psr, %o1
andn %o1, PSR_PIL, %o1
wr %o3, %o1, %psr
nop
nop
nop
1:
retl
nop
#endif
#endif
ENTRY(_lock_cas)
rd %psr, %o4 ! disable interrupts
or %o4, PSR_PIL, %o5
wr %o5, 0, %psr
nop
nop
nop
srl %o0, 3, %o5
and %o5, 1023, %o5
set _C_LABEL(_lock_hash), %o3
add %o5, %o3, %o5
1:
ldstub [%o5], %o3 ! %o5 == interlock address
tst %o3
bz,a 2f
nop
nop
nop
b,a 1b ! spin
nop
2:
ld [%o0], %o3 ! lock value
cmp %o1, %o3 ! same as expected value?
be,a 3f ! yes, store new value
st %o2, [%o0]
stb %g0, [%o5]
wr %o4, 0, %psr ! enable interrupts
nop
nop
nop
retl
mov %g0, %o0 ! nope
3:
stb %g0, [%o5]
wr %o4, 0, %psr ! enable interrupts
nop
nop
nop
retl
or %g0, 1, %o0