[xtensa-cvscommit] linux/arch/xtensa/kernel sys.S,1.3,1.4 sysxtensa.c,1.2,1.3
Brought to you by:
zankel
|
From: <joe...@us...> - 2003-03-21 18:53:39
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel
In directory sc8-pr-cvs1:/tmp/cvs-serv5812/arch/xtensa/kernel
Modified Files:
sys.S sysxtensa.c
Log Message:
Add kernel support for additional atomic operations that user tasks cannot perform themselves. glibc will use them.
Index: sys.S
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/sys.S,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** sys.S 13 Feb 2003 00:17:21 -0000 1.3
--- sys.S 21 Mar 2003 18:11:53 -0000 1.4
***************
*** 98,102 ****
/* Same as handle_sys_kernel, except user-mode version. The
* distinct kernel and user versions avoid the overhead of
! * testing PS.PSTK bit to determine whether to branch to
* handle_kernel or handle_user. */
--- 98,102 ----
/* Same as handle_sys_kernel, except user-mode version. The
* distinct kernel and user versions avoid the overhead of
! * testing PS.UM bit to determine whether to branch to
* handle_kernel or handle_user. */
***************
*** 207,210 ****
--- 207,212 ----
+ /* XTFIXME: The last three unhandled cases present an optimization opportunity. */
+
.data
.align 4
***************
*** 212,217 ****
.word quick_unhandled
.word quick_atomic_set
! #if XTENSA_SYSXTENSA_COUNT != 2
#error Number of sysxtensa calls and registered handlers are different
#endif
--- 214,222 ----
.word quick_unhandled
.word quick_atomic_set
+ .word quick_unhandled
+ .word quick_unhandled
+ .word quick_unhandled
! #if XTENSA_SYSXTENSA_COUNT != 5
#error Number of sysxtensa calls and registered handlers are different
#endif
***************
*** 867,876 ****
/* Make PS suitable for windowed-register calls in kernel:
* INTLEVEL = 0 // clear for panic() and printk()
! * EXCM = 0 // leave exception mode
! * PSTK (UM) = 0 // enter kernel mode
! * RING = 0 // assume kernel memory
! * OWB = 0 // don't care
! * CALLINC = 0 // don't care
! * WOE = 1 // required for "entry" insn
*/
movi a7, XCHAL_PS_WOE_MASK
--- 872,881 ----
/* Make PS suitable for windowed-register calls in kernel:
* INTLEVEL = 0 // clear for panic() and printk()
! * EXCM = 0 // leave exception mode
! * UM = 0 // enter kernel mode
! * RING = 0 // assume kernel memory
! * OWB = 0 // don't care
! * CALLINC = 0 // don't care
! * WOE = 1 // required for "entry" insn
*/
movi a7, XCHAL_PS_WOE_MASK
Index: sysxtensa.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/sysxtensa.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** sysxtensa.c 28 Feb 2003 01:53:09 -0000 1.2
--- sysxtensa.c 21 Mar 2003 18:11:53 -0000 1.3
***************
*** 31,37 ****
switch(cmd) {
! case XTENSA_ATOMIC_SET: {
/* Sets value atomically and returns original value. */
p = (int *) arg1;
--- 31,39 ----
switch(cmd) {
! case XTENSA_ATOMIC_SET:
! {
/* Sets value atomically and returns original value. */
+ /* int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused); */
p = (int *) arg1;
***************
*** 59,62 ****
--- 61,141 ----
: "=a" (tmp), "=a" (retval)
: "a" (p), "a" (arg2), "i" (-EFAULT)
+ : "a15"
+ );
+ goto out;
+ }
+
+ case XTENSA_ATOMIC_EXG_ADD:
+ case XTENSA_ATOMIC_ADD:
+ {
+
+ /* Atomically add value to memory, return original value. */
+
+ /* int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused); */
+ /* int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused); */
+
+ p = (int *) arg1;
+ retval = verify_area(VERIFY_WRITE, p, sizeof(*p));
+ if (retval)
+ return retval;
+
+ __asm__ __volatile__(
+ " rsil a15, "XTSTR(LOCKLEVEL)"\n"
+ "1: l32i %1, %2, 0 \n"
+ " add %3, %3, %1 \n"
+ "2: s32i %3, %2, 0 \n"
+ "5: wsr a15, "XTSTR(PS)" \n"
+ " rsync \n"
+ " .section .fixup,\"ax\" \n"
+ " .align 4 \n"
+ "6: .word 5b \n"
+ "7: l32r %0, 6b \n"
+ " movi %1, %4 \n"
+ " jx %0 \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " .word 1b, 7b \n"
+ " .word 2b, 7b \n"
+ " .previous \n"
+ : "=a" (tmp), "=a" (retval)
+ : "a" (p), "a" (arg2), "i" (-EFAULT)
+ : "a15"
+ );
+ goto out;
+ }
+
+ case XTENSA_ATOMIC_CMP_SWP:
+ {
+ /* Atomically store newval iif *ptr == oldval */
+ /* int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval); */
+
+ p = (int *) arg1;
+ retval = verify_area(VERIFY_WRITE, p, sizeof(*p));
+ if (retval)
+ return retval;
+
+ __asm__ __volatile__(
+ " rsil a15, "XTSTR(LOCKLEVEL)"\n"
+ "1: l32i %1, %2, 0 \n"
+ " beq %1, %3, 2f \n"
+ " movi %1, 0 \n"
+ " j 5f \n"
+ "2: s32i %4, %2, 0 \n"
+ " movi %1, 1 \n"
+ "5: wsr a15, "XTSTR(PS)" \n"
+ " rsync \n"
+ " .section .fixup,\"ax\" \n"
+ " .align 4 \n"
+ "6: .word 5b \n"
+ "7: l32r %0, 6b \n"
+ " movi %1, %5 \n"
+ " jx %0 \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " .word 1b, 7b \n"
+ " .word 2b, 7b \n"
+ " .previous \n"
+ : "=a" (tmp), "=a" (retval)
+ : "a" (p), "a" (arg2), "a" (arg3), "i" (-EFAULT)
: "a15"
);
|