1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (c) 2023 Ventana Micro Systems Inc. |
4 | */ |
5 | |
6 | #include <linux/linkage.h> |
7 | #include <linux/export.h> |
8 | #include <asm/asm.h> |
9 | #include <asm/alternative-macros.h> |
10 | #include <asm/hwcap.h> |
11 | #include <asm/insn-def.h> |
12 | #include <asm/page.h> |
13 | |
14 | #define CBOZ_ALT(order, old, new) \ |
15 | ALTERNATIVE(old, new, 0, \ |
16 | ((order) << 16) | RISCV_ISA_EXT_ZICBOZ, \ |
17 | CONFIG_RISCV_ISA_ZICBOZ) |
18 | |
19 | /* void clear_page(void *page) */ |
20 | SYM_FUNC_START(clear_page) |
21 | li a2, PAGE_SIZE |
22 | |
23 | /* |
24 | * If Zicboz isn't present, or somehow has a block |
25 | * size larger than 4K, then fallback to memset. |
26 | */ |
27 | CBOZ_ALT(12, "j .Lno_zicboz" , "nop" ) |
28 | |
29 | lw a1, riscv_cboz_block_size |
30 | add a2, a0, a2 |
31 | .Lzero_loop: |
32 | CBO_ZERO(a0) |
33 | add a0, a0, a1 |
34 | CBOZ_ALT(11, "bltu a0, a2, .Lzero_loop; ret" , "nop; nop" ) |
35 | CBO_ZERO(a0) |
36 | add a0, a0, a1 |
37 | CBOZ_ALT(10, "bltu a0, a2, .Lzero_loop; ret" , "nop; nop" ) |
38 | CBO_ZERO(a0) |
39 | add a0, a0, a1 |
40 | CBO_ZERO(a0) |
41 | add a0, a0, a1 |
42 | CBOZ_ALT(9, "bltu a0, a2, .Lzero_loop; ret" , "nop; nop" ) |
43 | CBO_ZERO(a0) |
44 | add a0, a0, a1 |
45 | CBO_ZERO(a0) |
46 | add a0, a0, a1 |
47 | CBO_ZERO(a0) |
48 | add a0, a0, a1 |
49 | CBO_ZERO(a0) |
50 | add a0, a0, a1 |
51 | CBOZ_ALT(8, "bltu a0, a2, .Lzero_loop; ret" , "nop; nop" ) |
52 | CBO_ZERO(a0) |
53 | add a0, a0, a1 |
54 | CBO_ZERO(a0) |
55 | add a0, a0, a1 |
56 | CBO_ZERO(a0) |
57 | add a0, a0, a1 |
58 | CBO_ZERO(a0) |
59 | add a0, a0, a1 |
60 | CBO_ZERO(a0) |
61 | add a0, a0, a1 |
62 | CBO_ZERO(a0) |
63 | add a0, a0, a1 |
64 | CBO_ZERO(a0) |
65 | add a0, a0, a1 |
66 | CBO_ZERO(a0) |
67 | add a0, a0, a1 |
68 | bltu a0, a2, .Lzero_loop |
69 | ret |
70 | .Lno_zicboz: |
71 | li a1, 0 |
72 | tail __memset |
73 | SYM_FUNC_END(clear_page) |
74 | EXPORT_SYMBOL(clear_page) |
75 | |