8 Commits

Author SHA1 Message Date
SalimTerryLi 8be49d94b5 board: spacemit-k3: Add support for boot console and its pinctrl
First usable state reached: SPL booted and console printed
2026-05-10 03:50:13 +08:00
SalimTerryLi 3e2f66ea03 board: spacemit-k3: SPL entrypoint 2026-05-10 03:50:13 +08:00
SalimTerryLi c5afbce6f0 board: spacemit-k3: BROM loadable SPL build
bootinfo.bin generation is added but not implemented
2026-05-10 03:50:13 +08:00
SalimTerryLi 6cab30ddfb board: spacemit-k3: enable FIT 2026-05-10 03:50:13 +08:00
SalimTerryLi 8cf3ca5aae board: spacemit-k3: BINMAN skeleton 2026-05-10 03:50:13 +08:00
SalimTerryLi c14843fe35 board: spacemit-k3: SPL skeleton 2026-05-10 03:50:13 +08:00
SalimTerryLi ba8fc652bb board: spacemit-k3: skeleton support 2026-05-10 03:50:13 +08:00
Chuan 4609811251 spi: fsl_qspi: add clock handling
Add support for the clocks used by the SpacemiT K3 QSPI
controller by retrieving and enabling the qspi_en and qspi
clocks during probe.

Signed-off-by: Jichuan Feng<jichuan.or@isrc.iscas.ac.cn>
2026-05-10 03:46:13 +08:00
24 changed files with 955 additions and 0 deletions
+5
View File
@@ -47,6 +47,9 @@ config TARGET_SIPEED_MAIX
bool "Support Sipeed Maix Board"
select SYS_CACHE_SHIFT_6
config TARGET_SPACEMIT_K3
bool "Support SpacemiT K3 based Boards"
config TARGET_STARFIVE_VISIONFIVE2
bool "Support StarFive VisionFive2 Board"
select BOARD_LATE_INIT
@@ -116,6 +119,7 @@ source "board/sipeed/maix/Kconfig"
source "board/sophgo/milkv_duo/Kconfig"
source "board/sophgo/licheerv_nano/Kconfig"
source "board/spacemit/bananapi-f3/Kconfig"
source "board/spacemit/k3-generic/Kconfig"
source "board/starfive/visionfive2/Kconfig"
source "board/thead/th1520_lpi4a/Kconfig"
source "board/xilinx/mbv/Kconfig"
@@ -129,6 +133,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/k3/Kconfig"
source "arch/riscv/cpu/k230/Kconfig"
source "arch/riscv/cpu/th1520/Kconfig"
+55
View File
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
# Due to limitation of Kconfig, the following symbols cannot be selected here:
# CONFIG_ARCH_RV64I
# CONFIG_RISCV_SMODE
config SPACEMIT_K3
bool
select ARCH_EARLY_INIT_R
select SUPPORT_SPL
select SPL
select BINMAN
imply CPU
imply CPU_RISCV
imply SPL_CPU
imply RISCV_ISA_ZICBOM
imply FIT
imply SPL_LOAD_FIT
imply SPL_LOAD_FIT_FULL
imply PINCTRL
imply SPL_PINCTRL
imply PINCTRL_SINGLE
imply SYS_NS16550
if SPACEMIT_K3
config SYS_CPU
default "k3"
config SPL_SMP
default n
config SPL_TEXT_BASE
hex
default 0xc0801000
config SPL_MAX_SIZE
hex
default 0x6AF00
config SPL_BSS_START_ADDR
hex
default 0xc0874000
config SPL_BSS_MAX_SIZE
hex
default 0x3000
config SPL_OPENSBI_LOAD_ADDR
hex
default 0x100000000
endif
+8
View File
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
obj-$(CONFIG_XPL_BUILD) += spl.o
obj-y += cpu.o
obj-y += cache.o
obj-y += dram.o
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include <asm/io.h>
#include <cpu_func.h>
#include <linux/bitops.h>
#if CONFIG_IS_ENABLED(RISCV_MMODE)
void icache_enable(void)
{
csr_set(0x7c0, 0x2);
}
void dcache_enable(void)
{
csr_set(0x7c0, 0x1);
csr_set(0x7f0, 0x1);
}
int icache_status(void)
{
return (csr_read(0x7c0) & 0x2) != 0;
}
int dcache_status(void)
{
return (csr_read(0x7c0) & 0x1) != 0;
}
#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */
+24
View File
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include <irq_func.h>
#include <asm/cache.h>
/*
* cleanup_before_linux() is called just before we call linux
* it prepares the processor for linux
*
* we disable interrupt and caches.
*/
int cleanup_before_linux(void)
{
disable_interrupts();
cache_flush();
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include <fdtdec.h>
#include <init.h>
#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
__weak int dram_init(void)
{
return fdtdec_setup_mem_size_base();
}
__weak int dram_init_banksize(void)
{
return fdtdec_setup_memory_banksize();
}
+32
View File
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include <config.h>
#include <linux/types.h>
#include <asm/spl.h>
#include <spl.h>
#include <cpu_func.h>
void harts_early_init(void)
{
icache_enable();
dcache_enable();
}
void board_boot_order(u32 *spl_boot_list)
{
/* Boot from SPI NOR with YMODEM UART fallback. */
spl_boot_list[0] = BOOT_DEVICE_SPI;
spl_boot_list[1] = BOOT_DEVICE_UART;
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
int spl_board_init_f(void)
{
int ret;
return 0;
}
+74
View File
@@ -0,0 +1,74 @@
/ {
cpus {
bootph-all;
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <24000000>;
cpu_0: cpu@0 {
bootph-all;
compatible = "spacemit,x100", "riscv";
device_type = "cpu";
reg = <0>;
riscv,isa = "rv64imafdcvh_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zfhmin_zba_zbb_zbc_zbs_zkt_zvbb_zvbc_zvfh_zvfhmin_zvkb_zvkg_zvkn_zvknc_zvkned_zvkng_zvknha_zvknhb_zvks_zvksc_zvksed_zvksh_zvksg_zvkt_ssaia_sscofpmf_sstc_svinval_svnapot_svpbmt_smstateen";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "h",
"zicbom", "zicboz", "zicntr", "zicond", "zicsr",
"zifencei", "zihintpause", "zihpm", "zfh", "zfhmin",
"zba", "zbb", "zbc", "zbs", "zkt", "zvbb", "zvbc",
"zvfh", "zvfhmin", "zvkb", "zvkg", "zvkn", "zvknc",
"zvkned", "zvkng", "zvknha", "zvknhb", "zvks",
"zvksc", "zvksed", "zvksh", "zvksg", "zvkt", "ssaia",
"sscofpmf", "sstc", "svinval", "svnapot", "svpbmt",
"smstateen";
riscv,cbom-block-size = <64>;
/*riscv,cbop-block-size = <64>;*/
riscv,cboz-block-size = <64>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <256>;
d-cache-block-size = <64>;
d-cache-size = <65536>;
d-cache-sets = <256>;
next-level-cache = <&cluster0_l2_cache>;
mmu-type = "riscv,sv39";
};
cluster0_l2_cache: l2-cache0 {
bootph-all;
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <4194304>;
cache-sets = <4096>;
cache-unified;
};
cluster1_l2_cache: l2-cache1 {
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <4194304>;
cache-sets = <4096>;
cache-unified;
};
cluster2_l2_cache: l2-cache2 {
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <1048576>;
cache-sets = <1024>;
cache-unified;
};
cluster3_l2_cache: l2-cache3 {
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <1048576>;
cache-sets = <1024>;
cache-unified;
};
};
};
+46
View File
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Copyright (c) 2025 Spacemit, Inc */
#include <dt-bindings/pinctrl/k3-pinctrl.h>
&pinctrl {
pinctrl_uart0_0: uart0_0_grp {
bootph-all;
pinctrl-single,pins = <
K3_PADCONF(149, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
K3_PADCONF(150, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
>;
};
pinctrl_uart0_1: uart0_1_grp {
bootph-all;
pinctrl-single,pins = <
K3_PADCONF(132, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
K3_PADCONF(133, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
>;
};
pinctrl_uart0_2: uart0_2_grp {
bootph-all;
pinctrl-single,pins = <
K3_PADCONF(145, MUX_MODE5, (PULL_UP | PAD_DS8)) /* tx */
K3_PADCONF(146, MUX_MODE5, (PULL_UP | PAD_DS8)) /* rx */
>;
};
pinctrl_uart0_3: uart0_3_grp {
bootph-all;
pinctrl-single,pins = <
K3_PADCONF(42, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
K3_PADCONF(43, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
>;
};
pinctrl_uart0_4: uart0_4_grp {
bootph-all;
pinctrl-single,pins = <
K3_PADCONF(93, MUX_MODE3, (PULL_UP | PAD_DS8)) /* tx */
K3_PADCONF(94, MUX_MODE3, (PULL_UP | PAD_DS8)) /* rx */
>;
};
};
+28
View File
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include "k3.dtsi"
#include "k3-pinctrl.dtsi"
#include "binman.dtsi"
/ {
model = "SpacemiT K3 DEB1 Board";
compatible = "spacemit,k3-deb1", "spacemit,k3";
chosen {
stdout-path = "serial0";
};
memory@0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
};
};
&serial0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0_0>;
status = "okay";
};
+26
View File
@@ -0,0 +1,26 @@
&binman {
bootinfo_nor {
filename = "bootinfo_nor.bin";
mkimage {
args = "-s -T spacemit-binfo";
};
};
spl {
filename = "spacemit-spl-unsigned.bin";
mkimage {
args = "-T spacemit-spl";
offset = <0xFE0>;
section {
// Use a section to pad SPL at 32B align-size, before passing to mkimage
blob {
align-size = <32>;
filename = "spl/u-boot-spl.bin";
};
};
};
};
};
+55
View File
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
/dts-v1/;
#include "k3-cpus.dtsi"
/ {
#address-cells = <2>;
#size-cells = <2>;
model = "SpacemiT K3";
compatible = "spacemit,k3";
aliases {
serial0 = &serial0;
};
soc {
bootph-all;
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges;
pinctrl: pinctrl@d401e000 {
bootph-all;
compatible = "pinctrl-single";
reg = <0x0 0xd401e000 0x0 0x400>;
#address-cells = <1>;
#size-cells = <1>;
#pinctrl-cells = <1>;
#gpio-range-cells = <3>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0xffff>;
range: gpio-range {
bootph-all;
#pinctrl-single,gpio-range-cells = <3>;
};
};
serial0: serial@d4017000 {
bootph-all;
compatible = "intel,xscale-uart";
reg = <0x00000000 0xD4017000 0x00000000 0x00000100>;
reg-shift = <2>;
reg-io-width = <4>;
clock-frequency = <14745600>;
status = "disabled";
};
};
};
+35
View File
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
if TARGET_SPACEMIT_K3
config SYS_VENDOR
default "spacemit"
config SYS_BOARD
default "k3-generic"
config SYS_CONFIG_NAME
default "spacemit-k3-generic"
config CUSTOM_SYS_INIT_SP_ADDR
default 0xc0880000
config TEXT_BASE
hex
default 0x80200000 if RISCV_SMODE
config SYS_LOAD_ADDR
hex
default 0x102000000
config DEFAULT_DEVICE_TREE
default "k3-spacemit-deb1"
config BOARD_SPECIFIC_OPTIONS
def_bool y
select SPACEMIT_K3
select HAS_CUSTOM_SYS_INIT_SP_ADDR
endif
+5
View File
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
obj-y := k3-generic.o
+10
View File
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
*/
int board_init(void)
{
/* Add board-specific initialization */
return 0;
}
+2
View File
@@ -185,6 +185,8 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_STARFIVE_SPL, "sfspl", "StarFive SPL Image" },
{ IH_TYPE_TFA_BL31, "tfa-bl31", "TFA BL31 Image", },
{ IH_TYPE_STM32IMAGE_V2, "stm32imagev2", "STMicroelectronics STM32 Image V2.0" },
{ IH_TYPE_SPACEMIT_BOOTINFO, "spacemit-binfo", "SpacemiT BootInfo Binary Header" },
{ IH_TYPE_SPACEMIT_SPL, "spacemit-spl", "SpacemiT BootROM loadable Image" },
{ -1, "", "", },
};
+4
View File
@@ -0,0 +1,4 @@
CONFIG_RISCV=y
CONFIG_TARGET_SPACEMIT_K3=y
CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
+19
View File
@@ -38,6 +38,7 @@
#include <linux/sizes.h>
#include <linux/err.h>
#include <asm/io.h>
#include <clk.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -271,6 +272,10 @@ struct fsl_qspi {
struct udevice *dev;
void __iomem *iobase;
void __iomem *ahb_addr;
#if CONFIG_IS_ENABLED(CLK)
struct clk clk_en;
struct clk clk;
#endif
u32 memmap_phy;
u32 memmap_size;
const struct fsl_qspi_devtype_data *devtype_data;
@@ -820,7 +825,21 @@ static int fsl_qspi_probe(struct udevice *bus)
dm_bus->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
66000000);
#if CONFIG_IS_ENABLED(CLK)
ret = clk_get_by_name(bus, "qspi_en", &q->clk_en);
if (ret) {
dev_err(bus, "cannot find qspi_en clock\n");
return ret;
}
ret = clk_get_by_name(bus, "qspi", &q->clk);
if (ret) {
dev_err(bus, "cannot find qspi clock\n");
return ret;
}
clk_enable(&q->clk_en);
clk_enable(&q->clk);
#endif
fsl_qspi_default_setup(q);
return 0;
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#define CFG_SYS_NS16550_IER 0x40
#endif /* __CONFIG_H */
+229
View File
@@ -0,0 +1,229 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __DT_BINDINGS_K3_PINCTRL_H
#define __DT_BINDINGS_K3_PINCTRL_H
/*
* For K3:
* +---------+----------+-----------+--------+--------+----------+--------+
* | pull | drive | schmitter | slew | edge | strong | mux |
* | up/down | strength | trigger | rate | detect | pull | mode |
* +---------+----------+-----------+--------+--------+----------+--------+
* 3 bits 4 bits 1 bits 1 bit 3 bits 1 bit 3 bits
*/
/* pinnum list */
#define GPIO_00 (0)
#define GPIO_01 (1)
#define GPIO_02 (2)
#define GPIO_03 (3)
#define GPIO_04 (4)
#define GPIO_05 (5)
#define GPIO_06 (6)
#define GPIO_07 (7)
#define GPIO_08 (8)
#define GPIO_09 (9)
#define GPIO_10 (10)
#define GPIO_11 (11)
#define GPIO_12 (12)
#define GPIO_13 (13)
#define GPIO_14 (14)
#define GPIO_15 (15)
#define GPIO_16 (16)
#define GPIO_17 (17)
#define GPIO_18 (18)
#define GPIO_19 (19)
#define GPIO_20 (20)
#define GPIO_21 (21)
#define GPIO_22 (22)
#define GPIO_23 (23)
#define GPIO_24 (24)
#define GPIO_25 (25)
#define GPIO_26 (26)
#define GPIO_27 (27)
#define GPIO_28 (28)
#define GPIO_29 (29)
#define GPIO_30 (30)
#define GPIO_31 (31)
#define GPIO_32 (32)
#define GPIO_33 (33)
#define GPIO_34 (34)
#define GPIO_35 (35)
#define GPIO_36 (36)
#define GPIO_37 (37)
#define GPIO_38 (38)
#define GPIO_39 (39)
#define GPIO_40 (40)
#define GPIO_41 (41)
#define GPIO_42 (42)
#define GPIO_43 (43)
#define GPIO_44 (44)
#define GPIO_45 (45)
#define GPIO_46 (46)
#define GPIO_47 (47)
#define GPIO_48 (48)
#define GPIO_49 (49)
#define GPIO_50 (50)
#define GPIO_51 (51)
#define GPIO_52 (52)
#define GPIO_53 (53)
#define GPIO_54 (54)
#define GPIO_55 (55)
#define GPIO_56 (56)
#define GPIO_57 (57)
#define GPIO_58 (58)
#define GPIO_59 (59)
#define GPIO_60 (60)
#define GPIO_61 (61)
#define GPIO_62 (62)
#define GPIO_63 (63)
#define GPIO_64 (64)
#define GPIO_65 (65)
#define GPIO_66 (66)
#define GPIO_67 (67)
#define GPIO_68 (68)
#define GPIO_69 (69)
#define GPIO_70 (70)
#define GPIO_71 (71)
#define GPIO_72 (72)
#define GPIO_73 (73)
#define GPIO_74 (74)
#define GPIO_75 (75)
#define GPIO_76 (76)
#define GPIO_77 (77)
#define GPIO_78 (78)
#define GPIO_79 (79)
#define GPIO_80 (80)
#define GPIO_81 (81)
#define GPIO_82 (82)
#define GPIO_83 (83)
#define GPIO_84 (84)
#define GPIO_85 (85)
#define GPIO_86 (86)
#define GPIO_87 (87)
#define GPIO_88 (88)
#define GPIO_89 (89)
#define GPIO_90 (90)
#define GPIO_91 (91)
#define GPIO_92 (92)
#define GPIO_93 (93)
#define GPIO_94 (94)
#define GPIO_95 (95)
#define GPIO_96 (96)
#define GPIO_97 (97)
#define GPIO_98 (98)
#define GPIO_99 (99)
#define GPIO_100 (100)
#define GPIO_101 (101)
#define GPIO_102 (102)
#define GPIO_103 (103)
#define GPIO_104 (104)
#define GPIO_105 (105)
#define GPIO_106 (106)
#define GPIO_107 (107)
#define GPIO_108 (108)
#define GPIO_109 (109)
#define GPIO_110 (110)
#define GPIO_111 (111)
#define GPIO_112 (112)
#define GPIO_113 (113)
#define GPIO_114 (114)
#define GPIO_115 (115)
#define GPIO_116 (116)
#define GPIO_117 (117)
#define GPIO_118 (118)
#define GPIO_119 (119)
#define GPIO_120 (120)
#define GPIO_121 (121)
#define GPIO_122 (122)
#define GPIO_123 (123)
#define GPIO_124 (124)
#define GPIO_125 (125)
#define GPIO_126 (126)
#define GPIO_127 (127)
#define PWR_SCL (128)
#define PWR_SDA (129)
#define VCXO_EN (130)
#define PMIC_INT_N (131)
#define MMC1_DAT3 (132)
#define MMC1_DAT2 (133)
#define MMC1_DAT1 (134)
#define MMC1_DAT0 (135)
#define MMC1_CMD (136)
#define MMC1_CLK (137)
#define QSPI_DAT0 (138)
#define QSPI_DAT1 (139)
#define QSPI_DAT2 (140)
#define QSPI_DAT3 (141)
#define QSPI_CS0 (142)
#define QSPI_CS1 (143)
#define QSPI_CLK (144)
#define PRI_TDI (145)
#define PRI_TMS (146)
#define PRI_TCK (147)
#define PRI_TDO (148)
#define PWR_SSP_SCLK (149)
#define PWR_SSP_FRM (150)
#define PWR_SSP_TXD (151)
#define PWR_SSP_RXD (152)
/* pin mux */
#define PAD_MUX GENMASK(2, 0)
#define MUX_MODE0 0
#define MUX_MODE1 1
#define MUX_MODE2 2
#define MUX_MODE3 3
#define MUX_MODE4 4
#define MUX_MODE5 5
#define MUX_MODE6 6
#define MUX_MODE7 7
#define PAD_STRONG_PULL BIT(3)
#define PAD_EDGE GENMASK(6, 4)
#define PAD_EDGE_RISE BIT(4)
#define PAD_EDGE_FALL BIT(5)
#define PAD_EDGE_CLEAR BIT(6)
#define PAD_SLEW_RATE_EN BIT(7)
#define PAD_SCHMITT BIT(8)
#define PAD_PULLDOWN BIT(13)
#define PAD_PULLUP BIT(14)
#define PAD_PULL_EN BIT(15)
/*
* drive strength
* DRIVE[3:0] -> bits[12:9]
*/
#define PAD_DRIVE GENMASK(12, 9)
#define PAD_DS0 (0 << 9) /* bit[12:9] 0000 */
#define PAD_DS1 (1 << 9) /* bit[12:9] 0001 */
#define PAD_DS2 (2 << 9) /* bit[12:9] 0010 */
#define PAD_DS3 (3 << 9) /* bit[12:9] 0011 */
#define PAD_DS4 (4 << 9) /* bit[12:9] 0100 */
#define PAD_DS5 (5 << 9) /* bit[12:9] 0101 */
#define PAD_DS6 (6 << 9) /* bit[12:9] 0110 */
#define PAD_DS7 (7 << 9) /* bit[12:9] 0111 */
#define PAD_DS8 (8 << 9) /* bit[12:9] 1000 */
#define PAD_DS9 (9 << 9) /* bit[12:9] 1001 */
#define PAD_DS10 (10 << 9) /* bit[12:9] 1010 */
#define PAD_DS11 (11 << 9) /* bit[12:9] 1011 */
#define PAD_DS12 (12 << 9) /* bit[12:9] 1100 */
#define PAD_DS13 (13 << 9) /* bit[12:9] 1101 */
#define PAD_DS14 (14 << 9) /* bit[12:9] 1110 */
#define PAD_DS15 (15 << 9) /* bit[12:9] 1111 */
/* pull up/down */
#define PULL_DIS (0 << 13) /* bit[15:13] 000 */
#define PULL_UP (6 << 13) /* bit[15:13] 110 */
#define PULL_DOWN (5 << 13) /* bit[15:13] 101 */
// pin reg offset
#define PIN_ID(x) ((x) > 130? (x) + 2: (x))
// pinctrl-single,pins
#define K3_PADCONF(pinid, mux, conf) ((PIN_ID(pinid)) << 2) ((conf) | (mux))
#endif /* __DT_BINDINGS_K3_PINCTRL_H */
+2
View File
@@ -234,6 +234,8 @@ enum image_type_t {
IH_TYPE_STARFIVE_SPL, /* StarFive SPL image */
IH_TYPE_TFA_BL31, /* TFA BL31 image */
IH_TYPE_STM32IMAGE_V2, /* STMicroelectronics STM32 Image V2.0 */
IH_TYPE_SPACEMIT_BOOTINFO, /* SpacemiT BootInfo Binary Header */
IH_TYPE_SPACEMIT_SPL, /* SpacemiT BootROM loadable Image */
IH_TYPE_COUNT, /* Number of image types */
};
+3
View File
@@ -108,6 +108,8 @@ KWB_IMAGE_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := kwbimage.o
ROCKCHIP_OBS = generated/lib/rc4.o rkcommon.o rkimage.o rksd.o rkspi.o
SPACEMIT_OBJS = spacemit-boot.o spacemit-spl.o
# common objs for dumpimage and mkimage
dumpimage-mkimage-objs := aisimage.o \
atmelimage.o \
@@ -140,6 +142,7 @@ dumpimage-mkimage-objs := aisimage.o \
stm32image.o \
$(ROCKCHIP_OBS) \
socfpgaimage.o \
$(SPACEMIT_OBJS) \
sunxi_egon.o \
generated/lib/crc16-ccitt.o \
generated/lib/hash-checksum.o \
+101
View File
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include "imagetool.h"
struct bootinfo_hdr {
struct {
/** @magic: MAGIC value, always 0xB00714F0 */
uint32_t magic;
/** @version: ???*/
uint32_t version;
/** @flash_type: oneof "NORF", "BLCK" */
uint32_t flash_type;
/** @mid: ???*/
uint8_t mid;
uint8_t _reserved_0[1];
/** @did: ???*/
uint16_t did;
/** @page_size: ???*/
uint32_t page_size;
/** @block_size: ???*/
uint32_t block_size;
/** @total_size: ???*/
uint32_t total_size;
/** @multi_plane: ???*/
uint8_t multi_plane;
uint8_t _reserved_1[3];
/** @spl0_offset: Offset to primary SPL image */
uint32_t spl0_offset;
/** @spl1_offset: Offset to backup SPL image */
uint32_t spl1_offset;
/** @spl_size_limit: Max size of SPL image */
uint32_t spl_size_limit;
/** @partitiontable0_offset: ??? */
uint32_t partitiontable0_offset;
/** @partitiontable1_offset: ??? */
uint32_t partitiontable1_offset;
uint8_t _reserved_2[12];
} data;
struct {
/** @crc32: crc32 of data */
uint32_t crc32;
uint8_t _reserved_0[12];
} checksum;
};
static int spacemit_bootinfo_check_params(struct image_tool_params *params)
{
/* Only the RISC-V architecture is supported */
if (params->Aflag && params->arch != IH_ARCH_RISCV)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
static int spacemit_bootinfo_verify_header(unsigned char *buf, int size,
struct image_tool_params *params)
{
printf("spacemit_bootinfo_verify_header\n");
return EXIT_SUCCESS;
}
static void spacemit_bootinfo_print_header(const void *buf,
struct image_tool_params *params)
{
printf("spacemit_bootinfo_print_header\n");
}
static void spacemit_bootinfo_set_header(void *buf, struct stat *sbuf, int infd,
struct image_tool_params *params)
{
printf("spacemit_bootinfo_set_header\n");
}
static int spacemit_bootinfo_check_image_type(uint8_t type)
{
if (type == IH_TYPE_SPACEMIT_BOOTINFO)
return EXIT_SUCCESS;
return EXIT_FAILURE;
}
static struct bootinfo_hdr spacemit_bootinfo_hdr;
U_BOOT_IMAGE_TYPE(
spacemit_bootinfo, /* id */
"SpacemiT BootInfo Header", /* name */
sizeof(struct bootinfo_hdr), /* header_size */
&spacemit_bootinfo_hdr, /* header */
spacemit_bootinfo_check_params, /* check_params */
spacemit_bootinfo_verify_header, /* verify header */
spacemit_bootinfo_print_header, /* print header */
spacemit_bootinfo_set_header, /* set header */
NULL, /* extract_subimage */
spacemit_bootinfo_check_image_type, /* check_image_type */
NULL, /* fflag_handle */
NULL /* vrec_header */
);
+129
View File
@@ -0,0 +1,129 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
*/
#include "imagetool.h"
#include <u-boot/crc.h>
#include <openssl/engine.h>
#define SPACEMIT_SPL_HDR_MAGIC_LE32 0x44484941
struct spl_hdr {
struct {
/** @magic: MAGIC value, always 0x44484941 */
uint32_t magic;
/** @version: ??? */
uint8_t version;
/** @secure: ??? */
uint8_t secure;
uint8_t _reserved_0[2];
/** @payload_size: Size of payload only */
uint64_t payload_size;
/** @loadaddr: Target load address */
uint64_t loadaddr;
} header;
struct {
/** @header: crc32 of header data */
uint32_t header;
/** @payload: crc32 of payload image */
uint32_t payload;
} checksum;
// Useful for mmap-ed output file
uint8_t payload[0];
};
static int spacemit_spl_check_params(struct image_tool_params *params)
{
/* Only the RISC-V architecture is supported */
if (params->Aflag && params->arch != IH_ARCH_RISCV)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
static int spacemit_spl_verify_header(unsigned char *buf, int size,
struct image_tool_params *params)
{
const struct spl_hdr *hdr = (void *)buf;
if (le32_to_cpu(hdr->header.magic) != SPACEMIT_SPL_HDR_MAGIC_LE32) {
printf("Unmatched header MAGIC value: %08x\n", le32_to_cpu(hdr->header.magic));
return EXIT_FAILURE;
}
if (le32_to_cpu(hdr->checksum.header) != crc32(0, (void *)&hdr->header, sizeof(hdr->header))) {
printf("Unmatched header checksum\n");
return EXIT_FAILURE;
}
if (le32_to_cpu(hdr->header.payload_size) + sizeof(struct spl_hdr) > params->file_size) {
printf("Payload size (%lu) exceeds file size (%u) - header size (%lu)\n",
le32_to_cpu(hdr->header.payload_size), params->file_size, sizeof(struct spl_hdr));
return EXIT_FAILURE;
}
if (le32_to_cpu(hdr->checksum.payload) != crc32(0, (void *)&hdr->payload, le32_to_cpu(hdr->header.payload_size))) {
printf("Unmatched payload checksum\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static void spacemit_spl_print_header(const void *buf,
struct image_tool_params *params)
{
const struct spl_hdr *hdr = buf;
printf("SpacemiT BootROM Loadable Image\n");
printf("-> Header Version: 0x%02x\n", hdr->header.version);
printf("-> Secure Mode: ");
if (hdr->header.secure == 0) {
printf("Disabled\n");
} else {
printf("Enabled (0x%02x)\n", hdr->header.secure);
}
printf("-> Payload Size: %lu\n", le64_to_cpu(hdr->header.payload_size));
printf("-> Payload Load Addr: %lu\n", le64_to_cpu(hdr->header.loadaddr));
}
static void spacemit_spl_set_header(void *buf, struct stat *sbuf, int infd,
struct image_tool_params *params)
{
// Filling header info
struct spl_hdr *hdr = buf;
memset((void *)hdr, 0, sizeof(struct spl_hdr));
hdr->header.magic = cpu_to_le32(SPACEMIT_SPL_HDR_MAGIC_LE32);
hdr->header.version = 0x01;
hdr->header.secure = 0;
hdr->header.payload_size = cpu_to_le64(params->file_size - sizeof(struct spl_hdr));
hdr->header.loadaddr = cpu_to_le64(0x0);
hdr->checksum.header = cpu_to_le32(crc32(0, (void *)&hdr->header, sizeof(hdr->header)));
hdr->checksum.payload = cpu_to_le32(crc32(0, (void *)hdr->payload, le64_to_cpu(hdr->header.payload_size)));
// Payload is already copied by mkimage
// Generate signature
// Here we directly call into OpenSSL to avoid U-Boot overheads
}
static int spacemit_spl_check_image_type(uint8_t type)
{
if (type == IH_TYPE_SPACEMIT_SPL)
return EXIT_SUCCESS;
return EXIT_FAILURE;
}
static struct spl_hdr spacemit_spl_hdr;
U_BOOT_IMAGE_TYPE(
spacemit_spl, /* id */
"SpacemiT BROM loadable Image", /* name */
sizeof(struct spl_hdr), /* header_size */
&spacemit_spl_hdr, /* header */
spacemit_spl_check_params, /* check_params */
spacemit_spl_verify_header, /* verify header */
spacemit_spl_print_header, /* print header */
spacemit_spl_set_header, /* set header */
NULL, /* extract_subimage */
spacemit_spl_check_image_type, /* check_image_type */
NULL, /* fflag_handle */
NULL /* vrec_header */
);