| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* |
| * Copyright (c) 2023 Ventana Micro Systems Inc. |
| */ |
| |
| #include <linux/linkage.h> |
| #include <linux/export.h> |
| #include <asm/asm.h> |
| #include <asm/alternative-macros.h> |
| #include <asm/hwcap.h> |
| #include <asm/insn-def.h> |
| #include <asm/page.h> |
| |
| #define CBOZ_ALT(order, old, new) \ |
| ALTERNATIVE(old, new, 0, \ |
| ((order) << 16) | RISCV_ISA_EXT_ZICBOZ, \ |
| CONFIG_RISCV_ISA_ZICBOZ) |
| |
| /* void clear_page(void *page) */ |
| SYM_FUNC_START(clear_page) |
| li a2, PAGE_SIZE |
| |
| /* |
| * If Zicboz isn't present, or somehow has a block |
| * size larger than 4K, then fallback to memset. |
| */ |
| CBOZ_ALT(12, "j .Lno_zicboz", "nop") |
| |
| lw a1, riscv_cboz_block_size |
| add a2, a0, a2 |
| .Lzero_loop: |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBOZ_ALT(11, "bltu a0, a2, .Lzero_loop; ret", "nop; nop") |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBOZ_ALT(10, "bltu a0, a2, .Lzero_loop; ret", "nop; nop") |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBOZ_ALT(9, "bltu a0, a2, .Lzero_loop; ret", "nop; nop") |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBOZ_ALT(8, "bltu a0, a2, .Lzero_loop; ret", "nop; nop") |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| CBO_ZERO(a0) |
| add a0, a0, a1 |
| bltu a0, a2, .Lzero_loop |
| ret |
| .Lno_zicboz: |
| li a1, 0 |
| tail __memset |
| SYM_FUNC_END(clear_page) |
| EXPORT_SYMBOL(clear_page) |