OSDN Git Service

RISC-V: Add Zicboz detection and block size parsing
authorAndrew Jones <ajones@ventanamicro.com>
Fri, 24 Feb 2023 16:26:27 +0000 (17:26 +0100)
committerPalmer Dabbelt <palmer@rivosinc.com>
Wed, 15 Mar 2023 04:26:04 +0000 (21:26 -0700)
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: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230224162631.405473-5-ajones@ventanamicro.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/cacheflush.h
arch/riscv/include/asm/hwcap.h
arch/riscv/kernel/cpu.c
arch/riscv/kernel/cpufeature.c
arch/riscv/kernel/setup.c
arch/riscv/mm/cacheflush.c

index 03e3b95..8091b8b 100644 (file)
@@ -50,7 +50,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
 #endif /* CONFIG_SMP */
 
 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
 void riscv_noncoherent_supported(void);
index e3021b2..5955fbe 100644 (file)
@@ -42,6 +42,7 @@
 #define RISCV_ISA_EXT_ZBB              30
 #define RISCV_ISA_EXT_ZICBOM           31
 #define RISCV_ISA_EXT_ZIHINTPAUSE      32
+#define RISCV_ISA_EXT_ZICBOZ           33
 
 #define RISCV_ISA_EXT_MAX              64
 #define RISCV_ISA_EXT_NAME_LEN_MAX     32
index 8400f0c..1b04112 100644 (file)
@@ -186,6 +186,7 @@ arch_initcall(riscv_cpuinfo_init);
  */
 static struct riscv_isa_ext_data isa_ext_arr[] = {
        __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(zbb, RISCV_ISA_EXT_ZBB),
        __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
index 6569d96..538779d 100644 (file)
@@ -74,6 +74,15 @@ static bool riscv_isa_extension_check(int id)
                        return false;
                }
                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;
@@ -222,6 +231,7 @@ void __init riscv_fill_hwcap(void)
                                SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
                                SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
                                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);
                        }
 #undef SET_ISA_EXT_MAP
index 376d282..5d3184c 100644 (file)
@@ -297,7 +297,7 @@ void __init setup_arch(char **cmdline_p)
        setup_smp();
 #endif
 
-       riscv_init_cbom_blocksize();
+       riscv_init_cbo_blocksizes();
        riscv_fill_hwcap();
        apply_boot_alternatives();
        if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
index 9f37c7a..632d6d0 100644 (file)
@@ -100,6 +100,9 @@ void flush_icache_pte(pte_t pte)
 unsigned int 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,
                               const char *name, u32 *block_size,
                               unsigned long *first_hartid)
@@ -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;
-       unsigned long cbom_hartid;
-       u32 probed_block_size;
 
-       probed_block_size = 0;
        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",
-                                  &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)
-               riscv_cbom_block_size = probed_block_size;
+       if (cbom_block_size)
+               riscv_cbom_block_size = cbom_block_size;
+
+       if (cboz_block_size)
+               riscv_cboz_block_size = cboz_block_size;
 }