mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
2.3 KiB
126 lines
2.3 KiB
#include <linux/linkage.h> |
|
#include <asm-generic/export.h> |
|
#include <asm/asm.h> |
|
#include <asm/csr.h> |
|
|
|
.macro fixup op reg addr lbl |
|
100: |
|
\op \reg, \addr |
|
.section __ex_table,"a" |
|
.balign RISCV_SZPTR |
|
RISCV_PTR 100b, \lbl |
|
.previous |
|
.endm |
|
|
|
ENTRY(__asm_copy_to_user) |
|
ENTRY(__asm_copy_from_user) |
|
|
|
/* Enable access to user memory */ |
|
li t6, SR_SUM |
|
csrs CSR_STATUS, 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 CSR_STATUS, 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) |
|
EXPORT_SYMBOL(__asm_copy_to_user) |
|
EXPORT_SYMBOL(__asm_copy_from_user) |
|
|
|
|
|
ENTRY(__clear_user) |
|
|
|
/* Enable access to user memory */ |
|
li t6, SR_SUM |
|
csrs CSR_STATUS, 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 CSR_STATUS, 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) |
|
EXPORT_SYMBOL(__clear_user) |
|
|
|
.section .fixup,"ax" |
|
.balign 4 |
|
/* Fixup code for __copy_user(10) and __clear_user(11) */ |
|
10: |
|
/* Disable access to user memory */ |
|
csrs CSR_STATUS, t6 |
|
mv a0, a2 |
|
ret |
|
11: |
|
csrs CSR_STATUS, t6 |
|
mv a0, a1 |
|
ret |
|
.previous
|
|
|