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