2006-11-27 04:06:26 +01:00
|
|
|
/*
|
2005-04-17 00:20:36 +02:00
|
|
|
* __clear_user_page, __clear_user, clear_page implementation of SuperH
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001 Kaz Kojima
|
|
|
|
* Copyright (C) 2001, 2002 Niibe Yutaka
|
2006-11-27 04:06:26 +01:00
|
|
|
* Copyright (C) 2006 Paul Mundt
|
2005-04-17 00:20:36 +02:00
|
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
2006-11-27 04:06:26 +01:00
|
|
|
#include <asm/page.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/*
|
2007-11-23 05:55:02 +01:00
|
|
|
* clear_page
|
2005-04-17 00:20:36 +02:00
|
|
|
* @to: P1 address
|
|
|
|
*
|
2007-11-23 05:55:02 +01:00
|
|
|
* void clear_page(void *to)
|
2005-04-17 00:20:36 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* r0 --- scratch
|
|
|
|
* r4 --- to
|
2006-11-27 04:06:26 +01:00
|
|
|
* r5 --- to + PAGE_SIZE
|
2005-04-17 00:20:36 +02:00
|
|
|
*/
|
2007-11-23 05:55:02 +01:00
|
|
|
ENTRY(clear_page)
|
2005-04-17 00:20:36 +02:00
|
|
|
mov r4,r5
|
2006-11-27 04:06:26 +01:00
|
|
|
mov.l .Llimit,r0
|
2005-04-17 00:20:36 +02:00
|
|
|
add r0,r5
|
|
|
|
mov #0,r0
|
|
|
|
!
|
|
|
|
1:
|
|
|
|
#if defined(CONFIG_CPU_SH3)
|
|
|
|
mov.l r0,@r4
|
|
|
|
#elif defined(CONFIG_CPU_SH4)
|
|
|
|
movca.l r0,@r4
|
|
|
|
mov r4,r1
|
|
|
|
#endif
|
|
|
|
add #32,r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
mov.l r0,@-r4
|
|
|
|
#if defined(CONFIG_CPU_SH4)
|
|
|
|
ocbwb @r1
|
|
|
|
#endif
|
|
|
|
cmp/eq r5,r4
|
|
|
|
bf/s 1b
|
|
|
|
add #28,r4
|
|
|
|
!
|
|
|
|
rts
|
|
|
|
nop
|
2006-11-27 04:06:26 +01:00
|
|
|
.Llimit: .long (PAGE_SIZE-28)
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
ENTRY(__clear_user)
|
|
|
|
!
|
|
|
|
mov #0, r0
|
|
|
|
mov #0xe0, r1 ! 0xffffffe0
|
|
|
|
!
|
|
|
|
! r4..(r4+31)&~32 -------- not aligned [ Area 0 ]
|
|
|
|
! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ]
|
|
|
|
! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ]
|
|
|
|
!
|
|
|
|
! Clear area 0
|
|
|
|
mov r4, r2
|
|
|
|
!
|
|
|
|
tst r1, r5 ! length < 32
|
|
|
|
bt .Larea2 ! skip to remainder
|
|
|
|
!
|
|
|
|
add #31, r2
|
|
|
|
and r1, r2
|
|
|
|
cmp/eq r4, r2
|
|
|
|
bt .Larea1
|
|
|
|
mov r2, r3
|
|
|
|
sub r4, r3
|
|
|
|
mov r3, r7
|
|
|
|
mov r4, r2
|
|
|
|
!
|
|
|
|
.L0: dt r3
|
|
|
|
0: mov.b r0, @r2
|
|
|
|
bf/s .L0
|
|
|
|
add #1, r2
|
|
|
|
!
|
|
|
|
sub r7, r5
|
|
|
|
mov r2, r4
|
|
|
|
.Larea1:
|
|
|
|
mov r4, r3
|
|
|
|
add r5, r3
|
|
|
|
and r1, r3
|
|
|
|
cmp/hi r2, r3
|
|
|
|
bf .Larea2
|
|
|
|
!
|
|
|
|
! Clear area 1
|
|
|
|
#if defined(CONFIG_CPU_SH4)
|
|
|
|
1: movca.l r0, @r2
|
|
|
|
#else
|
|
|
|
1: mov.l r0, @r2
|
|
|
|
#endif
|
|
|
|
add #4, r2
|
|
|
|
2: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
3: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
4: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
5: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
6: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
7: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
8: mov.l r0, @r2
|
|
|
|
add #4, r2
|
|
|
|
cmp/hi r2, r3
|
|
|
|
bt/s 1b
|
|
|
|
nop
|
|
|
|
!
|
|
|
|
! Clear area 2
|
|
|
|
.Larea2:
|
|
|
|
mov r4, r3
|
|
|
|
add r5, r3
|
|
|
|
cmp/hs r3, r2
|
|
|
|
bt/s .Ldone
|
|
|
|
sub r2, r3
|
|
|
|
.L2: dt r3
|
|
|
|
9: mov.b r0, @r2
|
|
|
|
bf/s .L2
|
|
|
|
add #1, r2
|
|
|
|
!
|
|
|
|
.Ldone: rts
|
|
|
|
mov #0, r0 ! return 0 as normal return
|
|
|
|
|
|
|
|
! return the number of bytes remained
|
|
|
|
.Lbad_clear_user:
|
|
|
|
mov r4, r0
|
|
|
|
add r5, r0
|
|
|
|
rts
|
|
|
|
sub r2, r0
|
|
|
|
|
|
|
|
.section __ex_table,"a"
|
|
|
|
.align 2
|
|
|
|
.long 0b, .Lbad_clear_user
|
|
|
|
.long 1b, .Lbad_clear_user
|
|
|
|
.long 2b, .Lbad_clear_user
|
|
|
|
.long 3b, .Lbad_clear_user
|
|
|
|
.long 4b, .Lbad_clear_user
|
|
|
|
.long 5b, .Lbad_clear_user
|
|
|
|
.long 6b, .Lbad_clear_user
|
|
|
|
.long 7b, .Lbad_clear_user
|
|
|
|
.long 8b, .Lbad_clear_user
|
|
|
|
.long 9b, .Lbad_clear_user
|
|
|
|
.previous
|