#include #include #include .altmacro .macro fixup op reg addr lbl LOCAL _epc _epc: \op \reg, \addr .section __ex_table,"a" .balign RISCV_SZPTR RISCV_PTR _epc, \lbl .previous .endm ENTRY(__copy_user) /* Enable access to user memory */ li t6, SR_SUM csrs sstatus, t6 add a3, a1, a2 /* Use word-oriented copy only if low-order bits match */ andi t0, a0, SZREG-1 andi t1, a1, SZREG-1 bne t0, t1, 2f addi t0, a1, SZREG-1 andi t1, a3, ~(SZREG-1) andi t0, t0, ~(SZREG-1) /* * a3: terminal address of source region * t0: lowest XLEN-aligned address in source * t1: highest XLEN-aligned address in source */ bgeu t0, t1, 2f bltu a1, t0, 4f 1: fixup REG_L, t2, (a1), 10f fixup REG_S, t2, (a0), 10f addi a1, a1, SZREG addi a0, a0, SZREG bltu a1, t1, 1b 2: bltu a1, a3, 5f 3: /* Disable access to user memory */ csrc sstatus, t6 li a0, 0 ret 4: /* Edge case: unalignment */ fixup lbu, t2, (a1), 10f fixup sb, t2, (a0), 10f addi a1, a1, 1 addi a0, a0, 1 bltu a1, t0, 4b j 1b 5: /* Edge case: remainder */ fixup lbu, t2, (a1), 10f fixup sb, t2, (a0), 10f addi a1, a1, 1 addi a0, a0, 1 bltu a1, a3, 5b j 3b ENDPROC(__copy_user) ENTRY(__clear_user) /* Enable access to user memory */ li t6, SR_SUM csrs sstatus, t6 add a3, a0, a1 addi t0, a0, SZREG-1 andi t1, a3, ~(SZREG-1) andi t0, t0, ~(SZREG-1) /* * a3: terminal address of target region * t0: lowest doubleword-aligned address in target region * t1: highest doubleword-aligned address in target region */ bgeu t0, t1, 2f bltu a0, t0, 4f 1: fixup REG_S, zero, (a0), 10f addi a0, a0, SZREG bltu a0, t1, 1b 2: bltu a0, a3, 5f 3: /* Disable access to user memory */ csrc sstatus, t6 li a0, 0 ret 4: /* Edge case: unalignment */ fixup sb, zero, (a0), 10f addi a0, a0, 1 bltu a0, t0, 4b j 1b 5: /* Edge case: remainder */ fixup sb, zero, (a0), 10f addi a0, a0, 1 bltu a0, a3, 5b j 3b ENDPROC(__clear_user) .section .fixup,"ax" .balign 4 10: /* Disable access to user memory */ csrs sstatus, t6 sub a0, a3, a0 ret .previous