mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
510c72ad2d
There were a number of places that made evil PAGE_SIZE == 4k assumptions that ended up breaking when trying to play with 8k and 64k page sizes, this fixes those up. The most significant change is the way we load THREAD_SIZE, previously this was done via: mov #(THREAD_SIZE >> 8), reg shll8 reg to avoid a memory access and allow the immediate load. With a 64k PAGE_SIZE, we're out of range for the immediate load size without resorting to special instructions available in later ISAs (movi20s and so on). The "workaround" for this is to bump up the shift to 10 and insert a shll2, which gives a bit more flexibility while still being much cheaper than a memory access. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
198 lines
2.9 KiB
ArmAsm
198 lines
2.9 KiB
ArmAsm
/*
|
|
* __clear_user_page, __clear_user, clear_page implementation of SuperH
|
|
*
|
|
* Copyright (C) 2001 Kaz Kojima
|
|
* Copyright (C) 2001, 2002 Niibe Yutaka
|
|
* Copyright (C) 2006 Paul Mundt
|
|
*/
|
|
#include <linux/linkage.h>
|
|
#include <asm/page.h>
|
|
|
|
/*
|
|
* clear_page_slow
|
|
* @to: P1 address
|
|
*
|
|
* void clear_page_slow(void *to)
|
|
*/
|
|
|
|
/*
|
|
* r0 --- scratch
|
|
* r4 --- to
|
|
* r5 --- to + PAGE_SIZE
|
|
*/
|
|
ENTRY(clear_page_slow)
|
|
mov r4,r5
|
|
mov.l .Llimit,r0
|
|
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
|
|
.Llimit: .long (PAGE_SIZE-28)
|
|
|
|
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
|
|
|
|
#if defined(CONFIG_CPU_SH4)
|
|
/*
|
|
* __clear_user_page
|
|
* @to: P3 address (with same color)
|
|
* @orig_to: P1 address
|
|
*
|
|
* void __clear_user_page(void *to, void *orig_to)
|
|
*/
|
|
|
|
/*
|
|
* r0 --- scratch
|
|
* r4 --- to
|
|
* r5 --- orig_to
|
|
* r6 --- to + PAGE_SIZE
|
|
*/
|
|
ENTRY(__clear_user_page)
|
|
mov.l .Lpsz,r0
|
|
mov r4,r6
|
|
add r0,r6
|
|
mov #0,r0
|
|
!
|
|
1: ocbi @r5
|
|
add #32,r5
|
|
movca.l r0,@r4
|
|
mov r4,r1
|
|
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
|
|
add #28,r4
|
|
cmp/eq r6,r4
|
|
bf/s 1b
|
|
ocbwb @r1
|
|
!
|
|
rts
|
|
nop
|
|
.Lpsz: .long PAGE_SIZE
|
|
|
|
#endif
|
|
|