mirror of
https://github.com/torvalds/linux.git
synced 2026-05-21 13:27:57 +02:00
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 <guoren@kernel.org> Signed-off-by: Guo Ren <guoren@kernel.org> Tested-by: Andrea Parri <parri.andrea@gmail.com> Link: https://lore.kernel.org/r/20250421142441.395849-3-alexghiti@rivosinc.com Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
This commit is contained in:
parent
f0f4e64b9e
commit
8d496b5a98
|
|
@ -842,6 +842,21 @@ config RISCV_ISA_ZICBOZ
|
|||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
config RISCV_ISA_ZICBOP
|
||||
bool "Zicbop extension support for cache block prefetch"
|
||||
depends on MMU
|
||||
depends on RISCV_ALTERNATIVE
|
||||
default y
|
||||
help
|
||||
Adds support to dynamically detect the presence of the ZICBOP
|
||||
extension (Cache Block Prefetch Operations) and enable its
|
||||
usage.
|
||||
|
||||
The Zicbop extension can be used to prefetch cache blocks for
|
||||
read/write fetch.
|
||||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
|
||||
def_bool y
|
||||
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@
|
|||
#include <asm/cmpxchg.h>
|
||||
#include <asm/fence.h>
|
||||
|
||||
#define nop() __asm__ __volatile__ ("nop")
|
||||
#define __nops(n) ".rept " #n "\nnop\n.endr\n"
|
||||
#define nops(n) __asm__ __volatile__ (__nops(n))
|
||||
|
||||
|
||||
/* These barriers need to enforce ordering on both devices or memory. */
|
||||
#define __mb() RISCV_FENCE(iorw, iorw)
|
||||
#define __rmb() RISCV_FENCE(ir, ir)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
|
|||
|
||||
extern unsigned int riscv_cbom_block_size;
|
||||
extern unsigned int riscv_cboz_block_size;
|
||||
extern unsigned int riscv_cbop_block_size;
|
||||
void riscv_init_cbo_blocksizes(void);
|
||||
|
||||
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@
|
|||
#define RISCV_ISA_EXT_ZVFBFWMA 96
|
||||
#define RISCV_ISA_EXT_ZAAMO 97
|
||||
#define RISCV_ISA_EXT_ZALRSC 98
|
||||
#define RISCV_ISA_EXT_ZICBOP 99
|
||||
|
||||
#define RISCV_ISA_EXT_XLINUXENVCFG 127
|
||||
|
||||
|
|
|
|||
|
|
@ -263,4 +263,10 @@
|
|||
|
||||
#define RISCV_INSN_NOP4 _AC(0x00000013, U)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define nop() __asm__ __volatile__ ("nop")
|
||||
#define __nops(n) ".rept " #n "\nnop\n.endr\n"
|
||||
#define nops(n) __asm__ __volatile__ (__nops(n))
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_INSN_DEF_H */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
struct task_struct;
|
||||
struct pt_regs;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
|
||||
|
||||
static bool any_cpu_has_zicboz;
|
||||
static bool any_cpu_has_zicbop;
|
||||
static bool any_cpu_has_zicbom;
|
||||
|
||||
unsigned long elf_hwcap __read_mostly;
|
||||
|
|
@ -119,6 +120,21 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_zicbop_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!riscv_cbop_block_size) {
|
||||
pr_err("Zicbop detected in ISA string, disabling as no cbop-block-size found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!is_power_of_2(riscv_cbop_block_size)) {
|
||||
pr_err("Zicbop disabled as cbop-block-size present, but is not a power-of-2\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
any_cpu_has_zicbop = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_f_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
|
|
@ -442,6 +458,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
|||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(v, RISCV_ISA_EXT_v, riscv_v_exts, riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts, riscv_ext_zicbom_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zicbop, RISCV_ISA_EXT_ZICBOP, riscv_ext_zicbop_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, riscv_ext_zicboz_validate),
|
||||
__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
|
||||
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
|
||||
|
|
@ -1112,6 +1129,10 @@ void __init riscv_user_isa_enable(void)
|
|||
current->thread.envcfg |= ENVCFG_CBCFE;
|
||||
else if (any_cpu_has_zicbom)
|
||||
pr_warn("Zicbom disabled as it is unavailable on some harts\n");
|
||||
|
||||
if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOP) &&
|
||||
any_cpu_has_zicbop)
|
||||
pr_warn("Zicbop disabled as it is unavailable on some harts\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RISCV_ALTERNATIVE
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ EXPORT_SYMBOL_GPL(riscv_cbom_block_size);
|
|||
unsigned int riscv_cboz_block_size;
|
||||
EXPORT_SYMBOL_GPL(riscv_cboz_block_size);
|
||||
|
||||
unsigned int riscv_cbop_block_size;
|
||||
EXPORT_SYMBOL_GPL(riscv_cbop_block_size);
|
||||
|
||||
static void __init cbo_get_block_size(struct device_node *node,
|
||||
const char *name, u32 *block_size,
|
||||
unsigned long *first_hartid)
|
||||
|
|
@ -125,8 +128,8 @@ static void __init cbo_get_block_size(struct device_node *node,
|
|||
|
||||
void __init riscv_init_cbo_blocksizes(void)
|
||||
{
|
||||
unsigned long cbom_hartid, cboz_hartid;
|
||||
u32 cbom_block_size = 0, cboz_block_size = 0;
|
||||
unsigned long cbom_hartid, cboz_hartid, cbop_hartid;
|
||||
u32 cbom_block_size = 0, cboz_block_size = 0, cbop_block_size = 0;
|
||||
struct device_node *node;
|
||||
struct acpi_table_header *rhct;
|
||||
acpi_status status;
|
||||
|
|
@ -138,13 +141,15 @@ void __init riscv_init_cbo_blocksizes(void)
|
|||
&cbom_block_size, &cbom_hartid);
|
||||
cbo_get_block_size(node, "riscv,cboz-block-size",
|
||||
&cboz_block_size, &cboz_hartid);
|
||||
cbo_get_block_size(node, "riscv,cbop-block-size",
|
||||
&cbop_block_size, &cbop_hartid);
|
||||
}
|
||||
} else {
|
||||
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
acpi_get_cbo_block_size(rhct, &cbom_block_size, &cboz_block_size, NULL);
|
||||
acpi_get_cbo_block_size(rhct, &cbom_block_size, &cboz_block_size, &cbop_block_size);
|
||||
acpi_put_table((struct acpi_table_header *)rhct);
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +158,9 @@ void __init riscv_init_cbo_blocksizes(void)
|
|||
|
||||
if (cboz_block_size)
|
||||
riscv_cboz_block_size = cboz_block_size;
|
||||
|
||||
if (cbop_block_size)
|
||||
riscv_cbop_block_size = cbop_block_size;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user