forked from OERV-BSP/u-boot
CI: https://source.denx.de/u-boot/custodians/u-boot-riscv/-/pipelines/24215 - RISC-V: Add "riscv,isa-extensions" and multi-letter extension parsing support - RISC-V: Add default cache line size - Board: Canaan: Add K230-CanMV support - Board: VisionFive2: Split out target specific configuration
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -14,8 +14,12 @@
|
||||
#include <log.h>
|
||||
#include <asm/encoding.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
/*
|
||||
* The variables here must be stored in the data section since they are used
|
||||
@@ -33,60 +37,565 @@ 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)
|
||||
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."
|
||||
@@ -122,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')) {
|
||||
|
||||
14
arch/riscv/cpu/k230/Kconfig
Normal file
14
arch/riscv/cpu/k230/Kconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
|
||||
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
|
||||
6
arch/riscv/cpu/k230/Makefile
Normal file
6
arch/riscv/cpu/k230/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
|
||||
obj-y += dram.o
|
||||
obj-y += cpu.o
|
||||
9
arch/riscv/cpu/k230/cpu.c
Normal file
9
arch/riscv/cpu/k230/cpu.c
Normal file
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
*/
|
||||
|
||||
int cleanup_before_linux(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
21
arch/riscv/cpu/k230/dram.c
Normal file
21
arch/riscv/cpu/k230/dram.c
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
|
||||
*/
|
||||
|
||||
#include <asm/global_data.h>
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*/
|
||||
|
||||
#include "jh7110-common-u-boot.dtsi"
|
||||
#include "starfive-visionfive2-binman.dtsi"
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*/
|
||||
|
||||
#include "jh7110-common-u-boot.dtsi"
|
||||
#include "starfive-visionfive2-binman.dtsi"
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*/
|
||||
|
||||
#include "jh7110-common-u-boot.dtsi"
|
||||
#include "starfive-visionfive2-binman.dtsi"
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*/
|
||||
|
||||
#include "jh7110-common-u-boot.dtsi"
|
||||
#include "starfive-visionfive2-binman.dtsi"
|
||||
|
||||
31
arch/riscv/dts/k230-canmv.dts
Normal file
31
arch/riscv/dts/k230-canmv.dts
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
|
||||
* Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
*/
|
||||
|
||||
/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";
|
||||
};
|
||||
25
arch/riscv/dts/k230-u-boot.dtsi
Normal file
25
arch/riscv/dts/k230-u-boot.dtsi
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
*/
|
||||
|
||||
#include <linux/stringify.h>
|
||||
|
||||
/ {
|
||||
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";
|
||||
};
|
||||
};
|
||||
};
|
||||
175
arch/riscv/dts/k230.dtsi
Normal file
175
arch/riscv/dts/k230.dtsi
Normal file
@@ -0,0 +1,175 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
|
||||
* Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
/ {
|
||||
#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";
|
||||
};
|
||||
};
|
||||
};
|
||||
102
arch/riscv/dts/starfive-visionfive2-binman.dtsi
Normal file
102
arch/riscv/dts/starfive-visionfive2-binman.dtsi
Normal file
@@ -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 {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
37
arch/riscv/include/asm/cpufeature.h
Normal file
37
arch/riscv/include/asm/cpufeature.h
Normal file
@@ -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
|
||||
105
arch/riscv/include/asm/hwcap.h
Normal file
105
arch/riscv/include/asm/hwcap.h
Normal file
@@ -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 */
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
19
board/canaan/k230_canmv/Kconfig
Normal file
19
board/canaan/k230_canmv/Kconfig
Normal file
@@ -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
|
||||
6
board/canaan/k230_canmv/MAINTAINERS
Normal file
6
board/canaan/k230_canmv/MAINTAINERS
Normal file
@@ -0,0 +1,6 @@
|
||||
K230 CANMV
|
||||
M: Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
S: Maintained
|
||||
F: board/canaan/k230_canmv/
|
||||
F: configs/k230_canmv_defconfig
|
||||
F: doc/board/canaan/k230_canmv.rst
|
||||
5
board/canaan/k230_canmv/Makefile
Normal file
5
board/canaan/k230_canmv/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
|
||||
obj-y += board.o
|
||||
9
board/canaan/k230_canmv/board.c
Normal file
9
board/canaan/k230_canmv/board.c
Normal file
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>
|
||||
*/
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
19
configs/k230_canmv_defconfig
Normal file
19
configs/k230_canmv_defconfig
Normal file
@@ -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
|
||||
8
doc/board/canaan/index.rst
Normal file
8
doc/board/canaan/index.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Canaan
|
||||
======
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
k230_canmv
|
||||
88
doc/board/canaan/k230_canmv.rst
Normal file
88
doc/board/canaan/k230_canmv.rst
Normal file
@@ -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 <U-Boot-dir>
|
||||
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#
|
||||
@@ -21,6 +21,7 @@ Board-specific doc
|
||||
beagle/index
|
||||
broadcom/index
|
||||
bsh/index
|
||||
canaan/index
|
||||
cloos/index
|
||||
congatec/index
|
||||
coolpi/index
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user