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>
 #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);
 
 #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
 
  */
 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),
 
                        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;
                                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
 
        setup_smp();
 #endif
 
-       riscv_init_cbom_blocksize();
+       riscv_init_cbo_blocksizes();
        riscv_fill_hwcap();
        apply_boot_alternatives();
        if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
 
 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)
        }
 }
 
-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;
 }