#include "opt_multiprocessor.h"
#include "opt_cpuoptions.h"
#include "assym.h"
#include <machine/asm.h>
#include <arm/locore.h>
#if defined(__XSCALE__) || defined(_ARM_ARCH_6)
#include "bcopyinout_xscale.S"
#else
RCSID("$NetBSD: bcopyinout.S,v 1.23 2022/10/20 06:58:38 skrll Exp $")
.text
.align 0
#define SAVE_REGS stmfd sp!, {r4-r11}
#define RESTORE_REGS ldmfd sp!, {r4-r11}
#if defined(__XSCALE__) || defined(_ARM_ARCH_6)
#define HELLOCPP #
#define PREFETCH(rx,o) pld [ rx , HELLOCPP (o) ]
#else
#define PREFETCH(rx,o)
#endif
ENTRY(copyin)
teq r2, #0
moveq r0, #0
RETc(eq)
SAVE_REGS
GET_CURPCB(r4)
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
cmp r2, #0x08
blt .Licleanup
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lialend
.word .Lialend
.word .Lial3
.word .Lial2
.word .Lial1
.Lial3: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lial2: ldrbt r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lial1: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lialend:
cmp r2, #0x08
blt .Licleanup
ands r3, r0, #0x03
bne .Licleanup
cmp r2, #0x60
blt .Licleanup8
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Licaligned
.word .Licaligned
.word .Lical28
.word .Lical24
.word .Lical20
.word .Lical16
.word .Lical12
.word .Lical8
.word .Lical4
.Lical28:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical24:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical20:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical16:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical12:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical8:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical4:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Licaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
ldrt r10, [r0], #4
ldrt r11, [r0], #4
ldrt r6, [r0], #4
ldrt r7, [r0], #4
ldrt r8, [r0], #4
ldrt r9, [r0], #4
stmia r1!, {r10-r11}
ldrt r10, [r0], #4
ldrt r11, [r0], #4
stmia r1!, {r6-r11}
cmp r2, #0x40
bge .Licaligned
sub r2, r2, #0x20
ldrt r10, [r0], #4
ldrt r11, [r0], #4
ldrt r6, [r0], #4
ldrt r7, [r0], #4
ldrt r8, [r0], #4
ldrt r9, [r0], #4
stmia r1!, {r10-r11}
ldrt r10, [r0], #4
ldrt r11, [r0], #4
stmia r1!, {r6-r11}
cmp r2, #0x08
blt .Liprecleanup
.Licleanup8:
ldrt r8, [r0], #4
ldrt r9, [r0], #4
sub r2, r2, #8
stmia r1!, {r8, r9}
cmp r2, #8
bge .Licleanup8
.Liprecleanup:
cmp r2, #0
beq .Liout
.Licleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Licend
.word .Lic4
.word .Lic1
.word .Lic2
.word .Lic3
.Lic4: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lic3: ldrbt r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lic2: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lic1: ldrbt r7, [r0], #1
subs r2, r2, #1
strb r7, [r1], #1
.Licend:
bne .Licleanup
.Liout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
RET
.Lcopyfault:
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
RET
END(copyin)
ENTRY(copyout)
teq r2, #0
moveq r0, #0
moveq pc, lr
SAVE_REGS
GET_CURPCB(r4)
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
cmp r2, #0x08
blt .Lcleanup
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lalend
.word .Lalend
.word .Lal3
.word .Lal2
.word .Lal1
.Lal3: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lal2: ldrb r7, [r0], #1
sub r2, r2, #1
strbt r7, [r1], #1
.Lal1: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lalend:
cmp r2, #0x08
blt .Lcleanup
ands r3, r0, #0x03
bne .Lcleanup
cmp r2, #0x60
blt .Lcleanup8
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Lcaligned
.word .Lcaligned
.word .Lcal28
.word .Lcal24
.word .Lcal20
.word .Lcal16
.word .Lcal12
.word .Lcal8
.word .Lcal4
.Lcal28:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal24:ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal20:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal16:ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal12:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal8: ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal4: ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
ldmia r0!, {r6-r11}
strt r6, [r1], #4
strt r7, [r1], #4
ldmia r0!, {r6-r7}
strt r8, [r1], #4
strt r9, [r1], #4
strt r10, [r1], #4
strt r11, [r1], #4
strt r6, [r1], #4
strt r7, [r1], #4
cmp r2, #0x40
bge .Lcaligned
sub r2, r2, #0x20
ldmia r0!, {r6-r11}
strt r6, [r1], #4
strt r7, [r1], #4
ldmia r0!, {r6-r7}
strt r8, [r1], #4
strt r9, [r1], #4
strt r10, [r1], #4
strt r11, [r1], #4
strt r6, [r1], #4
strt r7, [r1], #4
cmp r2, #0x08
blt .Lprecleanup
.Lcleanup8:
ldmia r0!, {r8-r9}
sub r2, r2, #8
strt r8, [r1], #4
strt r9, [r1], #4
cmp r2, #8
bge .Lcleanup8
.Lprecleanup:
cmp r2, #0
beq .Lout
.Lcleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lcend
.word .Lc4
.word .Lc1
.word .Lc2
.word .Lc3
.Lc4: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lc3: ldrb r7, [r0], #1
sub r2, r2, #1
strbt r7, [r1], #1
.Lc2: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lc1: ldrb r7, [r0], #1
subs r2, r2, #1
strbt r7, [r1], #1
.Lcend:
bne .Lcleanup
.Lout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
RET
END(copyout)
ENTRY(kcopy)
teq r2, #0
moveq r0, #0
moveq pc, lr
SAVE_REGS
GET_CURPCB(r4)
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
cmp r2, #0x08
blt .Lkcleanup
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lkalend
.word .Lkalend
.word .Lkal3
.word .Lkal2
.word .Lkal1
.Lkal3: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkal2: ldrb r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lkal1: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkalend:
cmp r2, #0x08
blt .Lkcleanup
ands r3, r0, #0x03
bne .Lkcleanup
cmp r2, #0x60
blt .Lkcleanup8
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Lkcaligned
.word .Lkcaligned
.word .Lkcal28
.word .Lkcal24
.word .Lkcal20
.word .Lkcal16
.word .Lkcal12
.word .Lkcal8
.word .Lkcal4
.Lkcal28:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal24:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal20:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal16:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal12:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal8:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal4:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
ldmia r0!, {r6-r11}
stmia r1!, {r6, r7}
ldmia r0!, {r6, r7}
stmia r1!, {r8-r11}
stmia r1!, {r6, r7}
cmp r2, #0x40
bge .Lkcaligned
sub r2, r2, #0x20
ldmia r0!, {r6-r11}
stmia r1!, {r6-r7}
ldmia r0!, {r6-r7}
stmia r1!, {r8-r11}
stmia r1!, {r6-r7}
cmp r2, #0x08
blt .Lkprecleanup
.Lkcleanup8:
ldmia r0!, {r8-r9}
sub r2, r2, #8
stmia r1!, {r8-r9}
cmp r2, #8
bge .Lkcleanup8
.Lkprecleanup:
cmp r2, #0
beq .Lkout
.Lkcleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lkcend
.word .Lkc4
.word .Lkc1
.word .Lkc2
.word .Lkc3
.Lkc4: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkc3: ldrb r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lkc2: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkc1: ldrb r7, [r0], #1
subs r2, r2, #1
strb r7, [r1], #1
.Lkcend:
bne .Lkcleanup
.Lkout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
RET
END(kcopy)
#endif
ENTRY(badaddr_read_1)
GET_CURPCB(r2)
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldrb r3, [r0]
nop
nop
nop
strb r3, [r1]
mov r0, #0
1: str ip, [r2, #PCB_ONFAULT]
RET
END(badaddr_read_1)
ENTRY(badaddr_read_2)
GET_CURPCB(r2)
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldrh r3, [r0]
nop
nop
nop
strh r3, [r1]
mov r0, #0
1: str ip, [r2, #PCB_ONFAULT]
RET
END(badaddr_read_2)
ENTRY(badaddr_read_4)
GET_CURPCB(r2)
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldr r3, [r0]
nop
nop
nop
str r3, [r1]
mov r0, #0
1: str ip, [r2, #PCB_ONFAULT]
RET
END(badaddr_read_4)