Skip to content

Commit 8d496b5

Browse files
Alexandre Ghitipalmer-dabbelt
authored andcommitted
riscv: Add support for Zicbop
Zicbop introduces cache blocks prefetching instructions, add the necessary support for the kernel to use it in the coming commits. Co-developed-by: Guo Ren <[email protected]> Signed-off-by: Guo Ren <[email protected]> Tested-by: Andrea Parri <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Ghiti <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent f0f4e64 commit 8d496b5

File tree

8 files changed

+55
-9
lines changed

8 files changed

+55
-9
lines changed

arch/riscv/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,21 @@ config RISCV_ISA_ZICBOZ
842842

843843
If you don't know what to do here, say Y.
844844

845+
config RISCV_ISA_ZICBOP
846+
bool "Zicbop extension support for cache block prefetch"
847+
depends on MMU
848+
depends on RISCV_ALTERNATIVE
849+
default y
850+
help
851+
Adds support to dynamically detect the presence of the ZICBOP
852+
extension (Cache Block Prefetch Operations) and enable its
853+
usage.
854+
855+
The Zicbop extension can be used to prefetch cache blocks for
856+
read/write fetch.
857+
858+
If you don't know what to do here, say Y.
859+
845860
config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
846861
def_bool y
847862
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc

arch/riscv/include/asm/barrier.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
#include <asm/cmpxchg.h>
1515
#include <asm/fence.h>
1616

17-
#define nop() __asm__ __volatile__ ("nop")
18-
#define __nops(n) ".rept " #n "\nnop\n.endr\n"
19-
#define nops(n) __asm__ __volatile__ (__nops(n))
20-
21-
2217
/* These barriers need to enforce ordering on both devices or memory. */
2318
#define __mb() RISCV_FENCE(iorw, iorw)
2419
#define __rmb() RISCV_FENCE(ir, ir)

arch/riscv/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
8080

8181
extern unsigned int riscv_cbom_block_size;
8282
extern unsigned int riscv_cboz_block_size;
83+
extern unsigned int riscv_cbop_block_size;
8384
void riscv_init_cbo_blocksizes(void);
8485

8586
#ifdef CONFIG_RISCV_DMA_NONCOHERENT

arch/riscv/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#define RISCV_ISA_EXT_ZVFBFWMA 96
106106
#define RISCV_ISA_EXT_ZAAMO 97
107107
#define RISCV_ISA_EXT_ZALRSC 98
108+
#define RISCV_ISA_EXT_ZICBOP 99
108109

109110
#define RISCV_ISA_EXT_XLINUXENVCFG 127
110111

arch/riscv/include/asm/insn-def.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,10 @@
263263

264264
#define RISCV_INSN_NOP4 _AC(0x00000013, U)
265265

266+
#ifndef __ASSEMBLY__
267+
#define nop() __asm__ __volatile__ ("nop")
268+
#define __nops(n) ".rept " #n "\nnop\n.endr\n"
269+
#define nops(n) __asm__ __volatile__ (__nops(n))
270+
#endif
271+
266272
#endif /* __ASM_INSN_DEF_H */

arch/riscv/include/asm/processor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
#endif
5353

5454
#ifndef __ASSEMBLY__
55-
#include <linux/cpumask.h>
5655

5756
struct task_struct;
5857
struct pt_regs;

arch/riscv/kernel/cpufeature.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
3333

3434
static bool any_cpu_has_zicboz;
35+
static bool any_cpu_has_zicbop;
3536
static bool any_cpu_has_zicbom;
3637

3738
unsigned long elf_hwcap __read_mostly;
@@ -119,6 +120,21 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
119120
return 0;
120121
}
121122

123+
static int riscv_ext_zicbop_validate(const struct riscv_isa_ext_data *data,
124+
const unsigned long *isa_bitmap)
125+
{
126+
if (!riscv_cbop_block_size) {
127+
pr_err("Zicbop detected in ISA string, disabling as no cbop-block-size found\n");
128+
return -EINVAL;
129+
}
130+
if (!is_power_of_2(riscv_cbop_block_size)) {
131+
pr_err("Zicbop disabled as cbop-block-size present, but is not a power-of-2\n");
132+
return -EINVAL;
133+
}
134+
any_cpu_has_zicbop = true;
135+
return 0;
136+
}
137+
122138
static int riscv_ext_f_validate(const struct riscv_isa_ext_data *data,
123139
const unsigned long *isa_bitmap)
124140
{
@@ -442,6 +458,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
442458
__RISCV_ISA_EXT_SUPERSET_VALIDATE(v, RISCV_ISA_EXT_v, riscv_v_exts, riscv_ext_vector_float_validate),
443459
__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
444460
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts, riscv_ext_zicbom_validate),
461+
__RISCV_ISA_EXT_DATA_VALIDATE(zicbop, RISCV_ISA_EXT_ZICBOP, riscv_ext_zicbop_validate),
445462
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, riscv_ext_zicboz_validate),
446463
__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
447464
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
@@ -1112,6 +1129,10 @@ void __init riscv_user_isa_enable(void)
11121129
current->thread.envcfg |= ENVCFG_CBCFE;
11131130
else if (any_cpu_has_zicbom)
11141131
pr_warn("Zicbom disabled as it is unavailable on some harts\n");
1132+
1133+
if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOP) &&
1134+
any_cpu_has_zicbop)
1135+
pr_warn("Zicbop disabled as it is unavailable on some harts\n");
11151136
}
11161137

11171138
#ifdef CONFIG_RISCV_ALTERNATIVE

arch/riscv/mm/cacheflush.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ EXPORT_SYMBOL_GPL(riscv_cbom_block_size);
101101
unsigned int riscv_cboz_block_size;
102102
EXPORT_SYMBOL_GPL(riscv_cboz_block_size);
103103

104+
unsigned int riscv_cbop_block_size;
105+
EXPORT_SYMBOL_GPL(riscv_cbop_block_size);
106+
104107
static void __init cbo_get_block_size(struct device_node *node,
105108
const char *name, u32 *block_size,
106109
unsigned long *first_hartid)
@@ -125,8 +128,8 @@ static void __init cbo_get_block_size(struct device_node *node,
125128

126129
void __init riscv_init_cbo_blocksizes(void)
127130
{
128-
unsigned long cbom_hartid, cboz_hartid;
129-
u32 cbom_block_size = 0, cboz_block_size = 0;
131+
unsigned long cbom_hartid, cboz_hartid, cbop_hartid;
132+
u32 cbom_block_size = 0, cboz_block_size = 0, cbop_block_size = 0;
130133
struct device_node *node;
131134
struct acpi_table_header *rhct;
132135
acpi_status status;
@@ -138,13 +141,15 @@ void __init riscv_init_cbo_blocksizes(void)
138141
&cbom_block_size, &cbom_hartid);
139142
cbo_get_block_size(node, "riscv,cboz-block-size",
140143
&cboz_block_size, &cboz_hartid);
144+
cbo_get_block_size(node, "riscv,cbop-block-size",
145+
&cbop_block_size, &cbop_hartid);
141146
}
142147
} else {
143148
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
144149
if (ACPI_FAILURE(status))
145150
return;
146151

147-
acpi_get_cbo_block_size(rhct, &cbom_block_size, &cboz_block_size, NULL);
152+
acpi_get_cbo_block_size(rhct, &cbom_block_size, &cboz_block_size, &cbop_block_size);
148153
acpi_put_table((struct acpi_table_header *)rhct);
149154
}
150155

@@ -153,6 +158,9 @@ void __init riscv_init_cbo_blocksizes(void)
153158

154159
if (cboz_block_size)
155160
riscv_cboz_block_size = cboz_block_size;
161+
162+
if (cbop_block_size)
163+
riscv_cbop_block_size = cbop_block_size;
156164
}
157165

158166
#ifdef CONFIG_SMP

0 commit comments

Comments
 (0)