## Steps to replace OpenSBI on Spacemit K1 The Spacemit Version of OpenSBI is outdated and disabled printf and consumes the wrong dts with wrong isa string, causing some debugging features that needs `printf` does not work, and zicboz can not be activated. This file will tell you how to replace OpenSBI to mainline (v1.4+) on Spacemit K1, and it also compatible with factory sdk kernel. ### Prerequisites You have flashed [Bianbu](https://docs.banana-pi.org/en/BPI-F3/BananaPi_BPI-F3) or [Armbian](https://github.com/BPI-SINOVOIP/armbian-build/tree/v24.04.30) for BPI-F3 and flashed to SD Card. ### Find where OpenSBI stored The layout of boot images can be found from GPT: ```console sudo gdisk /dev/rdisk5 GPT fdisk (gdisk) version 1.0.9 Partition table scan: MBR: MBR only BSD: not present APM: not present GPT: present Found valid MBR and GPT. Which do you want to use? 1 - MBR 2 - GPT 3 - Create blank GPT Your answer: 2 Using GPT and creating fresh protective MBR. Command (? for help): p Disk /dev/rdisk5: 120934400 sectors, 57.7 GiB Sector size (logical): 512 bytes Disk identifier (GUID): 9DCE1E0A-7673-4B7D-BC12-D7114641BF8A Partition table holds up to 128 entries Main partition table begins at sector 2 and ends at sector 33 First usable sector is 34, last usable sector is 8158 Partitions will be aligned on 256-sector boundaries Total free space is 2493 sectors (1.2 MiB) Number Start (sector) End (sector) Size Code Name 1 512 1023 256.0 KiB 8300 fsbl 2 1024 1279 128.0 KiB 8300 3 1280 2047 384.0 KiB 8300 opensbi 4 2048 6143 2.0 MiB 8300 uboot Command (? for help): ``` Thus, we can directly replace the opensbi from the 1280 sector. Which is the same as the [armbian script from BananaPi F3](https://github.com/BPI-SINOVOIP/armbian-build/blob/v24.04.30/config/boards/bananapif3.conf#L84). ### Compile OpenSBI ssh to k1, then: Install these packages: ```shell apt install -y u-boot-tools build-essential dtc ``` Compile opensbi: ```console [cyy@k1 ~]$ git clone https://github.com/cyyself/opensbi.git -b k1-opensbi Cloning into 'opensbi'... remote: Enumerating objects: 13172, done. remote: Counting objects: 100% (325/325), done. remote: Compressing objects: 100% (211/211), done. remote: Total 13172 (delta 104), reused 265 (delta 94), pack-reused 12847 Receiving objects: 100% (13172/13172), 2.89 MiB | 3.69 MiB/s, done. Resolving deltas: 100% (8049/8049), done. [cyy@k1 ~]$ cd opensbi/ [cyy@k1 opensbi]$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- PLATFORM=generic -j `nproc` Loaded configuration '/home/cyy/opensbi/platform/generic/configs/defconfig' Configuration saved to '/home/cyy/opensbi/build/platform/generic/kconfig/.config' ... FIT description: Configuration to load OpenSBI before U-Boot Created: Mon Jun 10 15:06:00 2024 Image 0 (opensbi) Description: OpenSBI fw_dynamic Firmware Created: Mon Jun 10 15:06:00 2024 Type: Firmware Compression: uncompressed Data Size: 272648 Bytes = 266.26 KiB = 0.26 MiB Architecture: RISC-V OS: RISC-V OpenSBI Load Address: 0x00000000 Hash algo: crc32 Hash value: 40e14962 Default Configuration: 'config_1' Configuration 0 (config_1) Description: opensbi FIT config Kernel: unavailable Firmware: opensbi ``` ### Replace OpenSBI ```console [cyy@k1 opensbi]$ sudo dd if=build/platform/generic/firmware/fw_dynamic.itb of=/dev/mmcblk0 bs=512 seek=1280 535+1 records in 535+1 records out 274303 bytes (274 kB, 268 KiB) copied, 0.0243828 s, 11.2 MB/s [cyy@k1 opensbi]$ ``` ### Enjoy After reboot, you will see new OpenSBI installed. ```console sys: 0x2 try sd... bm:3 j... U-Boot SPL 2022.10spacemit (May 06 2024 - 03:49:58 +0000) lpddr4_silicon_init consume 11ms BPI: partition=2 part_name[uboot] BPI: p=1 info.name=[XBOOTLDR partition] info.start[32000] BPI: p=2 info.name=[Linux filesystem] info.start[b2000] BPI: p=3 info.name=[uboot] info.start[800] BPI:hdr read sector 800, count=1 Boot from fit configuration k1-x_deb1 ## Checking hash(es) for config conf_2 ... OK ## Checking hash(es) for Image uboot ... crc32+ OK ## Checking hash(es) for Image fdt_2 ... crc32+ OK BPI: partition=1 part_name[opensbi] BPI: p=1 info.name=[XBOOTLDR partition] info.start[32000] BPI: p=2 info.name=[Linux filesystem] info.start[b2000] BPI: p=3 info.name=[opensbi] info.start[500] BPI:hdr read sector 500, count=1 ## Checking hash(es) for config config_1 ... OK ## Checking hash(es) for Image opensbi ... crc32+ OK OpenSBI v1.0-654-gafc2617 ____ _____ ____ _____ / __ \ / ____| _ \_ _| | | | |_ __ ___ _ __ | (___ | |_) || | | | | | '_ \ / _ \ '_ \ \___ \| _ < | | | |__| | |_) | __/ | | |____) | |_) || |_ \____/| .__/ \___|_| |_|_____/|____/_____| | | |_| PSCI Power Domain Map: Domain Node : Level 2, parent_node 4294967295, State ON (0x0) Domain Node : Level 1, parent_node 0, State ON (0x0) Domain Node : Level 1, parent_node 0, State OFF (0x2) CPU Node : MPID 0x0, parent_node 1, State ON (0x0) CPU Node : MPID 0xffffffffffffffff, parent_node 1, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 1, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 1, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 2, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 2, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 2, State OFF (0x2) CPU Node : MPID 0xffffffffffffffff, parent_node 2, State OFF (0x2) Platform Name : spacemit k1-x deb1 board Platform Features : medeleg Platform HART Count : 8 Platform IPI Device : aclint-mswi Platform Timer Device : aclint-mtimer @ 24000000Hz Platform Console Device : uart8250 Platform HSM Device : spacemit-hsm Platform PMU Device : --- Platform Reboot Device : --- Platform Shutdown Device : --- Platform Suspend Device : spacemit-system-suspend Platform CPPC Device : --- Firmware Base : 0x0 Firmware Size : 399 KB Firmware RW Offset : 0x40000 Firmware RW Size : 143 KB Firmware Heap Offset : 0x57000 Firmware Heap Size : 51 KB (total), 3 KB (reserved), 11 KB (used), 36 KB (free) Firmware Scratch Size : 4096 B (total), 1536 B (used), 2560 B (free) Runtime SBI Version : 2.0 Domain0 Name : root Domain0 Boot HART : 0 Domain0 HARTs : 0*,1*,2*,3*,4*,5*,6*,7* Domain0 Region00 : 0x00000000d4017000-0x00000000d4017fff M: (I,R,W) S/U: (R,W) Domain0 Region01 : 0x00000000e4000000-0x00000000e400ffff M: (I,R,W) S/U: () Domain0 Region02 : 0x0000000000000000-0x000000000003ffff M: (R,X) S/U: () Domain0 Region03 : 0x0000000000040000-0x000000000007ffff M: (R,W) S/U: () Domain0 Region04 : 0x00000000e0000000-0x00000000e3ffffff M: (I,R,W) S/U: (R,W) Domain0 Region05 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X) Domain0 Next Address : 0x0000000000200000 Domain0 Next Arg1 : 0x0000000000317770 Domain0 Next Mode : S-mode Domain0 SysReset : yes Domain0 SysSuspend : yes Boot HART ID : 0 Boot HART Domain : root Boot HART Priv Version : v1.12 Boot HART Base ISA : rv64imafdcbvx Boot HART ISA Extensions : sscofpmf,sstc,zicntr,zihpm,zicboz,zicbom,svpbmt,sdtrig Boot HART PMP Count : 32 Boot HART PMP Granularity : 12 bits Boot HART PMP Address Bits: 38 Boot HART MHPM Info : 16 (0x0007fff8) Boot HART Debug Triggers : 8 triggers Boot HART MIDELEG : 0x0000000000002222 Boot HART MEDELEG : 0x000000000000b109 U-Boot 2022.10spacemit (May 06 2024 - 03:49:58 +0000) CPU: rv64imafdcvsu_zicsr_zifencei_zicbom_zihintpause_zba_zbb_zbc_zbs_svpbmt_sstc_sscofpmf Model: spacemit k1-x deb1 board DRAM: 4 GiB Core: 399 devices, 27 uclasses, devicetree: board ``` Note: The version shows v1.0, but it is actually the master branch after the v1.4 tag. ### Off topic: strange pxa uart K1 has a special pxa-uart device from factory sdk, which needs a dma driver to work. What's worse, once the driver is enabled in the kernel, it will produce a nonportable kernel, which is very bad. A simple work around can be turn on `CONFIG_RISCV_SBI_V01`, `CONFIG_NONPORTABLE` and `CONFIG_HVC_RISCV_SBI`, then use `console=hvc0` so we will have a pulling based uart for debugging purpose. Luckily, I found that uart is compatible with `intel,xscale-uart`, so we can write dts like this: ```dts uart_clk: uart-clock { compatible = "fixed-clock"; clock-frequency = <14000000>; #clock-cells = <0>; }; uart0: uart@d4017000 { compatible = "intel,xscale-uart"; reg = <0x0 0xd4017000 0x0 0x100>; clocks = <&uart_clk>; reg-shift = <2>; reg-io-width = <4>; interrupts = <42>; interrupt-parent = <&plic>; }; ``` Then it works: ```console ~ # uname -a Linux (none) 6.9.0-05160-g20b43b33a764 #30 SMP Mon Jun 10 22:42:55 CST 2024 riscv64 GNU/Linux ~ # cat proc/cpuinfo | head processor : 0 hart : 0 isa : rv64imafdcv_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zvfh_sscofpmf_sstc_svpbmt mmu : sv39 mvendorid : 0x710 marchid : 0x8000000058000001 mimpid : 0x1000000049772200 hart isa : rv64imafdcv_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zvfh_sscofpmf_sstc_svpbmt processor : 1 ~ # cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 10: 621 384 379 1007 415 201 289 306 RISC-V INTC 5 Edge riscv-timer 12: 117 0 0 0 0 0 0 0 SiFive PLIC 42 Edge ttyS0 13: 0 0 0 0 0 0 0 0 RISC-V INTC 13 Edge riscv-pmu IPI0: 0 8 5 13 14 6 10 7 Rescheduling interrupts IPI1: 752 101 55 171 654 86 21 28 Function call interrupts IPI2: 0 0 0 0 0 0 0 0 CPU stop interrupts IPI3: 0 0 0 0 0 0 0 0 CPU stop (for crash dump) interrupts IPI4: 0 0 0 0 0 0 0 0 IRQ work interrupts IPI5: 0 0 0 0 0 0 0 0 Timer broadcast interrupts ~ # dmesg | grep tty [ 0.000000] Kernel command line: earlycon=sbi rdinit=/sbin/init console=ttyS0,115200 clk_ignore_unused [ 1.411786] printk: legacy console [ttyS0] disabled [ 1.419744] d4017000.uart: ttyS0 at MMIO 0xd4017000 (irq = 12, base_baud = 875000) is a XScale [ 1.440171] printk: legacy console [ttyS0] enabled ~ # ```