#include "opt_gprof.h"
#include <sys/errno.h>
#include <aarch64/asm.h>
#include "assym.h"
RCSID("$NetBSD: copyinout.S,v 1.16 2021/02/11 08:35:11 ryo Exp $");
#ifdef ARMV81_PAN
#define PAN_ENABLE \
adrl x9, _C_LABEL(aarch64_pan_enabled) ; \
ldr w9, [x9] ; \
cbz w9, 666f ; \
msr pan, #1 ; \
666:
#define PAN_DISABLE \
adrl x9, _C_LABEL(aarch64_pan_enabled) ; \
ldr w9, [x9] ; \
cbz w9, 666f ; \
msr pan, #0 ; \
666:
#else
#define PAN_ENABLE
#define PAN_DISABLE
#endif
ARMV8_DEFINE_OPTIONS
.macro enter_cpu_onfault
stp fp, lr, [sp, #-16]!
mov fp, sp
stp x19, x20, [sp, #-16]!
mov x19, x0
mov x20, x1
sub sp, sp, #FB_T_SIZE
mov x0, sp
stp x2, x3, [sp, #-16]!
bl cpu_set_onfault
ldp x2, x3, [sp], #16
mov x8, x0
cbnz x0, 9f
mov x0, x19
mov x1, x20
PAN_DISABLE
.endm
.macro exit_cpu_onfault
mrs x0, tpidr_el1
str xzr, [x0, #L_MD_ONFAULT]
9:
PAN_ENABLE
add sp, sp, #FB_T_SIZE
ldp x19, x20, [sp], #16
ldp fp, lr, [sp], #16
mov x0, x8
.endm
ENTRY(copyin)
enter_cpu_onfault
lsr x4, x2, #5
cbz x4, .Lcopyin_last_suboword
and x5, x0, #31
cbz x5, .Lcopyin_loop
add x2, x2, x5
sub x2, x2, #32
lsr x4, x2, #5
tbz x0, #0, .Lcopyin_hword_aligned
ldtrb w5, [x0]
add x0, x0, #1
strb w5, [x1], #1
.Lcopyin_hword_aligned:
tbz x0, #1, .Lcopyin_word_aligned
ldtrh w5, [x0]
add x0, x0, #2
strh w5, [x1], #2
.Lcopyin_word_aligned:
tbz x0, #2, .Lcopyin_dword_aligned
ldtr w5, [x0]
add x0, x0, #4
str w5, [x1], #4
.Lcopyin_dword_aligned:
tbz x0, #3, .Lcopyin_qword_aligned
ldtr x5, [x0]
add x0, x0, #8
str x5, [x1], #8
.Lcopyin_qword_aligned:
tbz x0, #4, .Lcopyin_loop0
ldtr x5, [x0, #0]
ldtr x6, [x0, #8]
add x0, x0, #16
stp x5, x6, [x1], #16
.Lcopyin_loop0:
cbz x4, .Lcopyin_last_suboword
.Lcopyin_loop:
ldtr x5, [x0, #0]
ldtr x6, [x0, #8]
ldtr x7, [x0, #16]
ldtr x8, [x0, #24]
add x0, x0, #32
stp x5, x6, [x1], #16
stp x7, x8, [x1], #16
sub x4, x4, #1
cbnz x4, .Lcopyin_loop
.Lcopyin_last_suboword:
tbz x2, #4, .Lcopyin_last_subqword
ldtr x5, [x0, #0]
ldtr x6, [x0, #8]
add x0, x0, #16
stp x5, x6, [x1], #16
.Lcopyin_last_subqword:
tbz x2, #3, .Lcopyin_last_subdword
ldtr x5, [x0]
add x0, x0, #8
str x5, [x1], #8
.Lcopyin_last_subdword:
tbz x2, #2, .Lcopyin_last_subword
ldtr w5, [x0]
add x0, x0, #4
str w5, [x1], #4
.Lcopyin_last_subword:
tbz x2, #1, .Lcopyin_last_subhword
ldtrh w5, [x0]
add x0, x0, #2
strh w5, [x1], #2
.Lcopyin_last_subhword:
tbz x2, #0, .Lcopyin_done
ldtrb w5, [x0]
strb w5, [x1]
.Lcopyin_done:
mov x8, #0
exit_cpu_onfault
ret
END(copyin)
ENTRY(copyout)
enter_cpu_onfault
lsr x4, x2, #5
cbz x4, .Lcopyout_last_suboword
and x5, x0, #31
cbz x5, .Lcopyout_loop
add x2, x2, x5
sub x2, x2, #32
lsr x4, x2, #5
tbz x0, #0, .Lcopyout_hword_aligned
ldrb w5, [x0], #1
sttrb w5, [x1]
add x1, x1, #1
.Lcopyout_hword_aligned:
tbz x0, #1, .Lcopyout_word_aligned
ldrh w5, [x0], #2
sttrh w5, [x1]
add x1, x1, #2
.Lcopyout_word_aligned:
tbz x0, #2, .Lcopyout_dword_aligned
ldr w5, [x0], #4
sttr w5, [x1]
add x1, x1, #4
.Lcopyout_dword_aligned:
tbz x0, #3, .Lcopyout_qword_aligned
ldr x5, [x0], #8
sttr x5, [x1]
add x1, x1, #8
.Lcopyout_qword_aligned:
tbz x0, #4, .Lcopyout_loop0
ldp x5, x6, [x0], #16
sttr x5, [x1, #0]
sttr x6, [x1, #8]
add x1, x1, #16
.Lcopyout_loop0:
cbz x4, .Lcopyout_last_suboword
.Lcopyout_loop:
ldp x5, x6, [x0], #16
ldp x7, x8, [x0], #16
sttr x5, [x1, #0]
sttr x6, [x1, #8]
sttr x7, [x1, #16]
sttr x8, [x1, #24]
add x1, x1, #32
sub x4, x4, #1
cbnz x4, .Lcopyout_loop
.Lcopyout_last_suboword:
tbz x2, #4, .Lcopyout_last_subqword
ldp x5, x6, [x0], #16
sttr x5, [x1, #0]
sttr x6, [x1, #8]
add x1, x1, #16
.Lcopyout_last_subqword:
tbz x2, #3, .Lcopyout_last_subdword
ldr x5, [x0], #8
sttr x5, [x1]
add x1, x1, #8
.Lcopyout_last_subdword:
tbz x2, #2, .Lcopyout_last_subword
ldr w5, [x0], #4
sttr w5, [x1]
add x1, x1, #4
.Lcopyout_last_subword:
tbz x2, #1, .Lcopyout_last_subhword
ldrh w5, [x0], #2
sttrh w5, [x1]
add x1, x1, #2
.Lcopyout_last_subhword:
tbz x2, #0, .Lcopyout_done
ldrb w5, [x0]
sttrb w5, [x1]
.Lcopyout_done:
mov x8, #0
exit_cpu_onfault
ret
END(copyout)
ENTRY(copyinstr)
enter_cpu_onfault
mov x8, #0
mov x4, xzr
cbz x2, copyinstr_done
copyinstr_loop:
ldtrb w5, [x0]
add x0, x0, #1
strb w5, [x1], #1
add x4, x4, #1
cbz w5, copyinstr_done
cmp x4, x2
bcc copyinstr_loop
mov x8, #ENAMETOOLONG
copyinstr_done:
cbz x3, 1f
str x4, [x3]
1:
exit_cpu_onfault
ret
END(copyinstr)
ENTRY(copyoutstr)
enter_cpu_onfault
mov x8, #0
mov x4, xzr
cbz x2, copyoutstr_done
copyoutstr_loop:
ldrb w5, [x0], #1
sttrb w5, [x1]
add x1, x1, #1
add x4, x4, #1
cbz w5, copyoutstr_done
cmp x4, x2
bcc copyoutstr_loop
mov x8, #ENAMETOOLONG
copyoutstr_done:
cbz x3, 1f
str x4, [x3]
1:
exit_cpu_onfault
ret
END(copyoutstr)
ENTRY(kcopy)
enter_cpu_onfault
mov x3, x0
mov x0, x1
mov x1, x3
bl _C_LABEL(memcpy)
mov x8, #0
exit_cpu_onfault
ret
END(kcopy)
ENTRY(_ucas_32)
tbnz x0, AARCH64_ADDRTOP_TAG_BIT, 3f
ands x8, x0, #3
cbnz x8, 3f
enter_cpu_onfault
1: ldxr w4, [x0]
cmp w4, w1
b.ne 2f
stxr w5, w2, [x0]
cbnz w5, 1b
2: str w4, [x3]
mov x8, #0
exit_cpu_onfault
ret
3:
mov x0, #EFAULT
ret
END(_ucas_32)
ENTRY(_ucas_64)
tbnz x0, AARCH64_ADDRTOP_TAG_BIT, 3f
ands x8, x0, #7
cbnz x8, 3f
enter_cpu_onfault
1: ldxr x4, [x0]
cmp x4, x1
b.ne 2f
stxr w5, x2, [x0]
cbnz w5, 1b
2: str x4, [x3]
mov x8, #0
exit_cpu_onfault
ret
3:
mov x0, #EFAULT
ret
END(_ucas_64)