forked from Minki/linux
[S390] Inline assembly cleanup.
Major cleanup of all s390 inline assemblies. They now have a common coding style. Quite a few have been shortened, mainly by using register asm variables. Use of the EX_TABLE macro helps as well. The atomic ops, bit ops and locking inlines new use the Q-constraint if a newer gcc is used. That results in slightly better code. Thanks to Christian Borntraeger for proof reading the changes. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
25d83cbfaa
commit
94c12cc7d1
@ -104,63 +104,6 @@ struct crypt_s390_query_status {
|
|||||||
u64 low;
|
u64 low;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard fixup and ex_table sections for crypt_s390 inline functions.
|
|
||||||
* label 0: the s390 crypto operation
|
|
||||||
* label 1: just after 1 to catch illegal operation exception
|
|
||||||
* (unsupported model)
|
|
||||||
* label 6: the return point after fixup
|
|
||||||
* label 7: set error value if exception _in_ crypto operation
|
|
||||||
* label 8: set error value if illegal operation exception
|
|
||||||
* [ret] is the variable to receive the error code
|
|
||||||
* [ERR] is the error code value
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
#define __crypt_s390_fixup \
|
|
||||||
".section .fixup,\"ax\" \n" \
|
|
||||||
"7: lhi %0,%h[e1] \n" \
|
|
||||||
" bras 1,9f \n" \
|
|
||||||
" .long 6b \n" \
|
|
||||||
"8: lhi %0,%h[e2] \n" \
|
|
||||||
" bras 1,9f \n" \
|
|
||||||
" .long 6b \n" \
|
|
||||||
"9: l 1,0(1) \n" \
|
|
||||||
" br 1 \n" \
|
|
||||||
".previous \n" \
|
|
||||||
".section __ex_table,\"a\" \n" \
|
|
||||||
" .align 4 \n" \
|
|
||||||
" .long 0b,7b \n" \
|
|
||||||
" .long 1b,8b \n" \
|
|
||||||
".previous"
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
#define __crypt_s390_fixup \
|
|
||||||
".section .fixup,\"ax\" \n" \
|
|
||||||
"7: lhi %0,%h[e1] \n" \
|
|
||||||
" jg 6b \n" \
|
|
||||||
"8: lhi %0,%h[e2] \n" \
|
|
||||||
" jg 6b \n" \
|
|
||||||
".previous\n" \
|
|
||||||
".section __ex_table,\"a\" \n" \
|
|
||||||
" .align 8 \n" \
|
|
||||||
" .quad 0b,7b \n" \
|
|
||||||
" .quad 1b,8b \n" \
|
|
||||||
".previous"
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard code for setting the result of s390 crypto instructions.
|
|
||||||
* %0: the register which will receive the result
|
|
||||||
* [result]: the register containing the result (e.g. second operand length
|
|
||||||
* to compute number of processed bytes].
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
#define __crypt_s390_set_result \
|
|
||||||
" lr %0,%[result] \n"
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
#define __crypt_s390_set_result \
|
|
||||||
" lgr %0,%[result] \n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Executes the KM (CIPHER MESSAGE) operation of the CPU.
|
* Executes the KM (CIPHER MESSAGE) operation of the CPU.
|
||||||
* @param func: the function code passed to KM; see crypt_s390_km_func
|
* @param func: the function code passed to KM; see crypt_s390_km_func
|
||||||
@ -176,28 +119,24 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
|
|||||||
{
|
{
|
||||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||||
register void* __param asm("1") = param;
|
register void* __param asm("1") = param;
|
||||||
register u8* __dest asm("4") = dest;
|
|
||||||
register const u8* __src asm("2") = src;
|
register const u8* __src asm("2") = src;
|
||||||
register long __src_len asm("3") = src_len;
|
register long __src_len asm("3") = src_len;
|
||||||
|
register u8* __dest asm("4") = dest;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
asm volatile(
|
||||||
__asm__ __volatile__ (
|
"0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */
|
||||||
"0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */
|
|
||||||
"1: brc 1,0b \n" /* handle partial completion */
|
"1: brc 1,0b \n" /* handle partial completion */
|
||||||
__crypt_s390_set_result
|
" ahi %0,%h7\n"
|
||||||
"6: \n"
|
"2: ahi %0,%h8\n"
|
||||||
__crypt_s390_fixup
|
"3:\n"
|
||||||
: "+d" (ret), "+a" (__dest), "+a" (__src),
|
EX_TABLE(0b,3b) EX_TABLE(1b,2b)
|
||||||
[result] "+d" (__src_len)
|
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
|
||||||
: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
|
: "d" (__func), "a" (__param), "0" (-EFAULT),
|
||||||
"a" (__param)
|
"K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
|
||||||
: "cc", "memory"
|
if (ret < 0)
|
||||||
);
|
return ret;
|
||||||
if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
|
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||||
ret = src_len - ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -215,28 +154,24 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
|
|||||||
{
|
{
|
||||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||||
register void* __param asm("1") = param;
|
register void* __param asm("1") = param;
|
||||||
register u8* __dest asm("4") = dest;
|
|
||||||
register const u8* __src asm("2") = src;
|
register const u8* __src asm("2") = src;
|
||||||
register long __src_len asm("3") = src_len;
|
register long __src_len asm("3") = src_len;
|
||||||
|
register u8* __dest asm("4") = dest;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
asm volatile(
|
||||||
__asm__ __volatile__ (
|
"0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
|
||||||
"0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
|
|
||||||
"1: brc 1,0b \n" /* handle partial completion */
|
"1: brc 1,0b \n" /* handle partial completion */
|
||||||
__crypt_s390_set_result
|
" ahi %0,%h7\n"
|
||||||
"6: \n"
|
"2: ahi %0,%h8\n"
|
||||||
__crypt_s390_fixup
|
"3:\n"
|
||||||
: "+d" (ret), "+a" (__dest), "+a" (__src),
|
EX_TABLE(0b,3b) EX_TABLE(1b,2b)
|
||||||
[result] "+d" (__src_len)
|
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
|
||||||
: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
|
: "d" (__func), "a" (__param), "0" (-EFAULT),
|
||||||
"a" (__param)
|
"K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
|
||||||
: "cc", "memory"
|
if (ret < 0)
|
||||||
);
|
return ret;
|
||||||
if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
|
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||||
ret = src_len - ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -258,22 +193,19 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
|
|||||||
register long __src_len asm("3") = src_len;
|
register long __src_len asm("3") = src_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
asm volatile(
|
||||||
__asm__ __volatile__ (
|
"0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
|
||||||
"0: .insn rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
|
"1: brc 1,0b \n" /* handle partial completion */
|
||||||
"1: brc 1,0b \n" /* handle partical completion */
|
" ahi %0,%h6\n"
|
||||||
__crypt_s390_set_result
|
"2: ahi %0,%h7\n"
|
||||||
"6: \n"
|
"3:\n"
|
||||||
__crypt_s390_fixup
|
EX_TABLE(0b,3b) EX_TABLE(1b,2b)
|
||||||
: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
|
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||||
: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
|
: "d" (__func), "a" (__param), "0" (-EFAULT),
|
||||||
"a" (__param)
|
"K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
|
||||||
: "cc", "memory"
|
if (ret < 0)
|
||||||
);
|
return ret;
|
||||||
if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
|
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||||
ret = src_len - ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -294,22 +226,19 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
|
|||||||
register long __src_len asm("3") = src_len;
|
register long __src_len asm("3") = src_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
asm volatile(
|
||||||
__asm__ __volatile__ (
|
"0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
|
||||||
"0: .insn rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
|
"1: brc 1,0b \n" /* handle partial completion */
|
||||||
"1: brc 1,0b \n" /* handle partical completion */
|
" ahi %0,%h6\n"
|
||||||
__crypt_s390_set_result
|
"2: ahi %0,%h7\n"
|
||||||
"6: \n"
|
"3:\n"
|
||||||
__crypt_s390_fixup
|
EX_TABLE(0b,3b) EX_TABLE(1b,2b)
|
||||||
: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
|
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||||
: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
|
: "d" (__func), "a" (__param), "0" (-EFAULT),
|
||||||
"a" (__param)
|
"K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
|
||||||
: "cc", "memory"
|
if (ret < 0)
|
||||||
);
|
return ret;
|
||||||
if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
|
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||||
ret = src_len - ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -331,22 +260,19 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
|
|||||||
register long __src_len asm("3") = src_len;
|
register long __src_len asm("3") = src_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
asm volatile(
|
||||||
__asm__ __volatile__ (
|
"0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
|
||||||
"0: .insn rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
|
"1: brc 1,0b \n" /* handle partial completion */
|
||||||
"1: brc 1,0b \n" /* handle partical completion */
|
" ahi %0,%h6\n"
|
||||||
__crypt_s390_set_result
|
"2: ahi %0,%h7\n"
|
||||||
"6: \n"
|
"3:\n"
|
||||||
__crypt_s390_fixup
|
EX_TABLE(0b,3b) EX_TABLE(1b,2b)
|
||||||
: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
|
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||||
: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
|
: "d" (__func), "a" (__param), "0" (-EFAULT),
|
||||||
"a" (__param)
|
"K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
|
||||||
: "cc", "memory"
|
if (ret < 0)
|
||||||
);
|
return ret;
|
||||||
if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
|
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||||
ret = src_len - ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -333,22 +333,14 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
|
|||||||
register unsigned long _subcode asm("0") = subcode;
|
register unsigned long _subcode asm("0") = subcode;
|
||||||
register unsigned long _size asm("1") = size;
|
register unsigned long _size asm("1") = size;
|
||||||
|
|
||||||
asm volatile (" diag %2,%0,0x204\n"
|
asm volatile(
|
||||||
"0: \n" ".section __ex_table,\"a\"\n"
|
" diag %2,%0,0x204\n"
|
||||||
#ifndef __s390x__
|
"0:\n"
|
||||||
" .align 4\n"
|
EX_TABLE(0b,0b)
|
||||||
" .long 0b,0b\n"
|
: "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory");
|
||||||
#else
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b,0b\n"
|
|
||||||
#endif
|
|
||||||
".previous":"+d" (_subcode), "+d"(_size)
|
|
||||||
:"d"(addr)
|
|
||||||
:"memory");
|
|
||||||
if (_subcode)
|
if (_subcode)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
return _size;
|
||||||
return _size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -491,8 +483,7 @@ out:
|
|||||||
|
|
||||||
static void diag224(void *ptr)
|
static void diag224(void *ptr)
|
||||||
{
|
{
|
||||||
asm volatile(" diag %0,%1,0x224\n"
|
asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory");
|
||||||
: :"d" (0), "d"(ptr) : "memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diag224_get_name_table(void)
|
static int diag224_get_name_table(void)
|
||||||
|
@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs)
|
|||||||
current->ptrace &= ~PT_DTRACE;
|
current->ptrace &= ~PT_DTRACE;
|
||||||
task_unlock(current);
|
task_unlock(current);
|
||||||
current->thread.fp_regs.fpc=0;
|
current->thread.fp_regs.fpc=0;
|
||||||
__asm__ __volatile__
|
asm volatile("sfpc %0,0" : : "d" (0));
|
||||||
("sr 0,0\n\t"
|
|
||||||
"sfpc 0,0\n\t"
|
|
||||||
: : :"0");
|
|
||||||
}
|
}
|
||||||
putname(filename);
|
putname(filename);
|
||||||
out:
|
out:
|
||||||
|
@ -25,11 +25,8 @@ static char cpcmd_buf[241];
|
|||||||
*/
|
*/
|
||||||
int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
|
int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
|
||||||
{
|
{
|
||||||
const int mask = 0x40000000L;
|
unsigned long flags, cmdlen;
|
||||||
unsigned long flags;
|
int return_code, return_len;
|
||||||
int return_code;
|
|
||||||
int return_len;
|
|
||||||
int cmdlen;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&cpcmd_lock, flags);
|
spin_lock_irqsave(&cpcmd_lock, flags);
|
||||||
cmdlen = strlen(cmd);
|
cmdlen = strlen(cmd);
|
||||||
@ -38,64 +35,44 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
|
|||||||
ASCEBC(cpcmd_buf, cmdlen);
|
ASCEBC(cpcmd_buf, cmdlen);
|
||||||
|
|
||||||
if (response != NULL && rlen > 0) {
|
if (response != NULL && rlen > 0) {
|
||||||
|
register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
|
||||||
|
register unsigned long reg3 asm ("3") = (addr_t) response;
|
||||||
|
register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
|
||||||
|
register unsigned long reg5 asm ("5") = rlen;
|
||||||
|
|
||||||
memset(response, 0, rlen);
|
memset(response, 0, rlen);
|
||||||
|
asm volatile(
|
||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
asm volatile ( "lra 2,0(%2)\n"
|
" diag %2,%0,0x8\n"
|
||||||
"lr 4,%3\n"
|
" brc 8,1f\n"
|
||||||
"o 4,%6\n"
|
" ar %1,%4\n"
|
||||||
"lra 3,0(%4)\n"
|
|
||||||
"lr 5,%5\n"
|
|
||||||
"diag 2,4,0x8\n"
|
|
||||||
"brc 8, 1f\n"
|
|
||||||
"ar 5, %5\n"
|
|
||||||
"1: \n"
|
|
||||||
"lr %0,4\n"
|
|
||||||
"lr %1,5\n"
|
|
||||||
: "=d" (return_code), "=d" (return_len)
|
|
||||||
: "a" (cpcmd_buf), "d" (cmdlen),
|
|
||||||
"a" (response), "d" (rlen), "m" (mask)
|
|
||||||
: "cc", "2", "3", "4", "5" );
|
|
||||||
#else /* CONFIG_64BIT */
|
#else /* CONFIG_64BIT */
|
||||||
asm volatile ( "lrag 2,0(%2)\n"
|
" sam31\n"
|
||||||
"lgr 4,%3\n"
|
" diag %2,%0,0x8\n"
|
||||||
"o 4,%6\n"
|
" sam64\n"
|
||||||
"lrag 3,0(%4)\n"
|
" brc 8,1f\n"
|
||||||
"lgr 5,%5\n"
|
" agr %1,%4\n"
|
||||||
"sam31\n"
|
|
||||||
"diag 2,4,0x8\n"
|
|
||||||
"sam64\n"
|
|
||||||
"brc 8, 1f\n"
|
|
||||||
"agr 5, %5\n"
|
|
||||||
"1: \n"
|
|
||||||
"lgr %0,4\n"
|
|
||||||
"lgr %1,5\n"
|
|
||||||
: "=d" (return_code), "=d" (return_len)
|
|
||||||
: "a" (cpcmd_buf), "d" (cmdlen),
|
|
||||||
"a" (response), "d" (rlen), "m" (mask)
|
|
||||||
: "cc", "2", "3", "4", "5" );
|
|
||||||
#endif /* CONFIG_64BIT */
|
#endif /* CONFIG_64BIT */
|
||||||
|
"1:\n"
|
||||||
|
: "+d" (reg4), "+d" (reg5)
|
||||||
|
: "d" (reg2), "d" (reg3), "d" (rlen) : "cc");
|
||||||
|
return_code = (int) reg4;
|
||||||
|
return_len = (int) reg5;
|
||||||
EBCASC(response, rlen);
|
EBCASC(response, rlen);
|
||||||
} else {
|
} else {
|
||||||
|
register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
|
||||||
|
register unsigned long reg3 asm ("3") = cmdlen;
|
||||||
return_len = 0;
|
return_len = 0;
|
||||||
|
asm volatile(
|
||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
asm volatile ( "lra 2,0(%1)\n"
|
" diag %1,%0,0x8\n"
|
||||||
"lr 3,%2\n"
|
|
||||||
"diag 2,3,0x8\n"
|
|
||||||
"lr %0,3\n"
|
|
||||||
: "=d" (return_code)
|
|
||||||
: "a" (cpcmd_buf), "d" (cmdlen)
|
|
||||||
: "2", "3" );
|
|
||||||
#else /* CONFIG_64BIT */
|
#else /* CONFIG_64BIT */
|
||||||
asm volatile ( "lrag 2,0(%1)\n"
|
" sam31\n"
|
||||||
"lgr 3,%2\n"
|
" diag %1,%0,0x8\n"
|
||||||
"sam31\n"
|
" sam64\n"
|
||||||
"diag 2,3,0x8\n"
|
|
||||||
"sam64\n"
|
|
||||||
"lgr %0,3\n"
|
|
||||||
: "=d" (return_code)
|
|
||||||
: "a" (cpcmd_buf), "d" (cmdlen)
|
|
||||||
: "2", "3" );
|
|
||||||
#endif /* CONFIG_64BIT */
|
#endif /* CONFIG_64BIT */
|
||||||
|
: "+d" (reg3) : "d" (reg2) : "cc");
|
||||||
|
return_code = (int) reg3;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&cpcmd_lock, flags);
|
spin_unlock_irqrestore(&cpcmd_lock, flags);
|
||||||
if (response_code != NULL)
|
if (response_code != NULL)
|
||||||
|
@ -120,24 +120,15 @@ static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
|
|||||||
|
|
||||||
static int diag308(unsigned long subcode, void *addr)
|
static int diag308(unsigned long subcode, void *addr)
|
||||||
{
|
{
|
||||||
register unsigned long _addr asm("0") = (unsigned long)addr;
|
register unsigned long _addr asm("0") = (unsigned long) addr;
|
||||||
register unsigned long _rc asm("1") = 0;
|
register unsigned long _rc asm("1") = 0;
|
||||||
|
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" diag %0,%2,0x308\n"
|
" diag %0,%2,0x308\n"
|
||||||
"0: \n"
|
"0:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,0b)
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b, 0b\n"
|
|
||||||
#else
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b, 0b\n"
|
|
||||||
#endif
|
|
||||||
".previous\n"
|
|
||||||
: "+d" (_addr), "+d" (_rc)
|
: "+d" (_addr), "+d" (_rc)
|
||||||
: "d" (subcode) : "cc", "memory" );
|
: "d" (subcode) : "cc", "memory");
|
||||||
|
|
||||||
return _rc;
|
return _rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/timer.h>
|
#include <asm/timer.h>
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
|
asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return saved PC of a blocked thread. used in kernel/sched.
|
* Return saved PC of a blocked thread. used in kernel/sched.
|
||||||
@ -177,7 +177,8 @@ void show_regs(struct pt_regs *regs)
|
|||||||
|
|
||||||
extern void kernel_thread_starter(void);
|
extern void kernel_thread_starter(void);
|
||||||
|
|
||||||
__asm__(".align 4\n"
|
asm(
|
||||||
|
".align 4\n"
|
||||||
"kernel_thread_starter:\n"
|
"kernel_thread_starter:\n"
|
||||||
" la 2,0(10)\n"
|
" la 2,0(10)\n"
|
||||||
" basr 14,9\n"
|
" basr 14,9\n"
|
||||||
|
@ -26,17 +26,17 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
|
|||||||
{
|
{
|
||||||
int old_val, new_val;
|
int old_val, new_val;
|
||||||
|
|
||||||
__asm__ __volatile__(" l %0,0(%3)\n"
|
asm volatile(
|
||||||
"0: ltr %1,%0\n"
|
" l %0,0(%3)\n"
|
||||||
" jhe 1f\n"
|
"0: ltr %1,%0\n"
|
||||||
" lhi %1,0\n"
|
" jhe 1f\n"
|
||||||
"1: ar %1,%4\n"
|
" lhi %1,0\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
"1: ar %1,%4\n"
|
||||||
" jl 0b\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
: "=&d" (old_val), "=&d" (new_val),
|
" jl 0b\n"
|
||||||
"=m" (sem->count)
|
: "=&d" (old_val), "=&d" (new_val), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "d" (incr), "m" (sem->count)
|
: "a" (&sem->count), "d" (incr), "m" (sem->count)
|
||||||
: "cc" );
|
: "cc");
|
||||||
return old_val;
|
return old_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ void __devinit cpu_init (void)
|
|||||||
/*
|
/*
|
||||||
* Store processor id in lowcore (used e.g. in timer_interrupt)
|
* Store processor id in lowcore (used e.g. in timer_interrupt)
|
||||||
*/
|
*/
|
||||||
asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
|
asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
|
||||||
S390_lowcore.cpu_data.cpu_addr = addr;
|
S390_lowcore.cpu_data.cpu_addr = addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -63,7 +63,7 @@ static void smp_ext_bitcall(int, ec_bit_sig);
|
|||||||
static void smp_ext_bitcall_others(ec_bit_sig);
|
static void smp_ext_bitcall_others(ec_bit_sig);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure and data for smp_call_function(). This is designed to minimise
|
5B * Structure and data for smp_call_function(). This is designed to minimise
|
||||||
* static memory requirements. It also looks cleaner.
|
* static memory requirements. It also looks cleaner.
|
||||||
*/
|
*/
|
||||||
static DEFINE_SPINLOCK(call_lock);
|
static DEFINE_SPINLOCK(call_lock);
|
||||||
@ -418,59 +418,49 @@ void smp_send_reschedule(int cpu)
|
|||||||
/*
|
/*
|
||||||
* parameter area for the set/clear control bit callbacks
|
* parameter area for the set/clear control bit callbacks
|
||||||
*/
|
*/
|
||||||
typedef struct
|
struct ec_creg_mask_parms {
|
||||||
{
|
|
||||||
__u16 start_ctl;
|
|
||||||
__u16 end_ctl;
|
|
||||||
unsigned long orvals[16];
|
unsigned long orvals[16];
|
||||||
unsigned long andvals[16];
|
unsigned long andvals[16];
|
||||||
} ec_creg_mask_parms;
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* callback for setting/clearing control bits
|
* callback for setting/clearing control bits
|
||||||
*/
|
*/
|
||||||
void smp_ctl_bit_callback(void *info) {
|
void smp_ctl_bit_callback(void *info) {
|
||||||
ec_creg_mask_parms *pp;
|
struct ec_creg_mask_parms *pp = info;
|
||||||
unsigned long cregs[16];
|
unsigned long cregs[16];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pp = (ec_creg_mask_parms *) info;
|
__ctl_store(cregs, 0, 15);
|
||||||
__ctl_store(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl);
|
for (i = 0; i <= 15; i++)
|
||||||
for (i = pp->start_ctl; i <= pp->end_ctl; i++)
|
|
||||||
cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i];
|
cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i];
|
||||||
__ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl);
|
__ctl_load(cregs, 0, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a bit in a control register of all cpus
|
* Set a bit in a control register of all cpus
|
||||||
*/
|
*/
|
||||||
void smp_ctl_set_bit(int cr, int bit) {
|
void smp_ctl_set_bit(int cr, int bit)
|
||||||
ec_creg_mask_parms parms;
|
{
|
||||||
|
struct ec_creg_mask_parms parms;
|
||||||
|
|
||||||
parms.start_ctl = cr;
|
memset(&parms.orvals, 0, sizeof(parms.orvals));
|
||||||
parms.end_ctl = cr;
|
memset(&parms.andvals, 0xff, sizeof(parms.andvals));
|
||||||
parms.orvals[cr] = 1 << bit;
|
parms.orvals[cr] = 1 << bit;
|
||||||
parms.andvals[cr] = -1L;
|
on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
|
||||||
preempt_disable();
|
|
||||||
smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
|
|
||||||
__ctl_set_bit(cr, bit);
|
|
||||||
preempt_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear a bit in a control register of all cpus
|
* Clear a bit in a control register of all cpus
|
||||||
*/
|
*/
|
||||||
void smp_ctl_clear_bit(int cr, int bit) {
|
void smp_ctl_clear_bit(int cr, int bit)
|
||||||
ec_creg_mask_parms parms;
|
{
|
||||||
|
struct ec_creg_mask_parms parms;
|
||||||
|
|
||||||
parms.start_ctl = cr;
|
memset(&parms.orvals, 0, sizeof(parms.orvals));
|
||||||
parms.end_ctl = cr;
|
memset(&parms.andvals, 0xff, sizeof(parms.andvals));
|
||||||
parms.orvals[cr] = 0;
|
|
||||||
parms.andvals[cr] = ~(1L << bit);
|
parms.andvals[cr] = ~(1L << bit);
|
||||||
preempt_disable();
|
on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
|
||||||
smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
|
|
||||||
__ctl_clear_bit(cr, bit);
|
|
||||||
preempt_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -650,9 +640,9 @@ __cpu_up(unsigned int cpu)
|
|||||||
sf->gprs[9] = (unsigned long) sf;
|
sf->gprs[9] = (unsigned long) sf;
|
||||||
cpu_lowcore->save_area[15] = (unsigned long) sf;
|
cpu_lowcore->save_area[15] = (unsigned long) sf;
|
||||||
__ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15);
|
__ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15);
|
||||||
__asm__ __volatile__("stam 0,15,0(%0)"
|
asm volatile(
|
||||||
: : "a" (&cpu_lowcore->access_regs_save_area)
|
" stam 0,15,0(%0)"
|
||||||
: "memory");
|
: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
|
||||||
cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
|
cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
|
||||||
cpu_lowcore->current_task = (unsigned long) idle;
|
cpu_lowcore->current_task = (unsigned long) idle;
|
||||||
cpu_lowcore->cpu_data.cpu_nr = cpu;
|
cpu_lowcore->cpu_data.cpu_nr = cpu;
|
||||||
@ -708,7 +698,7 @@ int
|
|||||||
__cpu_disable(void)
|
__cpu_disable(void)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ec_creg_mask_parms cr_parms;
|
struct ec_creg_mask_parms cr_parms;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
spin_lock_irqsave(&smp_reserve_lock, flags);
|
spin_lock_irqsave(&smp_reserve_lock, flags);
|
||||||
@ -724,30 +714,21 @@ __cpu_disable(void)
|
|||||||
pfault_fini();
|
pfault_fini();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* disable all external interrupts */
|
memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals));
|
||||||
|
memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals));
|
||||||
|
|
||||||
cr_parms.start_ctl = 0;
|
/* disable all external interrupts */
|
||||||
cr_parms.end_ctl = 0;
|
|
||||||
cr_parms.orvals[0] = 0;
|
cr_parms.orvals[0] = 0;
|
||||||
cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 |
|
cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 |
|
||||||
1<<11 | 1<<10 | 1<< 6 | 1<< 4);
|
1<<11 | 1<<10 | 1<< 6 | 1<< 4);
|
||||||
smp_ctl_bit_callback(&cr_parms);
|
|
||||||
|
|
||||||
/* disable all I/O interrupts */
|
/* disable all I/O interrupts */
|
||||||
|
|
||||||
cr_parms.start_ctl = 6;
|
|
||||||
cr_parms.end_ctl = 6;
|
|
||||||
cr_parms.orvals[6] = 0;
|
cr_parms.orvals[6] = 0;
|
||||||
cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 |
|
cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 |
|
||||||
1<<27 | 1<<26 | 1<<25 | 1<<24);
|
1<<27 | 1<<26 | 1<<25 | 1<<24);
|
||||||
smp_ctl_bit_callback(&cr_parms);
|
|
||||||
|
|
||||||
/* disable most machine checks */
|
/* disable most machine checks */
|
||||||
|
|
||||||
cr_parms.start_ctl = 14;
|
|
||||||
cr_parms.end_ctl = 14;
|
|
||||||
cr_parms.orvals[14] = 0;
|
cr_parms.orvals[14] = 0;
|
||||||
cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24);
|
cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24);
|
||||||
|
|
||||||
smp_ctl_bit_callback(&cr_parms);
|
smp_ctl_bit_callback(&cr_parms);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&smp_reserve_lock, flags);
|
spin_unlock_irqrestore(&smp_reserve_lock, flags);
|
||||||
|
@ -351,10 +351,12 @@ void __init time_init(void)
|
|||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
/* kick the TOD clock */
|
/* kick the TOD clock */
|
||||||
asm volatile ("STCK 0(%1)\n\t"
|
asm volatile(
|
||||||
"IPM %0\n\t"
|
" stck 0(%2)\n"
|
||||||
"SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc)
|
" ipm %0\n"
|
||||||
: "memory", "cc");
|
" srl %0,28"
|
||||||
|
: "=d" (cc), "=m" (init_timer_cc)
|
||||||
|
: "a" (&init_timer_cc) : "cc");
|
||||||
switch (cc) {
|
switch (cc) {
|
||||||
case 0: /* clock in set state: all is fine */
|
case 0: /* clock in set state: all is fine */
|
||||||
break;
|
break;
|
||||||
|
@ -597,8 +597,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
|
|||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
if (MACHINE_HAS_IEEE)
|
if (MACHINE_HAS_IEEE)
|
||||||
__asm__ volatile ("stfpc %0\n\t"
|
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
|
||||||
: "=m" (current->thread.fp_regs.fpc));
|
|
||||||
|
|
||||||
#ifdef CONFIG_MATHEMU
|
#ifdef CONFIG_MATHEMU
|
||||||
else if (regs->psw.mask & PSW_MASK_PSTATE) {
|
else if (regs->psw.mask & PSW_MASK_PSTATE) {
|
||||||
|
@ -27,9 +27,7 @@ void __delay(unsigned long loops)
|
|||||||
* yield the megahertz number of the cpu. The important function
|
* yield the megahertz number of the cpu. The important function
|
||||||
* is udelay and that is done using the tod clock. -- martin.
|
* is udelay and that is done using the tod clock. -- martin.
|
||||||
*/
|
*/
|
||||||
__asm__ __volatile__(
|
asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1));
|
||||||
"0: brct %0,0b"
|
|
||||||
: /* no outputs */ : "r" ((loops/2) + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -38,13 +36,12 @@ void __delay(unsigned long loops)
|
|||||||
*/
|
*/
|
||||||
void __udelay(unsigned long usecs)
|
void __udelay(unsigned long usecs)
|
||||||
{
|
{
|
||||||
uint64_t start_cc, end_cc;
|
uint64_t start_cc;
|
||||||
|
|
||||||
if (usecs == 0)
|
if (usecs == 0)
|
||||||
return;
|
return;
|
||||||
asm volatile ("STCK %0" : "=m" (start_cc));
|
start_cc = get_clock();
|
||||||
do {
|
do {
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
asm volatile ("STCK %0" : "=m" (end_cc));
|
} while (((get_clock() - start_cc)/4096) < usecs);
|
||||||
} while (((end_cc - start_cc)/4096) < usecs);
|
|
||||||
}
|
}
|
||||||
|
@ -1564,52 +1564,52 @@ static int emu_tceb (struct pt_regs *regs, int rx, long val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void emu_load_regd(int reg) {
|
static inline void emu_load_regd(int reg) {
|
||||||
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
||||||
return;
|
return;
|
||||||
asm volatile ( /* load reg from fp_regs.fprs[reg] */
|
asm volatile( /* load reg from fp_regs.fprs[reg] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" ld 0,0(%1)\n"
|
" ld 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d)
|
: "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d)
|
||||||
: "1" );
|
: "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void emu_load_rege(int reg) {
|
static inline void emu_load_rege(int reg) {
|
||||||
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
||||||
return;
|
return;
|
||||||
asm volatile ( /* load reg from fp_regs.fprs[reg] */
|
asm volatile( /* load reg from fp_regs.fprs[reg] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" le 0,0(%1)\n"
|
" le 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f)
|
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f)
|
||||||
: "1" );
|
: "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void emu_store_regd(int reg) {
|
static inline void emu_store_regd(int reg) {
|
||||||
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
||||||
return;
|
return;
|
||||||
asm volatile ( /* store reg to fp_regs.fprs[reg] */
|
asm volatile( /* store reg to fp_regs.fprs[reg] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" std 0,0(%1)\n"
|
" std 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d)
|
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d)
|
||||||
: "1" );
|
: "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void emu_store_rege(int reg) {
|
static inline void emu_store_rege(int reg) {
|
||||||
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
if ((reg&9) != 0) /* test if reg in {0,2,4,6} */
|
||||||
return;
|
return;
|
||||||
asm volatile ( /* store reg to fp_regs.fprs[reg] */
|
asm volatile( /* store reg to fp_regs.fprs[reg] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" ste 0,0(%1)\n"
|
" ste 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f)
|
: "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f)
|
||||||
: "1" );
|
: "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
|
int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
|
||||||
@ -2089,23 +2089,22 @@ int math_emu_ldr(__u8 *opcode) {
|
|||||||
|
|
||||||
if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
|
if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
|
||||||
/* we got an exception therfore ry can't be in {0,2,4,6} */
|
/* we got an exception therfore ry can't be in {0,2,4,6} */
|
||||||
__asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */
|
asm volatile( /* load rx from fp_regs.fprs[ry] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" ld 0,0(%1)\n"
|
" ld 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (opc & 0xf0),
|
: "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].d)
|
||||||
"a" (&fp_regs->fprs[opc & 0xf].d)
|
: "1");
|
||||||
: "1" );
|
|
||||||
} else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
|
} else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
|
||||||
__asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */
|
asm volatile ( /* store ry to fp_regs.fprs[rx] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" std 0,0(%1)\n"
|
" std 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" ((opc & 0xf) << 4),
|
: "a" ((opc & 0xf) << 4),
|
||||||
"a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
|
"a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
|
||||||
: "1" );
|
: "1");
|
||||||
} else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
|
} else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
|
||||||
fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
|
fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
|
||||||
return 0;
|
return 0;
|
||||||
@ -2120,23 +2119,22 @@ int math_emu_ler(__u8 *opcode) {
|
|||||||
|
|
||||||
if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
|
if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */
|
||||||
/* we got an exception therfore ry can't be in {0,2,4,6} */
|
/* we got an exception therfore ry can't be in {0,2,4,6} */
|
||||||
__asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */
|
asm volatile( /* load rx from fp_regs.fprs[ry] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" le 0,0(%1)\n"
|
" le 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" (opc & 0xf0),
|
: "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].f)
|
||||||
"a" (&fp_regs->fprs[opc & 0xf].f)
|
: "1");
|
||||||
: "1" );
|
|
||||||
} else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
|
} else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */
|
||||||
__asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */
|
asm volatile( /* store ry to fp_regs.fprs[rx] */
|
||||||
" bras 1,0f\n"
|
" bras 1,0f\n"
|
||||||
" ste 0,0(%1)\n"
|
" ste 0,0(%1)\n"
|
||||||
"0: ex %0,0(1)"
|
"0: ex %0,0(1)"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "a" ((opc & 0xf) << 4),
|
: "a" ((opc & 0xf) << 4),
|
||||||
"a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
|
"a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
|
||||||
: "1" );
|
: "1");
|
||||||
} else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
|
} else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
|
||||||
fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
|
fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4,48 +4,51 @@
|
|||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \
|
#define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \
|
||||||
unsigned int __sh = (ah); \
|
unsigned int __sh = (ah); \
|
||||||
unsigned int __sl = (al); \
|
unsigned int __sl = (al); \
|
||||||
__asm__ (" alr %1,%3\n" \
|
asm volatile( \
|
||||||
" brc 12,0f\n" \
|
" alr %1,%3\n" \
|
||||||
" ahi %0,1\n" \
|
" brc 12,0f\n" \
|
||||||
"0: alr %0,%2" \
|
" ahi %0,1\n" \
|
||||||
: "+&d" (__sh), "+d" (__sl) \
|
"0: alr %0,%2" \
|
||||||
: "d" (bh), "d" (bl) : "cc" ); \
|
: "+&d" (__sh), "+d" (__sl) \
|
||||||
(sh) = __sh; \
|
: "d" (bh), "d" (bl) : "cc"); \
|
||||||
(sl) = __sl; \
|
(sh) = __sh; \
|
||||||
|
(sl) = __sl; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \
|
#define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \
|
||||||
unsigned int __sh = (ah); \
|
unsigned int __sh = (ah); \
|
||||||
unsigned int __sl = (al); \
|
unsigned int __sl = (al); \
|
||||||
__asm__ (" slr %1,%3\n" \
|
asm volatile( \
|
||||||
" brc 3,0f\n" \
|
" slr %1,%3\n" \
|
||||||
" ahi %0,-1\n" \
|
" brc 3,0f\n" \
|
||||||
"0: slr %0,%2" \
|
" ahi %0,-1\n" \
|
||||||
: "+&d" (__sh), "+d" (__sl) \
|
"0: slr %0,%2" \
|
||||||
: "d" (bh), "d" (bl) : "cc" ); \
|
: "+&d" (__sh), "+d" (__sl) \
|
||||||
(sh) = __sh; \
|
: "d" (bh), "d" (bl) : "cc"); \
|
||||||
(sl) = __sl; \
|
(sh) = __sh; \
|
||||||
|
(sl) = __sl; \
|
||||||
})
|
})
|
||||||
|
|
||||||
/* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */
|
/* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */
|
||||||
#define umul_ppmm(wh, wl, u, v) ({ \
|
#define umul_ppmm(wh, wl, u, v) ({ \
|
||||||
unsigned int __wh = u; \
|
unsigned int __wh = u; \
|
||||||
unsigned int __wl = v; \
|
unsigned int __wl = v; \
|
||||||
__asm__ (" ltr 1,%0\n" \
|
asm volatile( \
|
||||||
" mr 0,%1\n" \
|
" ltr 1,%0\n" \
|
||||||
" jnm 0f\n" \
|
" mr 0,%1\n" \
|
||||||
" alr 0,%1\n" \
|
" jnm 0f\n" \
|
||||||
"0: ltr %1,%1\n" \
|
" alr 0,%1\n" \
|
||||||
" jnm 1f\n" \
|
"0: ltr %1,%1\n" \
|
||||||
" alr 0,%0\n" \
|
" jnm 1f\n" \
|
||||||
"1: lr %0,0\n" \
|
" alr 0,%0\n" \
|
||||||
" lr %1,1\n" \
|
"1: lr %0,0\n" \
|
||||||
: "+d" (__wh), "+d" (__wl) \
|
" lr %1,1\n" \
|
||||||
: : "0", "1", "cc" ); \
|
: "+d" (__wh), "+d" (__wl) \
|
||||||
wh = __wh; \
|
: : "0", "1", "cc"); \
|
||||||
wl = __wl; \
|
wh = __wh; \
|
||||||
|
wl = __wl; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define udiv_qrnnd(q, r, n1, n0, d) \
|
#define udiv_qrnnd(q, r, n1, n0, d) \
|
||||||
|
@ -142,17 +142,17 @@ dcss_diag (__u8 func, void *parameter,
|
|||||||
|
|
||||||
rx = (unsigned long) parameter;
|
rx = (unsigned long) parameter;
|
||||||
ry = (unsigned long) func;
|
ry = (unsigned long) func;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
" sam31\n" // switch to 31 bit
|
" sam31\n"
|
||||||
" diag %0,%1,0x64\n"
|
" diag %0,%1,0x64\n"
|
||||||
" sam64\n" // switch back to 64 bit
|
" sam64\n"
|
||||||
#else
|
#else
|
||||||
" diag %0,%1,0x64\n"
|
" diag %0,%1,0x64\n"
|
||||||
#endif
|
#endif
|
||||||
" ipm %2\n"
|
" ipm %2\n"
|
||||||
" srl %2,28\n"
|
" srl %2,28\n"
|
||||||
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" );
|
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
|
||||||
*ret1 = rx;
|
*ret1 = rx;
|
||||||
*ret2 = ry;
|
*ret2 = ry;
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -424,20 +424,13 @@ int pfault_init(void)
|
|||||||
|
|
||||||
if (pfault_disable)
|
if (pfault_disable)
|
||||||
return -1;
|
return -1;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" diag %1,%0,0x258\n"
|
" diag %1,%0,0x258\n"
|
||||||
"0: j 2f\n"
|
"0: j 2f\n"
|
||||||
"1: la %0,8\n"
|
"1: la %0,8\n"
|
||||||
"2:\n"
|
"2:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,1b)
|
||||||
" .align 4\n"
|
: "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc");
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
" .quad 0b,1b\n"
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
".previous"
|
|
||||||
: "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
|
|
||||||
__ctl_set_bit(0, 9);
|
__ctl_set_bit(0, 9);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -450,18 +443,11 @@ void pfault_fini(void)
|
|||||||
if (pfault_disable)
|
if (pfault_disable)
|
||||||
return;
|
return;
|
||||||
__ctl_clear_bit(0,9);
|
__ctl_clear_bit(0,9);
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" diag %0,0,0x258\n"
|
" diag %0,0,0x258\n"
|
||||||
"0:\n"
|
"0:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,0b)
|
||||||
" .align 4\n"
|
: : "a" (&refbk), "m" (refbk) : "cc");
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
" .long 0b,0b\n"
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
" .quad 0b,0b\n"
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
".previous"
|
|
||||||
: : "a" (&refbk), "m" (refbk) : "cc" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void
|
asmlinkage void
|
||||||
|
@ -45,26 +45,17 @@ void diag10(unsigned long addr)
|
|||||||
{
|
{
|
||||||
if (addr >= 0x7ff00000)
|
if (addr >= 0x7ff00000)
|
||||||
return;
|
return;
|
||||||
|
asm volatile(
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
asm volatile (
|
" sam31\n"
|
||||||
" sam31\n"
|
" diag %0,%0,0x10\n"
|
||||||
" diag %0,%0,0x10\n"
|
"0: sam64\n"
|
||||||
"0: sam64\n"
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b, 0b\n"
|
|
||||||
".previous\n"
|
|
||||||
: : "a" (addr));
|
|
||||||
#else
|
#else
|
||||||
asm volatile (
|
" diag %0,%0,0x10\n"
|
||||||
" diag %0,%0,0x10\n"
|
|
||||||
"0:\n"
|
"0:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b, 0b\n"
|
|
||||||
".previous\n"
|
|
||||||
: : "a" (addr));
|
|
||||||
#endif
|
#endif
|
||||||
|
EX_TABLE(0b,0b)
|
||||||
|
: : "a" (addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_mem(void)
|
void show_mem(void)
|
||||||
@ -156,11 +147,10 @@ void __init paging_init(void)
|
|||||||
S390_lowcore.kernel_asce = pgdir_k;
|
S390_lowcore.kernel_asce = pgdir_k;
|
||||||
|
|
||||||
/* enable virtual mapping in kernel mode */
|
/* enable virtual mapping in kernel mode */
|
||||||
__asm__ __volatile__(" LCTL 1,1,%0\n"
|
__ctl_load(pgdir_k, 1, 1);
|
||||||
" LCTL 7,7,%0\n"
|
__ctl_load(pgdir_k, 7, 7);
|
||||||
" LCTL 13,13,%0\n"
|
__ctl_load(pgdir_k, 13, 13);
|
||||||
" SSM %1"
|
__raw_local_irq_ssm(ssm_mask);
|
||||||
: : "m" (pgdir_k), "m" (ssm_mask));
|
|
||||||
|
|
||||||
local_flush_tlb();
|
local_flush_tlb();
|
||||||
return;
|
return;
|
||||||
@ -241,11 +231,10 @@ void __init paging_init(void)
|
|||||||
S390_lowcore.kernel_asce = pgdir_k;
|
S390_lowcore.kernel_asce = pgdir_k;
|
||||||
|
|
||||||
/* enable virtual mapping in kernel mode */
|
/* enable virtual mapping in kernel mode */
|
||||||
__asm__ __volatile__("lctlg 1,1,%0\n\t"
|
__ctl_load(pgdir_k, 1, 1);
|
||||||
"lctlg 7,7,%0\n\t"
|
__ctl_load(pgdir_k, 7, 7);
|
||||||
"lctlg 13,13,%0\n\t"
|
__ctl_load(pgdir_k, 13, 13);
|
||||||
"ssm %1"
|
__raw_local_irq_ssm(ssm_mask);
|
||||||
: :"m" (pgdir_k), "m" (ssm_mask));
|
|
||||||
|
|
||||||
local_flush_tlb();
|
local_flush_tlb();
|
||||||
|
|
||||||
|
@ -63,44 +63,26 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
|
|||||||
* and function code cmd.
|
* and function code cmd.
|
||||||
* In case of an exception return 3. Otherwise return result of bitwise OR of
|
* In case of an exception return 3. Otherwise return result of bitwise OR of
|
||||||
* resulting condition code and DIAG return code. */
|
* resulting condition code and DIAG return code. */
|
||||||
static __inline__ int
|
static inline int dia250(void *iob, int cmd)
|
||||||
dia250(void *iob, int cmd)
|
|
||||||
{
|
{
|
||||||
|
register unsigned long reg0 asm ("0") = (unsigned long) iob;
|
||||||
typedef union {
|
typedef union {
|
||||||
struct dasd_diag_init_io init_io;
|
struct dasd_diag_init_io init_io;
|
||||||
struct dasd_diag_rw_io rw_io;
|
struct dasd_diag_rw_io rw_io;
|
||||||
} addr_type;
|
} addr_type;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
rc = 3;
|
||||||
#ifdef CONFIG_64BIT
|
asm volatile(
|
||||||
" lghi %0,3\n"
|
|
||||||
" lgr 0,%3\n"
|
|
||||||
" diag 0,%2,0x250\n"
|
" diag 0,%2,0x250\n"
|
||||||
"0: ipm %0\n"
|
"0: ipm %0\n"
|
||||||
" srl %0,28\n"
|
" srl %0,28\n"
|
||||||
" or %0,1\n"
|
" or %0,1\n"
|
||||||
"1:\n"
|
"1:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,1b)
|
||||||
" .align 8\n"
|
: "+d" (rc), "=m" (*(addr_type *) iob)
|
||||||
" .quad 0b,1b\n"
|
: "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob)
|
||||||
".previous\n"
|
: "1", "cc");
|
||||||
#else
|
|
||||||
" lhi %0,3\n"
|
|
||||||
" lr 0,%3\n"
|
|
||||||
" diag 0,%2,0x250\n"
|
|
||||||
"0: ipm %0\n"
|
|
||||||
" srl %0,28\n"
|
|
||||||
" or %0,1\n"
|
|
||||||
"1:\n"
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous\n"
|
|
||||||
#endif
|
|
||||||
: "=&d" (rc), "=m" (*(addr_type *) iob)
|
|
||||||
: "d" (cmd), "d" (iob), "m" (*(addr_type *) iob)
|
|
||||||
: "0", "1", "cc");
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,28 +89,15 @@ MODULE_LICENSE("GPL");
|
|||||||
*/
|
*/
|
||||||
static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
|
static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc = 2; /* return unused cc 2 if pgin traps */
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" lhi %0,2\n" /* return unused cc 2 if pgin traps */
|
" .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */
|
||||||
" .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */
|
"0: ipm %0\n"
|
||||||
"0: ipm %0\n"
|
" srl %0,28\n"
|
||||||
" srl %0,28\n"
|
|
||||||
"1:\n"
|
"1:\n"
|
||||||
#ifndef CONFIG_64BIT
|
EX_TABLE(0b,1b)
|
||||||
".section __ex_table,\"a\"\n"
|
: "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc");
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#else
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#endif
|
|
||||||
: "=&d" (cc)
|
|
||||||
: "a" (__pa(page_addr)), "a" (xpage_index)
|
|
||||||
: "cc" );
|
|
||||||
if (cc == 3)
|
if (cc == 3)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if (cc == 2) {
|
if (cc == 2) {
|
||||||
@ -137,28 +124,15 @@ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
|
|||||||
*/
|
*/
|
||||||
static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
|
static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc = 2; /* return unused cc 2 if pgin traps */
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" lhi %0,2\n" /* return unused cc 2 if pgout traps */
|
" .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */
|
||||||
" .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */
|
"0: ipm %0\n"
|
||||||
"0: ipm %0\n"
|
" srl %0,28\n"
|
||||||
" srl %0,28\n"
|
|
||||||
"1:\n"
|
"1:\n"
|
||||||
#ifndef CONFIG_64BIT
|
EX_TABLE(0b,1b)
|
||||||
".section __ex_table,\"a\"\n"
|
: "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc");
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#else
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#endif
|
|
||||||
: "=&d" (cc)
|
|
||||||
: "a" (__pa(page_addr)), "a" (xpage_index)
|
|
||||||
: "cc" );
|
|
||||||
if (cc == 3)
|
if (cc == 3)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if (cc == 2) {
|
if (cc == 2) {
|
||||||
|
@ -100,13 +100,12 @@ service_call(sclp_cmdw_t command, void *sccb)
|
|||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
|
" .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
|
||||||
" ipm %0\n"
|
" ipm %0\n"
|
||||||
" srl %0,28"
|
" srl %0,28"
|
||||||
: "=&d" (cc)
|
: "=&d" (cc) : "d" (command), "a" (__pa(sccb))
|
||||||
: "d" (command), "a" (__pa(sccb))
|
: "cc", "memory");
|
||||||
: "cc", "memory" );
|
|
||||||
if (cc == 3)
|
if (cc == 3)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (cc == 2)
|
if (cc == 2)
|
||||||
@ -360,16 +359,6 @@ sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
|
|||||||
sclp_process_queue();
|
sclp_process_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return current Time-Of-Day clock. */
|
|
||||||
static inline u64
|
|
||||||
sclp_get_clock(void)
|
|
||||||
{
|
|
||||||
u64 result;
|
|
||||||
|
|
||||||
asm volatile ("STCK 0(%1)" : "=m" (result) : "a" (&(result)) : "cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert interval in jiffies to TOD ticks. */
|
/* Convert interval in jiffies to TOD ticks. */
|
||||||
static inline u64
|
static inline u64
|
||||||
sclp_tod_from_jiffies(unsigned long jiffies)
|
sclp_tod_from_jiffies(unsigned long jiffies)
|
||||||
@ -382,7 +371,6 @@ sclp_tod_from_jiffies(unsigned long jiffies)
|
|||||||
void
|
void
|
||||||
sclp_sync_wait(void)
|
sclp_sync_wait(void)
|
||||||
{
|
{
|
||||||
unsigned long psw_mask;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long cr0, cr0_sync;
|
unsigned long cr0, cr0_sync;
|
||||||
u64 timeout;
|
u64 timeout;
|
||||||
@ -392,7 +380,7 @@ sclp_sync_wait(void)
|
|||||||
timeout = 0;
|
timeout = 0;
|
||||||
if (timer_pending(&sclp_request_timer)) {
|
if (timer_pending(&sclp_request_timer)) {
|
||||||
/* Get timeout TOD value */
|
/* Get timeout TOD value */
|
||||||
timeout = sclp_get_clock() +
|
timeout = get_clock() +
|
||||||
sclp_tod_from_jiffies(sclp_request_timer.expires -
|
sclp_tod_from_jiffies(sclp_request_timer.expires -
|
||||||
jiffies);
|
jiffies);
|
||||||
}
|
}
|
||||||
@ -406,13 +394,12 @@ sclp_sync_wait(void)
|
|||||||
cr0_sync |= 0x00000200;
|
cr0_sync |= 0x00000200;
|
||||||
cr0_sync &= 0xFFFFF3AC;
|
cr0_sync &= 0xFFFFF3AC;
|
||||||
__ctl_load(cr0_sync, 0, 0);
|
__ctl_load(cr0_sync, 0, 0);
|
||||||
asm volatile ("STOSM 0(%1),0x01"
|
__raw_local_irq_stosm(0x01);
|
||||||
: "=m" (psw_mask) : "a" (&psw_mask) : "memory");
|
|
||||||
/* Loop until driver state indicates finished request */
|
/* Loop until driver state indicates finished request */
|
||||||
while (sclp_running_state != sclp_running_state_idle) {
|
while (sclp_running_state != sclp_running_state_idle) {
|
||||||
/* Check for expired request timer */
|
/* Check for expired request timer */
|
||||||
if (timer_pending(&sclp_request_timer) &&
|
if (timer_pending(&sclp_request_timer) &&
|
||||||
sclp_get_clock() > timeout &&
|
get_clock() > timeout &&
|
||||||
del_timer(&sclp_request_timer))
|
del_timer(&sclp_request_timer))
|
||||||
sclp_request_timer.function(sclp_request_timer.data);
|
sclp_request_timer.function(sclp_request_timer.data);
|
||||||
barrier();
|
barrier();
|
||||||
|
@ -54,48 +54,20 @@ enum vmwdt_func {
|
|||||||
static int __diag288(enum vmwdt_func func, unsigned int timeout,
|
static int __diag288(enum vmwdt_func func, unsigned int timeout,
|
||||||
char *cmd, size_t len)
|
char *cmd, size_t len)
|
||||||
{
|
{
|
||||||
register unsigned long __func asm("2");
|
register unsigned long __func asm("2") = func;
|
||||||
register unsigned long __timeout asm("3");
|
register unsigned long __timeout asm("3") = timeout;
|
||||||
register unsigned long __cmdp asm("4");
|
register unsigned long __cmdp asm("4") = virt_to_phys(cmd);
|
||||||
register unsigned long __cmdl asm("5");
|
register unsigned long __cmdl asm("5") = len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
__func = func;
|
err = -EINVAL;
|
||||||
__timeout = timeout;
|
asm volatile(
|
||||||
__cmdp = virt_to_phys(cmd);
|
" diag %1,%3,0x288\n"
|
||||||
__cmdl = len;
|
"0: la %0,0\n"
|
||||||
err = 0;
|
"1:\n"
|
||||||
asm volatile (
|
EX_TABLE(0b,1b)
|
||||||
#ifdef CONFIG_64BIT
|
: "=d" (err) : "d"(__func), "d"(__timeout),
|
||||||
"diag %2,%4,0x288\n"
|
"d"(__cmdp), "d"(__cmdl), "0" (-EINVAL) : "1", "cc");
|
||||||
"1: \n"
|
|
||||||
".section .fixup,\"ax\"\n"
|
|
||||||
"2: lghi %0,%1\n"
|
|
||||||
" jg 1b\n"
|
|
||||||
".previous\n"
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 8\n"
|
|
||||||
" .quad 1b,2b\n"
|
|
||||||
".previous\n"
|
|
||||||
#else
|
|
||||||
"diag %2,%4,0x288\n"
|
|
||||||
"1: \n"
|
|
||||||
".section .fixup,\"ax\"\n"
|
|
||||||
"2: lhi %0,%1\n"
|
|
||||||
" bras 1,3f\n"
|
|
||||||
" .long 1b\n"
|
|
||||||
"3: l 1,0(1)\n"
|
|
||||||
" br 1\n"
|
|
||||||
".previous\n"
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 1b,2b\n"
|
|
||||||
".previous\n"
|
|
||||||
#endif
|
|
||||||
: "+&d"(err)
|
|
||||||
: "i"(-EINVAL), "d"(__func), "d"(__timeout),
|
|
||||||
"d"(__cmdp), "d"(__cmdl)
|
|
||||||
: "1", "cc");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,18 +42,15 @@ diag210(struct diag210 * addr)
|
|||||||
spin_lock_irqsave(&diag210_lock, flags);
|
spin_lock_irqsave(&diag210_lock, flags);
|
||||||
diag210_tmp = *addr;
|
diag210_tmp = *addr;
|
||||||
|
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" lhi %0,-1\n"
|
" lhi %0,-1\n"
|
||||||
" sam31\n"
|
" sam31\n"
|
||||||
" diag %1,0,0x210\n"
|
" diag %1,0,0x210\n"
|
||||||
"0: ipm %0\n"
|
"0: ipm %0\n"
|
||||||
" srl %0,28\n"
|
" srl %0,28\n"
|
||||||
"1: sam64\n"
|
"1: sam64\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,1b)
|
||||||
" .align 8\n"
|
: "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory");
|
||||||
" .quad 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" );
|
|
||||||
|
|
||||||
*addr = diag210_tmp;
|
*addr = diag210_tmp;
|
||||||
spin_unlock_irqrestore(&diag210_lock, flags);
|
spin_unlock_irqrestore(&diag210_lock, flags);
|
||||||
@ -66,17 +63,14 @@ diag210(struct diag210 * addr)
|
|||||||
{
|
{
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" lhi %0,-1\n"
|
" lhi %0,-1\n"
|
||||||
" diag %1,0,0x210\n"
|
" diag %1,0,0x210\n"
|
||||||
"0: ipm %0\n"
|
"0: ipm %0\n"
|
||||||
" srl %0,28\n"
|
" srl %0,28\n"
|
||||||
"1:\n"
|
"1:\n"
|
||||||
".section __ex_table,\"a\"\n"
|
EX_TABLE(0b,1b)
|
||||||
" .align 4\n"
|
: "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory");
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory" );
|
|
||||||
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
@ -25,106 +25,74 @@ struct tpi_info {
|
|||||||
static inline int stsch(struct subchannel_id schid,
|
static inline int stsch(struct subchannel_id schid,
|
||||||
volatile struct schib *addr)
|
volatile struct schib *addr)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" stsch 0(%2)\n"
|
||||||
" stsch 0(%2)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int stsch_err(struct subchannel_id schid,
|
static inline int stsch_err(struct subchannel_id schid,
|
||||||
volatile struct schib *addr)
|
volatile struct schib *addr)
|
||||||
{
|
{
|
||||||
int ccode;
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
|
int ccode = -EIO;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lhi %0,%3\n"
|
" stsch 0(%2)\n"
|
||||||
" lr 1,%1\n"
|
"0: ipm %0\n"
|
||||||
" stsch 0(%2)\n"
|
" srl %0,28\n"
|
||||||
"0: ipm %0\n"
|
|
||||||
" srl %0,28\n"
|
|
||||||
"1:\n"
|
"1:\n"
|
||||||
#ifdef CONFIG_64BIT
|
EX_TABLE(0b,1b)
|
||||||
".section __ex_table,\"a\"\n"
|
: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#else
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#endif
|
|
||||||
: "=&d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int msch(struct subchannel_id schid,
|
static inline int msch(struct subchannel_id schid,
|
||||||
volatile struct schib *addr)
|
volatile struct schib *addr)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" msch 0(%2)\n"
|
||||||
" msch 0(%2)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int msch_err(struct subchannel_id schid,
|
static inline int msch_err(struct subchannel_id schid,
|
||||||
volatile struct schib *addr)
|
volatile struct schib *addr)
|
||||||
{
|
{
|
||||||
int ccode;
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
|
int ccode = -EIO;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lhi %0,%3\n"
|
" msch 0(%2)\n"
|
||||||
" lr 1,%1\n"
|
"0: ipm %0\n"
|
||||||
" msch 0(%2)\n"
|
" srl %0,28\n"
|
||||||
"0: ipm %0\n"
|
|
||||||
" srl %0,28\n"
|
|
||||||
"1:\n"
|
"1:\n"
|
||||||
#ifdef CONFIG_64BIT
|
EX_TABLE(0b,1b)
|
||||||
".section __ex_table,\"a\"\n"
|
: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
" .align 8\n"
|
|
||||||
" .quad 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#else
|
|
||||||
".section __ex_table,\"a\"\n"
|
|
||||||
" .align 4\n"
|
|
||||||
" .long 0b,1b\n"
|
|
||||||
".previous"
|
|
||||||
#endif
|
|
||||||
: "=&d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tsch(struct subchannel_id schid,
|
static inline int tsch(struct subchannel_id schid,
|
||||||
volatile struct irb *addr)
|
volatile struct irb *addr)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" tsch 0(%2)\n"
|
||||||
" tsch 0(%2)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,89 +100,77 @@ static inline int tpi( volatile struct tpi_info *addr)
|
|||||||
{
|
{
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" tpi 0(%1)\n"
|
" tpi 0(%1)\n"
|
||||||
" ipm %0\n"
|
" ipm %0\n"
|
||||||
" srl %0,28"
|
" srl %0,28"
|
||||||
: "=d" (ccode)
|
: "=d" (ccode) : "a" (addr), "m" (*addr) : "cc");
|
||||||
: "a" (addr), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ssch(struct subchannel_id schid,
|
static inline int ssch(struct subchannel_id schid,
|
||||||
volatile struct orb *addr)
|
volatile struct orb *addr)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" ssch 0(%2)\n"
|
||||||
" ssch 0(%2)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid), "a" (addr), "m" (*addr)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int rsch(struct subchannel_id schid)
|
static inline int rsch(struct subchannel_id schid)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" rsch\n"
|
||||||
" rsch\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int csch(struct subchannel_id schid)
|
static inline int csch(struct subchannel_id schid)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" csch\n"
|
||||||
" csch\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int hsch(struct subchannel_id schid)
|
static inline int hsch(struct subchannel_id schid)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" hsch\n"
|
||||||
" hsch\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xsch(struct subchannel_id schid)
|
static inline int xsch(struct subchannel_id schid)
|
||||||
{
|
{
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" .insn rre,0xb2760000,%1,0\n"
|
||||||
" .insn rre,0xb2760000,%1,0\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28"
|
||||||
" srl %0,28"
|
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||||
: "=d" (ccode)
|
|
||||||
: "d" (schid)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,41 +179,27 @@ static inline int chsc(void *chsc_area)
|
|||||||
typedef struct { char _[4096]; } addr_type;
|
typedef struct { char _[4096]; } addr_type;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
".insn rre,0xb25f0000,%2,0 \n\t"
|
" .insn rre,0xb25f0000,%2,0\n"
|
||||||
"ipm %0 \n\t"
|
" ipm %0\n"
|
||||||
"srl %0,28 \n\t"
|
" srl %0,28\n"
|
||||||
: "=d" (cc), "=m" (*(addr_type *) chsc_area)
|
: "=d" (cc), "=m" (*(addr_type *) chsc_area)
|
||||||
: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
|
: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
|
||||||
: "cc" );
|
: "cc");
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int iac( void)
|
|
||||||
{
|
|
||||||
int ccode;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" iac 1\n"
|
|
||||||
" ipm %0\n"
|
|
||||||
" srl %0,28"
|
|
||||||
: "=d" (ccode) : : "cc", "1" );
|
|
||||||
return ccode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rchp(int chpid)
|
static inline int rchp(int chpid)
|
||||||
{
|
{
|
||||||
|
register unsigned int reg1 asm ("1") = chpid;
|
||||||
int ccode;
|
int ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n"
|
" lr 1,%1\n"
|
||||||
" rchp\n"
|
" rchp\n"
|
||||||
" ipm %0\n"
|
" ipm %0\n"
|
||||||
" srl %0,28"
|
" srl %0,28"
|
||||||
: "=d" (ccode)
|
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||||
: "d" (chpid)
|
|
||||||
: "cc", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,12 +274,11 @@ do_sqbs(unsigned long sch, unsigned char state, int queue,
|
|||||||
register unsigned long _sch asm ("1") = sch;
|
register unsigned long _sch asm ("1") = sch;
|
||||||
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
|
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
|
||||||
|
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t"
|
" .insn rsy,0xeb000000008A,%1,0,0(%2)"
|
||||||
: "+d" (_ccq), "+d" (_queuestart)
|
: "+d" (_ccq), "+d" (_queuestart)
|
||||||
: "d" ((unsigned long)state), "d" (_sch)
|
: "d" ((unsigned long)state), "d" (_sch)
|
||||||
: "memory", "cc"
|
: "memory", "cc");
|
||||||
);
|
|
||||||
*count = _ccq & 0xff;
|
*count = _ccq & 0xff;
|
||||||
*start = _queuestart & 0xff;
|
*start = _queuestart & 0xff;
|
||||||
|
|
||||||
@ -299,12 +298,11 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue,
|
|||||||
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
|
unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
|
||||||
unsigned long _state = 0;
|
unsigned long _state = 0;
|
||||||
|
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" .insn rrf,0xB99c0000,%1,%2,0,0 \n\t"
|
" .insn rrf,0xB99c0000,%1,%2,0,0"
|
||||||
: "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
|
: "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
|
||||||
: "d" (_sch)
|
: "d" (_sch)
|
||||||
: "memory", "cc"
|
: "memory", "cc" );
|
||||||
);
|
|
||||||
*count = _ccq & 0xff;
|
*count = _ccq & 0xff;
|
||||||
*start = _queuestart & 0xff;
|
*start = _queuestart & 0xff;
|
||||||
*state = _state & 0xff;
|
*state = _state & 0xff;
|
||||||
@ -319,69 +317,35 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue,
|
|||||||
static inline int
|
static inline int
|
||||||
do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
|
do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
|
||||||
{
|
{
|
||||||
|
register unsigned long reg0 asm ("0") = 2;
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
|
register unsigned long reg2 asm ("2") = mask1;
|
||||||
|
register unsigned long reg3 asm ("3") = mask2;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
asm volatile(
|
||||||
asm volatile (
|
" siga 0\n"
|
||||||
"lhi 0,2 \n\t"
|
" ipm %0\n"
|
||||||
"lr 1,%1 \n\t"
|
" srl %0,28\n"
|
||||||
"lr 2,%2 \n\t"
|
|
||||||
"lr 3,%3 \n\t"
|
|
||||||
"siga 0 \n\t"
|
|
||||||
"ipm %0 \n\t"
|
|
||||||
"srl %0,28 \n\t"
|
|
||||||
: "=d" (cc)
|
: "=d" (cc)
|
||||||
: "d" (schid), "d" (mask1), "d" (mask2)
|
: "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc");
|
||||||
: "cc", "0", "1", "2", "3"
|
|
||||||
);
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
asm volatile (
|
|
||||||
"lghi 0,2 \n\t"
|
|
||||||
"llgfr 1,%1 \n\t"
|
|
||||||
"llgfr 2,%2 \n\t"
|
|
||||||
"llgfr 3,%3 \n\t"
|
|
||||||
"siga 0 \n\t"
|
|
||||||
"ipm %0 \n\t"
|
|
||||||
"srl %0,28 \n\t"
|
|
||||||
: "=d" (cc)
|
|
||||||
: "d" (schid), "d" (mask1), "d" (mask2)
|
|
||||||
: "cc", "0", "1", "2", "3"
|
|
||||||
);
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
do_siga_input(struct subchannel_id schid, unsigned int mask)
|
do_siga_input(struct subchannel_id schid, unsigned int mask)
|
||||||
{
|
{
|
||||||
|
register unsigned long reg0 asm ("0") = 1;
|
||||||
|
register struct subchannel_id reg1 asm ("1") = schid;
|
||||||
|
register unsigned long reg2 asm ("2") = mask;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
asm volatile(
|
||||||
asm volatile (
|
" siga 0\n"
|
||||||
"lhi 0,1 \n\t"
|
" ipm %0\n"
|
||||||
"lr 1,%1 \n\t"
|
" srl %0,28\n"
|
||||||
"lr 2,%2 \n\t"
|
|
||||||
"siga 0 \n\t"
|
|
||||||
"ipm %0 \n\t"
|
|
||||||
"srl %0,28 \n\t"
|
|
||||||
: "=d" (cc)
|
: "=d" (cc)
|
||||||
: "d" (schid), "d" (mask)
|
: "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory");
|
||||||
: "cc", "0", "1", "2", "memory"
|
|
||||||
);
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
asm volatile (
|
|
||||||
"lghi 0,1 \n\t"
|
|
||||||
"llgfr 1,%1 \n\t"
|
|
||||||
"llgfr 2,%2 \n\t"
|
|
||||||
"siga 0 \n\t"
|
|
||||||
"ipm %0 \n\t"
|
|
||||||
"srl %0,28 \n\t"
|
|
||||||
: "=d" (cc)
|
|
||||||
: "d" (schid), "d" (mask)
|
|
||||||
: "cc", "0", "1", "2", "memory"
|
|
||||||
);
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,93 +353,35 @@ static inline int
|
|||||||
do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
|
do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
|
||||||
unsigned int fc)
|
unsigned int fc)
|
||||||
{
|
{
|
||||||
|
register unsigned long __fc asm("0") = fc;
|
||||||
|
register unsigned long __schid asm("1") = schid;
|
||||||
|
register unsigned long __mask asm("2") = mask;
|
||||||
int cc;
|
int cc;
|
||||||
__u32 busy_bit;
|
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
asm volatile(
|
||||||
asm volatile (
|
" siga 0\n"
|
||||||
"lhi 0,0 \n\t"
|
"0: ipm %0\n"
|
||||||
"lr 1,%2 \n\t"
|
" srl %0,28\n"
|
||||||
"lr 2,%3 \n\t"
|
"1:\n"
|
||||||
"siga 0 \n\t"
|
EX_TABLE(0b,1b)
|
||||||
"0:"
|
: "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask)
|
||||||
"ipm %0 \n\t"
|
: "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
|
||||||
"srl %0,28 \n\t"
|
: "cc", "memory");
|
||||||
"srl 0,31 \n\t"
|
(*bb) = ((unsigned int) __fc) >> 31;
|
||||||
"lr %1,0 \n\t"
|
|
||||||
"1: \n\t"
|
|
||||||
".section .fixup,\"ax\"\n\t"
|
|
||||||
"2: \n\t"
|
|
||||||
"lhi %0,%4 \n\t"
|
|
||||||
"bras 1,3f \n\t"
|
|
||||||
".long 1b \n\t"
|
|
||||||
"3: \n\t"
|
|
||||||
"l 1,0(1) \n\t"
|
|
||||||
"br 1 \n\t"
|
|
||||||
".previous \n\t"
|
|
||||||
".section __ex_table,\"a\"\n\t"
|
|
||||||
".align 4 \n\t"
|
|
||||||
".long 0b,2b \n\t"
|
|
||||||
".previous \n\t"
|
|
||||||
: "=d" (cc), "=d" (busy_bit)
|
|
||||||
: "d" (schid), "d" (mask),
|
|
||||||
"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
|
|
||||||
: "cc", "0", "1", "2", "memory"
|
|
||||||
);
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
asm volatile (
|
|
||||||
"llgfr 0,%5 \n\t"
|
|
||||||
"lgr 1,%2 \n\t"
|
|
||||||
"llgfr 2,%3 \n\t"
|
|
||||||
"siga 0 \n\t"
|
|
||||||
"0:"
|
|
||||||
"ipm %0 \n\t"
|
|
||||||
"srl %0,28 \n\t"
|
|
||||||
"srl 0,31 \n\t"
|
|
||||||
"llgfr %1,0 \n\t"
|
|
||||||
"1: \n\t"
|
|
||||||
".section .fixup,\"ax\"\n\t"
|
|
||||||
"lghi %0,%4 \n\t"
|
|
||||||
"jg 1b \n\t"
|
|
||||||
".previous\n\t"
|
|
||||||
".section __ex_table,\"a\"\n\t"
|
|
||||||
".align 8 \n\t"
|
|
||||||
".quad 0b,1b \n\t"
|
|
||||||
".previous \n\t"
|
|
||||||
: "=d" (cc), "=d" (busy_bit)
|
|
||||||
: "d" (schid), "d" (mask),
|
|
||||||
"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
|
|
||||||
: "cc", "0", "1", "2", "memory"
|
|
||||||
);
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
|
|
||||||
(*bb) = busy_bit;
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long
|
static inline unsigned long
|
||||||
do_clear_global_summary(void)
|
do_clear_global_summary(void)
|
||||||
{
|
{
|
||||||
|
register unsigned long __fn asm("1") = 3;
|
||||||
|
register unsigned long __tmp asm("2");
|
||||||
|
register unsigned long __time asm("3");
|
||||||
|
|
||||||
unsigned long time;
|
asm volatile(
|
||||||
|
" .insn rre,0xb2650000,2,0"
|
||||||
#ifndef CONFIG_64BIT
|
: "+d" (__fn), "=d" (__tmp), "=d" (__time));
|
||||||
asm volatile (
|
return __time;
|
||||||
"lhi 1,3 \n\t"
|
|
||||||
".insn rre,0xb2650000,2,0 \n\t"
|
|
||||||
"lr %0,3 \n\t"
|
|
||||||
: "=d" (time) : : "cc", "1", "2", "3"
|
|
||||||
);
|
|
||||||
#else /* CONFIG_64BIT */
|
|
||||||
asm volatile (
|
|
||||||
"lghi 1,3 \n\t"
|
|
||||||
".insn rre,0xb2650000,2,0 \n\t"
|
|
||||||
"lgr %0,3 \n\t"
|
|
||||||
: "=d" (time) : : "cc", "1", "2", "3"
|
|
||||||
);
|
|
||||||
#endif /* CONFIG_64BIT */
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -534,19 +534,15 @@ iucv_add_handler (handler *new)
|
|||||||
*
|
*
|
||||||
* Returns: return code from CP's IUCV call
|
* Returns: return code from CP's IUCV call
|
||||||
*/
|
*/
|
||||||
static __inline__ ulong
|
static inline ulong b2f0(__u32 code, void *parm)
|
||||||
b2f0(__u32 code, void *parm)
|
|
||||||
{
|
{
|
||||||
|
register unsigned long reg0 asm ("0");
|
||||||
|
register unsigned long reg1 asm ("1");
|
||||||
iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));
|
iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));
|
||||||
|
|
||||||
asm volatile (
|
reg0 = code;
|
||||||
"LRA 1,0(%1)\n\t"
|
reg1 = virt_to_phys(parm);
|
||||||
"LR 0,%0\n\t"
|
asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1));
|
||||||
".long 0xb2f01000"
|
|
||||||
:
|
|
||||||
: "d" (code), "a" (parm)
|
|
||||||
: "0", "1"
|
|
||||||
);
|
|
||||||
|
|
||||||
iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));
|
iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));
|
||||||
|
|
||||||
@ -1248,6 +1244,8 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
|
|||||||
static int
|
static int
|
||||||
iucv_query_generic(int want_maxconn)
|
iucv_query_generic(int want_maxconn)
|
||||||
{
|
{
|
||||||
|
register unsigned long reg0 asm ("0");
|
||||||
|
register unsigned long reg1 asm ("1");
|
||||||
iparml_purge *parm = (iparml_purge *)grab_param();
|
iparml_purge *parm = (iparml_purge *)grab_param();
|
||||||
int bufsize, maxconn;
|
int bufsize, maxconn;
|
||||||
int ccode;
|
int ccode;
|
||||||
@ -1256,18 +1254,15 @@ iucv_query_generic(int want_maxconn)
|
|||||||
* Call b2f0 and store R0 (max buffer size),
|
* Call b2f0 and store R0 (max buffer size),
|
||||||
* R1 (max connections) and CC.
|
* R1 (max connections) and CC.
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
reg0 = QUERY;
|
||||||
"LRA 1,0(%4)\n\t"
|
reg1 = virt_to_phys(parm);
|
||||||
"LR 0,%3\n\t"
|
asm volatile(
|
||||||
".long 0xb2f01000\n\t"
|
" .long 0xb2f01000\n"
|
||||||
"IPM %0\n\t"
|
" ipm %0\n"
|
||||||
"SRL %0,28\n\t"
|
" srl %0,28\n"
|
||||||
"ST 0,%1\n\t"
|
: "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
|
||||||
"ST 1,%2\n\t"
|
bufsize = reg0;
|
||||||
: "=d" (ccode), "=m" (bufsize), "=m" (maxconn)
|
maxconn = reg1;
|
||||||
: "d" (QUERY), "a" (parm)
|
|
||||||
: "0", "1", "cc"
|
|
||||||
);
|
|
||||||
release_param(parm);
|
release_param(parm);
|
||||||
|
|
||||||
if (ccode)
|
if (ccode)
|
||||||
|
@ -253,11 +253,12 @@ s390_revalidate_registers(struct mci *mci)
|
|||||||
kill_task = 1;
|
kill_task = 1;
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
asm volatile("ld 0,0(%0)\n"
|
asm volatile(
|
||||||
"ld 2,8(%0)\n"
|
" ld 0,0(%0)\n"
|
||||||
"ld 4,16(%0)\n"
|
" ld 2,8(%0)\n"
|
||||||
"ld 6,24(%0)"
|
" ld 4,16(%0)\n"
|
||||||
: : "a" (&S390_lowcore.floating_pt_save_area));
|
" ld 6,24(%0)"
|
||||||
|
: : "a" (&S390_lowcore.floating_pt_save_area));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (MACHINE_HAS_IEEE) {
|
if (MACHINE_HAS_IEEE) {
|
||||||
@ -274,37 +275,36 @@ s390_revalidate_registers(struct mci *mci)
|
|||||||
* Floating point control register can't be restored.
|
* Floating point control register can't be restored.
|
||||||
* Task will be terminated.
|
* Task will be terminated.
|
||||||
*/
|
*/
|
||||||
asm volatile ("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
|
asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
|
||||||
kill_task = 1;
|
kill_task = 1;
|
||||||
|
|
||||||
}
|
} else
|
||||||
else
|
asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
|
||||||
asm volatile (
|
|
||||||
"lfpc 0(%0)"
|
|
||||||
: : "a" (fpt_creg_save_area));
|
|
||||||
|
|
||||||
asm volatile("ld 0,0(%0)\n"
|
asm volatile(
|
||||||
"ld 1,8(%0)\n"
|
" ld 0,0(%0)\n"
|
||||||
"ld 2,16(%0)\n"
|
" ld 1,8(%0)\n"
|
||||||
"ld 3,24(%0)\n"
|
" ld 2,16(%0)\n"
|
||||||
"ld 4,32(%0)\n"
|
" ld 3,24(%0)\n"
|
||||||
"ld 5,40(%0)\n"
|
" ld 4,32(%0)\n"
|
||||||
"ld 6,48(%0)\n"
|
" ld 5,40(%0)\n"
|
||||||
"ld 7,56(%0)\n"
|
" ld 6,48(%0)\n"
|
||||||
"ld 8,64(%0)\n"
|
" ld 7,56(%0)\n"
|
||||||
"ld 9,72(%0)\n"
|
" ld 8,64(%0)\n"
|
||||||
"ld 10,80(%0)\n"
|
" ld 9,72(%0)\n"
|
||||||
"ld 11,88(%0)\n"
|
" ld 10,80(%0)\n"
|
||||||
"ld 12,96(%0)\n"
|
" ld 11,88(%0)\n"
|
||||||
"ld 13,104(%0)\n"
|
" ld 12,96(%0)\n"
|
||||||
"ld 14,112(%0)\n"
|
" ld 13,104(%0)\n"
|
||||||
"ld 15,120(%0)\n"
|
" ld 14,112(%0)\n"
|
||||||
: : "a" (fpt_save_area));
|
" ld 15,120(%0)\n"
|
||||||
|
: : "a" (fpt_save_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revalidate access registers */
|
/* Revalidate access registers */
|
||||||
asm volatile("lam 0,15,0(%0)"
|
asm volatile(
|
||||||
: : "a" (&S390_lowcore.access_regs_save_area));
|
" lam 0,15,0(%0)"
|
||||||
|
: : "a" (&S390_lowcore.access_regs_save_area));
|
||||||
if (!mci->ar)
|
if (!mci->ar)
|
||||||
/*
|
/*
|
||||||
* Access registers have unknown contents.
|
* Access registers have unknown contents.
|
||||||
@ -321,11 +321,13 @@ s390_revalidate_registers(struct mci *mci)
|
|||||||
s390_handle_damage("invalid control registers.");
|
s390_handle_damage("invalid control registers.");
|
||||||
else
|
else
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
asm volatile("lctlg 0,15,0(%0)"
|
asm volatile(
|
||||||
: : "a" (&S390_lowcore.cregs_save_area));
|
" lctlg 0,15,0(%0)"
|
||||||
|
: : "a" (&S390_lowcore.cregs_save_area));
|
||||||
#else
|
#else
|
||||||
asm volatile("lctl 0,15,0(%0)"
|
asm volatile(
|
||||||
: : "a" (&S390_lowcore.cregs_save_area));
|
" lctl 0,15,0(%0)"
|
||||||
|
: : "a" (&S390_lowcore.cregs_save_area));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -339,20 +341,23 @@ s390_revalidate_registers(struct mci *mci)
|
|||||||
* old contents (should be zero) otherwise set it to zero.
|
* old contents (should be zero) otherwise set it to zero.
|
||||||
*/
|
*/
|
||||||
if (!mci->pr)
|
if (!mci->pr)
|
||||||
asm volatile("sr 0,0\n"
|
asm volatile(
|
||||||
"sckpf"
|
" sr 0,0\n"
|
||||||
: : : "0", "cc");
|
" sckpf"
|
||||||
|
: : : "0", "cc");
|
||||||
else
|
else
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"l 0,0(%0)\n"
|
" l 0,0(%0)\n"
|
||||||
"sckpf"
|
" sckpf"
|
||||||
: : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc");
|
: : "a" (&S390_lowcore.tod_progreg_save_area)
|
||||||
|
: "0", "cc");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Revalidate clock comparator register */
|
/* Revalidate clock comparator register */
|
||||||
asm volatile ("stck 0(%1)\n"
|
asm volatile(
|
||||||
"sckc 0(%1)"
|
" stck 0(%1)\n"
|
||||||
: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
|
" sckc 0(%1)"
|
||||||
|
: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
|
||||||
|
|
||||||
/* Check if old PSW is valid */
|
/* Check if old PSW is valid */
|
||||||
if (!mci->wp)
|
if (!mci->wp)
|
||||||
|
@ -80,7 +80,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
|
|||||||
parm_list.product_id_addr = (unsigned long) id;
|
parm_list.product_id_addr = (unsigned long) id;
|
||||||
parm_list.buffer_addr = virt_to_phys(buffer);
|
parm_list.buffer_addr = virt_to_phys(buffer);
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"diag %1,%0,0xdc"
|
" diag %1,%0,0xdc"
|
||||||
: "=d" (ry)
|
: "=d" (ry)
|
||||||
: "d" (&parm_list), "m" (parm_list), "m" (*id)
|
: "d" (&parm_list), "m" (parm_list), "m" (*id)
|
||||||
: "cc");
|
: "cc");
|
||||||
|
@ -30,20 +30,43 @@ typedef struct {
|
|||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
|
|
||||||
#define __CS_LOOP(ptr, op_val, op_string) ({ \
|
#define __CS_LOOP(ptr, op_val, op_string) ({ \
|
||||||
typeof(ptr->counter) old_val, new_val; \
|
typeof(ptr->counter) old_val, new_val; \
|
||||||
__asm__ __volatile__(" l %0,0(%3)\n" \
|
asm volatile( \
|
||||||
"0: lr %1,%0\n" \
|
" l %0,%2\n" \
|
||||||
op_string " %1,%4\n" \
|
"0: lr %1,%0\n" \
|
||||||
" cs %0,%1,0(%3)\n" \
|
op_string " %1,%3\n" \
|
||||||
" jl 0b" \
|
" cs %0,%1,%2\n" \
|
||||||
: "=&d" (old_val), "=&d" (new_val), \
|
" jl 0b" \
|
||||||
"=m" (((atomic_t *)(ptr))->counter) \
|
: "=&d" (old_val), "=&d" (new_val), \
|
||||||
: "a" (ptr), "d" (op_val), \
|
"=Q" (((atomic_t *)(ptr))->counter) \
|
||||||
"m" (((atomic_t *)(ptr))->counter) \
|
: "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \
|
||||||
: "cc", "memory" ); \
|
: "cc", "memory"); \
|
||||||
new_val; \
|
new_val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
#define __CS_LOOP(ptr, op_val, op_string) ({ \
|
||||||
|
typeof(ptr->counter) old_val, new_val; \
|
||||||
|
asm volatile( \
|
||||||
|
" l %0,0(%3)\n" \
|
||||||
|
"0: lr %1,%0\n" \
|
||||||
|
op_string " %1,%4\n" \
|
||||||
|
" cs %0,%1,0(%3)\n" \
|
||||||
|
" jl 0b" \
|
||||||
|
: "=&d" (old_val), "=&d" (new_val), \
|
||||||
|
"=m" (((atomic_t *)(ptr))->counter) \
|
||||||
|
: "a" (ptr), "d" (op_val), \
|
||||||
|
"m" (((atomic_t *)(ptr))->counter) \
|
||||||
|
: "cc", "memory"); \
|
||||||
|
new_val; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#define atomic_read(v) ((v)->counter)
|
#define atomic_read(v) ((v)->counter)
|
||||||
#define atomic_set(v,i) (((v)->counter) = (i))
|
#define atomic_set(v,i) (((v)->counter) = (i))
|
||||||
|
|
||||||
@ -81,10 +104,19 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v)
|
|||||||
|
|
||||||
static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
|
static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(" cs %0,%3,0(%2)\n"
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
: "+d" (old), "=m" (v->counter)
|
asm volatile(
|
||||||
: "a" (v), "d" (new), "m" (v->counter)
|
" cs %0,%2,%1"
|
||||||
: "cc", "memory" );
|
: "+d" (old), "=Q" (v->counter)
|
||||||
|
: "d" (new), "Q" (v->counter)
|
||||||
|
: "cc", "memory");
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
asm volatile(
|
||||||
|
" cs %0,%3,0(%2)"
|
||||||
|
: "+d" (old), "=m" (v->counter)
|
||||||
|
: "a" (v), "d" (new), "m" (v->counter)
|
||||||
|
: "cc", "memory");
|
||||||
|
#endif /* __GNUC__ */
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,20 +145,43 @@ typedef struct {
|
|||||||
} __attribute__ ((aligned (8))) atomic64_t;
|
} __attribute__ ((aligned (8))) atomic64_t;
|
||||||
#define ATOMIC64_INIT(i) { (i) }
|
#define ATOMIC64_INIT(i) { (i) }
|
||||||
|
|
||||||
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
|
|
||||||
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
|
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
|
||||||
typeof(ptr->counter) old_val, new_val; \
|
typeof(ptr->counter) old_val, new_val; \
|
||||||
__asm__ __volatile__(" lg %0,0(%3)\n" \
|
asm volatile( \
|
||||||
"0: lgr %1,%0\n" \
|
" lg %0,%2\n" \
|
||||||
op_string " %1,%4\n" \
|
"0: lgr %1,%0\n" \
|
||||||
" csg %0,%1,0(%3)\n" \
|
op_string " %1,%3\n" \
|
||||||
" jl 0b" \
|
" csg %0,%1,%2\n" \
|
||||||
: "=&d" (old_val), "=&d" (new_val), \
|
" jl 0b" \
|
||||||
"=m" (((atomic_t *)(ptr))->counter) \
|
: "=&d" (old_val), "=&d" (new_val), \
|
||||||
: "a" (ptr), "d" (op_val), \
|
"=Q" (((atomic_t *)(ptr))->counter) \
|
||||||
"m" (((atomic_t *)(ptr))->counter) \
|
: "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \
|
||||||
: "cc", "memory" ); \
|
: "cc", "memory" ); \
|
||||||
new_val; \
|
new_val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
|
||||||
|
typeof(ptr->counter) old_val, new_val; \
|
||||||
|
asm volatile( \
|
||||||
|
" lg %0,0(%3)\n" \
|
||||||
|
"0: lgr %1,%0\n" \
|
||||||
|
op_string " %1,%4\n" \
|
||||||
|
" csg %0,%1,0(%3)\n" \
|
||||||
|
" jl 0b" \
|
||||||
|
: "=&d" (old_val), "=&d" (new_val), \
|
||||||
|
"=m" (((atomic_t *)(ptr))->counter) \
|
||||||
|
: "a" (ptr), "d" (op_val), \
|
||||||
|
"m" (((atomic_t *)(ptr))->counter) \
|
||||||
|
: "cc", "memory" ); \
|
||||||
|
new_val; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#define atomic64_read(v) ((v)->counter)
|
#define atomic64_read(v) ((v)->counter)
|
||||||
#define atomic64_set(v,i) (((v)->counter) = (i))
|
#define atomic64_set(v,i) (((v)->counter) = (i))
|
||||||
|
|
||||||
@ -163,10 +218,19 @@ static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
|
|||||||
static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
|
static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
|
||||||
long long old, long long new)
|
long long old, long long new)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(" csg %0,%3,0(%2)\n"
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
: "+d" (old), "=m" (v->counter)
|
asm volatile(
|
||||||
: "a" (v), "d" (new), "m" (v->counter)
|
" csg %0,%2,%1"
|
||||||
: "cc", "memory" );
|
: "+d" (old), "=Q" (v->counter)
|
||||||
|
: "d" (new), "Q" (v->counter)
|
||||||
|
: "cc", "memory");
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
asm volatile(
|
||||||
|
" csg %0,%3,0(%2)"
|
||||||
|
: "+d" (old), "=m" (v->counter)
|
||||||
|
: "a" (v), "d" (new), "m" (v->counter)
|
||||||
|
: "cc", "memory");
|
||||||
|
#endif /* __GNUC__ */
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,16 +67,35 @@ extern const char _sb_findmap[];
|
|||||||
#define __BITOPS_AND "nr"
|
#define __BITOPS_AND "nr"
|
||||||
#define __BITOPS_XOR "xr"
|
#define __BITOPS_XOR "xr"
|
||||||
|
|
||||||
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
__asm__ __volatile__(" l %0,0(%4)\n" \
|
|
||||||
"0: lr %1,%0\n" \
|
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
||||||
__op_string " %1,%3\n" \
|
asm volatile( \
|
||||||
" cs %0,%1,0(%4)\n" \
|
" l %0,%2\n" \
|
||||||
" jl 0b" \
|
"0: lr %1,%0\n" \
|
||||||
: "=&d" (__old), "=&d" (__new), \
|
__op_string " %1,%3\n" \
|
||||||
"=m" (*(unsigned long *) __addr) \
|
" cs %0,%1,%2\n" \
|
||||||
: "d" (__val), "a" (__addr), \
|
" jl 0b" \
|
||||||
"m" (*(unsigned long *) __addr) : "cc" );
|
: "=&d" (__old), "=&d" (__new), \
|
||||||
|
"=Q" (*(unsigned long *) __addr) \
|
||||||
|
: "d" (__val), "Q" (*(unsigned long *) __addr) \
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
||||||
|
asm volatile( \
|
||||||
|
" l %0,0(%4)\n" \
|
||||||
|
"0: lr %1,%0\n" \
|
||||||
|
__op_string " %1,%3\n" \
|
||||||
|
" cs %0,%1,0(%4)\n" \
|
||||||
|
" jl 0b" \
|
||||||
|
: "=&d" (__old), "=&d" (__new), \
|
||||||
|
"=m" (*(unsigned long *) __addr) \
|
||||||
|
: "d" (__val), "a" (__addr), \
|
||||||
|
"m" (*(unsigned long *) __addr) : "cc");
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
|
|
||||||
@ -86,21 +105,41 @@ extern const char _sb_findmap[];
|
|||||||
#define __BITOPS_AND "ngr"
|
#define __BITOPS_AND "ngr"
|
||||||
#define __BITOPS_XOR "xgr"
|
#define __BITOPS_XOR "xgr"
|
||||||
|
|
||||||
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
__asm__ __volatile__(" lg %0,0(%4)\n" \
|
|
||||||
"0: lgr %1,%0\n" \
|
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
||||||
__op_string " %1,%3\n" \
|
asm volatile( \
|
||||||
" csg %0,%1,0(%4)\n" \
|
" lg %0,%2\n" \
|
||||||
" jl 0b" \
|
"0: lgr %1,%0\n" \
|
||||||
: "=&d" (__old), "=&d" (__new), \
|
__op_string " %1,%3\n" \
|
||||||
"=m" (*(unsigned long *) __addr) \
|
" csg %0,%1,%2\n" \
|
||||||
: "d" (__val), "a" (__addr), \
|
" jl 0b" \
|
||||||
"m" (*(unsigned long *) __addr) : "cc" );
|
: "=&d" (__old), "=&d" (__new), \
|
||||||
|
"=Q" (*(unsigned long *) __addr) \
|
||||||
|
: "d" (__val), "Q" (*(unsigned long *) __addr) \
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
|
||||||
|
asm volatile( \
|
||||||
|
" lg %0,0(%4)\n" \
|
||||||
|
"0: lgr %1,%0\n" \
|
||||||
|
__op_string " %1,%3\n" \
|
||||||
|
" csg %0,%1,0(%4)\n" \
|
||||||
|
" jl 0b" \
|
||||||
|
: "=&d" (__old), "=&d" (__new), \
|
||||||
|
"=m" (*(unsigned long *) __addr) \
|
||||||
|
: "d" (__val), "a" (__addr), \
|
||||||
|
"m" (*(unsigned long *) __addr) : "cc");
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
|
||||||
#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
|
#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
|
||||||
#define __BITOPS_BARRIER() __asm__ __volatile__ ( "" : : : "memory" )
|
#define __BITOPS_BARRIER() asm volatile("" : : : "memory")
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/*
|
/*
|
||||||
@ -217,10 +256,10 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
asm volatile("oc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" oc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr) : "a" (addr),
|
||||||
"m" (*(char *) addr) : "cc" );
|
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -229,40 +268,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
switch (nr&7) {
|
*(unsigned char *) addr |= 1 << (nr & 7);
|
||||||
case 0:
|
|
||||||
asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define set_bit_simple(nr,addr) \
|
#define set_bit_simple(nr,addr) \
|
||||||
@ -279,10 +285,10 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
asm volatile("nc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" nc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr) : "a" (addr),
|
||||||
"m" (*(char *) addr) : "cc" );
|
"a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -291,40 +297,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
switch (nr&7) {
|
*(unsigned char *) addr &= ~(1 << (nr & 7));
|
||||||
case 0:
|
|
||||||
asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define clear_bit_simple(nr,addr) \
|
#define clear_bit_simple(nr,addr) \
|
||||||
@ -340,10 +313,10 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
asm volatile("xc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" xc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr) : "a" (addr),
|
||||||
"m" (*(char *) addr) : "cc" );
|
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -352,40 +325,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr)
|
|||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
switch (nr&7) {
|
*(unsigned char *) addr ^= 1 << (nr & 7);
|
||||||
case 0:
|
|
||||||
asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr)
|
|
||||||
: "a" (addr), "m" (*(char *) addr) : "cc" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define change_bit_simple(nr,addr) \
|
#define change_bit_simple(nr,addr) \
|
||||||
@ -404,10 +344,11 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
ch = *(unsigned char *) addr;
|
ch = *(unsigned char *) addr;
|
||||||
asm volatile("oc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" oc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr)
|
||||||
"m" (*(char *) addr) : "cc", "memory" );
|
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
||||||
|
"m" (*(char *) addr) : "cc", "memory");
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
|
#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
|
||||||
@ -423,10 +364,11 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
ch = *(unsigned char *) addr;
|
ch = *(unsigned char *) addr;
|
||||||
asm volatile("nc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" nc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr)
|
||||||
"m" (*(char *) addr) : "cc", "memory" );
|
: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
|
||||||
|
"m" (*(char *) addr) : "cc", "memory");
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
|
#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
|
||||||
@ -442,10 +384,11 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
|
|||||||
|
|
||||||
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
|
||||||
ch = *(unsigned char *) addr;
|
ch = *(unsigned char *) addr;
|
||||||
asm volatile("xc 0(1,%1),0(%2)"
|
asm volatile(
|
||||||
: "=m" (*(char *) addr)
|
" xc 0(1,%1),0(%2)"
|
||||||
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
: "=m" (*(char *) addr)
|
||||||
"m" (*(char *) addr) : "cc", "memory" );
|
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
|
||||||
|
"m" (*(char *) addr) : "cc", "memory");
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
|
#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
|
||||||
@ -557,35 +500,36 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" lhi %1,-1\n"
|
asm volatile(
|
||||||
" lr %2,%3\n"
|
" lhi %1,-1\n"
|
||||||
" slr %0,%0\n"
|
" lr %2,%3\n"
|
||||||
" ahi %2,31\n"
|
" slr %0,%0\n"
|
||||||
" srl %2,5\n"
|
" ahi %2,31\n"
|
||||||
"0: c %1,0(%0,%4)\n"
|
" srl %2,5\n"
|
||||||
" jne 1f\n"
|
"0: c %1,0(%0,%4)\n"
|
||||||
" la %0,4(%0)\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" la %0,4(%0)\n"
|
||||||
" lr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 4f\n"
|
" lr %0,%3\n"
|
||||||
"1: l %2,0(%0,%4)\n"
|
" j 4f\n"
|
||||||
" sll %0,3\n"
|
"1: l %2,0(%0,%4)\n"
|
||||||
" lhi %1,0xff\n"
|
" sll %0,3\n"
|
||||||
" tml %2,0xffff\n"
|
" lhi %1,0xff\n"
|
||||||
" jno 2f\n"
|
" tml %2,0xffff\n"
|
||||||
" ahi %0,16\n"
|
" jno 2f\n"
|
||||||
" srl %2,16\n"
|
" ahi %0,16\n"
|
||||||
"2: tml %2,0x00ff\n"
|
" srl %2,16\n"
|
||||||
" jno 3f\n"
|
"2: tml %2,0x00ff\n"
|
||||||
" ahi %0,8\n"
|
" jno 3f\n"
|
||||||
" srl %2,8\n"
|
" ahi %0,8\n"
|
||||||
"3: nr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"3: nr %2,%1\n"
|
||||||
" alr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"4:"
|
" alr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"4:"
|
||||||
: "a" (size), "a" (addr), "a" (&_zb_findmap),
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
"m" (*(addrtype *) addr) : "cc" );
|
: "a" (size), "a" (addr), "a" (&_zb_findmap),
|
||||||
|
"m" (*(addrtype *) addr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,35 +542,36 @@ find_first_bit(const unsigned long * addr, unsigned long size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" slr %1,%1\n"
|
asm volatile(
|
||||||
" lr %2,%3\n"
|
" slr %1,%1\n"
|
||||||
" slr %0,%0\n"
|
" lr %2,%3\n"
|
||||||
" ahi %2,31\n"
|
" slr %0,%0\n"
|
||||||
" srl %2,5\n"
|
" ahi %2,31\n"
|
||||||
"0: c %1,0(%0,%4)\n"
|
" srl %2,5\n"
|
||||||
" jne 1f\n"
|
"0: c %1,0(%0,%4)\n"
|
||||||
" la %0,4(%0)\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" la %0,4(%0)\n"
|
||||||
" lr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 4f\n"
|
" lr %0,%3\n"
|
||||||
"1: l %2,0(%0,%4)\n"
|
" j 4f\n"
|
||||||
" sll %0,3\n"
|
"1: l %2,0(%0,%4)\n"
|
||||||
" lhi %1,0xff\n"
|
" sll %0,3\n"
|
||||||
" tml %2,0xffff\n"
|
" lhi %1,0xff\n"
|
||||||
" jnz 2f\n"
|
" tml %2,0xffff\n"
|
||||||
" ahi %0,16\n"
|
" jnz 2f\n"
|
||||||
" srl %2,16\n"
|
" ahi %0,16\n"
|
||||||
"2: tml %2,0x00ff\n"
|
" srl %2,16\n"
|
||||||
" jnz 3f\n"
|
"2: tml %2,0x00ff\n"
|
||||||
" ahi %0,8\n"
|
" jnz 3f\n"
|
||||||
" srl %2,8\n"
|
" ahi %0,8\n"
|
||||||
"3: nr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"3: nr %2,%1\n"
|
||||||
" alr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"4:"
|
" alr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"4:"
|
||||||
: "a" (size), "a" (addr), "a" (&_sb_findmap),
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
"m" (*(addrtype *) addr) : "cc" );
|
: "a" (size), "a" (addr), "a" (&_sb_findmap),
|
||||||
|
"m" (*(addrtype *) addr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,39 +585,40 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" lghi %1,-1\n"
|
asm volatile(
|
||||||
" lgr %2,%3\n"
|
" lghi %1,-1\n"
|
||||||
" slgr %0,%0\n"
|
" lgr %2,%3\n"
|
||||||
" aghi %2,63\n"
|
" slgr %0,%0\n"
|
||||||
" srlg %2,%2,6\n"
|
" aghi %2,63\n"
|
||||||
"0: cg %1,0(%0,%4)\n"
|
" srlg %2,%2,6\n"
|
||||||
" jne 1f\n"
|
"0: cg %1,0(%0,%4)\n"
|
||||||
" la %0,8(%0)\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" la %0,8(%0)\n"
|
||||||
" lgr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 5f\n"
|
" lgr %0,%3\n"
|
||||||
"1: lg %2,0(%0,%4)\n"
|
" j 5f\n"
|
||||||
" sllg %0,%0,3\n"
|
"1: lg %2,0(%0,%4)\n"
|
||||||
" clr %2,%1\n"
|
" sllg %0,%0,3\n"
|
||||||
" jne 2f\n"
|
" clr %2,%1\n"
|
||||||
" aghi %0,32\n"
|
" jne 2f\n"
|
||||||
" srlg %2,%2,32\n"
|
" aghi %0,32\n"
|
||||||
"2: lghi %1,0xff\n"
|
" srlg %2,%2,32\n"
|
||||||
" tmll %2,0xffff\n"
|
"2: lghi %1,0xff\n"
|
||||||
" jno 3f\n"
|
" tmll %2,0xffff\n"
|
||||||
" aghi %0,16\n"
|
" jno 3f\n"
|
||||||
" srl %2,16\n"
|
" aghi %0,16\n"
|
||||||
"3: tmll %2,0x00ff\n"
|
" srl %2,16\n"
|
||||||
" jno 4f\n"
|
"3: tmll %2,0x00ff\n"
|
||||||
" aghi %0,8\n"
|
" jno 4f\n"
|
||||||
" srl %2,8\n"
|
" aghi %0,8\n"
|
||||||
"4: ngr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"4: ngr %2,%1\n"
|
||||||
" algr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"5:"
|
" algr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"5:"
|
||||||
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
: "a" (size), "a" (addr), "a" (&_zb_findmap),
|
: "a" (size), "a" (addr), "a" (&_zb_findmap),
|
||||||
"m" (*(addrtype *) addr) : "cc" );
|
"m" (*(addrtype *) addr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,39 +630,40 @@ find_first_bit(const unsigned long * addr, unsigned long size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" slgr %1,%1\n"
|
asm volatile(
|
||||||
" lgr %2,%3\n"
|
" slgr %1,%1\n"
|
||||||
" slgr %0,%0\n"
|
" lgr %2,%3\n"
|
||||||
" aghi %2,63\n"
|
" slgr %0,%0\n"
|
||||||
" srlg %2,%2,6\n"
|
" aghi %2,63\n"
|
||||||
"0: cg %1,0(%0,%4)\n"
|
" srlg %2,%2,6\n"
|
||||||
" jne 1f\n"
|
"0: cg %1,0(%0,%4)\n"
|
||||||
" aghi %0,8\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" aghi %0,8\n"
|
||||||
" lgr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 5f\n"
|
" lgr %0,%3\n"
|
||||||
"1: lg %2,0(%0,%4)\n"
|
" j 5f\n"
|
||||||
" sllg %0,%0,3\n"
|
"1: lg %2,0(%0,%4)\n"
|
||||||
" clr %2,%1\n"
|
" sllg %0,%0,3\n"
|
||||||
" jne 2f\n"
|
" clr %2,%1\n"
|
||||||
" aghi %0,32\n"
|
" jne 2f\n"
|
||||||
" srlg %2,%2,32\n"
|
" aghi %0,32\n"
|
||||||
"2: lghi %1,0xff\n"
|
" srlg %2,%2,32\n"
|
||||||
" tmll %2,0xffff\n"
|
"2: lghi %1,0xff\n"
|
||||||
" jnz 3f\n"
|
" tmll %2,0xffff\n"
|
||||||
" aghi %0,16\n"
|
" jnz 3f\n"
|
||||||
" srl %2,16\n"
|
" aghi %0,16\n"
|
||||||
"3: tmll %2,0x00ff\n"
|
" srl %2,16\n"
|
||||||
" jnz 4f\n"
|
"3: tmll %2,0x00ff\n"
|
||||||
" aghi %0,8\n"
|
" jnz 4f\n"
|
||||||
" srl %2,8\n"
|
" aghi %0,8\n"
|
||||||
"4: ngr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"4: ngr %2,%1\n"
|
||||||
" algr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"5:"
|
" algr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"5:"
|
||||||
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
: "a" (size), "a" (addr), "a" (&_sb_findmap),
|
: "a" (size), "a" (addr), "a" (&_sb_findmap),
|
||||||
"m" (*(addrtype *) addr) : "cc" );
|
"m" (*(addrtype *) addr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,36 +779,37 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" lhi %1,-1\n"
|
asm volatile(
|
||||||
" lr %2,%3\n"
|
" lhi %1,-1\n"
|
||||||
" ahi %2,31\n"
|
" lr %2,%3\n"
|
||||||
" srl %2,5\n"
|
" ahi %2,31\n"
|
||||||
" slr %0,%0\n"
|
" srl %2,5\n"
|
||||||
"0: cl %1,0(%0,%4)\n"
|
" slr %0,%0\n"
|
||||||
" jne 1f\n"
|
"0: cl %1,0(%0,%4)\n"
|
||||||
" ahi %0,4\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" ahi %0,4\n"
|
||||||
" lr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 4f\n"
|
" lr %0,%3\n"
|
||||||
"1: l %2,0(%0,%4)\n"
|
" j 4f\n"
|
||||||
" sll %0,3\n"
|
"1: l %2,0(%0,%4)\n"
|
||||||
" ahi %0,24\n"
|
" sll %0,3\n"
|
||||||
" lhi %1,0xff\n"
|
" ahi %0,24\n"
|
||||||
" tmh %2,0xffff\n"
|
" lhi %1,0xff\n"
|
||||||
" jo 2f\n"
|
" tmh %2,0xffff\n"
|
||||||
" ahi %0,-16\n"
|
" jo 2f\n"
|
||||||
" srl %2,16\n"
|
" ahi %0,-16\n"
|
||||||
"2: tml %2,0xff00\n"
|
" srl %2,16\n"
|
||||||
" jo 3f\n"
|
"2: tml %2,0xff00\n"
|
||||||
" ahi %0,-8\n"
|
" jo 3f\n"
|
||||||
" srl %2,8\n"
|
" ahi %0,-8\n"
|
||||||
"3: nr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"3: nr %2,%1\n"
|
||||||
" alr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"4:"
|
" alr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"4:"
|
||||||
: "a" (size), "a" (vaddr), "a" (&_zb_findmap),
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
"m" (*(addrtype *) vaddr) : "cc" );
|
: "a" (size), "a" (vaddr), "a" (&_zb_findmap),
|
||||||
|
"m" (*(addrtype *) vaddr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,39 +823,40 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
__asm__(" lghi %1,-1\n"
|
asm volatile(
|
||||||
" lgr %2,%3\n"
|
" lghi %1,-1\n"
|
||||||
" aghi %2,63\n"
|
" lgr %2,%3\n"
|
||||||
" srlg %2,%2,6\n"
|
" aghi %2,63\n"
|
||||||
" slgr %0,%0\n"
|
" srlg %2,%2,6\n"
|
||||||
"0: clg %1,0(%0,%4)\n"
|
" slgr %0,%0\n"
|
||||||
" jne 1f\n"
|
"0: clg %1,0(%0,%4)\n"
|
||||||
" aghi %0,8\n"
|
" jne 1f\n"
|
||||||
" brct %2,0b\n"
|
" aghi %0,8\n"
|
||||||
" lgr %0,%3\n"
|
" brct %2,0b\n"
|
||||||
" j 5f\n"
|
" lgr %0,%3\n"
|
||||||
"1: cl %1,0(%0,%4)\n"
|
" j 5f\n"
|
||||||
" jne 2f\n"
|
"1: cl %1,0(%0,%4)\n"
|
||||||
" aghi %0,4\n"
|
" jne 2f\n"
|
||||||
"2: l %2,0(%0,%4)\n"
|
" aghi %0,4\n"
|
||||||
" sllg %0,%0,3\n"
|
"2: l %2,0(%0,%4)\n"
|
||||||
" aghi %0,24\n"
|
" sllg %0,%0,3\n"
|
||||||
" lghi %1,0xff\n"
|
" aghi %0,24\n"
|
||||||
" tmlh %2,0xffff\n"
|
" lghi %1,0xff\n"
|
||||||
" jo 3f\n"
|
" tmlh %2,0xffff\n"
|
||||||
" aghi %0,-16\n"
|
" jo 3f\n"
|
||||||
" srl %2,16\n"
|
" aghi %0,-16\n"
|
||||||
"3: tmll %2,0xff00\n"
|
" srl %2,16\n"
|
||||||
" jo 4f\n"
|
"3: tmll %2,0xff00\n"
|
||||||
" aghi %0,-8\n"
|
" jo 4f\n"
|
||||||
" srl %2,8\n"
|
" aghi %0,-8\n"
|
||||||
"4: ngr %2,%1\n"
|
" srl %2,8\n"
|
||||||
" ic %2,0(%2,%5)\n"
|
"4: ngr %2,%1\n"
|
||||||
" algr %0,%2\n"
|
" ic %2,0(%2,%5)\n"
|
||||||
"5:"
|
" algr %0,%2\n"
|
||||||
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
"5:"
|
||||||
|
: "=&a" (res), "=&d" (cmp), "=&a" (count)
|
||||||
: "a" (size), "a" (vaddr), "a" (&_zb_findmap),
|
: "a" (size), "a" (vaddr), "a" (&_zb_findmap),
|
||||||
"m" (*(addrtype *) vaddr) : "cc" );
|
"m" (*(addrtype *) vaddr) : "cc");
|
||||||
return (res < size) ? res : size;
|
return (res < size) ? res : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,13 +876,16 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
|
|||||||
p = addr + offset / __BITOPS_WORDSIZE;
|
p = addr + offset / __BITOPS_WORDSIZE;
|
||||||
if (bit) {
|
if (bit) {
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
asm(" ic %0,0(%1)\n"
|
asm volatile(
|
||||||
" icm %0,2,1(%1)\n"
|
" ic %0,0(%1)\n"
|
||||||
" icm %0,4,2(%1)\n"
|
" icm %0,2,1(%1)\n"
|
||||||
" icm %0,8,3(%1)"
|
" icm %0,4,2(%1)\n"
|
||||||
: "=&a" (word) : "a" (p), "m" (*p) : "cc" );
|
" icm %0,8,3(%1)"
|
||||||
|
: "=&a" (word) : "a" (p), "m" (*p) : "cc");
|
||||||
#else
|
#else
|
||||||
asm(" lrvg %0,%1" : "=a" (word) : "m" (*p) );
|
asm volatile(
|
||||||
|
" lrvg %0,%1"
|
||||||
|
: "=a" (word) : "m" (*p) );
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* s390 version of ffz returns __BITOPS_WORDSIZE
|
* s390 version of ffz returns __BITOPS_WORDSIZE
|
||||||
|
@ -14,60 +14,54 @@
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
static __inline__ __u64 ___arch__swab64p(const __u64 *x)
|
static inline __u64 ___arch__swab64p(const __u64 *x)
|
||||||
{
|
{
|
||||||
__u64 result;
|
__u64 result;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x));
|
||||||
" lrvg %0,%1"
|
|
||||||
: "=d" (result) : "m" (*x) );
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ __u64 ___arch__swab64(__u64 x)
|
static inline __u64 ___arch__swab64(__u64 x)
|
||||||
{
|
{
|
||||||
__u64 result;
|
__u64 result;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x));
|
||||||
" lrvgr %0,%1"
|
|
||||||
: "=d" (result) : "d" (x) );
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void ___arch__swab64s(__u64 *x)
|
static inline void ___arch__swab64s(__u64 *x)
|
||||||
{
|
{
|
||||||
*x = ___arch__swab64p(x);
|
*x = ___arch__swab64p(x);
|
||||||
}
|
}
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
|
||||||
static __inline__ __u32 ___arch__swab32p(const __u32 *x)
|
static inline __u32 ___arch__swab32p(const __u32 *x)
|
||||||
{
|
{
|
||||||
__u32 result;
|
__u32 result;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" icm %0,8,3(%1)\n"
|
" icm %0,8,3(%1)\n"
|
||||||
" icm %0,4,2(%1)\n"
|
" icm %0,4,2(%1)\n"
|
||||||
" icm %0,2,1(%1)\n"
|
" icm %0,2,1(%1)\n"
|
||||||
" ic %0,0(%1)"
|
" ic %0,0(%1)"
|
||||||
: "=&d" (result) : "a" (x), "m" (*x) : "cc" );
|
: "=&d" (result) : "a" (x), "m" (*x) : "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lrv %0,%1"
|
" lrv %0,%1"
|
||||||
: "=d" (result) : "m" (*x) );
|
: "=d" (result) : "m" (*x));
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ __u32 ___arch__swab32(__u32 x)
|
static inline __u32 ___arch__swab32(__u32 x)
|
||||||
{
|
{
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
return ___arch__swab32p(&x);
|
return ___arch__swab32p(&x);
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
__u32 result;
|
__u32 result;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile("lrvr %0,%1" : "=d" (result) : "d" (x));
|
||||||
" lrvr %0,%1"
|
|
||||||
: "=d" (result) : "d" (x) );
|
|
||||||
return result;
|
return result;
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
}
|
}
|
||||||
@ -81,14 +75,14 @@ static __inline__ __u16 ___arch__swab16p(const __u16 *x)
|
|||||||
{
|
{
|
||||||
__u16 result;
|
__u16 result;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" icm %0,2,1(%1)\n"
|
" icm %0,2,1(%1)\n"
|
||||||
" ic %0,0(%1)\n"
|
" ic %0,0(%1)\n"
|
||||||
: "=&d" (result) : "a" (x), "m" (*x) : "cc" );
|
: "=&d" (result) : "a" (x), "m" (*x) : "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lrvh %0,%1"
|
" lrvh %0,%1"
|
||||||
: "=d" (result) : "m" (*x) );
|
: "=d" (result) : "m" (*x));
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -30,57 +30,13 @@
|
|||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
csum_partial(const unsigned char * buff, int len, unsigned int sum)
|
csum_partial(const unsigned char * buff, int len, unsigned int sum)
|
||||||
{
|
{
|
||||||
/*
|
register unsigned long reg2 asm("2") = (unsigned long) buff;
|
||||||
* Experiments with ethernet and slip connections show that buf
|
register unsigned long reg3 asm("3") = (unsigned long) len;
|
||||||
* is aligned on either a 2-byte or 4-byte boundary.
|
|
||||||
*/
|
|
||||||
#ifndef __s390x__
|
|
||||||
register_pair rp;
|
|
||||||
|
|
||||||
rp.subreg.even = (unsigned long) buff;
|
asm volatile(
|
||||||
rp.subreg.odd = (unsigned long) len;
|
"0: cksm %0,%1\n" /* do checksum on longs */
|
||||||
__asm__ __volatile__ (
|
" jo 0b\n"
|
||||||
"0: cksm %0,%1\n" /* do checksum on longs */
|
: "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory");
|
||||||
" jo 0b\n"
|
|
||||||
: "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
|
|
||||||
#else /* __s390x__ */
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
" lgr 2,%1\n" /* address in gpr 2 */
|
|
||||||
" lgfr 3,%2\n" /* length in gpr 3 */
|
|
||||||
"0: cksm %0,2\n" /* do checksum on longs */
|
|
||||||
" jo 0b\n"
|
|
||||||
: "+&d" (sum)
|
|
||||||
: "d" (buff), "d" (len)
|
|
||||||
: "cc", "memory", "2", "3" );
|
|
||||||
#endif /* __s390x__ */
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* csum_partial as an inline function
|
|
||||||
*/
|
|
||||||
static inline unsigned int
|
|
||||||
csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
|
|
||||||
{
|
|
||||||
#ifndef __s390x__
|
|
||||||
register_pair rp;
|
|
||||||
|
|
||||||
rp.subreg.even = (unsigned long) buff;
|
|
||||||
rp.subreg.odd = (unsigned long) len;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"0: cksm %0,%1\n" /* do checksum on longs */
|
|
||||||
" jo 0b\n"
|
|
||||||
: "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
|
|
||||||
#else /* __s390x__ */
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
" lgr 2,%1\n" /* address in gpr 2 */
|
|
||||||
" lgfr 3,%2\n" /* length in gpr 3 */
|
|
||||||
"0: cksm %0,2\n" /* do checksum on longs */
|
|
||||||
" jo 0b\n"
|
|
||||||
: "+&d" (sum)
|
|
||||||
: "d" (buff), "d" (len)
|
|
||||||
: "cc", "memory", "2", "3" );
|
|
||||||
#endif /* __s390x__ */
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +70,7 @@ static inline unsigned int
|
|||||||
csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum)
|
csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum)
|
||||||
{
|
{
|
||||||
memcpy(dst,src,len);
|
memcpy(dst,src,len);
|
||||||
return csum_partial_inline(dst, len, sum);
|
return csum_partial(dst, len, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -126,22 +82,22 @@ csum_fold(unsigned int sum)
|
|||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
register_pair rp;
|
register_pair rp;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" slr %N1,%N1\n" /* %0 = H L */
|
" slr %N1,%N1\n" /* %0 = H L */
|
||||||
" lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */
|
" lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */
|
||||||
" srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */
|
" srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */
|
||||||
" alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */
|
" alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */
|
||||||
" alr %0,%1\n" /* %0 = H+L+C L+H */
|
" alr %0,%1\n" /* %0 = H+L+C L+H */
|
||||||
" srl %0,16\n" /* %0 = H+L+C */
|
" srl %0,16\n" /* %0 = H+L+C */
|
||||||
: "+&d" (sum), "=d" (rp) : : "cc" );
|
: "+&d" (sum), "=d" (rp) : : "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" sr 3,3\n" /* %0 = H*65536 + L */
|
" sr 3,3\n" /* %0 = H*65536 + L */
|
||||||
" lr 2,%0\n" /* %0 = H L, R2/R3 = H L / 0 0 */
|
" lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */
|
||||||
" srdl 2,16\n" /* %0 = H L, R2/R3 = 0 H / L 0 */
|
" srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */
|
||||||
" alr 2,3\n" /* %0 = H L, R2/R3 = L H / L 0 */
|
" alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */
|
||||||
" alr %0,2\n" /* %0 = H+L+C L+H */
|
" alr %0,2\n" /* %0 = H+L+C L+H */
|
||||||
" srl %0,16\n" /* %0 = H+L+C */
|
" srl %0,16\n" /* %0 = H+L+C */
|
||||||
: "+&d" (sum) : : "cc", "2", "3");
|
: "+&d" (sum) : : "cc", "2", "3");
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
return ((unsigned short) ~sum);
|
return ((unsigned short) ~sum);
|
||||||
@ -155,29 +111,7 @@ csum_fold(unsigned int sum)
|
|||||||
static inline unsigned short
|
static inline unsigned short
|
||||||
ip_fast_csum(unsigned char *iph, unsigned int ihl)
|
ip_fast_csum(unsigned char *iph, unsigned int ihl)
|
||||||
{
|
{
|
||||||
unsigned long sum;
|
return csum_fold(csum_partial(iph, ihl*4, 0));
|
||||||
#ifndef __s390x__
|
|
||||||
register_pair rp;
|
|
||||||
|
|
||||||
rp.subreg.even = (unsigned long) iph;
|
|
||||||
rp.subreg.odd = (unsigned long) ihl*4;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
" sr %0,%0\n" /* set sum to zero */
|
|
||||||
"0: cksm %0,%1\n" /* do checksum on longs */
|
|
||||||
" jo 0b\n"
|
|
||||||
: "=&d" (sum), "+&a" (rp) : : "cc", "memory" );
|
|
||||||
#else /* __s390x__ */
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
" slgr %0,%0\n" /* set sum to zero */
|
|
||||||
" lgr 2,%1\n" /* address in gpr 2 */
|
|
||||||
" lgfr 3,%2\n" /* length in gpr 3 */
|
|
||||||
"0: cksm %0,2\n" /* do checksum on ints */
|
|
||||||
" jo 0b\n"
|
|
||||||
: "=&d" (sum)
|
|
||||||
: "d" (iph), "d" (ihl*4)
|
|
||||||
: "cc", "memory", "2", "3" );
|
|
||||||
#endif /* __s390x__ */
|
|
||||||
return csum_fold(sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -190,47 +124,47 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
|
|||||||
unsigned int sum)
|
unsigned int sum)
|
||||||
{
|
{
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" alr %0,%1\n" /* sum += saddr */
|
" alr %0,%1\n" /* sum += saddr */
|
||||||
" brc 12,0f\n"
|
" brc 12,0f\n"
|
||||||
" ahi %0,1\n" /* add carry */
|
" ahi %0,1\n" /* add carry */
|
||||||
"0:"
|
"0:"
|
||||||
: "+&d" (sum) : "d" (saddr) : "cc" );
|
: "+&d" (sum) : "d" (saddr) : "cc");
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" alr %0,%1\n" /* sum += daddr */
|
" alr %0,%1\n" /* sum += daddr */
|
||||||
" brc 12,1f\n"
|
" brc 12,1f\n"
|
||||||
" ahi %0,1\n" /* add carry */
|
" ahi %0,1\n" /* add carry */
|
||||||
"1:"
|
"1:"
|
||||||
: "+&d" (sum) : "d" (daddr) : "cc" );
|
: "+&d" (sum) : "d" (daddr) : "cc");
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */
|
" alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */
|
||||||
" brc 12,2f\n"
|
" brc 12,2f\n"
|
||||||
" ahi %0,1\n" /* add carry */
|
" ahi %0,1\n" /* add carry */
|
||||||
"2:"
|
"2:"
|
||||||
: "+&d" (sum)
|
: "+&d" (sum)
|
||||||
: "d" (((unsigned int) len<<16) + (unsigned int) proto)
|
: "d" (((unsigned int) len<<16) + (unsigned int) proto)
|
||||||
: "cc" );
|
: "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" lgfr %0,%0\n"
|
" lgfr %0,%0\n"
|
||||||
" algr %0,%1\n" /* sum += saddr */
|
" algr %0,%1\n" /* sum += saddr */
|
||||||
" brc 12,0f\n"
|
" brc 12,0f\n"
|
||||||
" aghi %0,1\n" /* add carry */
|
" aghi %0,1\n" /* add carry */
|
||||||
"0: algr %0,%2\n" /* sum += daddr */
|
"0: algr %0,%2\n" /* sum += daddr */
|
||||||
" brc 12,1f\n"
|
" brc 12,1f\n"
|
||||||
" aghi %0,1\n" /* add carry */
|
" aghi %0,1\n" /* add carry */
|
||||||
"1: algfr %0,%3\n" /* sum += (len<<16) + proto */
|
"1: algfr %0,%3\n" /* sum += (len<<16) + proto */
|
||||||
" brc 12,2f\n"
|
" brc 12,2f\n"
|
||||||
" aghi %0,1\n" /* add carry */
|
" aghi %0,1\n" /* add carry */
|
||||||
"2: srlg 0,%0,32\n"
|
"2: srlg 0,%0,32\n"
|
||||||
" alr %0,0\n" /* fold to 32 bits */
|
" alr %0,0\n" /* fold to 32 bits */
|
||||||
" brc 12,3f\n"
|
" brc 12,3f\n"
|
||||||
" ahi %0,1\n" /* add carry */
|
" ahi %0,1\n" /* add carry */
|
||||||
"3: llgfr %0,%0"
|
"3: llgfr %0,%0"
|
||||||
: "+&d" (sum)
|
: "+&d" (sum)
|
||||||
: "d" (saddr), "d" (daddr),
|
: "d" (saddr), "d" (daddr),
|
||||||
"d" (((unsigned int) len<<16) + (unsigned int) proto)
|
"d" (((unsigned int) len<<16) + (unsigned int) proto)
|
||||||
: "cc", "0" );
|
: "cc", "0");
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,16 @@ codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
|
|||||||
{
|
{
|
||||||
if (nr-- <= 0)
|
if (nr-- <= 0)
|
||||||
return;
|
return;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" bras 1,1f\n"
|
" bras 1,1f\n"
|
||||||
" tr 0(1,%0),0(%2)\n"
|
" tr 0(1,%0),0(%2)\n"
|
||||||
"0: tr 0(256,%0),0(%2)\n"
|
"0: tr 0(256,%0),0(%2)\n"
|
||||||
" la %0,256(%0)\n"
|
" la %0,256(%0)\n"
|
||||||
"1: ahi %1,-256\n"
|
"1: ahi %1,-256\n"
|
||||||
" jnm 0b\n"
|
" jnm 0b\n"
|
||||||
" ex %1,0(1)"
|
" ex %1,0(1)"
|
||||||
: "+&a" (addr), "+&a" (nr)
|
: "+&a" (addr), "+&a" (nr)
|
||||||
: "a" (codepage) : "cc", "memory", "1" );
|
: "a" (codepage) : "cc", "memory", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr)
|
#define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr)
|
||||||
|
@ -27,18 +27,16 @@
|
|||||||
static inline unsigned long virt_to_phys(volatile void * address)
|
static inline unsigned long virt_to_phys(volatile void * address)
|
||||||
{
|
{
|
||||||
unsigned long real_address;
|
unsigned long real_address;
|
||||||
__asm__ (
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" lra %0,0(%1)\n"
|
" lra %0,0(%1)\n"
|
||||||
" jz 0f\n"
|
|
||||||
" sr %0,%0\n"
|
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lrag %0,0(%1)\n"
|
" lrag %0,0(%1)\n"
|
||||||
" jz 0f\n"
|
|
||||||
" slgr %0,%0\n"
|
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
" jz 0f\n"
|
||||||
|
" la %0,0\n"
|
||||||
"0:"
|
"0:"
|
||||||
: "=a" (real_address) : "a" (address) : "cc" );
|
: "=a" (real_address) : "a" (address) : "cc");
|
||||||
return real_address;
|
return real_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,43 +10,93 @@
|
|||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
/* interrupt control.. */
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
#define raw_local_irq_enable() ({ \
|
|
||||||
unsigned long __dummy; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
"stosm 0(%1),0x03" \
|
|
||||||
: "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define raw_local_irq_disable() ({ \
|
/* store then or system mask. */
|
||||||
unsigned long __flags; \
|
#define __raw_local_irq_stosm(__or) \
|
||||||
__asm__ __volatile__ ( \
|
({ \
|
||||||
"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
|
unsigned long __mask; \
|
||||||
__flags; \
|
asm volatile( \
|
||||||
})
|
" stosm %0,%1" \
|
||||||
|
: "=Q" (__mask) : "i" (__or) : "memory"); \
|
||||||
#define raw_local_save_flags(x) \
|
__mask; \
|
||||||
do { \
|
|
||||||
typecheck(unsigned long, x); \
|
|
||||||
__asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) ); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define raw_local_irq_restore(x) \
|
|
||||||
do { \
|
|
||||||
typecheck(unsigned long, x); \
|
|
||||||
__asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define raw_irqs_disabled() \
|
|
||||||
({ \
|
|
||||||
unsigned long flags; \
|
|
||||||
raw_local_save_flags(flags); \
|
|
||||||
!((flags >> __FLAG_SHIFT) & 3); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* store then and system mask. */
|
||||||
|
#define __raw_local_irq_stnsm(__and) \
|
||||||
|
({ \
|
||||||
|
unsigned long __mask; \
|
||||||
|
asm volatile( \
|
||||||
|
" stnsm %0,%1" \
|
||||||
|
: "=Q" (__mask) : "i" (__and) : "memory"); \
|
||||||
|
__mask; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* set system mask. */
|
||||||
|
#define __raw_local_irq_ssm(__mask) \
|
||||||
|
({ \
|
||||||
|
asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
/* store then or system mask. */
|
||||||
|
#define __raw_local_irq_stosm(__or) \
|
||||||
|
({ \
|
||||||
|
unsigned long __mask; \
|
||||||
|
asm volatile( \
|
||||||
|
" stosm 0(%1),%2" \
|
||||||
|
: "=m" (__mask) \
|
||||||
|
: "a" (&__mask), "i" (__or) : "memory"); \
|
||||||
|
__mask; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* store then and system mask. */
|
||||||
|
#define __raw_local_irq_stnsm(__and) \
|
||||||
|
({ \
|
||||||
|
unsigned long __mask; \
|
||||||
|
asm volatile( \
|
||||||
|
" stnsm 0(%1),%2" \
|
||||||
|
: "=m" (__mask) \
|
||||||
|
: "a" (&__mask), "i" (__and) : "memory"); \
|
||||||
|
__mask; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* set system mask. */
|
||||||
|
#define __raw_local_irq_ssm(__mask) \
|
||||||
|
({ \
|
||||||
|
asm volatile( \
|
||||||
|
" ssm 0(%0)" \
|
||||||
|
: : "a" (&__mask), "m" (__mask) : "memory"); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
/* interrupt control.. */
|
||||||
|
static inline unsigned long raw_local_irq_enable(void)
|
||||||
|
{
|
||||||
|
return __raw_local_irq_stosm(0x03);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long raw_local_irq_disable(void)
|
||||||
|
{
|
||||||
|
return __raw_local_irq_stnsm(0xfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define raw_local_save_flags(x) \
|
||||||
|
do { \
|
||||||
|
typecheck(unsigned long, x); \
|
||||||
|
(x) = __raw_local_irq_stosm(0x00); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline void raw_local_irq_restore(unsigned long flags)
|
||||||
|
{
|
||||||
|
__raw_local_irq_ssm(flags);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||||
{
|
{
|
||||||
return !((flags >> __FLAG_SHIFT) & 3);
|
return !(flags & (3UL << (BITS_PER_LONG - 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For spinlocks etc */
|
/* For spinlocks etc */
|
||||||
|
@ -359,7 +359,7 @@ extern struct _lowcore *lowcore_ptr[];
|
|||||||
|
|
||||||
static inline void set_prefix(__u32 address)
|
static inline void set_prefix(__u32 address)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" );
|
asm volatile("spx %0" : : "m" (address) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __PANIC_MAGIC 0xDEADC0DE
|
#define __PANIC_MAGIC 0xDEADC0DE
|
||||||
|
@ -22,89 +22,45 @@
|
|||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#ifndef __s390x__
|
|
||||||
|
|
||||||
static inline void clear_page(void *page)
|
static inline void clear_page(void *page)
|
||||||
{
|
{
|
||||||
register_pair rp;
|
register unsigned long reg1 asm ("1") = 0;
|
||||||
|
register void *reg2 asm ("2") = page;
|
||||||
rp.subreg.even = (unsigned long) page;
|
register unsigned long reg3 asm ("3") = 4096;
|
||||||
rp.subreg.odd = (unsigned long) 4096;
|
asm volatile(
|
||||||
asm volatile (" slr 1,1\n"
|
" mvcl 2,0"
|
||||||
" mvcl %0,0"
|
: "+d" (reg2), "+d" (reg3) : "d" (reg1) : "memory", "cc");
|
||||||
: "+&a" (rp) : : "memory", "cc", "1" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void copy_page(void *to, void *from)
|
static inline void copy_page(void *to, void *from)
|
||||||
{
|
{
|
||||||
if (MACHINE_HAS_MVPG)
|
if (MACHINE_HAS_MVPG) {
|
||||||
asm volatile (" sr 0,0\n"
|
register unsigned long reg0 asm ("0") = 0;
|
||||||
" mvpg %0,%1"
|
asm volatile(
|
||||||
: : "a" ((void *)(to)), "a" ((void *)(from))
|
" mvpg %0,%1"
|
||||||
: "memory", "cc", "0" );
|
: : "a" (to), "a" (from), "d" (reg0)
|
||||||
else
|
: "memory", "cc");
|
||||||
asm volatile (" mvc 0(256,%0),0(%1)\n"
|
} else
|
||||||
" mvc 256(256,%0),256(%1)\n"
|
asm volatile(
|
||||||
" mvc 512(256,%0),512(%1)\n"
|
" mvc 0(256,%0),0(%1)\n"
|
||||||
" mvc 768(256,%0),768(%1)\n"
|
" mvc 256(256,%0),256(%1)\n"
|
||||||
" mvc 1024(256,%0),1024(%1)\n"
|
" mvc 512(256,%0),512(%1)\n"
|
||||||
" mvc 1280(256,%0),1280(%1)\n"
|
" mvc 768(256,%0),768(%1)\n"
|
||||||
" mvc 1536(256,%0),1536(%1)\n"
|
" mvc 1024(256,%0),1024(%1)\n"
|
||||||
" mvc 1792(256,%0),1792(%1)\n"
|
" mvc 1280(256,%0),1280(%1)\n"
|
||||||
" mvc 2048(256,%0),2048(%1)\n"
|
" mvc 1536(256,%0),1536(%1)\n"
|
||||||
" mvc 2304(256,%0),2304(%1)\n"
|
" mvc 1792(256,%0),1792(%1)\n"
|
||||||
" mvc 2560(256,%0),2560(%1)\n"
|
" mvc 2048(256,%0),2048(%1)\n"
|
||||||
" mvc 2816(256,%0),2816(%1)\n"
|
" mvc 2304(256,%0),2304(%1)\n"
|
||||||
" mvc 3072(256,%0),3072(%1)\n"
|
" mvc 2560(256,%0),2560(%1)\n"
|
||||||
" mvc 3328(256,%0),3328(%1)\n"
|
" mvc 2816(256,%0),2816(%1)\n"
|
||||||
" mvc 3584(256,%0),3584(%1)\n"
|
" mvc 3072(256,%0),3072(%1)\n"
|
||||||
" mvc 3840(256,%0),3840(%1)\n"
|
" mvc 3328(256,%0),3328(%1)\n"
|
||||||
: : "a"((void *)(to)),"a"((void *)(from))
|
" mvc 3584(256,%0),3584(%1)\n"
|
||||||
: "memory" );
|
" mvc 3840(256,%0),3840(%1)\n"
|
||||||
|
: : "a" (to), "a" (from) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* __s390x__ */
|
|
||||||
|
|
||||||
static inline void clear_page(void *page)
|
|
||||||
{
|
|
||||||
asm volatile (" lgr 2,%0\n"
|
|
||||||
" lghi 3,4096\n"
|
|
||||||
" slgr 1,1\n"
|
|
||||||
" mvcl 2,0"
|
|
||||||
: : "a" ((void *) (page))
|
|
||||||
: "memory", "cc", "1", "2", "3" );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void copy_page(void *to, void *from)
|
|
||||||
{
|
|
||||||
if (MACHINE_HAS_MVPG)
|
|
||||||
asm volatile (" sgr 0,0\n"
|
|
||||||
" mvpg %0,%1"
|
|
||||||
: : "a" ((void *)(to)), "a" ((void *)(from))
|
|
||||||
: "memory", "cc", "0" );
|
|
||||||
else
|
|
||||||
asm volatile (" mvc 0(256,%0),0(%1)\n"
|
|
||||||
" mvc 256(256,%0),256(%1)\n"
|
|
||||||
" mvc 512(256,%0),512(%1)\n"
|
|
||||||
" mvc 768(256,%0),768(%1)\n"
|
|
||||||
" mvc 1024(256,%0),1024(%1)\n"
|
|
||||||
" mvc 1280(256,%0),1280(%1)\n"
|
|
||||||
" mvc 1536(256,%0),1536(%1)\n"
|
|
||||||
" mvc 1792(256,%0),1792(%1)\n"
|
|
||||||
" mvc 2048(256,%0),2048(%1)\n"
|
|
||||||
" mvc 2304(256,%0),2304(%1)\n"
|
|
||||||
" mvc 2560(256,%0),2560(%1)\n"
|
|
||||||
" mvc 2816(256,%0),2816(%1)\n"
|
|
||||||
" mvc 3072(256,%0),3072(%1)\n"
|
|
||||||
" mvc 3328(256,%0),3328(%1)\n"
|
|
||||||
" mvc 3584(256,%0),3584(%1)\n"
|
|
||||||
" mvc 3840(256,%0),3840(%1)\n"
|
|
||||||
: : "a"((void *)(to)),"a"((void *)(from))
|
|
||||||
: "memory" );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __s390x__ */
|
|
||||||
|
|
||||||
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
||||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||||
|
|
||||||
@ -159,7 +115,7 @@ extern unsigned int default_storage_key;
|
|||||||
static inline void
|
static inline void
|
||||||
page_set_storage_key(unsigned long addr, unsigned int skey)
|
page_set_storage_key(unsigned long addr, unsigned int skey)
|
||||||
{
|
{
|
||||||
asm volatile ( "sske %0,%1" : : "d" (skey), "a" (addr) );
|
asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
@ -167,8 +123,7 @@ page_get_storage_key(unsigned long addr)
|
|||||||
{
|
{
|
||||||
unsigned int skey;
|
unsigned int skey;
|
||||||
|
|
||||||
asm volatile ( "iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0) );
|
asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0));
|
||||||
|
|
||||||
return skey;
|
return skey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,9 +554,10 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
|
|||||||
/* ipte in zarch mode can do the math */
|
/* ipte in zarch mode can do the math */
|
||||||
pte_t *pto = ptep;
|
pte_t *pto = ptep;
|
||||||
#endif
|
#endif
|
||||||
asm volatile ("ipte %2,%3"
|
asm volatile(
|
||||||
: "=m" (*ptep) : "m" (*ptep),
|
" ipte %2,%3"
|
||||||
"a" (pto), "a" (address) );
|
: "=m" (*ptep) : "m" (*ptep),
|
||||||
|
"a" (pto), "a" (address));
|
||||||
}
|
}
|
||||||
pte_val(*ptep) = _PAGE_TYPE_EMPTY;
|
pte_val(*ptep) = _PAGE_TYPE_EMPTY;
|
||||||
}
|
}
|
||||||
@ -609,16 +610,17 @@ ptep_establish(struct vm_area_struct *vma,
|
|||||||
/*
|
/*
|
||||||
* Test and clear referenced bit in storage key.
|
* Test and clear referenced bit in storage key.
|
||||||
*/
|
*/
|
||||||
#define page_test_and_clear_young(page) \
|
#define page_test_and_clear_young(page) \
|
||||||
({ \
|
({ \
|
||||||
struct page *__page = (page); \
|
struct page *__page = (page); \
|
||||||
unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
|
unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);\
|
||||||
int __ccode; \
|
int __ccode; \
|
||||||
asm volatile ("rrbe 0,%1\n\t" \
|
asm volatile( \
|
||||||
"ipm %0\n\t" \
|
" rrbe 0,%1\n" \
|
||||||
"srl %0,28\n\t" \
|
" ipm %0\n" \
|
||||||
: "=d" (__ccode) : "a" (__physpage) : "cc" ); \
|
" srl %0,28\n" \
|
||||||
(__ccode & 2); \
|
: "=d" (__ccode) : "a" (__physpage) : "cc"); \
|
||||||
|
(__ccode & 2); \
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#ifndef __ASM_S390_PROCESSOR_H
|
#ifndef __ASM_S390_PROCESSOR_H
|
||||||
#define __ASM_S390_PROCESSOR_H
|
#define __ASM_S390_PROCESSOR_H
|
||||||
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
@ -21,7 +20,7 @@
|
|||||||
* Default implementation of macro that returns current
|
* Default implementation of macro that returns current
|
||||||
* instruction pointer ("program counter").
|
* instruction pointer ("program counter").
|
||||||
*/
|
*/
|
||||||
#define current_text_addr() ({ void *pc; __asm__("basr %0,0":"=a"(pc)); pc; })
|
#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU type and hardware bug flags. Kept separately for each CPU.
|
* CPU type and hardware bug flags. Kept separately for each CPU.
|
||||||
@ -202,7 +201,7 @@ unsigned long get_wchan(struct task_struct *p);
|
|||||||
static inline void cpu_relax(void)
|
static inline void cpu_relax(void)
|
||||||
{
|
{
|
||||||
if (MACHINE_HAS_DIAG44)
|
if (MACHINE_HAS_DIAG44)
|
||||||
asm volatile ("diag 0,0,68" : : : "memory");
|
asm volatile("diag 0,0,68" : : : "memory");
|
||||||
else
|
else
|
||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
@ -213,9 +212,9 @@ static inline void cpu_relax(void)
|
|||||||
static inline void __load_psw(psw_t psw)
|
static inline void __load_psw(psw_t psw)
|
||||||
{
|
{
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
|
asm volatile("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
|
||||||
#else
|
#else
|
||||||
asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
|
asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,20 +231,20 @@ static inline void __load_psw_mask (unsigned long mask)
|
|||||||
psw.mask = mask;
|
psw.mask = mask;
|
||||||
|
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" basr %0,0\n"
|
" basr %0,0\n"
|
||||||
"0: ahi %0,1f-0b\n"
|
"0: ahi %0,1f-0b\n"
|
||||||
" st %0,4(%1)\n"
|
" st %0,4(%1)\n"
|
||||||
" lpsw 0(%1)\n"
|
" lpsw 0(%1)\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" );
|
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" larl %0,1f\n"
|
" larl %0,1f\n"
|
||||||
" stg %0,8(%1)\n"
|
" stg %0,8(%1)\n"
|
||||||
" lpswe 0(%1)\n"
|
" lpswe 0(%1)\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" );
|
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,56 +273,57 @@ static inline void disabled_wait(unsigned long code)
|
|||||||
* the processor is dead afterwards
|
* the processor is dead afterwards
|
||||||
*/
|
*/
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
asm volatile (" stctl 0,0,0(%2)\n"
|
asm volatile(
|
||||||
" ni 0(%2),0xef\n" /* switch off protection */
|
" stctl 0,0,0(%2)\n"
|
||||||
" lctl 0,0,0(%2)\n"
|
" ni 0(%2),0xef\n" /* switch off protection */
|
||||||
" stpt 0xd8\n" /* store timer */
|
" lctl 0,0,0(%2)\n"
|
||||||
" stckc 0xe0\n" /* store clock comparator */
|
" stpt 0xd8\n" /* store timer */
|
||||||
" stpx 0x108\n" /* store prefix register */
|
" stckc 0xe0\n" /* store clock comparator */
|
||||||
" stam 0,15,0x120\n" /* store access registers */
|
" stpx 0x108\n" /* store prefix register */
|
||||||
" std 0,0x160\n" /* store f0 */
|
" stam 0,15,0x120\n" /* store access registers */
|
||||||
" std 2,0x168\n" /* store f2 */
|
" std 0,0x160\n" /* store f0 */
|
||||||
" std 4,0x170\n" /* store f4 */
|
" std 2,0x168\n" /* store f2 */
|
||||||
" std 6,0x178\n" /* store f6 */
|
" std 4,0x170\n" /* store f4 */
|
||||||
" stm 0,15,0x180\n" /* store general registers */
|
" std 6,0x178\n" /* store f6 */
|
||||||
" stctl 0,15,0x1c0\n" /* store control registers */
|
" stm 0,15,0x180\n" /* store general registers */
|
||||||
" oi 0x1c0,0x10\n" /* fake protection bit */
|
" stctl 0,15,0x1c0\n" /* store control registers */
|
||||||
" lpsw 0(%1)"
|
" oi 0x1c0,0x10\n" /* fake protection bit */
|
||||||
: "=m" (ctl_buf)
|
" lpsw 0(%1)"
|
||||||
: "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
|
: "=m" (ctl_buf)
|
||||||
|
: "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
asm volatile (" stctg 0,0,0(%2)\n"
|
asm volatile(
|
||||||
" ni 4(%2),0xef\n" /* switch off protection */
|
" stctg 0,0,0(%2)\n"
|
||||||
" lctlg 0,0,0(%2)\n"
|
" ni 4(%2),0xef\n" /* switch off protection */
|
||||||
" lghi 1,0x1000\n"
|
" lctlg 0,0,0(%2)\n"
|
||||||
" stpt 0x328(1)\n" /* store timer */
|
" lghi 1,0x1000\n"
|
||||||
" stckc 0x330(1)\n" /* store clock comparator */
|
" stpt 0x328(1)\n" /* store timer */
|
||||||
" stpx 0x318(1)\n" /* store prefix register */
|
" stckc 0x330(1)\n" /* store clock comparator */
|
||||||
" stam 0,15,0x340(1)\n" /* store access registers */
|
" stpx 0x318(1)\n" /* store prefix register */
|
||||||
" stfpc 0x31c(1)\n" /* store fpu control */
|
" stam 0,15,0x340(1)\n"/* store access registers */
|
||||||
" std 0,0x200(1)\n" /* store f0 */
|
" stfpc 0x31c(1)\n" /* store fpu control */
|
||||||
" std 1,0x208(1)\n" /* store f1 */
|
" std 0,0x200(1)\n" /* store f0 */
|
||||||
" std 2,0x210(1)\n" /* store f2 */
|
" std 1,0x208(1)\n" /* store f1 */
|
||||||
" std 3,0x218(1)\n" /* store f3 */
|
" std 2,0x210(1)\n" /* store f2 */
|
||||||
" std 4,0x220(1)\n" /* store f4 */
|
" std 3,0x218(1)\n" /* store f3 */
|
||||||
" std 5,0x228(1)\n" /* store f5 */
|
" std 4,0x220(1)\n" /* store f4 */
|
||||||
" std 6,0x230(1)\n" /* store f6 */
|
" std 5,0x228(1)\n" /* store f5 */
|
||||||
" std 7,0x238(1)\n" /* store f7 */
|
" std 6,0x230(1)\n" /* store f6 */
|
||||||
" std 8,0x240(1)\n" /* store f8 */
|
" std 7,0x238(1)\n" /* store f7 */
|
||||||
" std 9,0x248(1)\n" /* store f9 */
|
" std 8,0x240(1)\n" /* store f8 */
|
||||||
" std 10,0x250(1)\n" /* store f10 */
|
" std 9,0x248(1)\n" /* store f9 */
|
||||||
" std 11,0x258(1)\n" /* store f11 */
|
" std 10,0x250(1)\n" /* store f10 */
|
||||||
" std 12,0x260(1)\n" /* store f12 */
|
" std 11,0x258(1)\n" /* store f11 */
|
||||||
" std 13,0x268(1)\n" /* store f13 */
|
" std 12,0x260(1)\n" /* store f12 */
|
||||||
" std 14,0x270(1)\n" /* store f14 */
|
" std 13,0x268(1)\n" /* store f13 */
|
||||||
" std 15,0x278(1)\n" /* store f15 */
|
" std 14,0x270(1)\n" /* store f14 */
|
||||||
" stmg 0,15,0x280(1)\n" /* store general registers */
|
" std 15,0x278(1)\n" /* store f15 */
|
||||||
" stctg 0,15,0x380(1)\n" /* store control registers */
|
" stmg 0,15,0x280(1)\n"/* store general registers */
|
||||||
" oi 0x384(1),0x10\n" /* fake protection bit */
|
" stctg 0,15,0x380(1)\n"/* store control registers */
|
||||||
" lpswe 0(%1)"
|
" oi 0x384(1),0x10\n"/* fake protection bit */
|
||||||
: "=m" (ctl_buf)
|
" lpswe 0(%1)"
|
||||||
: "a" (&dw_psw), "a" (&ctl_buf),
|
: "=m" (ctl_buf)
|
||||||
"m" (dw_psw) : "cc", "0", "1");
|
: "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0");
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ extern void show_regs(struct pt_regs * regs);
|
|||||||
static inline void
|
static inline void
|
||||||
psw_set_key(unsigned int key)
|
psw_set_key(unsigned int key)
|
||||||
{
|
{
|
||||||
asm volatile ( "spka 0(%0)" : : "d" (key) );
|
asm volatile("spka 0(%0)" : : "d" (key));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
@ -122,23 +122,23 @@ static inline void __down_read(struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old, new;
|
signed long old, new;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" ahi %1,%5\n"
|
" ahi %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" aghi %1,%5\n"
|
" aghi %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count),
|
: "a" (&sem->count), "m" (sem->count),
|
||||||
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" );
|
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
|
||||||
if (old < 0)
|
if (old < 0)
|
||||||
rwsem_down_read_failed(sem);
|
rwsem_down_read_failed(sem);
|
||||||
}
|
}
|
||||||
@ -150,27 +150,27 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old, new;
|
signed long old, new;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: ltr %1,%0\n"
|
"0: ltr %1,%0\n"
|
||||||
" jm 1f\n"
|
" jm 1f\n"
|
||||||
" ahi %1,%5\n"
|
" ahi %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
"1:"
|
"1:"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: ltgr %1,%0\n"
|
"0: ltgr %1,%0\n"
|
||||||
" jm 1f\n"
|
" jm 1f\n"
|
||||||
" aghi %1,%5\n"
|
" aghi %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
"1:"
|
"1:"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count),
|
: "a" (&sem->count), "m" (sem->count),
|
||||||
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" );
|
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
|
||||||
return old >= 0 ? 1 : 0;
|
return old >= 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,23 +182,23 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
|
|||||||
signed long old, new, tmp;
|
signed long old, new, tmp;
|
||||||
|
|
||||||
tmp = RWSEM_ACTIVE_WRITE_BIAS;
|
tmp = RWSEM_ACTIVE_WRITE_BIAS;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" a %1,%5\n"
|
" a %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" ag %1,%5\n"
|
" ag %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
if (old != 0)
|
if (old != 0)
|
||||||
rwsem_down_write_failed(sem);
|
rwsem_down_write_failed(sem);
|
||||||
}
|
}
|
||||||
@ -215,24 +215,24 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old;
|
signed long old;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%2)\n"
|
" l %0,0(%2)\n"
|
||||||
"0: ltr %0,%0\n"
|
"0: ltr %0,%0\n"
|
||||||
" jnz 1f\n"
|
" jnz 1f\n"
|
||||||
" cs %0,%4,0(%2)\n"
|
" cs %0,%4,0(%2)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%2)\n"
|
" lg %0,0(%2)\n"
|
||||||
"0: ltgr %0,%0\n"
|
"0: ltgr %0,%0\n"
|
||||||
" jnz 1f\n"
|
" jnz 1f\n"
|
||||||
" csg %0,%4,0(%2)\n"
|
" csg %0,%4,0(%2)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (old), "=m" (sem->count)
|
: "=&d" (old), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count),
|
: "a" (&sem->count), "m" (sem->count),
|
||||||
"d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory" );
|
"d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory");
|
||||||
return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
|
return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,24 +243,24 @@ static inline void __up_read(struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old, new;
|
signed long old, new;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" ahi %1,%5\n"
|
" ahi %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" aghi %1,%5\n"
|
" aghi %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count),
|
: "a" (&sem->count), "m" (sem->count),
|
||||||
"i" (-RWSEM_ACTIVE_READ_BIAS)
|
"i" (-RWSEM_ACTIVE_READ_BIAS)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
if (new < 0)
|
if (new < 0)
|
||||||
if ((new & RWSEM_ACTIVE_MASK) == 0)
|
if ((new & RWSEM_ACTIVE_MASK) == 0)
|
||||||
rwsem_wake(sem);
|
rwsem_wake(sem);
|
||||||
@ -274,23 +274,23 @@ static inline void __up_write(struct rw_semaphore *sem)
|
|||||||
signed long old, new, tmp;
|
signed long old, new, tmp;
|
||||||
|
|
||||||
tmp = -RWSEM_ACTIVE_WRITE_BIAS;
|
tmp = -RWSEM_ACTIVE_WRITE_BIAS;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" a %1,%5\n"
|
" a %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" ag %1,%5\n"
|
" ag %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
if (new < 0)
|
if (new < 0)
|
||||||
if ((new & RWSEM_ACTIVE_MASK) == 0)
|
if ((new & RWSEM_ACTIVE_MASK) == 0)
|
||||||
rwsem_wake(sem);
|
rwsem_wake(sem);
|
||||||
@ -304,23 +304,23 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
|
|||||||
signed long old, new, tmp;
|
signed long old, new, tmp;
|
||||||
|
|
||||||
tmp = -RWSEM_WAITING_BIAS;
|
tmp = -RWSEM_WAITING_BIAS;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" a %1,%5\n"
|
" a %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" ag %1,%5\n"
|
" ag %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
if (new > 1)
|
if (new > 1)
|
||||||
rwsem_downgrade_wake(sem);
|
rwsem_downgrade_wake(sem);
|
||||||
}
|
}
|
||||||
@ -332,23 +332,23 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old, new;
|
signed long old, new;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" ar %1,%5\n"
|
" ar %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" agr %1,%5\n"
|
" agr %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count), "d" (delta)
|
: "a" (&sem->count), "m" (sem->count), "d" (delta)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -358,23 +358,23 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
|
|||||||
{
|
{
|
||||||
signed long old, new;
|
signed long old, new;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: lr %1,%0\n"
|
"0: lr %1,%0\n"
|
||||||
" ar %1,%5\n"
|
" ar %1,%5\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: lgr %1,%0\n"
|
"0: lgr %1,%0\n"
|
||||||
" agr %1,%5\n"
|
" agr %1,%5\n"
|
||||||
" csg %0,%1,0(%3)\n"
|
" csg %0,%1,0(%3)\n"
|
||||||
" jl 0b"
|
" jl 0b"
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
: "=&d" (old), "=&d" (new), "=m" (sem->count)
|
||||||
: "a" (&sem->count), "m" (sem->count), "d" (delta)
|
: "a" (&sem->count), "m" (sem->count), "d" (delta)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,17 +85,17 @@ static inline int down_trylock(struct semaphore * sem)
|
|||||||
* sem->count.counter = --new_val;
|
* sem->count.counter = --new_val;
|
||||||
* In the ppc code this is called atomic_dec_if_positive.
|
* In the ppc code this is called atomic_dec_if_positive.
|
||||||
*/
|
*/
|
||||||
__asm__ __volatile__ (
|
asm volatile(
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: ltr %1,%0\n"
|
"0: ltr %1,%0\n"
|
||||||
" jle 1f\n"
|
" jle 1f\n"
|
||||||
" ahi %1,-1\n"
|
" ahi %1,-1\n"
|
||||||
" cs %0,%1,0(%3)\n"
|
" cs %0,%1,0(%3)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter)
|
: "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter)
|
||||||
: "a" (&sem->count.counter), "m" (sem->count.counter)
|
: "a" (&sem->count.counter), "m" (sem->count.counter)
|
||||||
: "cc", "memory" );
|
: "cc", "memory");
|
||||||
return old_val <= 0;
|
return old_val <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,21 +76,23 @@
|
|||||||
unsigned int __r2 = (x2) + (y2); \
|
unsigned int __r2 = (x2) + (y2); \
|
||||||
unsigned int __r1 = (x1); \
|
unsigned int __r1 = (x1); \
|
||||||
unsigned int __r0 = (x0); \
|
unsigned int __r0 = (x0); \
|
||||||
__asm__ (" alr %2,%3\n" \
|
asm volatile( \
|
||||||
" brc 12,0f\n" \
|
" alr %2,%3\n" \
|
||||||
" lhi 0,1\n" \
|
" brc 12,0f\n" \
|
||||||
" alr %1,0\n" \
|
" lhi 0,1\n" \
|
||||||
" brc 12,0f\n" \
|
" alr %1,0\n" \
|
||||||
" alr %0,0\n" \
|
" brc 12,0f\n" \
|
||||||
"0:" \
|
" alr %0,0\n" \
|
||||||
: "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \
|
"0:" \
|
||||||
: "d" (y0), "i" (1) : "cc", "0" ); \
|
: "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \
|
||||||
__asm__ (" alr %1,%2\n" \
|
: "d" (y0), "i" (1) : "cc", "0" ); \
|
||||||
" brc 12,0f\n" \
|
asm volatile( \
|
||||||
" ahi %0,1\n" \
|
" alr %1,%2\n" \
|
||||||
"0:" \
|
" brc 12,0f\n" \
|
||||||
: "+&d" (__r2), "+&d" (__r1) \
|
" ahi %0,1\n" \
|
||||||
: "d" (y1) : "cc" ); \
|
"0:" \
|
||||||
|
: "+&d" (__r2), "+&d" (__r1) \
|
||||||
|
: "d" (y1) : "cc"); \
|
||||||
(r2) = __r2; \
|
(r2) = __r2; \
|
||||||
(r1) = __r1; \
|
(r1) = __r1; \
|
||||||
(r0) = __r0; \
|
(r0) = __r0; \
|
||||||
@ -100,21 +102,23 @@
|
|||||||
unsigned int __r2 = (x2) - (y2); \
|
unsigned int __r2 = (x2) - (y2); \
|
||||||
unsigned int __r1 = (x1); \
|
unsigned int __r1 = (x1); \
|
||||||
unsigned int __r0 = (x0); \
|
unsigned int __r0 = (x0); \
|
||||||
__asm__ (" slr %2,%3\n" \
|
asm volatile( \
|
||||||
" brc 3,0f\n" \
|
" slr %2,%3\n" \
|
||||||
" lhi 0,1\n" \
|
" brc 3,0f\n" \
|
||||||
" slr %1,0\n" \
|
" lhi 0,1\n" \
|
||||||
" brc 3,0f\n" \
|
" slr %1,0\n" \
|
||||||
" slr %0,0\n" \
|
" brc 3,0f\n" \
|
||||||
"0:" \
|
" slr %0,0\n" \
|
||||||
: "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \
|
"0:" \
|
||||||
: "d" (y0) : "cc", "0" ); \
|
: "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \
|
||||||
__asm__ (" slr %1,%2\n" \
|
: "d" (y0) : "cc", "0"); \
|
||||||
" brc 3,0f\n" \
|
asm volatile( \
|
||||||
" ahi %0,-1\n" \
|
" slr %1,%2\n" \
|
||||||
"0:" \
|
" brc 3,0f\n" \
|
||||||
: "+&d" (__r2), "+&d" (__r1) \
|
" ahi %0,-1\n" \
|
||||||
: "d" (y1) : "cc" ); \
|
"0:" \
|
||||||
|
: "+&d" (__r2), "+&d" (__r1) \
|
||||||
|
: "d" (y1) : "cc"); \
|
||||||
(r2) = __r2; \
|
(r2) = __r2; \
|
||||||
(r1) = __r1; \
|
(r1) = __r1; \
|
||||||
(r0) = __r0; \
|
(r0) = __r0; \
|
||||||
|
@ -70,16 +70,16 @@ typedef enum
|
|||||||
static inline sigp_ccode
|
static inline sigp_ccode
|
||||||
signal_processor(__u16 cpu_addr, sigp_order_code order_code)
|
signal_processor(__u16 cpu_addr, sigp_order_code order_code)
|
||||||
{
|
{
|
||||||
|
register unsigned long reg1 asm ("1") = 0;
|
||||||
sigp_ccode ccode;
|
sigp_ccode ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" sr 1,1\n" /* parameter=0 in gpr 1 */
|
" sigp %1,%2,0(%3)\n"
|
||||||
" sigp 1,%1,0(%2)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28\n"
|
||||||
" srl %0,28\n"
|
: "=d" (ccode)
|
||||||
: "=d" (ccode)
|
: "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
|
||||||
: "d" (__cpu_logical_map[cpu_addr]), "a" (order_code)
|
"a" (order_code) : "cc" , "memory");
|
||||||
: "cc" , "memory", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,20 +87,18 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code)
|
|||||||
* Signal processor with parameter
|
* Signal processor with parameter
|
||||||
*/
|
*/
|
||||||
static inline sigp_ccode
|
static inline sigp_ccode
|
||||||
signal_processor_p(__u32 parameter, __u16 cpu_addr,
|
signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code)
|
||||||
sigp_order_code order_code)
|
|
||||||
{
|
{
|
||||||
|
register unsigned int reg1 asm ("1") = parameter;
|
||||||
sigp_ccode ccode;
|
sigp_ccode ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" lr 1,%1\n" /* parameter in gpr 1 */
|
" sigp %1,%2,0(%3)\n"
|
||||||
" sigp 1,%2,0(%3)\n"
|
" ipm %0\n"
|
||||||
" ipm %0\n"
|
" srl %0,28\n"
|
||||||
" srl %0,28\n"
|
|
||||||
: "=d" (ccode)
|
: "=d" (ccode)
|
||||||
: "d" (parameter), "d" (__cpu_logical_map[cpu_addr]),
|
: "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
|
||||||
"a" (order_code)
|
"a" (order_code) : "cc" , "memory");
|
||||||
: "cc" , "memory", "1" );
|
|
||||||
return ccode;
|
return ccode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,24 +106,21 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr,
|
|||||||
* Signal processor with parameter and return status
|
* Signal processor with parameter and return status
|
||||||
*/
|
*/
|
||||||
static inline sigp_ccode
|
static inline sigp_ccode
|
||||||
signal_processor_ps(__u32 *statusptr, __u32 parameter,
|
signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr,
|
||||||
__u16 cpu_addr, sigp_order_code order_code)
|
sigp_order_code order_code)
|
||||||
{
|
{
|
||||||
|
register unsigned int reg1 asm ("1") = parameter;
|
||||||
sigp_ccode ccode;
|
sigp_ccode ccode;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
" sr 2,2\n" /* clear status */
|
" sigp %1,%2,0(%3)\n"
|
||||||
" lr 3,%2\n" /* parameter in gpr 3 */
|
" ipm %0\n"
|
||||||
" sigp 2,%3,0(%4)\n"
|
" srl %0,28\n"
|
||||||
" st 2,%1\n"
|
: "=d" (ccode), "+d" (reg1)
|
||||||
" ipm %0\n"
|
: "d" (__cpu_logical_map[cpu_addr]), "a" (order_code)
|
||||||
" srl %0,28\n"
|
: "cc" , "memory");
|
||||||
: "=d" (ccode), "=m" (*statusptr)
|
*statusptr = reg1;
|
||||||
: "d" (parameter), "d" (__cpu_logical_map[cpu_addr]),
|
return ccode;
|
||||||
"a" (order_code)
|
|
||||||
: "cc" , "memory", "2" , "3"
|
|
||||||
);
|
|
||||||
return ccode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __SIGP__ */
|
#endif /* __SIGP__ */
|
||||||
|
@ -56,7 +56,7 @@ static inline __u16 hard_smp_processor_id(void)
|
|||||||
{
|
{
|
||||||
__u16 cpu_address;
|
__u16 cpu_address;
|
||||||
|
|
||||||
__asm__ ("stap %0\n" : "=m" (cpu_address));
|
asm volatile("stap %0" : "=m" (cpu_address));
|
||||||
return cpu_address;
|
return cpu_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,17 +11,36 @@
|
|||||||
#ifndef __ASM_SPINLOCK_H
|
#ifndef __ASM_SPINLOCK_H
|
||||||
#define __ASM_SPINLOCK_H
|
#define __ASM_SPINLOCK_H
|
||||||
|
|
||||||
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
_raw_compare_and_swap(volatile unsigned int *lock,
|
_raw_compare_and_swap(volatile unsigned int *lock,
|
||||||
unsigned int old, unsigned int new)
|
unsigned int old, unsigned int new)
|
||||||
{
|
{
|
||||||
asm volatile ("cs %0,%3,0(%4)"
|
asm volatile(
|
||||||
: "=d" (old), "=m" (*lock)
|
" cs %0,%3,%1"
|
||||||
: "0" (old), "d" (new), "a" (lock), "m" (*lock)
|
: "=d" (old), "=Q" (*lock)
|
||||||
: "cc", "memory" );
|
: "0" (old), "d" (new), "Q" (*lock)
|
||||||
|
: "cc", "memory" );
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_raw_compare_and_swap(volatile unsigned int *lock,
|
||||||
|
unsigned int old, unsigned int new)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
" cs %0,%3,0(%4)"
|
||||||
|
: "=d" (old), "=m" (*lock)
|
||||||
|
: "0" (old), "d" (new), "a" (lock), "m" (*lock)
|
||||||
|
: "cc", "memory" );
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple spin lock operations. There are two variants, one clears IRQ's
|
* Simple spin lock operations. There are two variants, one clears IRQ's
|
||||||
* on the local processor, one does not.
|
* on the local processor, one does not.
|
||||||
|
@ -60,12 +60,13 @@ static inline void *memchr(const void * s, int c, size_t n)
|
|||||||
register int r0 asm("0") = (char) c;
|
register int r0 asm("0") = (char) c;
|
||||||
const void *ret = s + n;
|
const void *ret = s + n;
|
||||||
|
|
||||||
asm volatile ("0: srst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b\n"
|
"0: srst %0,%1\n"
|
||||||
" jl 1f\n"
|
" jo 0b\n"
|
||||||
" la %0,0\n"
|
" jl 1f\n"
|
||||||
"1:"
|
" la %0,0\n"
|
||||||
: "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
|
"1:"
|
||||||
|
: "+a" (ret), "+&a" (s) : "d" (r0) : "cc");
|
||||||
return (void *) ret;
|
return (void *) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,9 +75,10 @@ static inline void *memscan(void *s, int c, size_t n)
|
|||||||
register int r0 asm("0") = (char) c;
|
register int r0 asm("0") = (char) c;
|
||||||
const void *ret = s + n;
|
const void *ret = s + n;
|
||||||
|
|
||||||
asm volatile ("0: srst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b\n"
|
"0: srst %0,%1\n"
|
||||||
: "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
|
" jo 0b\n"
|
||||||
|
: "+a" (ret), "+&a" (s) : "d" (r0) : "cc");
|
||||||
return (void *) ret;
|
return (void *) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,12 +88,13 @@ static inline char *strcat(char *dst, const char *src)
|
|||||||
unsigned long dummy;
|
unsigned long dummy;
|
||||||
char *ret = dst;
|
char *ret = dst;
|
||||||
|
|
||||||
asm volatile ("0: srst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b\n"
|
"0: srst %0,%1\n"
|
||||||
"1: mvst %0,%2\n"
|
" jo 0b\n"
|
||||||
" jo 1b"
|
"1: mvst %0,%2\n"
|
||||||
: "=&a" (dummy), "+a" (dst), "+a" (src)
|
" jo 1b"
|
||||||
: "d" (r0), "0" (0) : "cc", "memory" );
|
: "=&a" (dummy), "+a" (dst), "+a" (src)
|
||||||
|
: "d" (r0), "0" (0) : "cc", "memory" );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,10 +103,11 @@ static inline char *strcpy(char *dst, const char *src)
|
|||||||
register int r0 asm("0") = 0;
|
register int r0 asm("0") = 0;
|
||||||
char *ret = dst;
|
char *ret = dst;
|
||||||
|
|
||||||
asm volatile ("0: mvst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b"
|
"0: mvst %0,%1\n"
|
||||||
: "+&a" (dst), "+&a" (src) : "d" (r0)
|
" jo 0b"
|
||||||
: "cc", "memory" );
|
: "+&a" (dst), "+&a" (src) : "d" (r0)
|
||||||
|
: "cc", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,9 +116,10 @@ static inline size_t strlen(const char *s)
|
|||||||
register unsigned long r0 asm("0") = 0;
|
register unsigned long r0 asm("0") = 0;
|
||||||
const char *tmp = s;
|
const char *tmp = s;
|
||||||
|
|
||||||
asm volatile ("0: srst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b"
|
"0: srst %0,%1\n"
|
||||||
: "+d" (r0), "+a" (tmp) : : "cc" );
|
" jo 0b"
|
||||||
|
: "+d" (r0), "+a" (tmp) : : "cc");
|
||||||
return r0 - (unsigned long) s;
|
return r0 - (unsigned long) s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,9 +129,10 @@ static inline size_t strnlen(const char * s, size_t n)
|
|||||||
const char *tmp = s;
|
const char *tmp = s;
|
||||||
const char *end = s + n;
|
const char *end = s + n;
|
||||||
|
|
||||||
asm volatile ("0: srst %0,%1\n"
|
asm volatile(
|
||||||
" jo 0b"
|
"0: srst %0,%1\n"
|
||||||
: "+a" (end), "+a" (tmp) : "d" (r0) : "cc" );
|
" jo 0b"
|
||||||
|
: "+a" (end), "+a" (tmp) : "d" (r0) : "cc");
|
||||||
return end - s;
|
return end - s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,74 +23,68 @@ struct task_struct;
|
|||||||
|
|
||||||
extern struct task_struct *__switch_to(void *, void *);
|
extern struct task_struct *__switch_to(void *, void *);
|
||||||
|
|
||||||
#ifdef __s390x__
|
|
||||||
#define __FLAG_SHIFT 56
|
|
||||||
#else /* ! __s390x__ */
|
|
||||||
#define __FLAG_SHIFT 24
|
|
||||||
#endif /* ! __s390x__ */
|
|
||||||
|
|
||||||
static inline void save_fp_regs(s390_fp_regs *fpregs)
|
static inline void save_fp_regs(s390_fp_regs *fpregs)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" std 0,8(%1)\n"
|
" std 0,8(%1)\n"
|
||||||
" std 2,24(%1)\n"
|
" std 2,24(%1)\n"
|
||||||
" std 4,40(%1)\n"
|
" std 4,40(%1)\n"
|
||||||
" std 6,56(%1)"
|
" std 6,56(%1)"
|
||||||
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" );
|
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
|
||||||
if (!MACHINE_HAS_IEEE)
|
if (!MACHINE_HAS_IEEE)
|
||||||
return;
|
return;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" stfpc 0(%1)\n"
|
" stfpc 0(%1)\n"
|
||||||
" std 1,16(%1)\n"
|
" std 1,16(%1)\n"
|
||||||
" std 3,32(%1)\n"
|
" std 3,32(%1)\n"
|
||||||
" std 5,48(%1)\n"
|
" std 5,48(%1)\n"
|
||||||
" std 7,64(%1)\n"
|
" std 7,64(%1)\n"
|
||||||
" std 8,72(%1)\n"
|
" std 8,72(%1)\n"
|
||||||
" std 9,80(%1)\n"
|
" std 9,80(%1)\n"
|
||||||
" std 10,88(%1)\n"
|
" std 10,88(%1)\n"
|
||||||
" std 11,96(%1)\n"
|
" std 11,96(%1)\n"
|
||||||
" std 12,104(%1)\n"
|
" std 12,104(%1)\n"
|
||||||
" std 13,112(%1)\n"
|
" std 13,112(%1)\n"
|
||||||
" std 14,120(%1)\n"
|
" std 14,120(%1)\n"
|
||||||
" std 15,128(%1)\n"
|
" std 15,128(%1)\n"
|
||||||
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" );
|
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restore_fp_regs(s390_fp_regs *fpregs)
|
static inline void restore_fp_regs(s390_fp_regs *fpregs)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" ld 0,8(%0)\n"
|
" ld 0,8(%0)\n"
|
||||||
" ld 2,24(%0)\n"
|
" ld 2,24(%0)\n"
|
||||||
" ld 4,40(%0)\n"
|
" ld 4,40(%0)\n"
|
||||||
" ld 6,56(%0)"
|
" ld 6,56(%0)"
|
||||||
: : "a" (fpregs), "m" (*fpregs) );
|
: : "a" (fpregs), "m" (*fpregs));
|
||||||
if (!MACHINE_HAS_IEEE)
|
if (!MACHINE_HAS_IEEE)
|
||||||
return;
|
return;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" lfpc 0(%0)\n"
|
" lfpc 0(%0)\n"
|
||||||
" ld 1,16(%0)\n"
|
" ld 1,16(%0)\n"
|
||||||
" ld 3,32(%0)\n"
|
" ld 3,32(%0)\n"
|
||||||
" ld 5,48(%0)\n"
|
" ld 5,48(%0)\n"
|
||||||
" ld 7,64(%0)\n"
|
" ld 7,64(%0)\n"
|
||||||
" ld 8,72(%0)\n"
|
" ld 8,72(%0)\n"
|
||||||
" ld 9,80(%0)\n"
|
" ld 9,80(%0)\n"
|
||||||
" ld 10,88(%0)\n"
|
" ld 10,88(%0)\n"
|
||||||
" ld 11,96(%0)\n"
|
" ld 11,96(%0)\n"
|
||||||
" ld 12,104(%0)\n"
|
" ld 12,104(%0)\n"
|
||||||
" ld 13,112(%0)\n"
|
" ld 13,112(%0)\n"
|
||||||
" ld 14,120(%0)\n"
|
" ld 14,120(%0)\n"
|
||||||
" ld 15,128(%0)\n"
|
" ld 15,128(%0)\n"
|
||||||
: : "a" (fpregs), "m" (*fpregs) );
|
: : "a" (fpregs), "m" (*fpregs));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void save_access_regs(unsigned int *acrs)
|
static inline void save_access_regs(unsigned int *acrs)
|
||||||
{
|
{
|
||||||
asm volatile ("stam 0,15,0(%0)" : : "a" (acrs) : "memory" );
|
asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restore_access_regs(unsigned int *acrs)
|
static inline void restore_access_regs(unsigned int *acrs)
|
||||||
{
|
{
|
||||||
asm volatile ("lam 0,15,0(%0)" : : "a" (acrs) );
|
asm volatile("lam 0,15,0(%0)" : : "a" (acrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define switch_to(prev,next,last) do { \
|
#define switch_to(prev,next,last) do { \
|
||||||
@ -126,7 +120,7 @@ extern void account_system_vtime(struct task_struct *);
|
|||||||
account_vtime(prev); \
|
account_vtime(prev); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define nop() __asm__ __volatile__ ("nop")
|
#define nop() asm volatile("nop")
|
||||||
|
|
||||||
#define xchg(ptr,x) \
|
#define xchg(ptr,x) \
|
||||||
({ \
|
({ \
|
||||||
@ -147,15 +141,15 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
|
|||||||
shift = (3 ^ (addr & 3)) << 3;
|
shift = (3 ^ (addr & 3)) << 3;
|
||||||
addr ^= addr & 3;
|
addr ^= addr & 3;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" l %0,0(%4)\n"
|
" l %0,0(%4)\n"
|
||||||
"0: lr 0,%0\n"
|
"0: lr 0,%0\n"
|
||||||
" nr 0,%3\n"
|
" nr 0,%3\n"
|
||||||
" or 0,%2\n"
|
" or 0,%2\n"
|
||||||
" cs %0,0,0(%4)\n"
|
" cs %0,0,0(%4)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
: "=&d" (old), "=m" (*(int *) addr)
|
: "=&d" (old), "=m" (*(int *) addr)
|
||||||
: "d" (x << shift), "d" (~(255 << shift)), "a" (addr),
|
: "d" (x << shift), "d" (~(255 << shift)), "a" (addr),
|
||||||
"m" (*(int *) addr) : "memory", "cc", "0" );
|
"m" (*(int *) addr) : "memory", "cc", "0");
|
||||||
x = old >> shift;
|
x = old >> shift;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
@ -163,36 +157,36 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
|
|||||||
shift = (2 ^ (addr & 2)) << 3;
|
shift = (2 ^ (addr & 2)) << 3;
|
||||||
addr ^= addr & 2;
|
addr ^= addr & 2;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" l %0,0(%4)\n"
|
" l %0,0(%4)\n"
|
||||||
"0: lr 0,%0\n"
|
"0: lr 0,%0\n"
|
||||||
" nr 0,%3\n"
|
" nr 0,%3\n"
|
||||||
" or 0,%2\n"
|
" or 0,%2\n"
|
||||||
" cs %0,0,0(%4)\n"
|
" cs %0,0,0(%4)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
: "=&d" (old), "=m" (*(int *) addr)
|
: "=&d" (old), "=m" (*(int *) addr)
|
||||||
: "d" (x << shift), "d" (~(65535 << shift)), "a" (addr),
|
: "d" (x << shift), "d" (~(65535 << shift)), "a" (addr),
|
||||||
"m" (*(int *) addr) : "memory", "cc", "0" );
|
"m" (*(int *) addr) : "memory", "cc", "0");
|
||||||
x = old >> shift;
|
x = old >> shift;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" l %0,0(%3)\n"
|
" l %0,0(%3)\n"
|
||||||
"0: cs %0,%2,0(%3)\n"
|
"0: cs %0,%2,0(%3)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
: "=&d" (old), "=m" (*(int *) ptr)
|
: "=&d" (old), "=m" (*(int *) ptr)
|
||||||
: "d" (x), "a" (ptr), "m" (*(int *) ptr)
|
: "d" (x), "a" (ptr), "m" (*(int *) ptr)
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
x = old;
|
x = old;
|
||||||
break;
|
break;
|
||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
case 8:
|
case 8:
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" lg %0,0(%3)\n"
|
" lg %0,0(%3)\n"
|
||||||
"0: csg %0,%2,0(%3)\n"
|
"0: csg %0,%2,0(%3)\n"
|
||||||
" jl 0b\n"
|
" jl 0b\n"
|
||||||
: "=&d" (old), "=m" (*(long *) ptr)
|
: "=&d" (old), "=m" (*(long *) ptr)
|
||||||
: "d" (x), "a" (ptr), "m" (*(long *) ptr)
|
: "d" (x), "a" (ptr), "m" (*(long *) ptr)
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
x = old;
|
x = old;
|
||||||
break;
|
break;
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
@ -224,55 +218,55 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
|||||||
shift = (3 ^ (addr & 3)) << 3;
|
shift = (3 ^ (addr & 3)) << 3;
|
||||||
addr ^= addr & 3;
|
addr ^= addr & 3;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" l %0,0(%4)\n"
|
" l %0,0(%4)\n"
|
||||||
"0: nr %0,%5\n"
|
"0: nr %0,%5\n"
|
||||||
" lr %1,%0\n"
|
" lr %1,%0\n"
|
||||||
" or %0,%2\n"
|
" or %0,%2\n"
|
||||||
" or %1,%3\n"
|
" or %1,%3\n"
|
||||||
" cs %0,%1,0(%4)\n"
|
" cs %0,%1,0(%4)\n"
|
||||||
" jnl 1f\n"
|
" jnl 1f\n"
|
||||||
" xr %1,%0\n"
|
" xr %1,%0\n"
|
||||||
" nr %1,%5\n"
|
" nr %1,%5\n"
|
||||||
" jnz 0b\n"
|
" jnz 0b\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (prev), "=&d" (tmp)
|
: "=&d" (prev), "=&d" (tmp)
|
||||||
: "d" (old << shift), "d" (new << shift), "a" (ptr),
|
: "d" (old << shift), "d" (new << shift), "a" (ptr),
|
||||||
"d" (~(255 << shift))
|
"d" (~(255 << shift))
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
return prev >> shift;
|
return prev >> shift;
|
||||||
case 2:
|
case 2:
|
||||||
addr = (unsigned long) ptr;
|
addr = (unsigned long) ptr;
|
||||||
shift = (2 ^ (addr & 2)) << 3;
|
shift = (2 ^ (addr & 2)) << 3;
|
||||||
addr ^= addr & 2;
|
addr ^= addr & 2;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" l %0,0(%4)\n"
|
" l %0,0(%4)\n"
|
||||||
"0: nr %0,%5\n"
|
"0: nr %0,%5\n"
|
||||||
" lr %1,%0\n"
|
" lr %1,%0\n"
|
||||||
" or %0,%2\n"
|
" or %0,%2\n"
|
||||||
" or %1,%3\n"
|
" or %1,%3\n"
|
||||||
" cs %0,%1,0(%4)\n"
|
" cs %0,%1,0(%4)\n"
|
||||||
" jnl 1f\n"
|
" jnl 1f\n"
|
||||||
" xr %1,%0\n"
|
" xr %1,%0\n"
|
||||||
" nr %1,%5\n"
|
" nr %1,%5\n"
|
||||||
" jnz 0b\n"
|
" jnz 0b\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=&d" (prev), "=&d" (tmp)
|
: "=&d" (prev), "=&d" (tmp)
|
||||||
: "d" (old << shift), "d" (new << shift), "a" (ptr),
|
: "d" (old << shift), "d" (new << shift), "a" (ptr),
|
||||||
"d" (~(65535 << shift))
|
"d" (~(65535 << shift))
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
return prev >> shift;
|
return prev >> shift;
|
||||||
case 4:
|
case 4:
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" cs %0,%2,0(%3)\n"
|
" cs %0,%2,0(%3)\n"
|
||||||
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
|
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
return prev;
|
return prev;
|
||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
case 8:
|
case 8:
|
||||||
asm volatile (
|
asm volatile(
|
||||||
" csg %0,%2,0(%3)\n"
|
" csg %0,%2,0(%3)\n"
|
||||||
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
|
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
|
||||||
: "memory", "cc" );
|
: "memory", "cc");
|
||||||
return prev;
|
return prev;
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
}
|
}
|
||||||
@ -289,8 +283,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
|||||||
* all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ).
|
* all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define eieio() __asm__ __volatile__ ( "bcr 15,0" : : : "memory" )
|
#define eieio() asm volatile("bcr 15,0" : : : "memory")
|
||||||
# define SYNC_OTHER_CORES(x) eieio()
|
#define SYNC_OTHER_CORES(x) eieio()
|
||||||
#define mb() eieio()
|
#define mb() eieio()
|
||||||
#define rmb() eieio()
|
#define rmb() eieio()
|
||||||
#define wmb() eieio()
|
#define wmb() eieio()
|
||||||
@ -307,117 +301,56 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
|||||||
|
|
||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
|
|
||||||
#define __ctl_load(array, low, high) ({ \
|
#define __ctl_load(array, low, high) ({ \
|
||||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" bras 1,0f\n" \
|
" lctlg %1,%2,0(%0)\n" \
|
||||||
" lctlg 0,0,0(%0)\n" \
|
: : "a" (&array), "i" (low), "i" (high), \
|
||||||
"0: ex %1,0(1)" \
|
"m" (*(addrtype *)(array))); \
|
||||||
: : "a" (&array), "a" (((low)<<4)+(high)), \
|
|
||||||
"m" (*(addrtype *)(array)) : "1" ); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __ctl_store(array, low, high) ({ \
|
#define __ctl_store(array, low, high) ({ \
|
||||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" bras 1,0f\n" \
|
" stctg %2,%3,0(%1)\n" \
|
||||||
" stctg 0,0,0(%1)\n" \
|
: "=m" (*(addrtype *)(array)) \
|
||||||
"0: ex %2,0(1)" \
|
: "a" (&array), "i" (low), "i" (high)); \
|
||||||
: "=m" (*(addrtype *)(array)) \
|
|
||||||
: "a" (&array), "a" (((low)<<4)+(high)) : "1" ); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __ctl_set_bit(cr, bit) ({ \
|
|
||||||
__u8 __dummy[24]; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
" bras 1,0f\n" /* skip indirect insns */ \
|
|
||||||
" stctg 0,0,0(%1)\n" \
|
|
||||||
" lctlg 0,0,0(%1)\n" \
|
|
||||||
"0: ex %2,0(1)\n" /* execute stctl */ \
|
|
||||||
" lg 0,0(%1)\n" \
|
|
||||||
" ogr 0,%3\n" /* set the bit */ \
|
|
||||||
" stg 0,0(%1)\n" \
|
|
||||||
"1: ex %2,6(1)" /* execute lctl */ \
|
|
||||||
: "=m" (__dummy) \
|
|
||||||
: "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
|
|
||||||
"a" (cr*17), "a" (1L<<(bit)) \
|
|
||||||
: "cc", "0", "1" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define __ctl_clear_bit(cr, bit) ({ \
|
|
||||||
__u8 __dummy[16]; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
" bras 1,0f\n" /* skip indirect insns */ \
|
|
||||||
" stctg 0,0,0(%1)\n" \
|
|
||||||
" lctlg 0,0,0(%1)\n" \
|
|
||||||
"0: ex %2,0(1)\n" /* execute stctl */ \
|
|
||||||
" lg 0,0(%1)\n" \
|
|
||||||
" ngr 0,%3\n" /* set the bit */ \
|
|
||||||
" stg 0,0(%1)\n" \
|
|
||||||
"1: ex %2,6(1)" /* execute lctl */ \
|
|
||||||
: "=m" (__dummy) \
|
|
||||||
: "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
|
|
||||||
"a" (cr*17), "a" (~(1L<<(bit))) \
|
|
||||||
: "cc", "0", "1" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
|
|
||||||
#define __ctl_load(array, low, high) ({ \
|
#define __ctl_load(array, low, high) ({ \
|
||||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" bras 1,0f\n" \
|
" lctl %1,%2,0(%0)\n" \
|
||||||
" lctl 0,0,0(%0)\n" \
|
: : "a" (&array), "i" (low), "i" (high), \
|
||||||
"0: ex %1,0(1)" \
|
"m" (*(addrtype *)(array))); \
|
||||||
: : "a" (&array), "a" (((low)<<4)+(high)), \
|
})
|
||||||
"m" (*(addrtype *)(array)) : "1" ); \
|
|
||||||
|
#define __ctl_store(array, low, high) ({ \
|
||||||
|
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||||
|
asm volatile( \
|
||||||
|
" stctl %2,%3,0(%1)\n" \
|
||||||
|
: "=m" (*(addrtype *)(array)) \
|
||||||
|
: "a" (&array), "i" (low), "i" (high)); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __ctl_store(array, low, high) ({ \
|
|
||||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
" bras 1,0f\n" \
|
|
||||||
" stctl 0,0,0(%1)\n" \
|
|
||||||
"0: ex %2,0(1)" \
|
|
||||||
: "=m" (*(addrtype *)(array)) \
|
|
||||||
: "a" (&array), "a" (((low)<<4)+(high)): "1" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define __ctl_set_bit(cr, bit) ({ \
|
|
||||||
__u8 __dummy[16]; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
" bras 1,0f\n" /* skip indirect insns */ \
|
|
||||||
" stctl 0,0,0(%1)\n" \
|
|
||||||
" lctl 0,0,0(%1)\n" \
|
|
||||||
"0: ex %2,0(1)\n" /* execute stctl */ \
|
|
||||||
" l 0,0(%1)\n" \
|
|
||||||
" or 0,%3\n" /* set the bit */ \
|
|
||||||
" st 0,0(%1)\n" \
|
|
||||||
"1: ex %2,4(1)" /* execute lctl */ \
|
|
||||||
: "=m" (__dummy) \
|
|
||||||
: "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
|
|
||||||
"a" (cr*17), "a" (1<<(bit)) \
|
|
||||||
: "cc", "0", "1" ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define __ctl_clear_bit(cr, bit) ({ \
|
|
||||||
__u8 __dummy[16]; \
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
" bras 1,0f\n" /* skip indirect insns */ \
|
|
||||||
" stctl 0,0,0(%1)\n" \
|
|
||||||
" lctl 0,0,0(%1)\n" \
|
|
||||||
"0: ex %2,0(1)\n" /* execute stctl */ \
|
|
||||||
" l 0,0(%1)\n" \
|
|
||||||
" nr 0,%3\n" /* set the bit */ \
|
|
||||||
" st 0,0(%1)\n" \
|
|
||||||
"1: ex %2,4(1)" /* execute lctl */ \
|
|
||||||
: "=m" (__dummy) \
|
|
||||||
: "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
|
|
||||||
"a" (cr*17), "a" (~(1<<(bit))) \
|
|
||||||
: "cc", "0", "1" ); \
|
|
||||||
})
|
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
|
|
||||||
|
#define __ctl_set_bit(cr, bit) ({ \
|
||||||
|
unsigned long __dummy; \
|
||||||
|
__ctl_store(__dummy, cr, cr); \
|
||||||
|
__dummy |= 1UL << (bit); \
|
||||||
|
__ctl_load(__dummy, cr, cr); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __ctl_clear_bit(cr, bit) ({ \
|
||||||
|
unsigned long __dummy; \
|
||||||
|
__ctl_store(__dummy, cr, cr); \
|
||||||
|
__dummy &= ~(1UL << (bit)); \
|
||||||
|
__ctl_load(__dummy, cr, cr); \
|
||||||
|
})
|
||||||
|
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -427,8 +360,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
|||||||
static inline void
|
static inline void
|
||||||
__set_psw_mask(unsigned long mask)
|
__set_psw_mask(unsigned long mask)
|
||||||
{
|
{
|
||||||
local_save_flags(mask);
|
__load_psw_mask(mask | (__raw_local_irq_stosm(0x00) & ~(-1UL >> 8)));
|
||||||
__load_psw_mask(mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS)
|
#define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS)
|
||||||
|
@ -15,20 +15,21 @@
|
|||||||
|
|
||||||
typedef unsigned long long cycles_t;
|
typedef unsigned long long cycles_t;
|
||||||
|
|
||||||
static inline cycles_t get_cycles(void)
|
|
||||||
{
|
|
||||||
cycles_t cycles;
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc");
|
|
||||||
return cycles >> 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long long get_clock (void)
|
static inline unsigned long long get_clock (void)
|
||||||
{
|
{
|
||||||
unsigned long long clk;
|
unsigned long long clk;
|
||||||
|
|
||||||
__asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||||
|
asm volatile("stck %0" : "=Q" (clk) : : "cc");
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
|
||||||
|
#endif /* __GNUC__ */
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline cycles_t get_cycles(void)
|
||||||
|
{
|
||||||
|
return (cycles_t) get_clock() >> 2;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define local_flush_tlb() \
|
#define local_flush_tlb() \
|
||||||
do { __asm__ __volatile__("ptlb": : :"memory"); } while (0)
|
do { asm volatile("ptlb": : :"memory"); } while (0)
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
|
|
||||||
@ -68,24 +68,24 @@ extern void smp_ptlb_all(void);
|
|||||||
|
|
||||||
static inline void global_flush_tlb(void)
|
static inline void global_flush_tlb(void)
|
||||||
{
|
{
|
||||||
|
register unsigned long reg2 asm("2");
|
||||||
|
register unsigned long reg3 asm("3");
|
||||||
|
register unsigned long reg4 asm("4");
|
||||||
|
long dummy;
|
||||||
|
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
if (!MACHINE_HAS_CSP) {
|
if (!MACHINE_HAS_CSP) {
|
||||||
smp_ptlb_all();
|
smp_ptlb_all();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* __s390x__ */
|
#endif /* __s390x__ */
|
||||||
{
|
|
||||||
register unsigned long addr asm("4");
|
|
||||||
long dummy;
|
|
||||||
|
|
||||||
dummy = 0;
|
dummy = 0;
|
||||||
addr = ((unsigned long) &dummy) + 1;
|
reg2 = reg3 = 0;
|
||||||
__asm__ __volatile__ (
|
reg4 = ((unsigned long) &dummy) + 1;
|
||||||
" slr 2,2\n"
|
asm volatile(
|
||||||
" slr 3,3\n"
|
" csp %0,%2"
|
||||||
" csp 2,%0"
|
: : "d" (reg2), "d" (reg3), "d" (reg4), "m" (dummy) : "cc" );
|
||||||
: : "a" (addr), "m" (dummy) : "cc", "2", "3" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -102,9 +102,9 @@ static inline void __flush_tlb_mm(struct mm_struct * mm)
|
|||||||
if (unlikely(cpus_empty(mm->cpu_vm_mask)))
|
if (unlikely(cpus_empty(mm->cpu_vm_mask)))
|
||||||
return;
|
return;
|
||||||
if (MACHINE_HAS_IDTE) {
|
if (MACHINE_HAS_IDTE) {
|
||||||
asm volatile (".insn rrf,0xb98e0000,0,%0,%1,0"
|
asm volatile(
|
||||||
: : "a" (2048),
|
" .insn rrf,0xb98e0000,0,%0,%1,0"
|
||||||
"a" (__pa(mm->pgd)&PAGE_MASK) : "cc" );
|
: : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
@ -38,25 +38,14 @@
|
|||||||
#define get_ds() (KERNEL_DS)
|
#define get_ds() (KERNEL_DS)
|
||||||
#define get_fs() (current->thread.mm_segment)
|
#define get_fs() (current->thread.mm_segment)
|
||||||
|
|
||||||
#ifdef __s390x__
|
|
||||||
#define set_fs(x) \
|
#define set_fs(x) \
|
||||||
({ \
|
({ \
|
||||||
unsigned long __pto; \
|
unsigned long __pto; \
|
||||||
current->thread.mm_segment = (x); \
|
current->thread.mm_segment = (x); \
|
||||||
__pto = current->thread.mm_segment.ar4 ? \
|
__pto = current->thread.mm_segment.ar4 ? \
|
||||||
S390_lowcore.user_asce : S390_lowcore.kernel_asce; \
|
S390_lowcore.user_asce : S390_lowcore.kernel_asce; \
|
||||||
asm volatile ("lctlg 7,7,%0" : : "m" (__pto) ); \
|
__ctl_load(__pto, 7, 7); \
|
||||||
})
|
})
|
||||||
#else /* __s390x__ */
|
|
||||||
#define set_fs(x) \
|
|
||||||
({ \
|
|
||||||
unsigned long __pto; \
|
|
||||||
current->thread.mm_segment = (x); \
|
|
||||||
__pto = current->thread.mm_segment.ar4 ? \
|
|
||||||
S390_lowcore.user_asce : S390_lowcore.kernel_asce; \
|
|
||||||
asm volatile ("lctl 7,7,%0" : : "m" (__pto) ); \
|
|
||||||
})
|
|
||||||
#endif /* __s390x__ */
|
|
||||||
|
|
||||||
#define segment_eq(a,b) ((a).ar4 == (b).ar4)
|
#define segment_eq(a,b) ((a).ar4 == (b).ar4)
|
||||||
|
|
||||||
|
@ -355,145 +355,145 @@ do { \
|
|||||||
|
|
||||||
#define _svc_clobber "1", "cc", "memory"
|
#define _svc_clobber "1", "cc", "memory"
|
||||||
|
|
||||||
#define _syscall0(type,name) \
|
#define _syscall0(type,name) \
|
||||||
type name(void) { \
|
type name(void) { \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name) \
|
: "i" (__NR_##name) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _syscall1(type,name,type1,arg1) \
|
#define _syscall1(type,name,type1,arg1) \
|
||||||
type name(type1 arg1) { \
|
type name(type1 arg1) { \
|
||||||
register type1 __arg1 asm("2") = arg1; \
|
register type1 __arg1 asm("2") = arg1; \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name), \
|
: "i" (__NR_##name), \
|
||||||
"0" (__arg1) \
|
"0" (__arg1) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _syscall2(type,name,type1,arg1,type2,arg2) \
|
#define _syscall2(type,name,type1,arg1,type2,arg2) \
|
||||||
type name(type1 arg1, type2 arg2) { \
|
type name(type1 arg1, type2 arg2) { \
|
||||||
register type1 __arg1 asm("2") = arg1; \
|
register type1 __arg1 asm("2") = arg1; \
|
||||||
register type2 __arg2 asm("3") = arg2; \
|
register type2 __arg2 asm("3") = arg2; \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name), \
|
: "i" (__NR_##name), \
|
||||||
"0" (__arg1), \
|
"0" (__arg1), \
|
||||||
"d" (__arg2) \
|
"d" (__arg2) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber ); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)\
|
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
|
||||||
type name(type1 arg1, type2 arg2, type3 arg3) { \
|
type name(type1 arg1, type2 arg2, type3 arg3) { \
|
||||||
register type1 __arg1 asm("2") = arg1; \
|
register type1 __arg1 asm("2") = arg1; \
|
||||||
register type2 __arg2 asm("3") = arg2; \
|
register type2 __arg2 asm("3") = arg2; \
|
||||||
register type3 __arg3 asm("4") = arg3; \
|
register type3 __arg3 asm("4") = arg3; \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name), \
|
: "i" (__NR_##name), \
|
||||||
"0" (__arg1), \
|
"0" (__arg1), \
|
||||||
"d" (__arg2), \
|
"d" (__arg2), \
|
||||||
"d" (__arg3) \
|
"d" (__arg3) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,\
|
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3, \
|
||||||
type4,name4) \
|
type4,name4) \
|
||||||
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
|
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
|
||||||
register type1 __arg1 asm("2") = arg1; \
|
register type1 __arg1 asm("2") = arg1; \
|
||||||
register type2 __arg2 asm("3") = arg2; \
|
register type2 __arg2 asm("3") = arg2; \
|
||||||
register type3 __arg3 asm("4") = arg3; \
|
register type3 __arg3 asm("4") = arg3; \
|
||||||
register type4 __arg4 asm("5") = arg4; \
|
register type4 __arg4 asm("5") = arg4; \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name), \
|
: "i" (__NR_##name), \
|
||||||
"0" (__arg1), \
|
"0" (__arg1), \
|
||||||
"d" (__arg2), \
|
"d" (__arg2), \
|
||||||
"d" (__arg3), \
|
"d" (__arg3), \
|
||||||
"d" (__arg4) \
|
"d" (__arg4) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,\
|
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3, \
|
||||||
type4,name4,type5,name5) \
|
type4,name4,type5,name5) \
|
||||||
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
|
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
|
||||||
type5 arg5) { \
|
type5 arg5) { \
|
||||||
register type1 __arg1 asm("2") = arg1; \
|
register type1 __arg1 asm("2") = arg1; \
|
||||||
register type2 __arg2 asm("3") = arg2; \
|
register type2 __arg2 asm("3") = arg2; \
|
||||||
register type3 __arg3 asm("4") = arg3; \
|
register type3 __arg3 asm("4") = arg3; \
|
||||||
register type4 __arg4 asm("5") = arg4; \
|
register type4 __arg4 asm("5") = arg4; \
|
||||||
register type5 __arg5 asm("6") = arg5; \
|
register type5 __arg5 asm("6") = arg5; \
|
||||||
register long __svcres asm("2"); \
|
register long __svcres asm("2"); \
|
||||||
long __res; \
|
long __res; \
|
||||||
__asm__ __volatile__ ( \
|
asm volatile( \
|
||||||
" .if %1 < 256\n" \
|
" .if %1 < 256\n" \
|
||||||
" svc %b1\n" \
|
" svc %b1\n" \
|
||||||
" .else\n" \
|
" .else\n" \
|
||||||
" la %%r1,%1\n" \
|
" la %%r1,%1\n" \
|
||||||
" svc 0\n" \
|
" svc 0\n" \
|
||||||
" .endif" \
|
" .endif" \
|
||||||
: "=d" (__svcres) \
|
: "=d" (__svcres) \
|
||||||
: "i" (__NR_##name), \
|
: "i" (__NR_##name), \
|
||||||
"0" (__arg1), \
|
"0" (__arg1), \
|
||||||
"d" (__arg2), \
|
"d" (__arg2), \
|
||||||
"d" (__arg3), \
|
"d" (__arg3), \
|
||||||
"d" (__arg4), \
|
"d" (__arg4), \
|
||||||
"d" (__arg5) \
|
"d" (__arg5) \
|
||||||
: _svc_clobber ); \
|
: _svc_clobber); \
|
||||||
__res = __svcres; \
|
__res = __svcres; \
|
||||||
__syscall_return(type,__res); \
|
__syscall_return(type,__res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||||
|
Loading…
Reference in New Issue
Block a user