Commit 9f0ff519 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390 update (15/27): 64 bit spinlocks.

Use diag 0x44 on s390x for spinlocks.
parent 33ccf4bd
......@@ -555,6 +555,17 @@ startup:basr %r13,0 # get base
oi 7(%r12),16 # set MVPG flag
0:
#
# find out if the diag 0x44 works in 64 bit mode
#
la %r1,0f-.LPG1(%r13) # set program check address
stg %r1,__LC_PGM_NEW_PSW+8
mvc __LC_DIAG44_OPCODE(8),.Lnop-.LPG1(%r13)
diag 0,0,0x44 # test diag 0x44
oi 7(%r12),32 # set diag44 flag
mvc __LC_DIAG44_OPCODE(8),.Ldiag44-.LPG1(%r13)
0:
lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
# virtual and never return ...
.align 16
......@@ -578,6 +589,8 @@ startup:basr %r13,0 # get base
.Lpcmsk:.quad 0x0000000180000000
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700
.Ldiag44:.long 0x83000044
.org PARMAREA-64
.Lduct: .long 0,0,0,0,0,0,0,0
......
......@@ -38,6 +38,8 @@
#define __LC_IO_INT_WORD 0x0C0
#define __LC_MCCK_CODE 0x0E8
#define __LC_DIAG44_OPCODE 0x214
#define __LC_SAVE_AREA 0xC00
#define __LC_KERNEL_STACK 0xD40
#define __LC_ASYNC_STACK 0xD48
......@@ -146,7 +148,8 @@ struct _lowcore
psw_t io_new_psw; /* 0x1f0 */
psw_t return_psw; /* 0x200 */
__u32 sync_io_word; /* 0x210 */
__u8 pad8[0xc00-0x214]; /* 0x214 */
__u32 diag44_opcode; /* 0x214 */
__u8 pad8[0xc00-0x218]; /* 0x218 */
/* System info area */
__u64 save_area[16]; /* 0xc00 */
__u8 pad9[0xd40-0xc80]; /* 0xc80 */
......
......@@ -25,11 +25,12 @@
*/
extern unsigned long machine_flags;
#define MACHINE_IS_VM (machine_flags & 1)
#define MACHINE_IS_P390 (machine_flags & 4)
#define MACHINE_HAS_MVPG (machine_flags & 16)
#define MACHINE_IS_VM (machine_flags & 1)
#define MACHINE_IS_P390 (machine_flags & 4)
#define MACHINE_HAS_MVPG (machine_flags & 16)
#define MACHINE_HAS_DIAG44 (machine_flags & 32)
#define MACHINE_HAS_HWC (!MACHINE_IS_P390)
#define MACHINE_HAS_HWC (!MACHINE_IS_P390)
/*
* Console mode. Override with conmode=
......
......@@ -16,7 +16,14 @@
* asm/spinlock.h. The diagnose is only available in kernel
* context.
*/
#ifdef __KERNEL__
#include <asm/lowcore.h>
#define __DIAG44_INSN "ex"
#define __DIAG44_OPERAND __LC_DIAG44_OPCODE
#else
#define __DIAG44_INSN "#"
#define __DIAG44_OPERAND 0
#endif
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
......@@ -38,12 +45,13 @@ extern inline void _raw_spin_lock(spinlock_t *lp)
{
unsigned long reg1, reg2;
__asm__ __volatile(" bras %1,1f\n"
"0: # diag 0,0,68\n"
"0: " __DIAG44_INSN " 0,%4\n"
"1: slr %0,%0\n"
" cs %0,%1,0(%3)\n"
" jl 0b\n"
: "=&d" (reg1), "=&d" (reg2), "+m" (lp->lock)
: "a" (&lp->lock) : "cc" );
: "a" (&lp->lock), "i" (__DIAG44_OPERAND)
: "cc" );
}
extern inline int _raw_spin_trylock(spinlock_t *lp)
......@@ -88,43 +96,47 @@ typedef struct {
#define _raw_read_lock(rw) \
asm volatile(" lg 2,0(%1)\n" \
" j 1f\n" \
"0: # diag 0,0,68\n" \
"0: " __DIAG44_INSN " 0,%2\n" \
"1: nihh 2,0x7fff\n" /* clear high (=write) bit */ \
" la 3,1(2)\n" /* one more reader */ \
" csg 2,3,0(%1)\n" /* try to write new value */ \
" jl 0b" \
: "+m" ((rw)->lock) : "a" (&(rw)->lock) \
: "+m" ((rw)->lock) \
: "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \
: "2", "3", "cc" )
#define _raw_read_unlock(rw) \
asm volatile(" lg 2,0(%1)\n" \
" j 1f\n" \
"0: # diag 0,0,68\n" \
"0: " __DIAG44_INSN " 0,%2\n" \
"1: lgr 3,2\n" \
" bctgr 3,0\n" /* one less reader */ \
" csg 2,3,0(%1)\n" \
" jl 0b" \
: "+m" ((rw)->lock) : "a" (&(rw)->lock) \
: "+m" ((rw)->lock) \
: "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \
: "2", "3", "cc" )
#define _raw_write_lock(rw) \
asm volatile(" llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
" j 1f\n" \
"0: # diag 0,0,68\n" \
"0: " __DIAG44_INSN " 0,%2\n" \
"1: slgr 2,2\n" /* old lock value must be 0 */ \
" csg 2,3,0(%1)\n" \
" jl 0b" \
: "+m" ((rw)->lock) : "a" (&(rw)->lock) \
: "+m" ((rw)->lock) \
: "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \
: "2", "3", "cc" )
#define _raw_write_unlock(rw) \
asm volatile(" slgr 3,3\n" /* new lock value = 0 */ \
" j 1f\n" \
"0: # diag 0,0,68\n" \
"0: " __DIAG44_INSN " 0,%2\n" \
"1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
" csg 2,3,0(%1)\n" \
" jl 0b" \
: "+m" ((rw)->lock) : "a" (&(rw)->lock) \
: "+m" ((rw)->lock) \
: "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \
: "2", "3", "cc" )
#endif /* __ASM_SPINLOCK_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment