RISC-V: Generic library routines and assembly
This patch contains code that is more specific to the RISC-V ISA than it is to Linux. It contains string and math operations, C wrappers for various assembly instructions, stack walking code, and uaccess. Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
This commit is contained in:
117
arch/riscv/lib/uaccess.S
Normal file
117
arch/riscv/lib/uaccess.S
Normal file
@@ -0,0 +1,117 @@
|
||||
#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(__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
|
Reference in New Issue
Block a user