/*
|
/*
|
* linux/include/asm-arm/proc-armv/segment.h
|
* linux/include/asm-arm/proc-armv/segment.h
|
*
|
*
|
* Copyright (C) 1996 Russell King
|
* Copyright (C) 1996 Russell King
|
*/
|
*/
|
|
|
#ifndef __ASM_PROC_SEGMENT_H
|
#ifndef __ASM_PROC_SEGMENT_H
|
#define __ASM_PROC_SEGMENT_H
|
#define __ASM_PROC_SEGMENT_H
|
|
|
static __inline__ void __put_user(unsigned long x, void * y, int size)
|
static __inline__ void __put_user(unsigned long x, void * y, int size)
|
{
|
{
|
switch (size) {
|
switch (size) {
|
case 1:
|
case 1:
|
__asm__(
|
__asm__(
|
"teq %2, #0\n"
|
"teq %2, #0\n"
|
"strnebt %0, [%1]\n"
|
"strnebt %0, [%1]\n"
|
"streqb %0, [%1]\n"
|
"streqb %0, [%1]\n"
|
: : "r" (x), "r" (y), "r" (current->tss.fs)
|
: : "r" (x), "r" (y), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
break;
|
break;
|
case 2:
|
case 2:
|
{ register unsigned long tmp1 = x; void *tmp2 = y;
|
{ register unsigned long tmp1 = x; void *tmp2 = y;
|
__asm__ __volatile__(
|
__asm__ __volatile__(
|
"teq %4, #0\n"
|
"teq %4, #0\n"
|
"strnebt %0, [%1], #1\n"
|
"strnebt %0, [%1], #1\n"
|
"streqb %0, [%1], #1\n"
|
"streqb %0, [%1], #1\n"
|
"mov %0, %0, lsr #8\n"
|
"mov %0, %0, lsr #8\n"
|
"strnebt %0, [%1]\n"
|
"strnebt %0, [%1]\n"
|
"streqb %0, [%1]\n"
|
"streqb %0, [%1]\n"
|
: "=&r" (tmp1), "=&r" (tmp2)
|
: "=&r" (tmp1), "=&r" (tmp2)
|
: "0" (tmp1), "1" (tmp2), "r" (current->tss.fs)
|
: "0" (tmp1), "1" (tmp2), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
}
|
}
|
break;
|
break;
|
case 4:
|
case 4:
|
__asm__(
|
__asm__(
|
"teq %2, #0\n"
|
"teq %2, #0\n"
|
"strnet %0, [%1]\n"
|
"strnet %0, [%1]\n"
|
"streq %0, [%1]\n"
|
"streq %0, [%1]\n"
|
: : "r" (x), "r" (y), "r" (current->tss.fs)
|
: : "r" (x), "r" (y), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
break;
|
break;
|
default:
|
default:
|
bad_user_access_length ();
|
bad_user_access_length ();
|
}
|
}
|
}
|
}
|
|
|
static __inline__ unsigned long __get_user(const void *y, int size)
|
static __inline__ unsigned long __get_user(const void *y, int size)
|
{
|
{
|
unsigned long result;
|
unsigned long result;
|
|
|
switch (size) {
|
switch (size) {
|
case 1:
|
case 1:
|
__asm__(
|
__asm__(
|
"teq %2, #0\n"
|
"teq %2, #0\n"
|
"ldrnebt %0, [%1]\n"
|
"ldrnebt %0, [%1]\n"
|
"ldreqb %0, [%1]\n"
|
"ldreqb %0, [%1]\n"
|
: "=r" (result)
|
: "=r" (result)
|
: "r" (y), "r" (current->tss.fs)
|
: "r" (y), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
return result;
|
return result;
|
case 2:
|
case 2:
|
__asm__(
|
__asm__(
|
"teq %2, #0\n"
|
"teq %2, #0\n"
|
"ldrnet %0, [%1]\n"
|
"ldrnet %0, [%1]\n"
|
"ldreq %0, [%1]\n"
|
"ldreq %0, [%1]\n"
|
"mov %0, %0, lsl #16\n"
|
"mov %0, %0, lsl #16\n"
|
"mov %0, %0, lsr #16\n"
|
"mov %0, %0, lsr #16\n"
|
: "=&r" (result)
|
: "=&r" (result)
|
: "r" (y), "r" (current->tss.fs)
|
: "r" (y), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
return result;
|
return result;
|
case 4:
|
case 4:
|
__asm__(
|
__asm__(
|
"teq %2, #0\n"
|
"teq %2, #0\n"
|
"ldrnet %0, [%1]\n"
|
"ldrnet %0, [%1]\n"
|
"ldreq %0, [%1]\n"
|
"ldreq %0, [%1]\n"
|
: "=r" (result)
|
: "=r" (result)
|
: "r" (y), "r" (current->tss.fs)
|
: "r" (y), "r" (current->tss.fs)
|
: "lr", "cc");
|
: "lr", "cc");
|
return result;
|
return result;
|
default:
|
default:
|
return bad_user_access_length ();
|
return bad_user_access_length ();
|
}
|
}
|
}
|
}
|
|
|
#endif /* __ASM_PROC_SEGMENT_H */
|
#endif /* __ASM_PROC_SEGMENT_H */
|
|
|
|
|