Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] Cleanup memory barriers for weakly ordered systems. [MIPS] Alchemy: Automatically enable CONFIG_RESOURCES_64BIT for PCI configs. [MIPS] Unify csum_partial.S [MIPS] SWARM: Fix a typo in #error directives [MIPS] Fix atomic.h build errors. [MIPS] Use SYSVIPC_COMPAT to fix various problems on N32 [MIPS] klconfig add missing bracket
This commit is contained in:
commit
91f433cacc
|
@ -16,6 +16,7 @@ config MIPS_MTX1
|
||||||
bool "4G Systems MTX-1 board"
|
bool "4G Systems MTX-1 board"
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SOC_AU1500
|
select SOC_AU1500
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
@ -32,6 +33,7 @@ config MIPS_PB1000
|
||||||
select SOC_AU1000
|
select SOC_AU1000
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SWAP_IO_SPACE
|
select SWAP_IO_SPACE
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
@ -41,6 +43,7 @@ config MIPS_PB1100
|
||||||
select SOC_AU1100
|
select SOC_AU1100
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SWAP_IO_SPACE
|
select SWAP_IO_SPACE
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
@ -50,6 +53,7 @@ config MIPS_PB1500
|
||||||
select SOC_AU1500
|
select SOC_AU1500
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
@ -59,6 +63,7 @@ config MIPS_PB1550
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
select MIPS_DISABLE_OBSOLETE_IDE
|
select MIPS_DISABLE_OBSOLETE_IDE
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
@ -67,6 +72,7 @@ config MIPS_PB1200
|
||||||
select SOC_AU1200
|
select SOC_AU1200
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select MIPS_DISABLE_OBSOLETE_IDE
|
select MIPS_DISABLE_OBSOLETE_IDE
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
@ -75,6 +81,7 @@ config MIPS_DB1000
|
||||||
select SOC_AU1000
|
select SOC_AU1000
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
@ -91,6 +98,7 @@ config MIPS_DB1500
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
select MIPS_DISABLE_OBSOLETE_IDE
|
select MIPS_DISABLE_OBSOLETE_IDE
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_BIG_ENDIAN
|
select SYS_SUPPORTS_BIG_ENDIAN
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
@ -101,6 +109,7 @@ config MIPS_DB1550
|
||||||
select HW_HAS_PCI
|
select HW_HAS_PCI
|
||||||
select DMA_NONCOHERENT
|
select DMA_NONCOHERENT
|
||||||
select MIPS_DISABLE_OBSOLETE_IDE
|
select MIPS_DISABLE_OBSOLETE_IDE
|
||||||
|
select RESOURCES_64BIT if PCI
|
||||||
select SYS_HAS_CPU_MIPS32_R1
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
@ -1268,6 +1277,7 @@ config CPU_RM9000
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
select WEAK_ORDERING
|
||||||
|
|
||||||
config CPU_SB1
|
config CPU_SB1
|
||||||
bool "SB1"
|
bool "SB1"
|
||||||
|
@ -1276,6 +1286,7 @@ config CPU_SB1
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
select WEAK_ORDERING
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
@ -1336,6 +1347,8 @@ config SYS_HAS_CPU_RM9000
|
||||||
config SYS_HAS_CPU_SB1
|
config SYS_HAS_CPU_SB1
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config WEAK_ORDERING
|
||||||
|
bool
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1940,6 +1953,11 @@ config COMPAT
|
||||||
depends on MIPS32_COMPAT
|
depends on MIPS32_COMPAT
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SYSVIPC_COMPAT
|
||||||
|
bool
|
||||||
|
depends on COMPAT && SYSVIPC
|
||||||
|
default y
|
||||||
|
|
||||||
config MIPS32_O32
|
config MIPS32_O32
|
||||||
bool "Kernel support for o32 binaries"
|
bool "Kernel support for o32 binaries"
|
||||||
depends on MIPS32_COMPAT
|
depends on MIPS32_COMPAT
|
||||||
|
|
|
@ -382,531 +382,6 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct msgbuf32 { s32 mtype; char mtext[1]; };
|
|
||||||
|
|
||||||
struct ipc_perm32
|
|
||||||
{
|
|
||||||
key_t key;
|
|
||||||
__compat_uid_t uid;
|
|
||||||
__compat_gid_t gid;
|
|
||||||
__compat_uid_t cuid;
|
|
||||||
__compat_gid_t cgid;
|
|
||||||
compat_mode_t mode;
|
|
||||||
unsigned short seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc64_perm32 {
|
|
||||||
key_t key;
|
|
||||||
__compat_uid_t uid;
|
|
||||||
__compat_gid_t gid;
|
|
||||||
__compat_uid_t cuid;
|
|
||||||
__compat_gid_t cgid;
|
|
||||||
compat_mode_t mode;
|
|
||||||
unsigned short seq;
|
|
||||||
unsigned short __pad1;
|
|
||||||
unsigned int __unused1;
|
|
||||||
unsigned int __unused2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct semid_ds32 {
|
|
||||||
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
|
|
||||||
compat_time_t sem_otime; /* last semop time */
|
|
||||||
compat_time_t sem_ctime; /* last change time */
|
|
||||||
u32 sem_base; /* ptr to first semaphore in array */
|
|
||||||
u32 sem_pending; /* pending operations to be processed */
|
|
||||||
u32 sem_pending_last; /* last pending operation */
|
|
||||||
u32 undo; /* undo requests on this array */
|
|
||||||
unsigned short sem_nsems; /* no. of semaphores in array */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct semid64_ds32 {
|
|
||||||
struct ipc64_perm32 sem_perm;
|
|
||||||
compat_time_t sem_otime;
|
|
||||||
compat_time_t sem_ctime;
|
|
||||||
unsigned int sem_nsems;
|
|
||||||
unsigned int __unused1;
|
|
||||||
unsigned int __unused2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct msqid_ds32
|
|
||||||
{
|
|
||||||
struct ipc_perm32 msg_perm;
|
|
||||||
u32 msg_first;
|
|
||||||
u32 msg_last;
|
|
||||||
compat_time_t msg_stime;
|
|
||||||
compat_time_t msg_rtime;
|
|
||||||
compat_time_t msg_ctime;
|
|
||||||
u32 wwait;
|
|
||||||
u32 rwait;
|
|
||||||
unsigned short msg_cbytes;
|
|
||||||
unsigned short msg_qnum;
|
|
||||||
unsigned short msg_qbytes;
|
|
||||||
compat_ipc_pid_t msg_lspid;
|
|
||||||
compat_ipc_pid_t msg_lrpid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct msqid64_ds32 {
|
|
||||||
struct ipc64_perm32 msg_perm;
|
|
||||||
compat_time_t msg_stime;
|
|
||||||
unsigned int __unused1;
|
|
||||||
compat_time_t msg_rtime;
|
|
||||||
unsigned int __unused2;
|
|
||||||
compat_time_t msg_ctime;
|
|
||||||
unsigned int __unused3;
|
|
||||||
unsigned int msg_cbytes;
|
|
||||||
unsigned int msg_qnum;
|
|
||||||
unsigned int msg_qbytes;
|
|
||||||
compat_pid_t msg_lspid;
|
|
||||||
compat_pid_t msg_lrpid;
|
|
||||||
unsigned int __unused4;
|
|
||||||
unsigned int __unused5;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shmid_ds32 {
|
|
||||||
struct ipc_perm32 shm_perm;
|
|
||||||
int shm_segsz;
|
|
||||||
compat_time_t shm_atime;
|
|
||||||
compat_time_t shm_dtime;
|
|
||||||
compat_time_t shm_ctime;
|
|
||||||
compat_ipc_pid_t shm_cpid;
|
|
||||||
compat_ipc_pid_t shm_lpid;
|
|
||||||
unsigned short shm_nattch;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shmid64_ds32 {
|
|
||||||
struct ipc64_perm32 shm_perm;
|
|
||||||
compat_size_t shm_segsz;
|
|
||||||
compat_time_t shm_atime;
|
|
||||||
compat_time_t shm_dtime;
|
|
||||||
compat_time_t shm_ctime;
|
|
||||||
compat_pid_t shm_cpid;
|
|
||||||
compat_pid_t shm_lpid;
|
|
||||||
unsigned int shm_nattch;
|
|
||||||
unsigned int __unused1;
|
|
||||||
unsigned int __unused2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_kludge32 {
|
|
||||||
u32 msgp;
|
|
||||||
s32 msgtyp;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_semctl(int first, int second, int third, void __user *uptr)
|
|
||||||
{
|
|
||||||
union semun fourth;
|
|
||||||
u32 pad;
|
|
||||||
int err, err2;
|
|
||||||
struct semid64_ds s;
|
|
||||||
mm_segment_t old_fs;
|
|
||||||
|
|
||||||
if (!uptr)
|
|
||||||
return -EINVAL;
|
|
||||||
err = -EFAULT;
|
|
||||||
if (get_user (pad, (u32 __user *)uptr))
|
|
||||||
return err;
|
|
||||||
if ((third & ~IPC_64) == SETVAL)
|
|
||||||
fourth.val = (int)pad;
|
|
||||||
else
|
|
||||||
fourth.__pad = (void __user *)A(pad);
|
|
||||||
switch (third & ~IPC_64) {
|
|
||||||
case IPC_INFO:
|
|
||||||
case IPC_RMID:
|
|
||||||
case IPC_SET:
|
|
||||||
case SEM_INFO:
|
|
||||||
case GETVAL:
|
|
||||||
case GETPID:
|
|
||||||
case GETNCNT:
|
|
||||||
case GETZCNT:
|
|
||||||
case GETALL:
|
|
||||||
case SETVAL:
|
|
||||||
case SETALL:
|
|
||||||
err = sys_semctl (first, second, third, fourth);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IPC_STAT:
|
|
||||||
case SEM_STAT:
|
|
||||||
fourth.__pad = (struct semid64_ds __user *)&s;
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_semctl(first, second, third | IPC_64, fourth);
|
|
||||||
set_fs(old_fs);
|
|
||||||
|
|
||||||
if (third & IPC_64) {
|
|
||||||
struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad);
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
|
|
||||||
err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
|
|
||||||
err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
|
|
||||||
err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
|
|
||||||
err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
|
|
||||||
err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
|
|
||||||
err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
|
|
||||||
err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
|
|
||||||
err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
|
|
||||||
err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
|
|
||||||
} else {
|
|
||||||
struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad);
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
|
|
||||||
err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
|
|
||||||
err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
|
|
||||||
err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
|
|
||||||
err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
|
|
||||||
err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
|
|
||||||
err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
|
|
||||||
err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
|
|
||||||
err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
|
|
||||||
err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
|
|
||||||
}
|
|
||||||
if (err2)
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = - EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_msgsnd (int first, int second, int third, void __user *uptr)
|
|
||||||
{
|
|
||||||
struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr;
|
|
||||||
struct msgbuf *p;
|
|
||||||
mm_segment_t old_fs;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (second < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
p = kmalloc (second + sizeof (struct msgbuf)
|
|
||||||
+ 4, GFP_USER);
|
|
||||||
if (!p)
|
|
||||||
return -ENOMEM;
|
|
||||||
err = get_user (p->mtype, &up->mtype);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
err |= __copy_from_user (p->mtext, &up->mtext, second);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
old_fs = get_fs ();
|
|
||||||
set_fs (KERNEL_DS);
|
|
||||||
err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third);
|
|
||||||
set_fs (old_fs);
|
|
||||||
out:
|
|
||||||
kfree (p);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_msgrcv (int first, int second, int msgtyp, int third,
|
|
||||||
int version, void __user *uptr)
|
|
||||||
{
|
|
||||||
struct msgbuf32 __user *up;
|
|
||||||
struct msgbuf *p;
|
|
||||||
mm_segment_t old_fs;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!version) {
|
|
||||||
struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr;
|
|
||||||
struct ipc_kludge32 ipck;
|
|
||||||
|
|
||||||
err = -EINVAL;
|
|
||||||
if (!uptr)
|
|
||||||
goto out;
|
|
||||||
err = -EFAULT;
|
|
||||||
if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
|
|
||||||
goto out;
|
|
||||||
uptr = (void __user *)AA(ipck.msgp);
|
|
||||||
msgtyp = ipck.msgtyp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (second < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
err = -ENOMEM;
|
|
||||||
p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
|
|
||||||
if (!p)
|
|
||||||
goto out;
|
|
||||||
old_fs = get_fs ();
|
|
||||||
set_fs (KERNEL_DS);
|
|
||||||
err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third);
|
|
||||||
set_fs (old_fs);
|
|
||||||
if (err < 0)
|
|
||||||
goto free_then_out;
|
|
||||||
up = (struct msgbuf32 __user *)uptr;
|
|
||||||
if (put_user (p->mtype, &up->mtype) ||
|
|
||||||
__copy_to_user (&up->mtext, p->mtext, err))
|
|
||||||
err = -EFAULT;
|
|
||||||
free_then_out:
|
|
||||||
kfree (p);
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_msgctl (int first, int second, void __user *uptr)
|
|
||||||
{
|
|
||||||
int err = -EINVAL, err2;
|
|
||||||
struct msqid64_ds m;
|
|
||||||
struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr;
|
|
||||||
struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr;
|
|
||||||
mm_segment_t old_fs;
|
|
||||||
|
|
||||||
switch (second & ~IPC_64) {
|
|
||||||
case IPC_INFO:
|
|
||||||
case IPC_RMID:
|
|
||||||
case MSG_INFO:
|
|
||||||
err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IPC_SET:
|
|
||||||
if (second & IPC_64) {
|
|
||||||
if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
|
|
||||||
err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
|
|
||||||
err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
|
|
||||||
err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
|
|
||||||
} else {
|
|
||||||
if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
|
|
||||||
err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
|
|
||||||
err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
|
|
||||||
err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
break;
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
|
|
||||||
set_fs(old_fs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IPC_STAT:
|
|
||||||
case MSG_STAT:
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
|
|
||||||
set_fs(old_fs);
|
|
||||||
if (second & IPC_64) {
|
|
||||||
if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
|
|
||||||
err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
|
|
||||||
err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
|
|
||||||
err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
|
|
||||||
err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
|
|
||||||
err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
|
|
||||||
err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
|
|
||||||
err2 |= __put_user(m.msg_stime, &up64->msg_stime);
|
|
||||||
err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
|
|
||||||
err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
|
|
||||||
err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
|
|
||||||
err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
|
|
||||||
err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
|
|
||||||
err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
|
|
||||||
err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
|
|
||||||
if (err2)
|
|
||||||
err = -EFAULT;
|
|
||||||
} else {
|
|
||||||
if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
|
|
||||||
err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
|
|
||||||
err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
|
|
||||||
err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
|
|
||||||
err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
|
|
||||||
err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
|
|
||||||
err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
|
|
||||||
err2 |= __put_user(m.msg_stime, &up32->msg_stime);
|
|
||||||
err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
|
|
||||||
err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
|
|
||||||
err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
|
|
||||||
err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
|
|
||||||
err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
|
|
||||||
err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
|
|
||||||
err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
|
|
||||||
if (err2)
|
|
||||||
err = -EFAULT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
|
|
||||||
{
|
|
||||||
unsigned long raddr;
|
|
||||||
u32 __user *uaddr = (u32 __user *)A((u32)third);
|
|
||||||
int err = -EINVAL;
|
|
||||||
|
|
||||||
if (version == 1)
|
|
||||||
return err;
|
|
||||||
err = do_shmat (first, uptr, second, &raddr);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
err = put_user (raddr, uaddr);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct shm_info32 {
|
|
||||||
int used_ids;
|
|
||||||
u32 shm_tot, shm_rss, shm_swp;
|
|
||||||
u32 swap_attempts, swap_successes;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_sys32_shmctl (int first, int second, void __user *uptr)
|
|
||||||
{
|
|
||||||
struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr;
|
|
||||||
struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr;
|
|
||||||
struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr;
|
|
||||||
int err = -EFAULT, err2;
|
|
||||||
struct shmid64_ds s64;
|
|
||||||
mm_segment_t old_fs;
|
|
||||||
struct shm_info si;
|
|
||||||
struct shmid_ds s;
|
|
||||||
|
|
||||||
switch (second & ~IPC_64) {
|
|
||||||
case IPC_INFO:
|
|
||||||
second = IPC_INFO; /* So that we don't have to translate it */
|
|
||||||
case IPC_RMID:
|
|
||||||
case SHM_LOCK:
|
|
||||||
case SHM_UNLOCK:
|
|
||||||
err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr);
|
|
||||||
break;
|
|
||||||
case IPC_SET:
|
|
||||||
if (second & IPC_64) {
|
|
||||||
err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
|
|
||||||
err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
|
|
||||||
err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
|
|
||||||
} else {
|
|
||||||
err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
|
|
||||||
err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
|
|
||||||
err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
break;
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s);
|
|
||||||
set_fs(old_fs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IPC_STAT:
|
|
||||||
case SHM_STAT:
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_shmctl(first, second | IPC_64, (void __user *) &s64);
|
|
||||||
set_fs(old_fs);
|
|
||||||
if (err < 0)
|
|
||||||
break;
|
|
||||||
if (second & IPC_64) {
|
|
||||||
if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
|
|
||||||
err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
|
|
||||||
err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
|
|
||||||
err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
|
|
||||||
err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
|
|
||||||
err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
|
|
||||||
err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
|
|
||||||
err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
|
|
||||||
err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
|
|
||||||
err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
|
|
||||||
} else {
|
|
||||||
if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
|
|
||||||
err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
|
|
||||||
err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
|
|
||||||
err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
|
|
||||||
err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
|
|
||||||
err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
|
|
||||||
err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
|
|
||||||
err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
|
|
||||||
err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
|
|
||||||
err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
|
|
||||||
err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
|
|
||||||
}
|
|
||||||
if (err2)
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHM_INFO:
|
|
||||||
old_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
err = sys_shmctl(first, second, (void __user *)&si);
|
|
||||||
set_fs(old_fs);
|
|
||||||
if (err < 0)
|
|
||||||
break;
|
|
||||||
err2 = put_user(si.used_ids, &uip->used_ids);
|
|
||||||
err2 |= __put_user(si.shm_tot, &uip->shm_tot);
|
|
||||||
err2 |= __put_user(si.shm_rss, &uip->shm_rss);
|
|
||||||
err2 |= __put_user(si.shm_swp, &uip->shm_swp);
|
|
||||||
err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
|
|
||||||
err2 |= __put_user (si.swap_successes, &uip->swap_successes);
|
|
||||||
if (err2)
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems,
|
|
||||||
const struct compat_timespec __user *timeout32)
|
|
||||||
{
|
|
||||||
struct compat_timespec t32;
|
|
||||||
struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64));
|
|
||||||
|
|
||||||
if (copy_from_user(&t32, timeout32, sizeof(t32)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (put_user(t32.tv_sec, &t64->tv_sec) ||
|
|
||||||
put_user(t32.tv_nsec, &t64->tv_nsec))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return sys_semtimedop(semid, tsems, nsems, t64);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage long
|
asmlinkage long
|
||||||
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
||||||
{
|
{
|
||||||
|
@ -918,48 +393,43 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
||||||
switch (call) {
|
switch (call) {
|
||||||
case SEMOP:
|
case SEMOP:
|
||||||
/* struct sembuf is the same on 32 and 64bit :)) */
|
/* struct sembuf is the same on 32 and 64bit :)) */
|
||||||
err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
|
err = sys_semtimedop(first, compat_ptr(ptr), second, NULL);
|
||||||
NULL);
|
|
||||||
break;
|
break;
|
||||||
case SEMTIMEDOP:
|
case SEMTIMEDOP:
|
||||||
err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
|
err = compat_sys_semtimedop(first, compat_ptr(ptr), second,
|
||||||
(const struct compat_timespec __user *)AA(fifth));
|
compat_ptr(fifth));
|
||||||
break;
|
break;
|
||||||
case SEMGET:
|
case SEMGET:
|
||||||
err = sys_semget (first, second, third);
|
err = sys_semget(first, second, third);
|
||||||
break;
|
break;
|
||||||
case SEMCTL:
|
case SEMCTL:
|
||||||
err = do_sys32_semctl (first, second, third,
|
err = compat_sys_semctl(first, second, third, compat_ptr(ptr));
|
||||||
(void __user *)AA(ptr));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSGSND:
|
case MSGSND:
|
||||||
err = do_sys32_msgsnd (first, second, third,
|
err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
|
||||||
(void __user *)AA(ptr));
|
|
||||||
break;
|
break;
|
||||||
case MSGRCV:
|
case MSGRCV:
|
||||||
err = do_sys32_msgrcv (first, second, fifth, third,
|
err = compat_sys_msgrcv(first, second, fifth, third,
|
||||||
version, (void __user *)AA(ptr));
|
version, compat_ptr(ptr));
|
||||||
break;
|
break;
|
||||||
case MSGGET:
|
case MSGGET:
|
||||||
err = sys_msgget ((key_t) first, second);
|
err = sys_msgget((key_t) first, second);
|
||||||
break;
|
break;
|
||||||
case MSGCTL:
|
case MSGCTL:
|
||||||
err = do_sys32_msgctl (first, second, (void __user *)AA(ptr));
|
err = compat_sys_msgctl(first, second, compat_ptr(ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHMAT:
|
case SHMAT:
|
||||||
err = do_sys32_shmat (first, second, third,
|
err = compat_sys_shmat(first, second, third, version,
|
||||||
version, (void __user *)AA(ptr));
|
compat_ptr(ptr));
|
||||||
break;
|
break;
|
||||||
case SHMDT:
|
case SHMDT:
|
||||||
err = sys_shmdt ((char __user *)A(ptr));
|
err = sys_shmdt(compat_ptr(ptr));
|
||||||
break;
|
break;
|
||||||
case SHMGET:
|
case SHMGET:
|
||||||
err = sys_shmget (first, (unsigned)second, third);
|
err = sys_shmget(first, (unsigned)second, third);
|
||||||
break;
|
break;
|
||||||
case SHMCTL:
|
case SHMCTL:
|
||||||
err = do_sys32_shmctl (first, second, (void __user *)AA(ptr));
|
err = compat_sys_shmctl(first, second, compat_ptr(ptr));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
@ -969,18 +439,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
|
#ifdef CONFIG_MIPS32_N32
|
||||||
int shmflg, int32_t __user *addr)
|
asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg)
|
||||||
{
|
{
|
||||||
unsigned long raddr;
|
/* compat_sys_semctl expects a pointer to union semun */
|
||||||
int err;
|
u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
|
||||||
|
if (put_user(ptr_to_compat(arg.__pad), uptr))
|
||||||
err = do_shmat(shmid, shmaddr, shmflg, &raddr);
|
return -EFAULT;
|
||||||
if (err)
|
return compat_sys_semctl(semid, semnum, cmd, uptr);
|
||||||
return err;
|
|
||||||
|
|
||||||
return put_user(raddr, addr);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sysctl_args32
|
struct sysctl_args32
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,8 +149,8 @@ EXPORT(sysn32_call_table)
|
||||||
PTR sys_mincore
|
PTR sys_mincore
|
||||||
PTR sys_madvise
|
PTR sys_madvise
|
||||||
PTR sys_shmget
|
PTR sys_shmget
|
||||||
PTR sys32_shmat
|
PTR sys_shmat
|
||||||
PTR sys_shmctl /* 6030 */
|
PTR compat_sys_shmctl /* 6030 */
|
||||||
PTR sys_dup
|
PTR sys_dup
|
||||||
PTR sys_dup2
|
PTR sys_dup2
|
||||||
PTR sys_pause
|
PTR sys_pause
|
||||||
|
@ -184,12 +184,12 @@ EXPORT(sysn32_call_table)
|
||||||
PTR sys32_newuname
|
PTR sys32_newuname
|
||||||
PTR sys_semget
|
PTR sys_semget
|
||||||
PTR sys_semop
|
PTR sys_semop
|
||||||
PTR sys_semctl
|
PTR sysn32_semctl
|
||||||
PTR sys_shmdt /* 6065 */
|
PTR sys_shmdt /* 6065 */
|
||||||
PTR sys_msgget
|
PTR sys_msgget
|
||||||
PTR sys_msgsnd
|
PTR compat_sys_msgsnd
|
||||||
PTR sys_msgrcv
|
PTR compat_sys_msgrcv
|
||||||
PTR sys_msgctl
|
PTR compat_sys_msgctl
|
||||||
PTR compat_sys_fcntl /* 6070 */
|
PTR compat_sys_fcntl /* 6070 */
|
||||||
PTR sys_flock
|
PTR sys_flock
|
||||||
PTR sys_fsync
|
PTR sys_fsync
|
||||||
|
@ -335,7 +335,7 @@ EXPORT(sysn32_call_table)
|
||||||
PTR compat_sys_fcntl64
|
PTR compat_sys_fcntl64
|
||||||
PTR sys_set_tid_address
|
PTR sys_set_tid_address
|
||||||
PTR sys_restart_syscall
|
PTR sys_restart_syscall
|
||||||
PTR sys_semtimedop /* 6215 */
|
PTR compat_sys_semtimedop /* 6215 */
|
||||||
PTR sys_fadvise64_64
|
PTR sys_fadvise64_64
|
||||||
PTR compat_sys_statfs64
|
PTR compat_sys_statfs64
|
||||||
PTR compat_sys_fstatfs64
|
PTR compat_sys_fstatfs64
|
||||||
|
|
|
@ -172,7 +172,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
|
||||||
|
|
||||||
spin_lock(&smp_call_lock);
|
spin_lock(&smp_call_lock);
|
||||||
call_data = &data;
|
call_data = &data;
|
||||||
mb();
|
smp_mb();
|
||||||
|
|
||||||
/* Send a message to all other CPUs and wait for them to respond */
|
/* Send a message to all other CPUs and wait for them to respond */
|
||||||
for_each_online_cpu(i)
|
for_each_online_cpu(i)
|
||||||
|
@ -204,7 +204,7 @@ void smp_call_function_interrupt(void)
|
||||||
* Notify initiating CPU that I've grabbed the data and am
|
* Notify initiating CPU that I've grabbed the data and am
|
||||||
* about to execute the function.
|
* about to execute the function.
|
||||||
*/
|
*/
|
||||||
mb();
|
smp_mb();
|
||||||
atomic_inc(&call_data->started);
|
atomic_inc(&call_data->started);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -215,7 +215,7 @@ void smp_call_function_interrupt(void)
|
||||||
irq_exit();
|
irq_exit();
|
||||||
|
|
||||||
if (wait) {
|
if (wait) {
|
||||||
mb();
|
smp_mb();
|
||||||
atomic_inc(&call_data->finished);
|
atomic_inc(&call_data->finished);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for MIPS-specific library files..
|
# Makefile for MIPS-specific library files..
|
||||||
#
|
#
|
||||||
|
|
||||||
lib-y += csum_partial.o memset.o watch.o
|
lib-y += memset.o watch.o
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
|
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
|
||||||
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
|
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
|
||||||
|
|
|
@ -1,240 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* Copyright (C) 1998 Ralf Baechle
|
|
||||||
*/
|
|
||||||
#include <asm/asm.h>
|
|
||||||
#include <asm/regdef.h>
|
|
||||||
|
|
||||||
#define ADDC(sum,reg) \
|
|
||||||
addu sum, reg; \
|
|
||||||
sltu v1, sum, reg; \
|
|
||||||
addu sum, v1
|
|
||||||
|
|
||||||
#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
|
|
||||||
lw t0, (offset + 0x00)(src); \
|
|
||||||
lw t1, (offset + 0x04)(src); \
|
|
||||||
lw t2, (offset + 0x08)(src); \
|
|
||||||
lw t3, (offset + 0x0c)(src); \
|
|
||||||
ADDC(sum, t0); \
|
|
||||||
ADDC(sum, t1); \
|
|
||||||
ADDC(sum, t2); \
|
|
||||||
ADDC(sum, t3); \
|
|
||||||
lw t0, (offset + 0x10)(src); \
|
|
||||||
lw t1, (offset + 0x14)(src); \
|
|
||||||
lw t2, (offset + 0x18)(src); \
|
|
||||||
lw t3, (offset + 0x1c)(src); \
|
|
||||||
ADDC(sum, t0); \
|
|
||||||
ADDC(sum, t1); \
|
|
||||||
ADDC(sum, t2); \
|
|
||||||
ADDC(sum, t3); \
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a0: source address
|
|
||||||
* a1: length of the area to checksum
|
|
||||||
* a2: partial checksum
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define src a0
|
|
||||||
#define dest a1
|
|
||||||
#define sum v0
|
|
||||||
|
|
||||||
.text
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
/* unknown src alignment and < 8 bytes to go */
|
|
||||||
small_csumcpy:
|
|
||||||
move a1, t2
|
|
||||||
|
|
||||||
andi t0, a1, 4
|
|
||||||
beqz t0, 1f
|
|
||||||
andi t0, a1, 2
|
|
||||||
|
|
||||||
/* Still a full word to go */
|
|
||||||
ulw t1, (src)
|
|
||||||
addiu src, 4
|
|
||||||
ADDC(sum, t1)
|
|
||||||
|
|
||||||
1: move t1, zero
|
|
||||||
beqz t0, 1f
|
|
||||||
andi t0, a1, 1
|
|
||||||
|
|
||||||
/* Still a halfword to go */
|
|
||||||
ulhu t1, (src)
|
|
||||||
addiu src, 2
|
|
||||||
|
|
||||||
1: beqz t0, 1f
|
|
||||||
sll t1, t1, 16
|
|
||||||
|
|
||||||
lbu t2, (src)
|
|
||||||
nop
|
|
||||||
|
|
||||||
#ifdef __MIPSEB__
|
|
||||||
sll t2, t2, 8
|
|
||||||
#endif
|
|
||||||
or t1, t2
|
|
||||||
|
|
||||||
1: ADDC(sum, t1)
|
|
||||||
|
|
||||||
/* fold checksum */
|
|
||||||
sll v1, sum, 16
|
|
||||||
addu sum, v1
|
|
||||||
sltu v1, sum, v1
|
|
||||||
srl sum, sum, 16
|
|
||||||
addu sum, v1
|
|
||||||
|
|
||||||
/* odd buffer alignment? */
|
|
||||||
beqz t7, 1f
|
|
||||||
nop
|
|
||||||
sll v1, sum, 8
|
|
||||||
srl sum, sum, 8
|
|
||||||
or sum, v1
|
|
||||||
andi sum, 0xffff
|
|
||||||
1:
|
|
||||||
.set reorder
|
|
||||||
/* Add the passed partial csum. */
|
|
||||||
ADDC(sum, a2)
|
|
||||||
jr ra
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
LEAF(csum_partial)
|
|
||||||
move sum, zero
|
|
||||||
move t7, zero
|
|
||||||
|
|
||||||
sltiu t8, a1, 0x8
|
|
||||||
bnez t8, small_csumcpy /* < 8 bytes to copy */
|
|
||||||
move t2, a1
|
|
||||||
|
|
||||||
beqz a1, out
|
|
||||||
andi t7, src, 0x1 /* odd buffer? */
|
|
||||||
|
|
||||||
hword_align:
|
|
||||||
beqz t7, word_align
|
|
||||||
andi t8, src, 0x2
|
|
||||||
|
|
||||||
lbu t0, (src)
|
|
||||||
subu a1, a1, 0x1
|
|
||||||
#ifdef __MIPSEL__
|
|
||||||
sll t0, t0, 8
|
|
||||||
#endif
|
|
||||||
ADDC(sum, t0)
|
|
||||||
addu src, src, 0x1
|
|
||||||
andi t8, src, 0x2
|
|
||||||
|
|
||||||
word_align:
|
|
||||||
beqz t8, dword_align
|
|
||||||
sltiu t8, a1, 56
|
|
||||||
|
|
||||||
lhu t0, (src)
|
|
||||||
subu a1, a1, 0x2
|
|
||||||
ADDC(sum, t0)
|
|
||||||
sltiu t8, a1, 56
|
|
||||||
addu src, src, 0x2
|
|
||||||
|
|
||||||
dword_align:
|
|
||||||
bnez t8, do_end_words
|
|
||||||
move t8, a1
|
|
||||||
|
|
||||||
andi t8, src, 0x4
|
|
||||||
beqz t8, qword_align
|
|
||||||
andi t8, src, 0x8
|
|
||||||
|
|
||||||
lw t0, 0x00(src)
|
|
||||||
subu a1, a1, 0x4
|
|
||||||
ADDC(sum, t0)
|
|
||||||
addu src, src, 0x4
|
|
||||||
andi t8, src, 0x8
|
|
||||||
|
|
||||||
qword_align:
|
|
||||||
beqz t8, oword_align
|
|
||||||
andi t8, src, 0x10
|
|
||||||
|
|
||||||
lw t0, 0x00(src)
|
|
||||||
lw t1, 0x04(src)
|
|
||||||
subu a1, a1, 0x8
|
|
||||||
ADDC(sum, t0)
|
|
||||||
ADDC(sum, t1)
|
|
||||||
addu src, src, 0x8
|
|
||||||
andi t8, src, 0x10
|
|
||||||
|
|
||||||
oword_align:
|
|
||||||
beqz t8, begin_movement
|
|
||||||
srl t8, a1, 0x7
|
|
||||||
|
|
||||||
lw t3, 0x08(src)
|
|
||||||
lw t4, 0x0c(src)
|
|
||||||
lw t0, 0x00(src)
|
|
||||||
lw t1, 0x04(src)
|
|
||||||
ADDC(sum, t3)
|
|
||||||
ADDC(sum, t4)
|
|
||||||
ADDC(sum, t0)
|
|
||||||
ADDC(sum, t1)
|
|
||||||
subu a1, a1, 0x10
|
|
||||||
addu src, src, 0x10
|
|
||||||
srl t8, a1, 0x7
|
|
||||||
|
|
||||||
begin_movement:
|
|
||||||
beqz t8, 1f
|
|
||||||
andi t2, a1, 0x40
|
|
||||||
|
|
||||||
move_128bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
|
|
||||||
CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
|
|
||||||
CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
|
|
||||||
CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
|
|
||||||
subu t8, t8, 0x01
|
|
||||||
bnez t8, move_128bytes
|
|
||||||
addu src, src, 0x80
|
|
||||||
|
|
||||||
1:
|
|
||||||
beqz t2, 1f
|
|
||||||
andi t2, a1, 0x20
|
|
||||||
|
|
||||||
move_64bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
|
|
||||||
CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
|
|
||||||
addu src, src, 0x40
|
|
||||||
|
|
||||||
1:
|
|
||||||
beqz t2, do_end_words
|
|
||||||
andi t8, a1, 0x1c
|
|
||||||
|
|
||||||
move_32bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
|
|
||||||
andi t8, a1, 0x1c
|
|
||||||
addu src, src, 0x20
|
|
||||||
|
|
||||||
do_end_words:
|
|
||||||
beqz t8, maybe_end_cruft
|
|
||||||
srl t8, t8, 0x2
|
|
||||||
|
|
||||||
end_words:
|
|
||||||
lw t0, (src)
|
|
||||||
subu t8, t8, 0x1
|
|
||||||
ADDC(sum, t0)
|
|
||||||
bnez t8, end_words
|
|
||||||
addu src, src, 0x4
|
|
||||||
|
|
||||||
maybe_end_cruft:
|
|
||||||
andi t2, a1, 0x3
|
|
||||||
|
|
||||||
small_memcpy:
|
|
||||||
j small_csumcpy; move a1, t2
|
|
||||||
beqz t2, out
|
|
||||||
move a1, t2
|
|
||||||
|
|
||||||
end_bytes:
|
|
||||||
lb t0, (src)
|
|
||||||
subu a1, a1, 0x1
|
|
||||||
bnez a2, end_bytes
|
|
||||||
addu src, src, 0x1
|
|
||||||
|
|
||||||
out:
|
|
||||||
jr ra
|
|
||||||
move v0, sum
|
|
||||||
END(csum_partial)
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for MIPS-specific library files..
|
# Makefile for MIPS-specific library files..
|
||||||
#
|
#
|
||||||
|
|
||||||
lib-y += csum_partial.o memset.o watch.o
|
lib-y += memset.o watch.o
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
|
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
|
||||||
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
|
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
|
||||||
|
|
|
@ -1,242 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* Quick'n'dirty IP checksum ...
|
|
||||||
*
|
|
||||||
* Copyright (C) 1998, 1999 Ralf Baechle
|
|
||||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
|
||||||
*/
|
|
||||||
#include <asm/asm.h>
|
|
||||||
#include <asm/regdef.h>
|
|
||||||
|
|
||||||
#define ADDC(sum,reg) \
|
|
||||||
addu sum, reg; \
|
|
||||||
sltu v1, sum, reg; \
|
|
||||||
addu sum, v1
|
|
||||||
|
|
||||||
#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
|
|
||||||
lw t0, (offset + 0x00)(src); \
|
|
||||||
lw t1, (offset + 0x04)(src); \
|
|
||||||
lw t2, (offset + 0x08)(src); \
|
|
||||||
lw t3, (offset + 0x0c)(src); \
|
|
||||||
ADDC(sum, t0); \
|
|
||||||
ADDC(sum, t1); \
|
|
||||||
ADDC(sum, t2); \
|
|
||||||
ADDC(sum, t3); \
|
|
||||||
lw t0, (offset + 0x10)(src); \
|
|
||||||
lw t1, (offset + 0x14)(src); \
|
|
||||||
lw t2, (offset + 0x18)(src); \
|
|
||||||
lw t3, (offset + 0x1c)(src); \
|
|
||||||
ADDC(sum, t0); \
|
|
||||||
ADDC(sum, t1); \
|
|
||||||
ADDC(sum, t2); \
|
|
||||||
ADDC(sum, t3); \
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a0: source address
|
|
||||||
* a1: length of the area to checksum
|
|
||||||
* a2: partial checksum
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define src a0
|
|
||||||
#define sum v0
|
|
||||||
|
|
||||||
.text
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
/* unknown src alignment and < 8 bytes to go */
|
|
||||||
small_csumcpy:
|
|
||||||
move a1, ta2
|
|
||||||
|
|
||||||
andi ta0, a1, 4
|
|
||||||
beqz ta0, 1f
|
|
||||||
andi ta0, a1, 2
|
|
||||||
|
|
||||||
/* Still a full word to go */
|
|
||||||
ulw ta1, (src)
|
|
||||||
daddiu src, 4
|
|
||||||
ADDC(sum, ta1)
|
|
||||||
|
|
||||||
1: move ta1, zero
|
|
||||||
beqz ta0, 1f
|
|
||||||
andi ta0, a1, 1
|
|
||||||
|
|
||||||
/* Still a halfword to go */
|
|
||||||
ulhu ta1, (src)
|
|
||||||
daddiu src, 2
|
|
||||||
|
|
||||||
1: beqz ta0, 1f
|
|
||||||
sll ta1, ta1, 16
|
|
||||||
|
|
||||||
lbu ta2, (src)
|
|
||||||
nop
|
|
||||||
|
|
||||||
#ifdef __MIPSEB__
|
|
||||||
sll ta2, ta2, 8
|
|
||||||
#endif
|
|
||||||
or ta1, ta2
|
|
||||||
|
|
||||||
1: ADDC(sum, ta1)
|
|
||||||
|
|
||||||
/* fold checksum */
|
|
||||||
sll v1, sum, 16
|
|
||||||
addu sum, v1
|
|
||||||
sltu v1, sum, v1
|
|
||||||
srl sum, sum, 16
|
|
||||||
addu sum, v1
|
|
||||||
|
|
||||||
/* odd buffer alignment? */
|
|
||||||
beqz t3, 1f
|
|
||||||
nop
|
|
||||||
sll v1, sum, 8
|
|
||||||
srl sum, sum, 8
|
|
||||||
or sum, v1
|
|
||||||
andi sum, 0xffff
|
|
||||||
1:
|
|
||||||
.set reorder
|
|
||||||
/* Add the passed partial csum. */
|
|
||||||
ADDC(sum, a2)
|
|
||||||
jr ra
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
LEAF(csum_partial)
|
|
||||||
move sum, zero
|
|
||||||
move t3, zero
|
|
||||||
|
|
||||||
sltiu t8, a1, 0x8
|
|
||||||
bnez t8, small_csumcpy /* < 8 bytes to copy */
|
|
||||||
move ta2, a1
|
|
||||||
|
|
||||||
beqz a1, out
|
|
||||||
andi t3, src, 0x1 /* odd buffer? */
|
|
||||||
|
|
||||||
hword_align:
|
|
||||||
beqz t3, word_align
|
|
||||||
andi t8, src, 0x2
|
|
||||||
|
|
||||||
lbu ta0, (src)
|
|
||||||
dsubu a1, a1, 0x1
|
|
||||||
#ifdef __MIPSEL__
|
|
||||||
sll ta0, ta0, 8
|
|
||||||
#endif
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
daddu src, src, 0x1
|
|
||||||
andi t8, src, 0x2
|
|
||||||
|
|
||||||
word_align:
|
|
||||||
beqz t8, dword_align
|
|
||||||
sltiu t8, a1, 56
|
|
||||||
|
|
||||||
lhu ta0, (src)
|
|
||||||
dsubu a1, a1, 0x2
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
sltiu t8, a1, 56
|
|
||||||
daddu src, src, 0x2
|
|
||||||
|
|
||||||
dword_align:
|
|
||||||
bnez t8, do_end_words
|
|
||||||
move t8, a1
|
|
||||||
|
|
||||||
andi t8, src, 0x4
|
|
||||||
beqz t8, qword_align
|
|
||||||
andi t8, src, 0x8
|
|
||||||
|
|
||||||
lw ta0, 0x00(src)
|
|
||||||
dsubu a1, a1, 0x4
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
daddu src, src, 0x4
|
|
||||||
andi t8, src, 0x8
|
|
||||||
|
|
||||||
qword_align:
|
|
||||||
beqz t8, oword_align
|
|
||||||
andi t8, src, 0x10
|
|
||||||
|
|
||||||
lw ta0, 0x00(src)
|
|
||||||
lw ta1, 0x04(src)
|
|
||||||
dsubu a1, a1, 0x8
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
ADDC(sum, ta1)
|
|
||||||
daddu src, src, 0x8
|
|
||||||
andi t8, src, 0x10
|
|
||||||
|
|
||||||
oword_align:
|
|
||||||
beqz t8, begin_movement
|
|
||||||
dsrl t8, a1, 0x7
|
|
||||||
|
|
||||||
lw ta3, 0x08(src)
|
|
||||||
lw t0, 0x0c(src)
|
|
||||||
lw ta0, 0x00(src)
|
|
||||||
lw ta1, 0x04(src)
|
|
||||||
ADDC(sum, ta3)
|
|
||||||
ADDC(sum, t0)
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
ADDC(sum, ta1)
|
|
||||||
dsubu a1, a1, 0x10
|
|
||||||
daddu src, src, 0x10
|
|
||||||
dsrl t8, a1, 0x7
|
|
||||||
|
|
||||||
begin_movement:
|
|
||||||
beqz t8, 1f
|
|
||||||
andi ta2, a1, 0x40
|
|
||||||
|
|
||||||
move_128bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
|
|
||||||
CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
|
|
||||||
CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0)
|
|
||||||
CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0)
|
|
||||||
dsubu t8, t8, 0x01
|
|
||||||
bnez t8, move_128bytes
|
|
||||||
daddu src, src, 0x80
|
|
||||||
|
|
||||||
1:
|
|
||||||
beqz ta2, 1f
|
|
||||||
andi ta2, a1, 0x20
|
|
||||||
|
|
||||||
move_64bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
|
|
||||||
CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
|
|
||||||
daddu src, src, 0x40
|
|
||||||
|
|
||||||
1:
|
|
||||||
beqz ta2, do_end_words
|
|
||||||
andi t8, a1, 0x1c
|
|
||||||
|
|
||||||
move_32bytes:
|
|
||||||
CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
|
|
||||||
andi t8, a1, 0x1c
|
|
||||||
daddu src, src, 0x20
|
|
||||||
|
|
||||||
do_end_words:
|
|
||||||
beqz t8, maybe_end_cruft
|
|
||||||
dsrl t8, t8, 0x2
|
|
||||||
|
|
||||||
end_words:
|
|
||||||
lw ta0, (src)
|
|
||||||
dsubu t8, t8, 0x1
|
|
||||||
ADDC(sum, ta0)
|
|
||||||
bnez t8, end_words
|
|
||||||
daddu src, src, 0x4
|
|
||||||
|
|
||||||
maybe_end_cruft:
|
|
||||||
andi ta2, a1, 0x3
|
|
||||||
|
|
||||||
small_memcpy:
|
|
||||||
j small_csumcpy; move a1, ta2 /* XXX ??? */
|
|
||||||
beqz t2, out
|
|
||||||
move a1, ta2
|
|
||||||
|
|
||||||
end_bytes:
|
|
||||||
lb ta0, (src)
|
|
||||||
dsubu a1, a1, 0x1
|
|
||||||
bnez a2, end_bytes
|
|
||||||
daddu src, src, 0x1
|
|
||||||
|
|
||||||
out:
|
|
||||||
jr ra
|
|
||||||
move v0, sum
|
|
||||||
END(csum_partial)
|
|
|
@ -2,8 +2,8 @@
|
||||||
# Makefile for MIPS-specific library files..
|
# Makefile for MIPS-specific library files..
|
||||||
#
|
#
|
||||||
|
|
||||||
lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
|
lib-y += csum_partial.o csum_partial_copy.o memcpy.o promlib.o \
|
||||||
strnlen_user.o uncached.o
|
strlen_user.o strncpy_user.o strnlen_user.o uncached.o
|
||||||
|
|
||||||
obj-y += iomap.o
|
obj-y += iomap.o
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Quick'n'dirty IP checksum ...
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998, 1999 Ralf Baechle
|
||||||
|
* Copyright (C) 1999 Silicon Graphics, Inc.
|
||||||
|
*/
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <asm/regdef.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_64BIT
|
||||||
|
#define T0 ta0
|
||||||
|
#define T1 ta1
|
||||||
|
#define T2 ta2
|
||||||
|
#define T3 ta3
|
||||||
|
#define T4 t0
|
||||||
|
#define T7 t3
|
||||||
|
#else
|
||||||
|
#define T0 t0
|
||||||
|
#define T1 t1
|
||||||
|
#define T2 t2
|
||||||
|
#define T3 t3
|
||||||
|
#define T4 t4
|
||||||
|
#define T7 t7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ADDC(sum,reg) \
|
||||||
|
addu sum, reg; \
|
||||||
|
sltu v1, sum, reg; \
|
||||||
|
addu sum, v1
|
||||||
|
|
||||||
|
#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
|
||||||
|
lw _t0, (offset + 0x00)(src); \
|
||||||
|
lw _t1, (offset + 0x04)(src); \
|
||||||
|
lw _t2, (offset + 0x08)(src); \
|
||||||
|
lw _t3, (offset + 0x0c)(src); \
|
||||||
|
ADDC(sum, _t0); \
|
||||||
|
ADDC(sum, _t1); \
|
||||||
|
ADDC(sum, _t2); \
|
||||||
|
ADDC(sum, _t3); \
|
||||||
|
lw _t0, (offset + 0x10)(src); \
|
||||||
|
lw _t1, (offset + 0x14)(src); \
|
||||||
|
lw _t2, (offset + 0x18)(src); \
|
||||||
|
lw _t3, (offset + 0x1c)(src); \
|
||||||
|
ADDC(sum, _t0); \
|
||||||
|
ADDC(sum, _t1); \
|
||||||
|
ADDC(sum, _t2); \
|
||||||
|
ADDC(sum, _t3); \
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a0: source address
|
||||||
|
* a1: length of the area to checksum
|
||||||
|
* a2: partial checksum
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define src a0
|
||||||
|
#define sum v0
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
/* unknown src alignment and < 8 bytes to go */
|
||||||
|
small_csumcpy:
|
||||||
|
move a1, T2
|
||||||
|
|
||||||
|
andi T0, a1, 4
|
||||||
|
beqz T0, 1f
|
||||||
|
andi T0, a1, 2
|
||||||
|
|
||||||
|
/* Still a full word to go */
|
||||||
|
ulw T1, (src)
|
||||||
|
PTR_ADDIU src, 4
|
||||||
|
ADDC(sum, T1)
|
||||||
|
|
||||||
|
1: move T1, zero
|
||||||
|
beqz T0, 1f
|
||||||
|
andi T0, a1, 1
|
||||||
|
|
||||||
|
/* Still a halfword to go */
|
||||||
|
ulhu T1, (src)
|
||||||
|
PTR_ADDIU src, 2
|
||||||
|
|
||||||
|
1: beqz T0, 1f
|
||||||
|
sll T1, T1, 16
|
||||||
|
|
||||||
|
lbu T2, (src)
|
||||||
|
nop
|
||||||
|
|
||||||
|
#ifdef __MIPSEB__
|
||||||
|
sll T2, T2, 8
|
||||||
|
#endif
|
||||||
|
or T1, T2
|
||||||
|
|
||||||
|
1: ADDC(sum, T1)
|
||||||
|
|
||||||
|
/* fold checksum */
|
||||||
|
sll v1, sum, 16
|
||||||
|
addu sum, v1
|
||||||
|
sltu v1, sum, v1
|
||||||
|
srl sum, sum, 16
|
||||||
|
addu sum, v1
|
||||||
|
|
||||||
|
/* odd buffer alignment? */
|
||||||
|
beqz T7, 1f
|
||||||
|
nop
|
||||||
|
sll v1, sum, 8
|
||||||
|
srl sum, sum, 8
|
||||||
|
or sum, v1
|
||||||
|
andi sum, 0xffff
|
||||||
|
1:
|
||||||
|
.set reorder
|
||||||
|
/* Add the passed partial csum. */
|
||||||
|
ADDC(sum, a2)
|
||||||
|
jr ra
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.align 5
|
||||||
|
LEAF(csum_partial)
|
||||||
|
move sum, zero
|
||||||
|
move T7, zero
|
||||||
|
|
||||||
|
sltiu t8, a1, 0x8
|
||||||
|
bnez t8, small_csumcpy /* < 8 bytes to copy */
|
||||||
|
move T2, a1
|
||||||
|
|
||||||
|
beqz a1, out
|
||||||
|
andi T7, src, 0x1 /* odd buffer? */
|
||||||
|
|
||||||
|
hword_align:
|
||||||
|
beqz T7, word_align
|
||||||
|
andi t8, src, 0x2
|
||||||
|
|
||||||
|
lbu T0, (src)
|
||||||
|
LONG_SUBU a1, a1, 0x1
|
||||||
|
#ifdef __MIPSEL__
|
||||||
|
sll T0, T0, 8
|
||||||
|
#endif
|
||||||
|
ADDC(sum, T0)
|
||||||
|
PTR_ADDU src, src, 0x1
|
||||||
|
andi t8, src, 0x2
|
||||||
|
|
||||||
|
word_align:
|
||||||
|
beqz t8, dword_align
|
||||||
|
sltiu t8, a1, 56
|
||||||
|
|
||||||
|
lhu T0, (src)
|
||||||
|
LONG_SUBU a1, a1, 0x2
|
||||||
|
ADDC(sum, T0)
|
||||||
|
sltiu t8, a1, 56
|
||||||
|
PTR_ADDU src, src, 0x2
|
||||||
|
|
||||||
|
dword_align:
|
||||||
|
bnez t8, do_end_words
|
||||||
|
move t8, a1
|
||||||
|
|
||||||
|
andi t8, src, 0x4
|
||||||
|
beqz t8, qword_align
|
||||||
|
andi t8, src, 0x8
|
||||||
|
|
||||||
|
lw T0, 0x00(src)
|
||||||
|
LONG_SUBU a1, a1, 0x4
|
||||||
|
ADDC(sum, T0)
|
||||||
|
PTR_ADDU src, src, 0x4
|
||||||
|
andi t8, src, 0x8
|
||||||
|
|
||||||
|
qword_align:
|
||||||
|
beqz t8, oword_align
|
||||||
|
andi t8, src, 0x10
|
||||||
|
|
||||||
|
lw T0, 0x00(src)
|
||||||
|
lw T1, 0x04(src)
|
||||||
|
LONG_SUBU a1, a1, 0x8
|
||||||
|
ADDC(sum, T0)
|
||||||
|
ADDC(sum, T1)
|
||||||
|
PTR_ADDU src, src, 0x8
|
||||||
|
andi t8, src, 0x10
|
||||||
|
|
||||||
|
oword_align:
|
||||||
|
beqz t8, begin_movement
|
||||||
|
LONG_SRL t8, a1, 0x7
|
||||||
|
|
||||||
|
lw T3, 0x08(src)
|
||||||
|
lw T4, 0x0c(src)
|
||||||
|
lw T0, 0x00(src)
|
||||||
|
lw T1, 0x04(src)
|
||||||
|
ADDC(sum, T3)
|
||||||
|
ADDC(sum, T4)
|
||||||
|
ADDC(sum, T0)
|
||||||
|
ADDC(sum, T1)
|
||||||
|
LONG_SUBU a1, a1, 0x10
|
||||||
|
PTR_ADDU src, src, 0x10
|
||||||
|
LONG_SRL t8, a1, 0x7
|
||||||
|
|
||||||
|
begin_movement:
|
||||||
|
beqz t8, 1f
|
||||||
|
andi T2, a1, 0x40
|
||||||
|
|
||||||
|
move_128bytes:
|
||||||
|
CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
|
||||||
|
CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
|
||||||
|
CSUM_BIGCHUNK(src, 0x40, sum, T0, T1, T3, T4)
|
||||||
|
CSUM_BIGCHUNK(src, 0x60, sum, T0, T1, T3, T4)
|
||||||
|
LONG_SUBU t8, t8, 0x01
|
||||||
|
bnez t8, move_128bytes
|
||||||
|
PTR_ADDU src, src, 0x80
|
||||||
|
|
||||||
|
1:
|
||||||
|
beqz T2, 1f
|
||||||
|
andi T2, a1, 0x20
|
||||||
|
|
||||||
|
move_64bytes:
|
||||||
|
CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
|
||||||
|
CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
|
||||||
|
PTR_ADDU src, src, 0x40
|
||||||
|
|
||||||
|
1:
|
||||||
|
beqz T2, do_end_words
|
||||||
|
andi t8, a1, 0x1c
|
||||||
|
|
||||||
|
move_32bytes:
|
||||||
|
CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
|
||||||
|
andi t8, a1, 0x1c
|
||||||
|
PTR_ADDU src, src, 0x20
|
||||||
|
|
||||||
|
do_end_words:
|
||||||
|
beqz t8, maybe_end_cruft
|
||||||
|
LONG_SRL t8, t8, 0x2
|
||||||
|
|
||||||
|
end_words:
|
||||||
|
lw T0, (src)
|
||||||
|
LONG_SUBU t8, t8, 0x1
|
||||||
|
ADDC(sum, T0)
|
||||||
|
bnez t8, end_words
|
||||||
|
PTR_ADDU src, src, 0x4
|
||||||
|
|
||||||
|
maybe_end_cruft:
|
||||||
|
andi T2, a1, 0x3
|
||||||
|
|
||||||
|
small_memcpy:
|
||||||
|
j small_csumcpy; move a1, T2 /* XXX ??? */
|
||||||
|
beqz t2, out
|
||||||
|
move a1, T2
|
||||||
|
|
||||||
|
end_bytes:
|
||||||
|
lb T0, (src)
|
||||||
|
LONG_SUBU a1, a1, 0x1
|
||||||
|
bnez a2, end_bytes
|
||||||
|
PTR_ADDU src, src, 0x1
|
||||||
|
|
||||||
|
out:
|
||||||
|
jr ra
|
||||||
|
move v0, sum
|
||||||
|
END(csum_partial)
|
|
@ -43,7 +43,7 @@
|
||||||
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
||||||
#include <asm/sibyte/sb1250_regs.h>
|
#include <asm/sibyte/sb1250_regs.h>
|
||||||
#else
|
#else
|
||||||
#error invalid SiByte board configuation
|
#error invalid SiByte board configuration
|
||||||
#endif
|
#endif
|
||||||
#include <asm/sibyte/sb1250_genbus.h>
|
#include <asm/sibyte/sb1250_genbus.h>
|
||||||
#include <asm/sibyte/board.h>
|
#include <asm/sibyte/board.h>
|
||||||
|
@ -53,7 +53,7 @@ extern void bcm1480_setup(void);
|
||||||
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
||||||
extern void sb1250_setup(void);
|
extern void sb1250_setup(void);
|
||||||
#else
|
#else
|
||||||
#error invalid SiByte board configuation
|
#error invalid SiByte board configuration
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int xicor_probe(void);
|
extern int xicor_probe(void);
|
||||||
|
@ -90,7 +90,7 @@ void __init plat_timer_setup(struct irqaction *irq)
|
||||||
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
||||||
sb1250_time_init();
|
sb1250_time_init();
|
||||||
#else
|
#else
|
||||||
#error invalid SiByte board configuation
|
#error invalid SiByte board configuration
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ void __init plat_mem_setup(void)
|
||||||
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
|
||||||
sb1250_setup();
|
sb1250_setup();
|
||||||
#else
|
#else
|
||||||
#error invalid SiByte board configuation
|
#error invalid SiByte board configuration
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
panic_timeout = 5; /* For debug. */
|
panic_timeout = 5; /* For debug. */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#define _ASM_ATOMIC_H
|
#define _ASM_ATOMIC_H
|
||||||
|
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
|
||||||
|
@ -130,6 +131,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -140,7 +143,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
|
||||||
" sc %0, %2 \n"
|
" sc %0, %2 \n"
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" addu %0, %1, %3 \n"
|
" addu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -155,7 +157,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
|
||||||
" sc %0, %2 \n"
|
" sc %0, %2 \n"
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" addu %0, %1, %3 \n"
|
" addu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -170,6 +171,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +180,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -187,7 +192,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
|
||||||
" sc %0, %2 \n"
|
" sc %0, %2 \n"
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -202,7 +206,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
|
||||||
" sc %0, %2 \n"
|
" sc %0, %2 \n"
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -217,6 +220,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +237,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -245,7 +252,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
" sync \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
|
@ -264,7 +270,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
" sync \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
|
@ -281,6 +286,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +382,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
|
|
||||||
typedef struct { volatile __s64 counter; } atomic64_t;
|
typedef struct { volatile long counter; } atomic64_t;
|
||||||
|
|
||||||
#define ATOMIC64_INIT(i) { (i) }
|
#define ATOMIC64_INIT(i) { (i) }
|
||||||
|
|
||||||
|
@ -484,6 +491,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -494,7 +503,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
||||||
" scd %0, %2 \n"
|
" scd %0, %2 \n"
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" addu %0, %1, %3 \n"
|
" addu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -509,7 +517,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
||||||
" scd %0, %2 \n"
|
" scd %0, %2 \n"
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" addu %0, %1, %3 \n"
|
" addu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -524,6 +531,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,6 +540,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -541,7 +552,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
||||||
" scd %0, %2 \n"
|
" scd %0, %2 \n"
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -556,7 +566,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
||||||
" scd %0, %2 \n"
|
" scd %0, %2 \n"
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" subu %0, %1, %3 \n"
|
" subu %0, %1, %3 \n"
|
||||||
" sync \n"
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
: "Ir" (i), "m" (v->counter)
|
: "Ir" (i), "m" (v->counter)
|
||||||
|
@ -571,6 +580,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,6 +597,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
|
@ -599,7 +612,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
||||||
" beqzl %0, 1b \n"
|
" beqzl %0, 1b \n"
|
||||||
" dsubu %0, %1, %3 \n"
|
" dsubu %0, %1, %3 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
" sync \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
|
@ -618,7 +630,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
||||||
" beqz %0, 1b \n"
|
" beqz %0, 1b \n"
|
||||||
" dsubu %0, %1, %3 \n"
|
" dsubu %0, %1, %3 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
" sync \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||||
|
@ -635,6 +646,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_BARRIER_H
|
||||||
|
#define __ASM_BARRIER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read_barrier_depends - Flush all pending reads that subsequents reads
|
||||||
|
* depend on.
|
||||||
|
*
|
||||||
|
* No data-dependent reads from memory-like regions are ever reordered
|
||||||
|
* over this barrier. All reads preceding this primitive are guaranteed
|
||||||
|
* to access memory (but not necessarily other CPUs' caches) before any
|
||||||
|
* reads following this primitive that depend on the data return by
|
||||||
|
* any of the preceding reads. This primitive is much lighter weight than
|
||||||
|
* rmb() on most CPUs, and is never heavier weight than is
|
||||||
|
* rmb().
|
||||||
|
*
|
||||||
|
* These ordering constraints are respected by both the local CPU
|
||||||
|
* and the compiler.
|
||||||
|
*
|
||||||
|
* Ordering is not guaranteed by anything other than these primitives,
|
||||||
|
* not even by data dependencies. See the documentation for
|
||||||
|
* memory_barrier() for examples and URLs to more information.
|
||||||
|
*
|
||||||
|
* For example, the following code would force ordering (the initial
|
||||||
|
* value of "a" is zero, "b" is one, and "p" is "&a"):
|
||||||
|
*
|
||||||
|
* <programlisting>
|
||||||
|
* CPU 0 CPU 1
|
||||||
|
*
|
||||||
|
* b = 2;
|
||||||
|
* memory_barrier();
|
||||||
|
* p = &b; q = p;
|
||||||
|
* read_barrier_depends();
|
||||||
|
* d = *q;
|
||||||
|
* </programlisting>
|
||||||
|
*
|
||||||
|
* because the read of "*q" depends on the read of "p" and these
|
||||||
|
* two reads are separated by a read_barrier_depends(). However,
|
||||||
|
* the following code, with the same initial values for "a" and "b":
|
||||||
|
*
|
||||||
|
* <programlisting>
|
||||||
|
* CPU 0 CPU 1
|
||||||
|
*
|
||||||
|
* a = 2;
|
||||||
|
* memory_barrier();
|
||||||
|
* b = 3; y = b;
|
||||||
|
* read_barrier_depends();
|
||||||
|
* x = a;
|
||||||
|
* </programlisting>
|
||||||
|
*
|
||||||
|
* does not enforce ordering, since there is no data dependency between
|
||||||
|
* the read of "a" and the read of "b". Therefore, on some CPUs, such
|
||||||
|
* as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
|
||||||
|
* in cases like this where there are no data dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define read_barrier_depends() do { } while(0)
|
||||||
|
#define smp_read_barrier_depends() do { } while(0)
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_HAS_SYNC
|
||||||
|
#define __sync() \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
".set push\n\t" \
|
||||||
|
".set noreorder\n\t" \
|
||||||
|
".set mips2\n\t" \
|
||||||
|
"sync\n\t" \
|
||||||
|
".set pop" \
|
||||||
|
: /* no output */ \
|
||||||
|
: /* no input */ \
|
||||||
|
: "memory")
|
||||||
|
#else
|
||||||
|
#define __sync() do { } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __fast_iob() \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
".set push\n\t" \
|
||||||
|
".set noreorder\n\t" \
|
||||||
|
"lw $0,%0\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
".set pop" \
|
||||||
|
: /* no output */ \
|
||||||
|
: "m" (*(int *)CKSEG1) \
|
||||||
|
: "memory")
|
||||||
|
|
||||||
|
#define fast_wmb() __sync()
|
||||||
|
#define fast_rmb() __sync()
|
||||||
|
#define fast_mb() __sync()
|
||||||
|
#define fast_iob() \
|
||||||
|
do { \
|
||||||
|
__sync(); \
|
||||||
|
__fast_iob(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_HAS_WB
|
||||||
|
|
||||||
|
#include <asm/wbflush.h>
|
||||||
|
|
||||||
|
#define wmb() fast_wmb()
|
||||||
|
#define rmb() fast_rmb()
|
||||||
|
#define mb() wbflush()
|
||||||
|
#define iob() wbflush()
|
||||||
|
|
||||||
|
#else /* !CONFIG_CPU_HAS_WB */
|
||||||
|
|
||||||
|
#define wmb() fast_wmb()
|
||||||
|
#define rmb() fast_rmb()
|
||||||
|
#define mb() fast_mb()
|
||||||
|
#define iob() fast_iob()
|
||||||
|
|
||||||
|
#endif /* !CONFIG_CPU_HAS_WB */
|
||||||
|
|
||||||
|
#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
|
||||||
|
#define __WEAK_ORDERING_MB " sync \n"
|
||||||
|
#else
|
||||||
|
#define __WEAK_ORDERING_MB " \n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||||
|
#define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||||
|
#define smp_wmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||||
|
|
||||||
|
#define set_mb(var, value) \
|
||||||
|
do { var = value; smp_mb(); } while (0)
|
||||||
|
|
||||||
|
#endif /* __ASM_BARRIER_H */
|
|
@ -3,7 +3,7 @@
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org)
|
* Copyright (c) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
|
||||||
* Copyright (c) 1999, 2000 Silicon Graphics, Inc.
|
* Copyright (c) 1999, 2000 Silicon Graphics, Inc.
|
||||||
*/
|
*/
|
||||||
#ifndef _ASM_BITOPS_H
|
#ifndef _ASM_BITOPS_H
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/bug.h>
|
#include <asm/bug.h>
|
||||||
#include <asm/byteorder.h> /* sigh ... */
|
#include <asm/byteorder.h> /* sigh ... */
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
|
@ -204,9 +205,6 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||||
" " __SC "%2, %1 \n"
|
" " __SC "%2, %1 \n"
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -226,9 +224,6 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||||
" " __SC "%2, %1 \n"
|
" " __SC "%2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -250,6 +245,8 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -275,9 +272,6 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||||
" " __SC "%2, %1 \n"
|
" " __SC "%2, %1 \n"
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -298,9 +292,6 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||||
" " __SC "%2, %1 \n"
|
" " __SC "%2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -322,6 +313,8 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -346,9 +339,6 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||||
" " __SC "%2, %1 \n"
|
" " __SC "%2, %1 \n"
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -368,9 +358,6 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||||
" " __SC "\t%2, %1 \n"
|
" " __SC "\t%2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
" and %2, %0, %3 \n"
|
" and %2, %0, %3 \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
: "=&r" (temp), "=m" (*m), "=&r" (res)
|
||||||
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
|
||||||
|
@ -391,6 +378,8 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <asm-generic/bitops/non-atomic.h>
|
#include <asm-generic/bitops/non-atomic.h>
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef struct {
|
||||||
s32 val[2];
|
s32 val[2];
|
||||||
} compat_fsid_t;
|
} compat_fsid_t;
|
||||||
typedef s32 compat_timer_t;
|
typedef s32 compat_timer_t;
|
||||||
|
typedef s32 compat_key_t;
|
||||||
|
|
||||||
typedef s32 compat_int_t;
|
typedef s32 compat_int_t;
|
||||||
typedef s32 compat_long_t;
|
typedef s32 compat_long_t;
|
||||||
|
@ -146,4 +147,71 @@ static inline void __user *compat_alloc_user_space(long len)
|
||||||
return (void __user *) (regs->regs[29] - len);
|
return (void __user *) (regs->regs[29] - len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct compat_ipc64_perm {
|
||||||
|
compat_key_t key;
|
||||||
|
__compat_uid32_t uid;
|
||||||
|
__compat_gid32_t gid;
|
||||||
|
__compat_uid32_t cuid;
|
||||||
|
__compat_gid32_t cgid;
|
||||||
|
compat_mode_t mode;
|
||||||
|
unsigned short seq;
|
||||||
|
unsigned short __pad2;
|
||||||
|
compat_ulong_t __unused1;
|
||||||
|
compat_ulong_t __unused2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct compat_semid64_ds {
|
||||||
|
struct compat_ipc64_perm sem_perm;
|
||||||
|
compat_time_t sem_otime;
|
||||||
|
compat_time_t sem_ctime;
|
||||||
|
compat_ulong_t sem_nsems;
|
||||||
|
compat_ulong_t __unused1;
|
||||||
|
compat_ulong_t __unused2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct compat_msqid64_ds {
|
||||||
|
struct compat_ipc64_perm msg_perm;
|
||||||
|
#ifndef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused1;
|
||||||
|
#endif
|
||||||
|
compat_time_t msg_stime;
|
||||||
|
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused1;
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused2;
|
||||||
|
#endif
|
||||||
|
compat_time_t msg_rtime;
|
||||||
|
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused2;
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused3;
|
||||||
|
#endif
|
||||||
|
compat_time_t msg_ctime;
|
||||||
|
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
compat_ulong_t __unused3;
|
||||||
|
#endif
|
||||||
|
compat_ulong_t msg_cbytes;
|
||||||
|
compat_ulong_t msg_qnum;
|
||||||
|
compat_ulong_t msg_qbytes;
|
||||||
|
compat_pid_t msg_lspid;
|
||||||
|
compat_pid_t msg_lrpid;
|
||||||
|
compat_ulong_t __unused4;
|
||||||
|
compat_ulong_t __unused5;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct compat_shmid64_ds {
|
||||||
|
struct compat_ipc64_perm shm_perm;
|
||||||
|
compat_size_t shm_segsz;
|
||||||
|
compat_time_t shm_atime;
|
||||||
|
compat_time_t shm_dtime;
|
||||||
|
compat_time_t shm_ctime;
|
||||||
|
compat_pid_t shm_cpid;
|
||||||
|
compat_pid_t shm_lpid;
|
||||||
|
compat_ulong_t shm_nattch;
|
||||||
|
compat_ulong_t __unused1;
|
||||||
|
compat_ulong_t __unused2;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _ASM_COMPAT_H */
|
#endif /* _ASM_COMPAT_H */
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006 Ralf Baechle (ralf@linux-mips.org)
|
||||||
|
*/
|
||||||
#ifndef _ASM_FUTEX_H
|
#ifndef _ASM_FUTEX_H
|
||||||
#define _ASM_FUTEX_H
|
#define _ASM_FUTEX_H
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
#define __FUTEX_SMP_SYNC " sync \n"
|
|
||||||
#else
|
|
||||||
#define __FUTEX_SMP_SYNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
||||||
{ \
|
{ \
|
||||||
if (cpu_has_llsc && R10000_LLSC_WAR) { \
|
if (cpu_has_llsc && R10000_LLSC_WAR) { \
|
||||||
|
@ -27,7 +29,7 @@
|
||||||
" .set mips3 \n" \
|
" .set mips3 \n" \
|
||||||
"2: sc $1, %2 \n" \
|
"2: sc $1, %2 \n" \
|
||||||
" beqzl $1, 1b \n" \
|
" beqzl $1, 1b \n" \
|
||||||
__FUTEX_SMP_SYNC \
|
__WEAK_ORDERING_MB \
|
||||||
"3: \n" \
|
"3: \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
" .set mips0 \n" \
|
" .set mips0 \n" \
|
||||||
|
@ -53,7 +55,7 @@
|
||||||
" .set mips3 \n" \
|
" .set mips3 \n" \
|
||||||
"2: sc $1, %2 \n" \
|
"2: sc $1, %2 \n" \
|
||||||
" beqz $1, 1b \n" \
|
" beqz $1, 1b \n" \
|
||||||
__FUTEX_SMP_SYNC \
|
__WEAK_ORDERING_MB \
|
||||||
"3: \n" \
|
"3: \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
" .set mips0 \n" \
|
" .set mips0 \n" \
|
||||||
|
@ -150,7 +152,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
"2: sc $1, %1 \n"
|
"2: sc $1, %1 \n"
|
||||||
" beqzl $1, 1b \n"
|
" beqzl $1, 1b \n"
|
||||||
__FUTEX_SMP_SYNC
|
__WEAK_ORDERING_MB
|
||||||
"3: \n"
|
"3: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
" .section .fixup,\"ax\" \n"
|
" .section .fixup,\"ax\" \n"
|
||||||
|
@ -177,7 +179,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
"2: sc $1, %1 \n"
|
"2: sc $1, %1 \n"
|
||||||
" beqz $1, 1b \n"
|
" beqz $1, 1b \n"
|
||||||
__FUTEX_SMP_SYNC
|
__WEAK_ORDERING_MB
|
||||||
"3: \n"
|
"3: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
" .section .fixup,\"ax\" \n"
|
" .section .fixup,\"ax\" \n"
|
||||||
|
|
|
@ -176,7 +176,7 @@ typedef struct kl_config_hdr {
|
||||||
/* --- New Macros for the changed kl_config_hdr_t structure --- */
|
/* --- New Macros for the changed kl_config_hdr_t structure --- */
|
||||||
|
|
||||||
#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
|
#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
|
||||||
(unsigned long)_k + (_k->ch_malloc_hdr_off)))
|
((unsigned long)_k + (_k->ch_malloc_hdr_off)))
|
||||||
|
|
||||||
#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
|
#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999, 2000 by Ralf Baechle
|
* Copyright (C) 1999, 2000, 06 by Ralf Baechle
|
||||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
||||||
*/
|
*/
|
||||||
#ifndef _ASM_SPINLOCK_H
|
#ifndef _ASM_SPINLOCK_H
|
||||||
#define _ASM_SPINLOCK_H
|
#define _ASM_SPINLOCK_H
|
||||||
|
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,7 +41,6 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
" beqzl %1, 1b \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" sync \n"
|
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (lock->lock), "=&r" (tmp)
|
: "=m" (lock->lock), "=&r" (tmp)
|
||||||
: "m" (lock->lock)
|
: "m" (lock->lock)
|
||||||
|
@ -53,19 +53,22 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
|
||||||
" li %1, 1 \n"
|
" li %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (lock->lock), "=&r" (tmp)
|
: "=m" (lock->lock), "=&r" (tmp)
|
||||||
: "m" (lock->lock)
|
: "m" (lock->lock)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
|
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
|
||||||
{
|
{
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" .set noreorder # __raw_spin_unlock \n"
|
" .set noreorder # __raw_spin_unlock \n"
|
||||||
" sync \n"
|
|
||||||
" sw $0, %0 \n"
|
" sw $0, %0 \n"
|
||||||
" .set\treorder \n"
|
" .set\treorder \n"
|
||||||
: "=m" (lock->lock)
|
: "=m" (lock->lock)
|
||||||
|
@ -86,7 +89,6 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" andi %2, %0, 1 \n"
|
" andi %2, %0, 1 \n"
|
||||||
" sync \n"
|
|
||||||
" .set reorder"
|
" .set reorder"
|
||||||
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
|
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
|
||||||
: "m" (lock->lock)
|
: "m" (lock->lock)
|
||||||
|
@ -99,13 +101,14 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
|
||||||
" sc %2, %1 \n"
|
" sc %2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
" andi %2, %0, 1 \n"
|
" andi %2, %0, 1 \n"
|
||||||
" sync \n"
|
|
||||||
" .set reorder"
|
" .set reorder"
|
||||||
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
|
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
|
||||||
: "m" (lock->lock)
|
: "m" (lock->lock)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return res == 0;
|
return res == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +146,6 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
" beqzl %1, 1b \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" sync \n"
|
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
|
@ -156,12 +158,14 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
|
||||||
" addu %1, 1 \n"
|
" addu %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note the use of sub, not subu which will make the kernel die with an
|
/* Note the use of sub, not subu which will make the kernel die with an
|
||||||
|
@ -171,13 +175,14 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (R10000_LLSC_WAR) {
|
if (R10000_LLSC_WAR) {
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ll %1, %2 # __raw_read_unlock \n"
|
"1: ll %1, %2 # __raw_read_unlock \n"
|
||||||
" sub %1, 1 \n"
|
" sub %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
" beqzl %1, 1b \n"
|
||||||
" sync \n"
|
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
@ -188,7 +193,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
|
||||||
" sub %1, 1 \n"
|
" sub %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
|
@ -208,7 +213,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
|
||||||
" lui %1, 0x8000 \n"
|
" lui %1, 0x8000 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
" beqzl %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
|
@ -221,18 +226,22 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
|
||||||
" lui %1, 0x8000 \n"
|
" lui %1, 0x8000 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp)
|
: "=m" (rw->lock), "=&r" (tmp)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __raw_write_unlock(raw_rwlock_t *rw)
|
static inline void __raw_write_unlock(raw_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" sync # __raw_write_unlock \n"
|
" # __raw_write_unlock \n"
|
||||||
" sw $0, %0 \n"
|
" sw $0, %0 \n"
|
||||||
: "=m" (rw->lock)
|
: "=m" (rw->lock)
|
||||||
: "m" (rw->lock)
|
: "m" (rw->lock)
|
||||||
|
@ -252,11 +261,10 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
|
||||||
" bnez %1, 2f \n"
|
" bnez %1, 2f \n"
|
||||||
" addu %1, 1 \n"
|
" addu %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
#ifdef CONFIG_SMP
|
" beqzl %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
#endif
|
__WEAK_ORDERING_MB
|
||||||
" li %2, 1 \n"
|
" li %2, 1 \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
||||||
|
@ -271,10 +279,9 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
|
||||||
" addu %1, 1 \n"
|
" addu %1, 1 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
|
" nop \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
#ifdef CONFIG_SMP
|
__WEAK_ORDERING_MB
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" li %2, 1 \n"
|
" li %2, 1 \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
||||||
|
@ -299,7 +306,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
|
||||||
" lui %1, 0x8000 \n"
|
" lui %1, 0x8000 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqzl %1, 1b \n"
|
" beqzl %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
|
__WEAK_ORDERING_MB
|
||||||
" li %2, 1 \n"
|
" li %2, 1 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
|
@ -315,7 +323,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
|
||||||
" lui %1, 0x8000 \n"
|
" lui %1, 0x8000 \n"
|
||||||
" sc %1, %0 \n"
|
" sc %1, %0 \n"
|
||||||
" beqz %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
" sync \n"
|
" nop \n"
|
||||||
|
__WEAK_ORDERING_MB
|
||||||
" li %2, 1 \n"
|
" li %2, 1 \n"
|
||||||
" .set reorder \n"
|
" .set reorder \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
|
* Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
|
||||||
* Copyright (C) 1996 by Paul M. Antoine
|
* Copyright (C) 1996 by Paul M. Antoine
|
||||||
* Copyright (C) 1999 Silicon Graphics
|
* Copyright (C) 1999 Silicon Graphics
|
||||||
* Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
|
* Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
|
||||||
|
@ -16,132 +16,12 @@
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
|
||||||
#include <asm/addrspace.h>
|
#include <asm/addrspace.h>
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
#include <asm/dsp.h>
|
#include <asm/dsp.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* read_barrier_depends - Flush all pending reads that subsequents reads
|
|
||||||
* depend on.
|
|
||||||
*
|
|
||||||
* No data-dependent reads from memory-like regions are ever reordered
|
|
||||||
* over this barrier. All reads preceding this primitive are guaranteed
|
|
||||||
* to access memory (but not necessarily other CPUs' caches) before any
|
|
||||||
* reads following this primitive that depend on the data return by
|
|
||||||
* any of the preceding reads. This primitive is much lighter weight than
|
|
||||||
* rmb() on most CPUs, and is never heavier weight than is
|
|
||||||
* rmb().
|
|
||||||
*
|
|
||||||
* These ordering constraints are respected by both the local CPU
|
|
||||||
* and the compiler.
|
|
||||||
*
|
|
||||||
* Ordering is not guaranteed by anything other than these primitives,
|
|
||||||
* not even by data dependencies. See the documentation for
|
|
||||||
* memory_barrier() for examples and URLs to more information.
|
|
||||||
*
|
|
||||||
* For example, the following code would force ordering (the initial
|
|
||||||
* value of "a" is zero, "b" is one, and "p" is "&a"):
|
|
||||||
*
|
|
||||||
* <programlisting>
|
|
||||||
* CPU 0 CPU 1
|
|
||||||
*
|
|
||||||
* b = 2;
|
|
||||||
* memory_barrier();
|
|
||||||
* p = &b; q = p;
|
|
||||||
* read_barrier_depends();
|
|
||||||
* d = *q;
|
|
||||||
* </programlisting>
|
|
||||||
*
|
|
||||||
* because the read of "*q" depends on the read of "p" and these
|
|
||||||
* two reads are separated by a read_barrier_depends(). However,
|
|
||||||
* the following code, with the same initial values for "a" and "b":
|
|
||||||
*
|
|
||||||
* <programlisting>
|
|
||||||
* CPU 0 CPU 1
|
|
||||||
*
|
|
||||||
* a = 2;
|
|
||||||
* memory_barrier();
|
|
||||||
* b = 3; y = b;
|
|
||||||
* read_barrier_depends();
|
|
||||||
* x = a;
|
|
||||||
* </programlisting>
|
|
||||||
*
|
|
||||||
* does not enforce ordering, since there is no data dependency between
|
|
||||||
* the read of "a" and the read of "b". Therefore, on some CPUs, such
|
|
||||||
* as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
|
|
||||||
* in cases like this where there are no data dependencies.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define read_barrier_depends() do { } while(0)
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_SYNC
|
|
||||||
#define __sync() \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
".set push\n\t" \
|
|
||||||
".set noreorder\n\t" \
|
|
||||||
".set mips2\n\t" \
|
|
||||||
"sync\n\t" \
|
|
||||||
".set pop" \
|
|
||||||
: /* no output */ \
|
|
||||||
: /* no input */ \
|
|
||||||
: "memory")
|
|
||||||
#else
|
|
||||||
#define __sync() do { } while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __fast_iob() \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
".set push\n\t" \
|
|
||||||
".set noreorder\n\t" \
|
|
||||||
"lw $0,%0\n\t" \
|
|
||||||
"nop\n\t" \
|
|
||||||
".set pop" \
|
|
||||||
: /* no output */ \
|
|
||||||
: "m" (*(int *)CKSEG1) \
|
|
||||||
: "memory")
|
|
||||||
|
|
||||||
#define fast_wmb() __sync()
|
|
||||||
#define fast_rmb() __sync()
|
|
||||||
#define fast_mb() __sync()
|
|
||||||
#define fast_iob() \
|
|
||||||
do { \
|
|
||||||
__sync(); \
|
|
||||||
__fast_iob(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_WB
|
|
||||||
|
|
||||||
#include <asm/wbflush.h>
|
|
||||||
|
|
||||||
#define wmb() fast_wmb()
|
|
||||||
#define rmb() fast_rmb()
|
|
||||||
#define mb() wbflush()
|
|
||||||
#define iob() wbflush()
|
|
||||||
|
|
||||||
#else /* !CONFIG_CPU_HAS_WB */
|
|
||||||
|
|
||||||
#define wmb() fast_wmb()
|
|
||||||
#define rmb() fast_rmb()
|
|
||||||
#define mb() fast_mb()
|
|
||||||
#define iob() fast_iob()
|
|
||||||
|
|
||||||
#endif /* !CONFIG_CPU_HAS_WB */
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
#define smp_mb() mb()
|
|
||||||
#define smp_rmb() rmb()
|
|
||||||
#define smp_wmb() wmb()
|
|
||||||
#define smp_read_barrier_depends() read_barrier_depends()
|
|
||||||
#else
|
|
||||||
#define smp_mb() barrier()
|
|
||||||
#define smp_rmb() barrier()
|
|
||||||
#define smp_wmb() barrier()
|
|
||||||
#define smp_read_barrier_depends() do { } while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define set_mb(var, value) \
|
|
||||||
do { var = value; mb(); } while (0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch_to(n) should switch tasks to task nr n, first
|
* switch_to(n) should switch tasks to task nr n, first
|
||||||
|
@ -217,9 +97,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
" sc %2, %1 \n"
|
" sc %2, %1 \n"
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||||
: "R" (*m), "Jr" (val)
|
: "R" (*m), "Jr" (val)
|
||||||
|
@ -235,9 +112,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
" sc %2, %1 \n"
|
" sc %2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||||
: "R" (*m), "Jr" (val)
|
: "R" (*m), "Jr" (val)
|
||||||
|
@ -251,6 +125,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
|
||||||
local_irq_restore(flags); /* implies memory barrier */
|
local_irq_restore(flags); /* implies memory barrier */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,9 +144,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
|
||||||
" move %2, %z4 \n"
|
" move %2, %z4 \n"
|
||||||
" scd %2, %1 \n"
|
" scd %2, %1 \n"
|
||||||
" beqzl %2, 1b \n"
|
" beqzl %2, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||||
: "R" (*m), "Jr" (val)
|
: "R" (*m), "Jr" (val)
|
||||||
|
@ -284,9 +157,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
|
||||||
" move %2, %z4 \n"
|
" move %2, %z4 \n"
|
||||||
" scd %2, %1 \n"
|
" scd %2, %1 \n"
|
||||||
" beqz %2, 1b \n"
|
" beqz %2, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
" .set mips0 \n"
|
" .set mips0 \n"
|
||||||
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
|
||||||
: "R" (*m), "Jr" (val)
|
: "R" (*m), "Jr" (val)
|
||||||
|
@ -300,6 +170,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
|
||||||
local_irq_restore(flags); /* implies memory barrier */
|
local_irq_restore(flags); /* implies memory barrier */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -345,9 +217,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
" sc $1, %1 \n"
|
" sc $1, %1 \n"
|
||||||
" beqzl $1, 1b \n"
|
" beqzl $1, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (retval), "=R" (*m)
|
: "=&r" (retval), "=R" (*m)
|
||||||
|
@ -365,9 +234,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
|
||||||
" .set mips3 \n"
|
" .set mips3 \n"
|
||||||
" sc $1, %1 \n"
|
" sc $1, %1 \n"
|
||||||
" beqz $1, 1b \n"
|
" beqz $1, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (retval), "=R" (*m)
|
: "=&r" (retval), "=R" (*m)
|
||||||
|
@ -383,6 +249,8 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
|
||||||
local_irq_restore(flags); /* implies memory barrier */
|
local_irq_restore(flags); /* implies memory barrier */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,9 +270,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
|
||||||
" move $1, %z4 \n"
|
" move $1, %z4 \n"
|
||||||
" scd $1, %1 \n"
|
" scd $1, %1 \n"
|
||||||
" beqzl $1, 1b \n"
|
" beqzl $1, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (retval), "=R" (*m)
|
: "=&r" (retval), "=R" (*m)
|
||||||
|
@ -420,9 +285,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
|
||||||
" move $1, %z4 \n"
|
" move $1, %z4 \n"
|
||||||
" scd $1, %1 \n"
|
" scd $1, %1 \n"
|
||||||
" beqz $1, 1b \n"
|
" beqz $1, 1b \n"
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" sync \n"
|
|
||||||
#endif
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
" .set pop \n"
|
" .set pop \n"
|
||||||
: "=&r" (retval), "=R" (*m)
|
: "=&r" (retval), "=R" (*m)
|
||||||
|
@ -438,6 +300,8 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
|
||||||
local_irq_restore(flags); /* implies memory barrier */
|
local_irq_restore(flags); /* implies memory barrier */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
Reference in New Issue