From 9c4d760637b01512c28987b1ca48672ab1e7f4b9 Mon Sep 17 00:00:00 2001 From: E Shattow Date: Tue, 31 Dec 2024 22:35:57 -0800 Subject: [PATCH 1/9] riscv: dts: starfive: split out visionfive2 target specific configuration Split out StarFive VisionFive2 multi-board target specific configuration into starfive-visionfive2-binman.dtsi in preparation for removal of jh7110-u-boot and jh7110-common-u-boot in part or whole as sent upstream. Signed-off-by: E Shattow Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/dts/jh7110-common-u-boot.dtsi | 95 ---------------- arch/riscv/dts/jh7110-milkv-mars-u-boot.dtsi | 1 + .../dts/jh7110-pine64-star64-u-boot.dtsi | 1 + ...10-starfive-visionfive-2-v1.2a-u-boot.dtsi | 1 + ...10-starfive-visionfive-2-v1.3b-u-boot.dtsi | 1 + .../dts/starfive-visionfive2-binman.dtsi | 102 ++++++++++++++++++ 6 files changed, 106 insertions(+), 95 deletions(-) create mode 100644 arch/riscv/dts/starfive-visionfive2-binman.dtsi diff --git a/arch/riscv/dts/jh7110-common-u-boot.dtsi b/arch/riscv/dts/jh7110-common-u-boot.dtsi index 7871294e90d..6d85b2d91a7 100644 --- a/arch/riscv/dts/jh7110-common-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-common-u-boot.dtsi @@ -3,7 +3,6 @@ * Copyright (C) 2023 StarFive Technology Co., Ltd. */ -#include "binman.dtsi" #include "jh7110-u-boot.dtsi" / { aliases { @@ -19,11 +18,6 @@ bootph-pre-ram; }; - config { - bootph-pre-ram; - u-boot,spl-payload-offset = <0x100000>; - }; - memory@40000000 { bootph-pre-ram; }; @@ -104,92 +98,3 @@ pagesize = <16>; }; }; - -&binman { - itb { - fit { - images { - fdt-jh7110-milkv-mars { - description = "jh7110-milkv-mars"; - load = <0x40400000>; - compression = "none"; - - blob-ext { - filename = "dts/upstream/src/riscv/starfive/jh7110-milkv-mars.dtb"; - }; - }; - - fdt-jh7110-pine64-star64 { - description = "jh7110-pine64-star64"; - load = <0x40400000>; - compression = "none"; - - blob-ext { - filename = "dts/upstream/src/riscv/starfive/jh7110-pine64-star64.dtb"; - }; - }; - - fdt-jh7110-starfive-visionfive-2-v1.2a { - description = "jh7110-starfive-visionfive-2-v1.2a"; - load = <0x40400000>; - compression = "none"; - - blob-ext { - filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.2a.dtb"; - }; - }; - - fdt-jh7110-starfive-visionfive-2-v1.3b { - description = "jh7110-starfive-visionfive-2-v1.3b"; - load = <0x40400000>; - compression = "none"; - - blob-ext { - filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.3b.dtb"; - }; - }; - }; - - configurations { - conf-jh7110-milkv-mars { - description = "jh7110-milkv-mars"; - firmware = "opensbi"; - loadables = "uboot"; - fdt = "fdt-jh7110-milkv-mars"; - }; - - conf-jh7110-pine64-star64 { - description = "jh7110-pine64-star64"; - firmware = "opensbi"; - loadables = "uboot"; - fdt = "fdt-jh7110-pine64-star64"; - }; - - conf-jh7110-starfive-visionfive-2-v1.2a { - description = "jh7110-starfive-visionfive-2-v1.2a"; - firmware = "opensbi"; - loadables = "uboot"; - fdt = "fdt-jh7110-starfive-visionfive-2-v1.2a"; - }; - - conf-jh7110-starfive-visionfive-2-v1.3b { - description = "jh7110-starfive-visionfive-2-v1.3b"; - firmware = "opensbi"; - loadables = "uboot"; - fdt = "fdt-jh7110-starfive-visionfive-2-v1.3b"; - }; - }; - }; - }; - - spl-img { - filename = "spl/u-boot-spl.bin.normal.out"; - - mkimage { - args = "-T sfspl"; - - u-boot-spl { - }; - }; - }; -}; diff --git a/arch/riscv/dts/jh7110-milkv-mars-u-boot.dtsi b/arch/riscv/dts/jh7110-milkv-mars-u-boot.dtsi index 9df1e5db553..ab882d07f6f 100644 --- a/arch/riscv/dts/jh7110-milkv-mars-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-milkv-mars-u-boot.dtsi @@ -4,3 +4,4 @@ */ #include "jh7110-common-u-boot.dtsi" +#include "starfive-visionfive2-binman.dtsi" diff --git a/arch/riscv/dts/jh7110-pine64-star64-u-boot.dtsi b/arch/riscv/dts/jh7110-pine64-star64-u-boot.dtsi index 9df1e5db553..ab882d07f6f 100644 --- a/arch/riscv/dts/jh7110-pine64-star64-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-pine64-star64-u-boot.dtsi @@ -4,3 +4,4 @@ */ #include "jh7110-common-u-boot.dtsi" +#include "starfive-visionfive2-binman.dtsi" diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi index 9df1e5db553..ab882d07f6f 100644 --- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi @@ -4,3 +4,4 @@ */ #include "jh7110-common-u-boot.dtsi" +#include "starfive-visionfive2-binman.dtsi" diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi index e6bc6630dcd..874074174ff 100644 --- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi @@ -4,3 +4,4 @@ */ #include "jh7110-common-u-boot.dtsi" +#include "starfive-visionfive2-binman.dtsi" diff --git a/arch/riscv/dts/starfive-visionfive2-binman.dtsi b/arch/riscv/dts/starfive-visionfive2-binman.dtsi new file mode 100644 index 00000000000..4cce001e80d --- /dev/null +++ b/arch/riscv/dts/starfive-visionfive2-binman.dtsi @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2023 StarFive Technology Co., Ltd. + */ + +#include "binman.dtsi" + +/ { + config { + bootph-pre-ram; + u-boot,spl-payload-offset = <0x100000>; + }; +}; + +&binman { + itb { + fit { + images { + fdt-jh7110-milkv-mars { + description = "jh7110-milkv-mars"; + load = <0x40400000>; + compression = "none"; + + blob-ext { + filename = "dts/upstream/src/riscv/starfive/jh7110-milkv-mars.dtb"; + }; + }; + + fdt-jh7110-pine64-star64 { + description = "jh7110-pine64-star64"; + load = <0x40400000>; + compression = "none"; + + blob-ext { + filename = "dts/upstream/src/riscv/starfive/jh7110-pine64-star64.dtb"; + }; + }; + + fdt-jh7110-starfive-visionfive-2-v1.2a { + description = "jh7110-starfive-visionfive-2-v1.2a"; + load = <0x40400000>; + compression = "none"; + + blob-ext { + filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.2a.dtb"; + }; + }; + + fdt-jh7110-starfive-visionfive-2-v1.3b { + description = "jh7110-starfive-visionfive-2-v1.3b"; + load = <0x40400000>; + compression = "none"; + + blob-ext { + filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.3b.dtb"; + }; + }; + }; + + configurations { + conf-jh7110-milkv-mars { + description = "jh7110-milkv-mars"; + firmware = "opensbi"; + loadables = "uboot"; + fdt = "fdt-jh7110-milkv-mars"; + }; + + conf-jh7110-pine64-star64 { + description = "jh7110-pine64-star64"; + firmware = "opensbi"; + loadables = "uboot"; + fdt = "fdt-jh7110-pine64-star64"; + }; + + conf-jh7110-starfive-visionfive-2-v1.2a { + description = "jh7110-starfive-visionfive-2-v1.2a"; + firmware = "opensbi"; + loadables = "uboot"; + fdt = "fdt-jh7110-starfive-visionfive-2-v1.2a"; + }; + + conf-jh7110-starfive-visionfive-2-v1.3b { + description = "jh7110-starfive-visionfive-2-v1.3b"; + firmware = "opensbi"; + loadables = "uboot"; + fdt = "fdt-jh7110-starfive-visionfive-2-v1.3b"; + }; + }; + }; + }; + + spl-img { + filename = "spl/u-boot-spl.bin.normal.out"; + + mkimage { + args = "-T sfspl"; + + u-boot-spl { + }; + }; + }; +}; From ab15e20ea9c71c73003d8e165811b51dbf042ff7 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Mon, 6 Jan 2025 13:04:04 +0000 Subject: [PATCH 2/9] riscv: Enhance extension probing Enhance the existing extension probing mechanism by adding support for more extensions and probing using the "riscv,isa" property. This patch is ported from the latest upstream linux. Signed-off-by: Mayuresh Chitale Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/cpu/cpu.c | 557 ++++++++++++++++++++++++++++ arch/riscv/include/asm/cpufeature.h | 37 ++ arch/riscv/include/asm/hwcap.h | 105 ++++++ 3 files changed, 699 insertions(+) create mode 100644 arch/riscv/include/asm/cpufeature.h create mode 100644 arch/riscv/include/asm/hwcap.h diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index affe70081b5..f3f9f9f2351 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -14,8 +14,12 @@ #include #include #include +#include +#include #include #include +#include +#include /* * The variables here must be stored in the data section since they are used @@ -33,6 +37,559 @@ u32 available_harts_lock = 1; #endif #endif +/* Host ISA bitmap */ +static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __section(".data"); + +static unsigned int riscv_cbom_block_size __section(".data"); +static unsigned int riscv_cboz_block_size __section(".data"); +/** + * __riscv_isa_extension_available() - Check whether given extension + * is available or not + * + * @bit: bit position of the desired extension + * Return: true or false + * + */ +static bool __riscv_isa_extension_available(unsigned int bit) +{ + if (bit >= RISCV_ISA_EXT_MAX) + return false; + + return test_bit(bit, riscv_isa) ? true : false; +} + +inline unsigned int riscv_get_cbom_block_size(void) +{ + return riscv_cbom_block_size; +} + +inline unsigned int riscv_get_cboz_block_size(void) +{ + return riscv_cboz_block_size; +} + +static int riscv_ext_zicbom_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + struct udevice *dev; + + if (!CONFIG_IS_ENABLED(RISCV_ISA_ZICBOM) || riscv_cbom_block_size) + return 0; + + uclass_first_device(UCLASS_CPU, &dev); + if (!dev) { + log_info("Failed to get cpu device!\n"); + return -ENXIO; + } + + if (!dev_read_u32(dev, "riscv,cbom-block-size", + &riscv_cbom_block_size)) { + if (!riscv_cbom_block_size) { + log_err("Zicbom detected in ISA string, disabling as no cbom-block-size found\n"); + return -EINVAL; + } + if (!is_power_of_2(riscv_cbom_block_size)) { + log_err("Zicbom disabled as cbom-block-size present, but is not a power-of-2\n"); + return -EINVAL; + } + return 0; + } else { + return -EINVAL; + } +} + +static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + struct udevice *dev; + + if (!CONFIG_IS_ENABLED(RISCV_ISA_ZICBOM) || riscv_cboz_block_size) + return 0; + + uclass_first_device(UCLASS_CPU, &dev); + if (!dev) { + log_debug("Failed to get cpu device!\n"); + return -ENXIO; + } + + if (!dev_read_u32(dev, "riscv,cboz-block-size", + &riscv_cboz_block_size)) { + if (!riscv_cboz_block_size) { + log_err("Zicboz detected in ISA string, disabling as no cboz-block-size found\n"); + return -EINVAL; + } + if (!is_power_of_2(riscv_cboz_block_size)) { + log_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n"); + return -EINVAL; + } + return 0; + } else { + return -EINVAL; + } +} + +static int riscv_ext_zca_depends(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (__riscv_isa_extension_available(RISCV_ISA_EXT_ZCA)) + return 0; + + return -EINVAL; +} + +static int riscv_ext_zcd_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (__riscv_isa_extension_available(RISCV_ISA_EXT_ZCA) && + __riscv_isa_extension_available(RISCV_ISA_EXT_d)) + return 0; + + return -EINVAL; +} + +static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (IS_ENABLED(CONFIG_64BIT)) + return -EINVAL; + + if (__riscv_isa_extension_available(RISCV_ISA_EXT_ZCA) && + __riscv_isa_extension_available(RISCV_ISA_EXT_f)) + return 0; + + return -EINVAL; +} + +static const unsigned int riscv_zk_bundled_exts[] = { + RISCV_ISA_EXT_ZBKB, + RISCV_ISA_EXT_ZBKC, + RISCV_ISA_EXT_ZBKX, + RISCV_ISA_EXT_ZKND, + RISCV_ISA_EXT_ZKNE, + RISCV_ISA_EXT_ZKR, + RISCV_ISA_EXT_ZKT, +}; + +static const unsigned int riscv_zkn_bundled_exts[] = { + RISCV_ISA_EXT_ZBKB, + RISCV_ISA_EXT_ZBKC, + RISCV_ISA_EXT_ZBKX, + RISCV_ISA_EXT_ZKND, + RISCV_ISA_EXT_ZKNE, + RISCV_ISA_EXT_ZKNH, +}; + +static const unsigned int riscv_zks_bundled_exts[] = { + RISCV_ISA_EXT_ZBKB, + RISCV_ISA_EXT_ZBKC, + RISCV_ISA_EXT_ZKSED, + RISCV_ISA_EXT_ZKSH +}; + +#define RISCV_ISA_EXT_ZVKN \ + RISCV_ISA_EXT_ZVKNED, \ + RISCV_ISA_EXT_ZVKNHB, \ + RISCV_ISA_EXT_ZVKB, \ + RISCV_ISA_EXT_ZVKT + +static const unsigned int riscv_zvkn_bundled_exts[] = { + RISCV_ISA_EXT_ZVKN +}; + +static const unsigned int riscv_zvknc_bundled_exts[] = { + RISCV_ISA_EXT_ZVKN, + RISCV_ISA_EXT_ZVBC +}; + +static const unsigned int riscv_zvkng_bundled_exts[] = { + RISCV_ISA_EXT_ZVKN, + RISCV_ISA_EXT_ZVKG +}; + +#define RISCV_ISA_EXT_ZVKS \ + RISCV_ISA_EXT_ZVKSED, \ + RISCV_ISA_EXT_ZVKSH, \ + RISCV_ISA_EXT_ZVKB, \ + RISCV_ISA_EXT_ZVKT + +static const unsigned int riscv_zvks_bundled_exts[] = { + RISCV_ISA_EXT_ZVKS +}; + +static const unsigned int riscv_zvksc_bundled_exts[] = { + RISCV_ISA_EXT_ZVKS, + RISCV_ISA_EXT_ZVBC +}; + +static const unsigned int riscv_zvksg_bundled_exts[] = { + RISCV_ISA_EXT_ZVKS, + RISCV_ISA_EXT_ZVKG +}; + +static const unsigned int riscv_zvbb_exts[] = { + RISCV_ISA_EXT_ZVKB +}; + +#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \ + RISCV_ISA_EXT_ZVE64X, \ + RISCV_ISA_EXT_ZVE32F, \ + RISCV_ISA_EXT_ZVE32X + +#define RISCV_ISA_EXT_ZVE64D_IMPLY_LIST \ + RISCV_ISA_EXT_ZVE64F, \ + RISCV_ISA_EXT_ZVE64F_IMPLY_LIST + +#define RISCV_ISA_EXT_V_IMPLY_LIST \ + RISCV_ISA_EXT_ZVE64D, \ + RISCV_ISA_EXT_ZVE64D_IMPLY_LIST + +static const unsigned int riscv_zve32f_exts[] = { + RISCV_ISA_EXT_ZVE32X +}; + +static const unsigned int riscv_zve64f_exts[] = { + RISCV_ISA_EXT_ZVE64F_IMPLY_LIST +}; + +static const unsigned int riscv_zve64d_exts[] = { + RISCV_ISA_EXT_ZVE64D_IMPLY_LIST +}; + +static const unsigned int riscv_v_exts[] = { + RISCV_ISA_EXT_V_IMPLY_LIST +}; + +static const unsigned int riscv_zve64x_exts[] = { + RISCV_ISA_EXT_ZVE32X, + RISCV_ISA_EXT_ZVE64X +}; + +/* + * While the [ms]envcfg CSRs were not defined until version 1.12 of the RISC-V + * privileged ISA, the existence of the CSRs is implied by any extension which + * specifies [ms]envcfg bit(s). Hence, we define a custom ISA extension for the + * existence of the CSR, and treat it as a subset of those other extensions. + */ +static const unsigned int riscv_xlinuxenvcfg_exts[] = { + RISCV_ISA_EXT_XLINUXENVCFG +}; + +/* + * Zc* spec states that: + * - C always implies Zca + * - C+F implies Zcf (RV32 only) + * - C+D implies Zcd + * + * These extensions will be enabled and then validated depending on the + * availability of F/D RV32. + */ +static const unsigned int riscv_c_exts[] = { + RISCV_ISA_EXT_ZCA, + RISCV_ISA_EXT_ZCF, + RISCV_ISA_EXT_ZCD, +}; + +/* + * The canonical order of ISA extension names in the ISA string is defined in + * chapter 27 of the unprivileged specification. + * + * Ordinarily, for in-kernel data structures, this order is unimportant but + * isa_ext_arr defines the order of the ISA string in /proc/cpuinfo. + * + * The specification uses vague wording, such as should, when it comes to + * ordering, so for our purposes the following rules apply: + * + * 1. All multi-letter extensions must be separated from other extensions by an + * underscore. + * + * 2. Additional standard extensions (starting with 'Z') must be sorted after + * single-letter extensions and before any higher-privileged extensions. + * + * 3. The first letter following the 'Z' conventionally indicates the most + * closely related alphabetical extension category, IMAFDQLCBKJTPVH. + * If multiple 'Z' extensions are named, they must be ordered first by + * category, then alphabetically within a category. + * + * 3. Standard supervisor-level extensions (starting with 'S') must be listed + * after standard unprivileged extensions. If multiple supervisor-level + * extensions are listed, they must be ordered alphabetically. + * + * 4. Standard machine-level extensions (starting with 'Zxm') must be listed + * after any lower-privileged, standard extensions. If multiple + * machine-level extensions are listed, they must be ordered + * alphabetically. + * + * 5. Non-standard extensions (starting with 'X') must be listed after all + * standard extensions. If multiple non-standard extensions are listed, they + * must be ordered alphabetically. + * + * An example string following the order is: + * rv64imadc_zifoo_zigoo_zafoo_sbar_scar_zxmbaz_xqux_xrux + * + * New entries to this struct should follow the ordering rules described above. + */ +const struct riscv_isa_ext_data riscv_isa_ext[] = { + __RISCV_ISA_EXT_DATA(i, RISCV_ISA_EXT_i), + __RISCV_ISA_EXT_DATA(m, RISCV_ISA_EXT_m), + __RISCV_ISA_EXT_DATA(a, RISCV_ISA_EXT_a), + __RISCV_ISA_EXT_DATA(f, RISCV_ISA_EXT_f), + __RISCV_ISA_EXT_DATA(d, RISCV_ISA_EXT_d), + __RISCV_ISA_EXT_DATA(q, RISCV_ISA_EXT_q), + __RISCV_ISA_EXT_SUPERSET(c, RISCV_ISA_EXT_c, riscv_c_exts), + __RISCV_ISA_EXT_SUPERSET(v, RISCV_ISA_EXT_v, riscv_v_exts), + __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_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, + riscv_ext_zicboz_validate), + __RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR), + __RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND), + __RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR), + __RISCV_ISA_EXT_DATA(zifencei, RISCV_ISA_EXT_ZIFENCEI), + __RISCV_ISA_EXT_DATA(zihintntl, RISCV_ISA_EXT_ZIHINTNTL), + __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE), + __RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM), + __RISCV_ISA_EXT_DATA(zimop, RISCV_ISA_EXT_ZIMOP), + __RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS), + __RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS), + __RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA), + __RISCV_ISA_EXT_DATA(zfh, RISCV_ISA_EXT_ZFH), + __RISCV_ISA_EXT_DATA(zfhmin, RISCV_ISA_EXT_ZFHMIN), + __RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA), + __RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends), + __RISCV_ISA_EXT_DATA_VALIDATE(zcd, RISCV_ISA_EXT_ZCD, riscv_ext_zcd_validate), + __RISCV_ISA_EXT_DATA_VALIDATE(zcf, RISCV_ISA_EXT_ZCF, riscv_ext_zcf_validate), + __RISCV_ISA_EXT_DATA_VALIDATE(zcmop, RISCV_ISA_EXT_ZCMOP, riscv_ext_zca_depends), + __RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA), + __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB), + __RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC), + __RISCV_ISA_EXT_DATA(zbkb, RISCV_ISA_EXT_ZBKB), + __RISCV_ISA_EXT_DATA(zbkc, RISCV_ISA_EXT_ZBKC), + __RISCV_ISA_EXT_DATA(zbkx, RISCV_ISA_EXT_ZBKX), + __RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS), + __RISCV_ISA_EXT_BUNDLE(zk, riscv_zk_bundled_exts), + __RISCV_ISA_EXT_BUNDLE(zkn, riscv_zkn_bundled_exts), + __RISCV_ISA_EXT_DATA(zknd, RISCV_ISA_EXT_ZKND), + __RISCV_ISA_EXT_DATA(zkne, RISCV_ISA_EXT_ZKNE), + __RISCV_ISA_EXT_DATA(zknh, RISCV_ISA_EXT_ZKNH), + __RISCV_ISA_EXT_DATA(zkr, RISCV_ISA_EXT_ZKR), + __RISCV_ISA_EXT_BUNDLE(zks, riscv_zks_bundled_exts), + __RISCV_ISA_EXT_DATA(zkt, RISCV_ISA_EXT_ZKT), + __RISCV_ISA_EXT_DATA(zksed, RISCV_ISA_EXT_ZKSED), + __RISCV_ISA_EXT_DATA(zksh, RISCV_ISA_EXT_ZKSH), + __RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO), + __RISCV_ISA_EXT_SUPERSET(zvbb, RISCV_ISA_EXT_ZVBB, riscv_zvbb_exts), + __RISCV_ISA_EXT_DATA(zvbc, RISCV_ISA_EXT_ZVBC), + __RISCV_ISA_EXT_SUPERSET(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts), + __RISCV_ISA_EXT_DATA(zve32x, RISCV_ISA_EXT_ZVE32X), + __RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts), + __RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts), + __RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts), + __RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH), + __RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN), + __RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB), + __RISCV_ISA_EXT_DATA(zvkg, RISCV_ISA_EXT_ZVKG), + __RISCV_ISA_EXT_BUNDLE(zvkn, riscv_zvkn_bundled_exts), + __RISCV_ISA_EXT_BUNDLE(zvknc, riscv_zvknc_bundled_exts), + __RISCV_ISA_EXT_DATA(zvkned, RISCV_ISA_EXT_ZVKNED), + __RISCV_ISA_EXT_BUNDLE(zvkng, riscv_zvkng_bundled_exts), + __RISCV_ISA_EXT_DATA(zvknha, RISCV_ISA_EXT_ZVKNHA), + __RISCV_ISA_EXT_DATA(zvknhb, RISCV_ISA_EXT_ZVKNHB), + __RISCV_ISA_EXT_BUNDLE(zvks, riscv_zvks_bundled_exts), + __RISCV_ISA_EXT_BUNDLE(zvksc, riscv_zvksc_bundled_exts), + __RISCV_ISA_EXT_DATA(zvksed, RISCV_ISA_EXT_ZVKSED), + __RISCV_ISA_EXT_DATA(zvksh, RISCV_ISA_EXT_ZVKSH), + __RISCV_ISA_EXT_BUNDLE(zvksg, riscv_zvksg_bundled_exts), + __RISCV_ISA_EXT_DATA(zvkt, RISCV_ISA_EXT_ZVKT), + __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM), + __RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_exts), + __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), + __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), + __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), + __RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_exts), + __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), + __RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL), + __RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT), + __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT), + __RISCV_ISA_EXT_DATA(svvptc, RISCV_ISA_EXT_SVVPTC), +}; + +const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext); + +static void riscv_isa_set_ext(const struct riscv_isa_ext_data *ext, unsigned long *bitmap) +{ + if (ext->id != RISCV_ISA_EXT_INVALID) + __set_bit(ext->id, bitmap); + + for (int i = 0; i < ext->subset_ext_size; i++) { + if (ext->subset_ext_ids[i] != RISCV_ISA_EXT_INVALID) + __set_bit(ext->subset_ext_ids[i], bitmap); + } +} + +static void match_isa_ext(const char *name, const char *name_end) +{ + for (int i = 0; i < riscv_isa_ext_count; i++) { + const struct riscv_isa_ext_data *ext = &riscv_isa_ext[i]; + + if ((name_end - name == strlen(ext->name)) && + !strncasecmp(name, ext->name, name_end - name)) { + if (ext->validate && !ext->validate(ext, riscv_isa)) + riscv_isa_set_ext(ext, riscv_isa); + break; + } + } +} + +static void riscv_parse_isa_string(const char *isa) +{ + /* + * For all possible cpus, we have already validated in + * the boot process that they at least contain "rv" and + * whichever of "32"/"64" this kernel supports, and so this + * section can be skipped. + */ + isa += 4; + + while (*isa) { + const char *ext = isa++; + const char *ext_end = isa; + bool ext_err = false; + + switch (*ext) { + case 'x': + case 'X': + log_warning("Vendor extensions are ignored in riscv,isa. Use riscv,isa-extensions instead."); + /* + * To skip an extension, we find its end. + * As multi-letter extensions must be split from other multi-letter + * extensions with an "_", the end of a multi-letter extension will + * either be the null character or the "_" at the start of the next + * multi-letter extension. + */ + for (; *isa && *isa != '_'; ++isa) + ; + ext_err = true; + break; + case 's': + /* + * Workaround for invalid single-letter 's' & 'u' (QEMU). + * No need to set the bit in riscv_isa as 's' & 'u' are + * not valid ISA extensions. It works unless the first + * multi-letter extension in the ISA string begins with + * "Su" and is not prefixed with an underscore. + */ + if (ext[-1] != '_' && ext[1] == 'u') { + ++isa; + ext_err = true; + break; + } + fallthrough; + case 'S': + case 'z': + case 'Z': + /* + * Before attempting to parse the extension itself, we find its end. + * As multi-letter extensions must be split from other multi-letter + * extensions with an "_", the end of a multi-letter extension will + * either be the null character or the "_" at the start of the next + * multi-letter extension. + * + * Next, as the extensions version is currently ignored, we + * eliminate that portion. This is done by parsing backwards from + * the end of the extension, removing any numbers. This may be a + * major or minor number however, so the process is repeated if a + * minor number was found. + * + * ext_end is intended to represent the first character *after* the + * name portion of an extension, but will be decremented to the last + * character itself while eliminating the extensions version number. + * A simple re-increment solves this problem. + */ + for (; *isa && *isa != '_'; ++isa) + if (unlikely(!isalnum(*isa))) + ext_err = true; + + ext_end = isa; + if (unlikely(ext_err)) + break; + + if (!isdigit(ext_end[-1])) + break; + + while (isdigit(*--ext_end)) + ; + + if (tolower(ext_end[0]) != 'p' || !isdigit(ext_end[-1])) { + ++ext_end; + break; + } + + while (isdigit(*--ext_end)) + ; + + ++ext_end; + break; + default: + /* + * Things are a little easier for single-letter extensions, as they + * are parsed forwards. + * + * After checking that our starting position is valid, we need to + * ensure that, when isa was incremented at the start of the loop, + * that it arrived at the start of the next extension. + * + * If we are already on a non-digit, there is nothing to do. Either + * we have a multi-letter extension's _, or the start of an + * extension. + * + * Otherwise we have found the current extension's major version + * number. Parse past it, and a subsequent p/minor version number + * if present. The `p` extension must not appear immediately after + * a number, so there is no fear of missing it. + * + */ + if (unlikely(!isalpha(*ext))) { + ext_err = true; + break; + } + + if (!isdigit(*isa)) + break; + + while (isdigit(*++isa)) + ; + + if (tolower(*isa) != 'p') + break; + + if (!isdigit(*++isa)) { + --isa; + break; + } + + while (isdigit(*++isa)) + ; + + break; + } + + /* + * The parser expects that at the start of an iteration isa points to the + * first character of the next extension. As we stop parsing an extension + * on meeting a non-alphanumeric character, an extra increment is needed + * where the succeeding extension is a multi-letter prefixed with an "_". + */ + if (*isa == '_') + ++isa; + + if (unlikely(ext_err)) + continue; + match_isa_ext(ext, ext_end); + } +} + static inline bool supports_extension(char ext) { #if CONFIG_IS_ENABLED(RISCV_MMODE) diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h new file mode 100644 index 00000000000..655180c993e --- /dev/null +++ b/arch/riscv/include/asm/cpufeature.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ASM_CPUFEATURE_H +#define _ASM_CPUFEATURE_H +struct riscv_isa_ext_data { + const unsigned int id; + const char *name; + const char *property; + const unsigned int *subset_ext_ids; + const unsigned int subset_ext_size; + int (*validate)(const struct riscv_isa_ext_data *data, const unsigned long *isa_bitmap); +}; + +#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \ + .name = #_name, \ + .property = #_name, \ + .id = _id, \ + .subset_ext_ids = _subset_exts, \ + .subset_ext_size = _subset_exts_size, \ + .validate = _validate \ +} + +#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL) +#define __RISCV_ISA_EXT_DATA_VALIDATE(_name, _id, _validate) \ + _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate) + +/* Used to declare pure "lasso" extension (Zk for instance) */ +#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \ + _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \ + ARRAY_SIZE(_bundled_exts), NULL) + +/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */ +#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \ + _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL) +#define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \ + _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate) +#endif diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h new file mode 100644 index 00000000000..aa68ada6b2b --- /dev/null +++ b/arch/riscv/include/asm/hwcap.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _ASM_RISCV_HWCAP_H +#define _ASM_RISCV_HWCAP_H + +#define RISCV_ISA_EXT_a ('a' - 'a') +#define RISCV_ISA_EXT_c ('c' - 'a') +#define RISCV_ISA_EXT_d ('d' - 'a') +#define RISCV_ISA_EXT_f ('f' - 'a') +#define RISCV_ISA_EXT_h ('h' - 'a') +#define RISCV_ISA_EXT_i ('i' - 'a') +#define RISCV_ISA_EXT_m ('m' - 'a') +#define RISCV_ISA_EXT_q ('q' - 'a') +#define RISCV_ISA_EXT_v ('v' - 'a') + +/* + * These macros represent the logical IDs of each multi-letter RISC-V ISA + * extension and are used in the ISA bitmap. The logical IDs start from + * RISCV_ISA_EXT_BASE, which allows the 0-25 range to be reserved for single + * letter extensions. The maximum, RISCV_ISA_EXT_MAX, is defined in order + * to allocate the bitmap and may be increased when necessary. + * + * New extensions should just be added to the bottom, rather than added + * alphabetically, in order to avoid unnecessary shuffling. + */ +#define RISCV_ISA_EXT_BASE 26 + +#define RISCV_ISA_EXT_SSCOFPMF 26 +#define RISCV_ISA_EXT_SSTC 27 +#define RISCV_ISA_EXT_SVINVAL 28 +#define RISCV_ISA_EXT_SVPBMT 29 +#define RISCV_ISA_EXT_ZBB 30 +#define RISCV_ISA_EXT_ZICBOM 31 +#define RISCV_ISA_EXT_ZIHINTPAUSE 32 +#define RISCV_ISA_EXT_SVNAPOT 33 +#define RISCV_ISA_EXT_ZICBOZ 34 +#define RISCV_ISA_EXT_SMAIA 35 +#define RISCV_ISA_EXT_SSAIA 36 +#define RISCV_ISA_EXT_ZBA 37 +#define RISCV_ISA_EXT_ZBS 38 +#define RISCV_ISA_EXT_ZICNTR 39 +#define RISCV_ISA_EXT_ZICSR 40 +#define RISCV_ISA_EXT_ZIFENCEI 41 +#define RISCV_ISA_EXT_ZIHPM 42 +#define RISCV_ISA_EXT_SMSTATEEN 43 +#define RISCV_ISA_EXT_ZICOND 44 +#define RISCV_ISA_EXT_ZBC 45 +#define RISCV_ISA_EXT_ZBKB 46 +#define RISCV_ISA_EXT_ZBKC 47 +#define RISCV_ISA_EXT_ZBKX 48 +#define RISCV_ISA_EXT_ZKND 49 +#define RISCV_ISA_EXT_ZKNE 50 +#define RISCV_ISA_EXT_ZKNH 51 +#define RISCV_ISA_EXT_ZKR 52 +#define RISCV_ISA_EXT_ZKSED 53 +#define RISCV_ISA_EXT_ZKSH 54 +#define RISCV_ISA_EXT_ZKT 55 +#define RISCV_ISA_EXT_ZVBB 56 +#define RISCV_ISA_EXT_ZVBC 57 +#define RISCV_ISA_EXT_ZVKB 58 +#define RISCV_ISA_EXT_ZVKG 59 +#define RISCV_ISA_EXT_ZVKNED 60 +#define RISCV_ISA_EXT_ZVKNHA 61 +#define RISCV_ISA_EXT_ZVKNHB 62 +#define RISCV_ISA_EXT_ZVKSED 63 +#define RISCV_ISA_EXT_ZVKSH 64 +#define RISCV_ISA_EXT_ZVKT 65 +#define RISCV_ISA_EXT_ZFH 66 +#define RISCV_ISA_EXT_ZFHMIN 67 +#define RISCV_ISA_EXT_ZIHINTNTL 68 +#define RISCV_ISA_EXT_ZVFH 69 +#define RISCV_ISA_EXT_ZVFHMIN 70 +#define RISCV_ISA_EXT_ZFA 71 +#define RISCV_ISA_EXT_ZTSO 72 +#define RISCV_ISA_EXT_ZACAS 73 +#define RISCV_ISA_EXT_ZVE32X 74 +#define RISCV_ISA_EXT_ZVE32F 75 +#define RISCV_ISA_EXT_ZVE64X 76 +#define RISCV_ISA_EXT_ZVE64F 77 +#define RISCV_ISA_EXT_ZVE64D 78 +#define RISCV_ISA_EXT_ZIMOP 79 +#define RISCV_ISA_EXT_ZCA 80 +#define RISCV_ISA_EXT_ZCB 81 +#define RISCV_ISA_EXT_ZCD 82 +#define RISCV_ISA_EXT_ZCF 83 +#define RISCV_ISA_EXT_ZCMOP 84 +#define RISCV_ISA_EXT_ZAWRS 85 +#define RISCV_ISA_EXT_SVVPTC 86 +#define RISCV_ISA_EXT_SMMPM 87 +#define RISCV_ISA_EXT_SMNPM 88 +#define RISCV_ISA_EXT_SSNPM 89 + +#define RISCV_ISA_EXT_XLINUXENVCFG 127 + +#define RISCV_ISA_EXT_MAX 128 +#define RISCV_ISA_EXT_INVALID U32_MAX + +#ifdef CONFIG_RISCV_M_MODE +#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA +#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SMNPM +#else +#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SSAIA +#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SSNPM +#endif + +#endif /* _ASM_RISCV_HWCAP_H */ From 4492c8db60f0cd452151e0cdfd1b5aaf671baaca Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Mon, 6 Jan 2025 13:04:05 +0000 Subject: [PATCH 3/9] riscv: Fallback to riscv,isa Update the cpu probing to fallback to "riscv,isa" property if "riscv,isa-extensions" is not available and modify the riscv CMO code to use the block size that was probed during cpu setup. Signed-off-by: Mayuresh Chitale Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/cpu/cpu.c | 71 +++++++++++++----------------------------- arch/riscv/lib/cache.c | 26 +++------------- 2 files changed, 25 insertions(+), 72 deletions(-) diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index f3f9f9f2351..06ecd92b9bc 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -595,55 +595,7 @@ static inline bool supports_extension(char ext) #if CONFIG_IS_ENABLED(RISCV_MMODE) return csr_read(CSR_MISA) & (1 << (ext - 'a')); #elif CONFIG_CPU - char sext[2] = {ext}; - struct udevice *dev; - const char *isa; - int ret, i; - - uclass_find_first_device(UCLASS_CPU, &dev); - if (!dev) { - debug("unable to find the RISC-V cpu device\n"); - return false; - } - - ret = dev_read_stringlist_search(dev, "riscv,isa-extensions", sext); - if (ret >= 0) - return true; - - /* - * Only if the property is not found (ENODATA) is the fallback to - * riscv,isa used, otherwise the extension is not present in this - * CPU. - */ - if (ret != -ENODATA) - return false; - - isa = dev_read_string(dev, "riscv,isa"); - if (!isa) - return false; - - /* - * Skip the first 4 characters (rv32|rv64). - */ - for (i = 4; i < sizeof(isa); i++) { - switch (isa[i]) { - case 's': - case 'x': - case 'z': - case '_': - case '\0': - /* - * Any of these characters mean the single - * letter extensions have all been consumed. - */ - return false; - default: - if (isa[i] == ext) - return true; - } - } - - return false; + return __riscv_isa_extension_available(ext); #else /* !CONFIG_CPU */ #warning "There is no way to determine the available extensions in S-mode." #warning "Please convert your board to use the RISC-V CPU driver." @@ -679,7 +631,26 @@ static void dummy_pending_ipi_clear(ulong hart, ulong arg0, ulong arg1) int riscv_cpu_setup(void) { - int __maybe_unused ret; + int ret = -ENODEV, ext_count, i; + const char *isa, **exts; + struct udevice *dev; + + uclass_find_first_device(UCLASS_CPU, &dev); + if (!dev) { + debug("unable to find the RISC-V cpu device\n"); + return ret; + } + + ext_count = dev_read_string_list(dev, "riscv,isa-extensions", &exts); + if (ext_count > 0) { + for (i = 0; i < ext_count; i++) + match_isa_ext(exts[i], exts[i] + strlen(exts[i])); + } else { + isa = dev_read_string(dev, "riscv,isa"); + if (!isa) + return ret; + riscv_parse_isa_string(isa); + } /* Enable FPU */ if (supports_extension('d') || supports_extension('f')) { diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c index e184d5e2059..71e4937ab54 100644 --- a/arch/riscv/lib/cache.c +++ b/arch/riscv/lib/cache.c @@ -24,7 +24,7 @@ enum { CBO_INVAL } riscv_cbo_ops; static int zicbom_block_size; - +extern unsigned int riscv_get_cbom_block_size(void); static inline void do_cbo_clean(unsigned long base) { asm volatile ("add a0, %0, zero\n" CBO_CLEAN(%0) :: @@ -79,25 +79,6 @@ void cbo_inval(unsigned long start, unsigned long end) cbo_op(CBO_INVAL, start, end); } -static int riscv_zicbom_init(void) -{ - struct udevice *dev; - - if (!CONFIG_IS_ENABLED(RISCV_ISA_ZICBOM) || zicbom_block_size) - return 1; - - uclass_first_device(UCLASS_CPU, &dev); - if (!dev) { - log_debug("Failed to get cpu device!\n"); - return 0; - } - - if (dev_read_u32(dev, "riscv,cbom-block-size", &zicbom_block_size)) - log_debug("riscv,cbom-block-size DT property not present\n"); - - return zicbom_block_size; -} - void invalidate_icache_all(void) { asm volatile ("fence.i" ::: "memory"); @@ -166,6 +147,7 @@ __weak int dcache_status(void) __weak void enable_caches(void) { - if (!riscv_zicbom_init()) - log_info("Zicbom not initialized.\n"); + zicbom_block_size = riscv_get_cbom_block_size(); + if (!zicbom_block_size) + log_debug("Zicbom not initialized.\n"); } From 6be961a75834ad4f6f42d034be7c5a4551fdc20e Mon Sep 17 00:00:00 2001 From: Yu-Chien Peter Lin Date: Fri, 10 Jan 2025 16:53:08 +0800 Subject: [PATCH 4/9] Kconfig: Add a default cache line size for RISC-V The RISC-V ISA profile RVA23U64 requires extension Zic64b (Cache blocks must be 64 bytes in size, naturally aligned in the address space). Some RISC-V platforms do not define the d-cache line size through SYS_CACHE_SHIFT_n. Set a default value of 64 bytes for such cases. Signed-off-by: Yu-Chien Peter Lin Reviewed-by: Heinrich Schuchardt Reviewed-by: Leo Yu-Chi Liang --- arch/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index bb2e7bedd10..b0190b1f415 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -52,7 +52,8 @@ config SYS_CACHELINE_SIZE default 64 if SYS_CACHE_SHIFT_6 default 32 if SYS_CACHE_SHIFT_5 default 16 if SYS_CACHE_SHIFT_4 - # Fall-back for MIPS + # Fall-back for MIPS and RISC-V + default 64 if RISCV default 32 if MIPS config LINKER_LIST_ALIGN From 892b31a1fb0b2c857bc31c60d3d0db091901a41a Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Wed, 15 Jan 2025 00:46:37 +0800 Subject: [PATCH 5/9] usb: dwc2: Add support for Canaan K230 Canaan Kendryte K230 SoC instantiates a dwc2 v4.30a core. This patch adds the compatible for it. Signed-off-by: Junhui Liu Reviewed-by: Leo Yu-Chi Liang --- doc/device-tree-bindings/usb/dwc2.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/device-tree-bindings/usb/dwc2.txt b/doc/device-tree-bindings/usb/dwc2.txt index 7a533f65934..9a87202d4b9 100644 --- a/doc/device-tree-bindings/usb/dwc2.txt +++ b/doc/device-tree-bindings/usb/dwc2.txt @@ -4,6 +4,7 @@ Platform DesignWare HS OTG USB 2.0 controller Required properties: - compatible : One of: - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. + - canaan,k230-otg: The DWC2 USB controller instance in the K230 SoC. - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC. - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; From a1135b7526ab8cd7bfd6f2d650bfcce1c9808402 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Wed, 15 Jan 2025 00:46:38 +0800 Subject: [PATCH 6/9] riscv: dts: canaan: Add basic device tree for K230 CanMV board Add initial dts for K230-CanMV powered by Canaan Kendryte K230 SoC, which has two RISC-V C908 cores, a big core with vector 1.0 extension and a small core without vector extension. This patch is basically comes from Linux Kernel [1] and it assumes u-boot is running on the big core. Additionally, bootctl and reboot nodes are added to support sysreset [2] and an clk_dummy node is added to satisfy dependencies for usb [3]. Currently, u-boot is booted by the vendor's u-boot-spl. To meet the requirements [4][5] of vendor's u-boot-spl for u-boot, a binman node with mkimage child node is added here, which will compress u-boot.bin with gzip and generate an image named "uboot" in the file u-boot-gz.img. [1] https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/log/?h=k230-basic [2] https://github.com/kendryte/k230_sdk/blob/v1.8/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/sysctl/sysctl_boot/sysctl_boot.c#L67 [3] https://lore.kernel.org/linux-riscv/tencent_AD84B436C2F31108B66B4739D6E306C5E80A@qq.com/ [4] https://github.com/kendryte/k230_sdk/blob/v1.8/src/little/uboot/board/canaan/common/k230_img.c#L306 [5] https://github.com/kendryte/k230_sdk/blob/v1.8/src/little/uboot/board/canaan/common/k230_img.c#L125 Signed-off-by: Junhui Liu Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/dts/Makefile | 1 + arch/riscv/dts/k230-canmv.dts | 31 ++++++ arch/riscv/dts/k230-u-boot.dtsi | 25 +++++ arch/riscv/dts/k230.dtsi | 175 ++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 arch/riscv/dts/k230-canmv.dts create mode 100644 arch/riscv/dts/k230-u-boot.dtsi create mode 100644 arch/riscv/dts/k230.dtsi diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index b64fc0daf3c..cf1872f3fdc 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -2,6 +2,7 @@ dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb dtb-$(CONFIG_TARGET_BANANAPI_F3) += k1-bananapi-f3.dtb +dtb-$(CONFIG_TARGET_K230_CANMV) += k230-canmv.dtb dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb dtb-$(CONFIG_TARGET_MILKV_DUO) += cv1800b-milkv-duo.dtb dtb-$(CONFIG_TARGET_LICHEERV_NANO) += sg2002-licheerv-nano-b.dtb diff --git a/arch/riscv/dts/k230-canmv.dts b/arch/riscv/dts/k230-canmv.dts new file mode 100644 index 00000000000..ced9c457cc2 --- /dev/null +++ b/arch/riscv/dts/k230-canmv.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2024 Yangyu Chen + * Copyright (C) 2025 Junhui Liu + */ + +/dts-v1/; +#include "k230.dtsi" + +/ { + model = "Canaan CanMV-K230"; + compatible = "canaan,canmv-k230", "canaan,kendryte-k230"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x20000000>; + }; +}; + +&uart0 { + status = "okay"; +}; + +/* onboard RTL8152 */ +&usb1 { + status = "okay"; +}; diff --git a/arch/riscv/dts/k230-u-boot.dtsi b/arch/riscv/dts/k230-u-boot.dtsi new file mode 100644 index 00000000000..bb66ad3c153 --- /dev/null +++ b/arch/riscv/dts/k230-u-boot.dtsi @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 Junhui Liu + */ + +#include + +/ { + binman: binman { + }; +}; + +&binman { + mkimage { + filename = "u-boot-gz.img"; + args = "-A", "riscv", "-T", "firmware", "-O", "u-boot", + "-C", "gzip", "-n", "uboot", + "-a", __stringify(CONFIG_TEXT_BASE), + "-e", __stringify(CONFIG_TEXT_BASE); + blob { + filename = "u-boot.bin"; + compress = "gzip"; + }; + }; +}; diff --git a/arch/riscv/dts/k230.dtsi b/arch/riscv/dts/k230.dtsi new file mode 100644 index 00000000000..cf596677de1 --- /dev/null +++ b/arch/riscv/dts/k230.dtsi @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2024 Yangyu Chen + * Copyright (C) 2025 Junhui Liu + */ + +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "canaan,kendryte-k230"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <27000000>; + + cpu@0 { + compatible = "thead,c908", "riscv"; + device_type = "cpu"; + reg = <0>; + riscv,isa = "rv64imafdcv_zicbom_zicbop_zicboz_zfh_zba_zbb_zbc_zbs_zvfh_svpbmt"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicbom", + "zicbop", "zicboz", "zicntr", "zicsr", "zifencei", + "zihpm", "zfh", "zba", "zbb", "zbc", "zbs", "zvfh", + "svpbmt"; + riscv,cbom-block-size = <64>; + riscv,cbop-block-size = <64>; + riscv,cboz-block-size = <64>; + mmu-type = "riscv,sv39"; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + }; + + apb_clk: apb-clk-clock { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + clock-output-names = "apb_clk"; + #clock-cells = <0>; + }; + + clk_dummy: clock-dummy { + compatible = "fixed-clock"; + clock-frequency = <0>; + clock-output-names = "clk_dummy"; + #clock-cells = <0>; + }; + + reboot: syscon-reboot { + compatible = "syscon-reboot"; + regmap = <&bootctl>; + offset = <0x60>; + mask = <0x10001>; + value = <0x10001>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&plic>; + #address-cells = <2>; + #size-cells = <2>; + dma-noncoherent; + ranges; + + bootctl: syscon@0x91102000 { + compatible = "syscon"; + reg = <0x0 0x91102000 0x0 0x1000>; + }; + + plic: interrupt-controller@f00000000 { + compatible = "canaan,k230-plic" ,"thead,c900-plic"; + reg = <0xf 0x00000000 0x0 0x04000000>; + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + riscv,ndev = <208>; + }; + + clint: timer@f04000000 { + compatible = "canaan,k230-clint", "thead,c900-clint"; + reg = <0xf 0x04000000 0x0 0x00010000>; + interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>; + }; + + uart0: serial@91400000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x91400000 0x0 0x1000>; + clocks = <&apb_clk>; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart1: serial@91401000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x91401000 0x0 0x1000>; + clocks = <&apb_clk>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart2: serial@91402000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x91402000 0x0 0x1000>; + clocks = <&apb_clk>; + interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart3: serial@91403000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x91403000 0x0 0x1000>; + clocks = <&apb_clk>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart4: serial@91404000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x91404000 0x0 0x1000>; + clocks = <&apb_clk>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + usb0: usb@91500000 { + compatible = "canaan,k230-otg", "snps,dwc2"; + reg = <0x0 0x91500000 0x0 0x40000>; + interrupts = <173 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_dummy>; + clock-names = "otg"; + g-rx-fifo-size = <512>; + g-np-tx-fifo-size = <64>; + g-tx-fifo-size = <512 1024 64 64 64 64>; + status = "disabled"; + }; + + usb1: usb@91540000 { + compatible = "canaan,k230-otg", "snps,dwc2"; + reg = <0x0 0x91540000 0x0 0x40000>; + interrupts = <174 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_dummy>; + clock-names = "otg"; + g-rx-fifo-size = <512>; + g-np-tx-fifo-size = <64>; + g-tx-fifo-size = <512 1024 64 64 64 64>; + status = "disabled"; + }; + }; +}; From 78d9ce3e36a48fff57648e247b53be1949803e48 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Wed, 15 Jan 2025 00:46:39 +0800 Subject: [PATCH 7/9] riscv: cpu: k230: Add support for Canaan Kendryte K230 SoC Add Canaan K230 SoC with sysreset support, running without cache enabled. Signed-off-by: Junhui Liu Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/Kconfig | 5 +++++ arch/riscv/cpu/k230/Kconfig | 14 ++++++++++++++ arch/riscv/cpu/k230/Makefile | 6 ++++++ arch/riscv/cpu/k230/cpu.c | 9 +++++++++ arch/riscv/cpu/k230/dram.c | 21 +++++++++++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 arch/riscv/cpu/k230/Kconfig create mode 100644 arch/riscv/cpu/k230/Makefile create mode 100644 arch/riscv/cpu/k230/cpu.c create mode 100644 arch/riscv/cpu/k230/dram.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index a160d24fb03..faf70cb5d4c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -14,6 +14,9 @@ config TARGET_ANDES_AE350 config TARGET_BANANAPI_F3 bool "Support BananaPi F3 Board" +config TARGET_K230_CANMV + bool "Support K230 CanMV Board" + config TARGET_LICHEERV_NANO bool "Support LicheeRV Nano Board" @@ -91,6 +94,7 @@ config SPL_ZERO_MEM_BEFORE_USE # board-specific options below source "board/andestech/ae350/Kconfig" source "board/aspeed/ibex_ast2700/Kconfig" +source "board/canaan/k230_canmv/Kconfig" source "board/emulation/qemu-riscv/Kconfig" source "board/microchip/mpfs_icicle/Kconfig" source "board/openpiton/riscv64/Kconfig" @@ -113,6 +117,7 @@ source "arch/riscv/cpu/ast2700/Kconfig" source "arch/riscv/cpu/generic/Kconfig" source "arch/riscv/cpu/jh7110/Kconfig" source "arch/riscv/cpu/k1/Kconfig" +source "arch/riscv/cpu/k230/Kconfig" # architecture-specific options below diff --git a/arch/riscv/cpu/k230/Kconfig b/arch/riscv/cpu/k230/Kconfig new file mode 100644 index 00000000000..d76ad92a049 --- /dev/null +++ b/arch/riscv/cpu/k230/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2025, Junhui Liu + +config CANAAN_K230 + bool + select ARCH_EARLY_INIT_R + select BINMAN + imply CPU + imply CPU_RISCV + imply RISCV_TIMER + imply CMD_CPU + imply SYSRESET + imply SYSRESET_SYSCON diff --git a/arch/riscv/cpu/k230/Makefile b/arch/riscv/cpu/k230/Makefile new file mode 100644 index 00000000000..6e321cf3ed1 --- /dev/null +++ b/arch/riscv/cpu/k230/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2025, Junhui Liu + +obj-y += dram.o +obj-y += cpu.o diff --git a/arch/riscv/cpu/k230/cpu.c b/arch/riscv/cpu/k230/cpu.c new file mode 100644 index 00000000000..417a25f0a8b --- /dev/null +++ b/arch/riscv/cpu/k230/cpu.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025, Junhui Liu + */ + +int cleanup_before_linux(void) +{ + return 0; +} diff --git a/arch/riscv/cpu/k230/dram.c b/arch/riscv/cpu/k230/dram.c new file mode 100644 index 00000000000..b2d3e4fd6a9 --- /dev/null +++ b/arch/riscv/cpu/k230/dram.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} From 9c402a54df3f641592d82f6833bb4b1af2e9aa10 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Wed, 15 Jan 2025 00:46:40 +0800 Subject: [PATCH 8/9] riscv: canaan: k230_canmv: Add initial support Add support for K230 CanMV board with serial console and usb otg support. It can boot via vendor's u-boot-spl and boot into Linux via tftp through the onboard RTL8152. Signed-off-by: Junhui Liu Reviewed-by: Leo Yu-Chi Liang --- board/canaan/k230_canmv/Kconfig | 19 +++++++++++++++++++ board/canaan/k230_canmv/MAINTAINERS | 6 ++++++ board/canaan/k230_canmv/Makefile | 5 +++++ board/canaan/k230_canmv/board.c | 9 +++++++++ configs/k230_canmv_defconfig | 19 +++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 board/canaan/k230_canmv/Kconfig create mode 100644 board/canaan/k230_canmv/MAINTAINERS create mode 100644 board/canaan/k230_canmv/Makefile create mode 100644 board/canaan/k230_canmv/board.c create mode 100644 configs/k230_canmv_defconfig diff --git a/board/canaan/k230_canmv/Kconfig b/board/canaan/k230_canmv/Kconfig new file mode 100644 index 00000000000..e793e9993e8 --- /dev/null +++ b/board/canaan/k230_canmv/Kconfig @@ -0,0 +1,19 @@ +if TARGET_K230_CANMV + +config SYS_BOARD + default "k230_canmv" + +config SYS_VENDOR + default "canaan" + +config SYS_CPU + default "k230" + +config TEXT_BASE + default 0x0 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select CANAAN_K230 + +endif diff --git a/board/canaan/k230_canmv/MAINTAINERS b/board/canaan/k230_canmv/MAINTAINERS new file mode 100644 index 00000000000..fb925e1b167 --- /dev/null +++ b/board/canaan/k230_canmv/MAINTAINERS @@ -0,0 +1,6 @@ +K230 CANMV +M: Junhui Liu +S: Maintained +F: board/canaan/k230_canmv/ +F: configs/k230_canmv_defconfig +F: doc/board/canaan/k230_canmv.rst diff --git a/board/canaan/k230_canmv/Makefile b/board/canaan/k230_canmv/Makefile new file mode 100644 index 00000000000..acab631106a --- /dev/null +++ b/board/canaan/k230_canmv/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2025, Junhui Liu + +obj-y += board.o diff --git a/board/canaan/k230_canmv/board.c b/board/canaan/k230_canmv/board.c new file mode 100644 index 00000000000..a705ee8f67b --- /dev/null +++ b/board/canaan/k230_canmv/board.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025, Junhui Liu + */ + +int board_init(void) +{ + return 0; +} diff --git a/configs/k230_canmv_defconfig b/configs/k230_canmv_defconfig new file mode 100644 index 00000000000..47fa1add2a9 --- /dev/null +++ b/configs/k230_canmv_defconfig @@ -0,0 +1,19 @@ +CONFIG_RISCV=y +CONFIG_SYS_MALLOC_F_LEN=0x40000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80400000 +CONFIG_DEFAULT_DEVICE_TREE="k230-canmv" +CONFIG_SYS_LOAD_ADDR=0xc000000 +CONFIG_TARGET_K230_CANMV=y +CONFIG_ARCH_RV64I=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="K230# " +CONFIG_CMD_USB=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SYS_NS16550=y +CONFIG_SYS_NS16550_MEM32=y +CONFIG_USB=y +CONFIG_USB_DWC2=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_RTL8152=y From b3ce35900cfa500a31fad652302a92cab604d6b5 Mon Sep 17 00:00:00 2001 From: Junhui Liu Date: Wed, 15 Jan 2025 00:46:41 +0800 Subject: [PATCH 9/9] doc: canaan: Add K230 CanMV board Add description of compiling u-boot for K230 CanMV. Since the vendor's u-boot-spl verifies u-boot header [1], it is necessary to use the Python script from vendor to add the header to the u-boot image. [1] https://github.com/kendryte/k230_sdk/blob/v1.8/src/little/uboot/board/canaan/common/k230_board_common.h#L52 Signed-off-by: Junhui Liu Reviewed-by: Leo Yu-Chi Liang --- doc/board/canaan/index.rst | 8 +++ doc/board/canaan/k230_canmv.rst | 88 +++++++++++++++++++++++++++++++++ doc/board/index.rst | 1 + 3 files changed, 97 insertions(+) create mode 100644 doc/board/canaan/index.rst create mode 100644 doc/board/canaan/k230_canmv.rst diff --git a/doc/board/canaan/index.rst b/doc/board/canaan/index.rst new file mode 100644 index 00000000000..e2892d2a7f3 --- /dev/null +++ b/doc/board/canaan/index.rst @@ -0,0 +1,8 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Canaan +====== +.. toctree:: + :maxdepth: 1 + + k230_canmv diff --git a/doc/board/canaan/k230_canmv.rst b/doc/board/canaan/k230_canmv.rst new file mode 100644 index 00000000000..534ad7cb7a8 --- /dev/null +++ b/doc/board/canaan/k230_canmv.rst @@ -0,0 +1,88 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +K230 CanMV +========== + +K230 RISC-V SoC +------------------ +The K230 chip is the latest generation SoC product in Canaan Technology's +Kendryte series of AIOT chips. + +Mainline support +---------------- + +The support for following drivers are already enabled: + +1. ns16550 UART +2. DWC2 OTG USB controller + +Building +~~~~~~~~ + +1. Get the RISC-V toolchain. +2. Setup cross compilation environment variable: +3. Get the `firmware_gen.py`_ from vendor. + +.. code-block:: console + + export CROSS_COMPILE=riscv64-linux-gnu- + cd + make k230_canmv_defconfig + make + cp u-boot-gz.img u-boot-gz.img.tmp + pip install gmssl pycryptodome + python3 firmware_gen.py -i u-boot-gz.img.tmp -o u-boot-head.img -n + +This will generate u-boot-head.img. + +.. _firmware_gen.py: https://raw.githubusercontent.com/kendryte/k230_sdk/refs/tags/v1.8/src/little/uboot/tools/firmware_gen.py + +Booting +~~~~~~~ + +Currently, we rely on vendor u-boot-spl to initialize the +ddr and load the u-boot image, then bootup from it. + +1. Prepare a SD card with the `vendor image`_ burned on it. + +2. Write the U-Boot image to the SD card at offset 2MB. + +.. code-block:: console + + dd if=u-boot-head.img of=/dev/sd[x] bs=1M seek=2 + +3. Insert the SD card into the board and power it on. + +.. _vendor image: https://kendryte-download.canaan-creative.com/developer/k230/CanMV-K230_debian_sdcard_sdk_1.3.img.gz + +Sample boot log from K230 CanMV board +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: none + + U-Boot 2025.01-00645-g2d81c4788455 (Jan 14 2025 - 23:15:07 +0800) + + DRAM: 512 MiB + Core: 15 devices, 11 uclasses, devicetree: separate + Loading Environment from nowhere... OK + In: serial@91400000 + Out: serial@91400000 + Err: serial@91400000 + Net: No ethernet found. + K230# cpu list + 0: cpu@0 thead,c908 + K230# usb start + starting USB... + Bus usb@91540000: USB DWC2 + scanning bus usb@91540000 for devices... + Warning: r8152_eth (eth0) using random MAC address - 1e:33:97:47:e6:32 + 2 USB Device(s) found + K230# usb tree + USB device tree: + 1 Hub (480 Mb/s, 0mA) + | U-Boot Root Hub + | + +-2 Vendor specific (480 Mb/s, 100mA) + Realtek USB 10/100 LAN 000000000000 + + K230# diff --git a/doc/board/index.rst b/doc/board/index.rst index b1c470eb2cb..74c4dd1f42d 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -21,6 +21,7 @@ Board-specific doc beagle/index broadcom/index bsh/index + canaan/index cloos/index congatec/index coolpi/index