xref: /openbmc/linux/arch/riscv/lib/clear_page.S (revision 8fcd94ad)
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 <asm/asm.h>
8#include <asm/alternative-macros.h>
9#include <asm-generic/export.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) */
20SYM_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
73SYM_FUNC_END(clear_page)
74EXPORT_SYMBOL(clear_page)
75