Commit 7ea5a736 authored by Andrew Jones's avatar Andrew Jones Committed by Palmer Dabbelt

RISC-V: Add Zicboz detection and block size parsing

Parse "riscv,cboz-block-size" from the DT by piggybacking on Zicbom's
riscv_init_cbom_blocksize(). Additionally check the DT for the presence
of the "zicboz" extension and, when it's present, validate the parsed
cboz block size as we do Zicbom's cbom block size with
riscv_isa_extension_check().
Signed-off-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Reviewed-by: default avatarHeiko Stuebner <heiko@sntech.de>
Reviewed-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230224162631.405473-5-ajones@ventanamicro.comSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent ea20f117
...@@ -50,7 +50,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local); ...@@ -50,7 +50,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern unsigned int riscv_cbom_block_size; extern unsigned int riscv_cbom_block_size;
void riscv_init_cbom_blocksize(void); extern unsigned int riscv_cboz_block_size;
void riscv_init_cbo_blocksizes(void);
#ifdef CONFIG_RISCV_DMA_NONCOHERENT #ifdef CONFIG_RISCV_DMA_NONCOHERENT
void riscv_noncoherent_supported(void); void riscv_noncoherent_supported(void);
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#define RISCV_ISA_EXT_ZBB 30 #define RISCV_ISA_EXT_ZBB 30
#define RISCV_ISA_EXT_ZICBOM 31 #define RISCV_ISA_EXT_ZICBOM 31
#define RISCV_ISA_EXT_ZIHINTPAUSE 32 #define RISCV_ISA_EXT_ZIHINTPAUSE 32
#define RISCV_ISA_EXT_ZICBOZ 33
#define RISCV_ISA_EXT_MAX 64 #define RISCV_ISA_EXT_MAX 64
#define RISCV_ISA_EXT_NAME_LEN_MAX 32 #define RISCV_ISA_EXT_NAME_LEN_MAX 32
......
...@@ -186,6 +186,7 @@ arch_initcall(riscv_cpuinfo_init); ...@@ -186,6 +186,7 @@ arch_initcall(riscv_cpuinfo_init);
*/ */
static struct riscv_isa_ext_data isa_ext_arr[] = { static struct riscv_isa_ext_data isa_ext_arr[] = {
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM), __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
__RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE), __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB), __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
......
...@@ -74,6 +74,15 @@ static bool riscv_isa_extension_check(int id) ...@@ -74,6 +74,15 @@ static bool riscv_isa_extension_check(int id)
return false; return false;
} }
return true; return true;
case RISCV_ISA_EXT_ZICBOZ:
if (!riscv_cboz_block_size) {
pr_err("Zicboz detected in ISA string, but no cboz-block-size found\n");
return false;
} else if (!is_power_of_2(riscv_cboz_block_size)) {
pr_err("cboz-block-size present, but is not a power-of-2\n");
return false;
}
return true;
} }
return true; return true;
...@@ -222,6 +231,7 @@ void __init riscv_fill_hwcap(void) ...@@ -222,6 +231,7 @@ void __init riscv_fill_hwcap(void)
SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT); SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB); SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM); SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
SET_ISA_EXT_MAP("zicboz", RISCV_ISA_EXT_ZICBOZ);
SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE); SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
} }
#undef SET_ISA_EXT_MAP #undef SET_ISA_EXT_MAP
......
...@@ -297,7 +297,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -297,7 +297,7 @@ void __init setup_arch(char **cmdline_p)
setup_smp(); setup_smp();
#endif #endif
riscv_init_cbom_blocksize(); riscv_init_cbo_blocksizes();
riscv_fill_hwcap(); riscv_fill_hwcap();
apply_boot_alternatives(); apply_boot_alternatives();
if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) && if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
......
...@@ -100,6 +100,9 @@ void flush_icache_pte(pte_t pte) ...@@ -100,6 +100,9 @@ void flush_icache_pte(pte_t pte)
unsigned int riscv_cbom_block_size; unsigned int riscv_cbom_block_size;
EXPORT_SYMBOL_GPL(riscv_cbom_block_size); EXPORT_SYMBOL_GPL(riscv_cbom_block_size);
unsigned int riscv_cboz_block_size;
EXPORT_SYMBOL_GPL(riscv_cboz_block_size);
static void cbo_get_block_size(struct device_node *node, static void cbo_get_block_size(struct device_node *node,
const char *name, u32 *block_size, const char *name, u32 *block_size,
unsigned long *first_hartid) unsigned long *first_hartid)
...@@ -122,19 +125,23 @@ static void cbo_get_block_size(struct device_node *node, ...@@ -122,19 +125,23 @@ static void cbo_get_block_size(struct device_node *node,
} }
} }
void riscv_init_cbom_blocksize(void) void riscv_init_cbo_blocksizes(void)
{ {
unsigned long cbom_hartid, cboz_hartid;
u32 cbom_block_size = 0, cboz_block_size = 0;
struct device_node *node; struct device_node *node;
unsigned long cbom_hartid;
u32 probed_block_size;
probed_block_size = 0;
for_each_of_cpu_node(node) { for_each_of_cpu_node(node) {
/* set block-size for cbom extension if available */ /* set block-size for cbom and/or cboz extension if available */
cbo_get_block_size(node, "riscv,cbom-block-size", cbo_get_block_size(node, "riscv,cbom-block-size",
&probed_block_size, &cbom_hartid); &cbom_block_size, &cbom_hartid);
cbo_get_block_size(node, "riscv,cboz-block-size",
&cboz_block_size, &cboz_hartid);
} }
if (probed_block_size) if (cbom_block_size)
riscv_cbom_block_size = probed_block_size; riscv_cbom_block_size = cbom_block_size;
if (cboz_block_size)
riscv_cboz_block_size = cboz_block_size;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment