123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include <linux/linkage.h>
- #include <asm/asm.h>
- #include <asm/csr.h>
- .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(__asm_copy_to_user)
- ENTRY(__asm_copy_from_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(__asm_copy_to_user)
- ENDPROC(__asm_copy_from_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), 11f
- 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), 11f
- addi a0, a0, 1
- bltu a0, t0, 4b
- j 1b
- 5: /* Edge case: remainder */
- fixup sb, zero, (a0), 11f
- addi a0, a0, 1
- bltu a0, a3, 5b
- j 3b
- ENDPROC(__clear_user)
- .section .fixup,"ax"
- .balign 4
- /* Fixup code for __copy_user(10) and __clear_user(11) */
- 10:
- /* Disable access to user memory */
- csrs sstatus, t6
- mv a0, a2
- ret
- 11:
- csrs sstatus, t6
- mv a0, a1
- ret
- .previous
|