Hello, This series adds support for RISC-V Platform Management Interface (RPMI) to U-Boot. RPMI is an OS-agnostic protocol for communication between an Application Processor (AP) and a Platform Microcontroller (PuC) [1]. There are some similarities between RPMI and SCMI.
This patchset first adds an abstraction layer for the transport (UCLASS_RPMI), then adds two transport layer (SBI MPXY and shared memory) and finally adds one client (or service group in RPMI jargon): the clock service group. This series also includes a sandbox mode for which the RPMI transport doesn't attach to a firmware but contains a simulation of a firmware. This reuses code from librpmi [2] to create the message responses. >From V3, this series also includes the "mpxy" command line tool created by Rahul [6]. Apart from the spec [1], this series reuses code from the Linux SBI MPXY driver [3], OpenSBI shared memory transport [4] and Linux RPMI clock driver [5]. This was tested on a PIC64-HPSC SoC which features an application cluster and a system controller with isolated address spaces, hence the need for RPMI. This series can also be tested with QEMU using the steps detailed in the following section. # Testing ## Build qemu Build QEMU using Subrahmanya Lingappa v11 patches [7] that adds support for librpmi along with another patch (by me) that adds some phony clocks for testing. This is available at [8] for your convenience. You will also need to download and build librpmi since it is a dependency of qemu, any recent version should do. The following commands do all of this: ```` git clone https://github.com/riscv-software-src/librpmi.git cd librpmi make make install I=install sed -i "s|\${prefix}|$(pwd)/install|g" ./install/lib/pkgconfig/librpmi.pc export PKG_CONFIG_PATH="$(pwd)/install/lib/pkgconfig:$PKG_CONFIG_PATH" cd .. git clone https://github.com/ch-perry/qemu.git -b rpmi_patches_with_clocks cd qemu ./configure --enable-librpmi make -j8 qemu-system-riscv32 qemu-system-riscv64 export PATH="$(pwd)/build:$PATH" ```` ## Device tree We also need to tweak a bit the device tree used by QEMU. This is done externally because we need to append a different fragment depending on if we're testing M mode U-Boot or S Mode U-Boot. For M mode U-Boot, we use: ``` cat <<EOF > overlay-mmode.dts / { clock-controller { #clock-cells = <1>; mboxes = <&{/soc/mailbox@10200000} 0x08>; compatible = "riscv,rpmi-clock"; }; }; EOF ``` While for S mode, we use: ``` cat <<EOF > overlay-smode.dts / { clock-controller { #clock-cells = <1>; mboxes = <&mbox 0x1000 0x00>; compatible = "riscv,rpmi-clock"; }; mbox: mailbox { #mbox-cells = <2>; compatible = "riscv,sbi-mpxy-mbox"; }; }; EOF ``` ## Test RV64 in M mode: Source your RV64 compiler, build U-Boot's qemu-riscv64_defconfig and test with QEMU: ``` make clean make qemu-riscv64_defconfig && echo CONFIG_CMD_CLK=y >> .config make -j8 qemu-system-riscv64 -cpu rv64 -smp 4 -M virt,rpmi=on,dumpdtb=qemu.dtb dtc -O dts qemu.dtb | cat - ./overlay-mmode.dts | dtc -o qemu_mmode.dtb -I dts - qemu-system-riscv64 -cpu rv64 -smp 4 -M virt,rpmi=on -dtb qemu_mmode.dtb -nographic -bios u-boot.bin ``` `clk dump` should report 2 clocks. ## Test RV64 in S mode: Build any recent version of OpenSBI using the generic platform and the default defconfig: ``` git clone https://github.com/riscv-software-src/opensbi.git cd opensbi make PLATFORM=generic cp build/platform/generic/firmware/fw_dynamic.bin ../u-boot/fw_dynamic_rv64.bin cd ../u-boot ``` Back in U-Boot, build qemu-riscv64_smode_defconfig and test with QEMU: ``` make clean make qemu-riscv64_smode_defconfig && echo CONFIG_CMD_CLK=y >> .config make -j8 qemu-system-riscv64 -cpu rv64 -smp 4 -M virt,rpmi=on,dumpdtb=qemu.dtb dtc -O dts qemu.dtb | cat - ./overlay-smode.dts | dtc -o qemu_smode.dtb -I dts - qemu-system-riscv64 -cpu rv64 -smp 4 -M virt,rpmi=on \ -dtb qemu_smode.dtb -nographic \ -bios fw_dynamic_rv64.bin \ -kernel u-boot.bin ``` `clk dump` should report 2 clocks. You can also use the `mpxy` command. ## Test RV32 in M mode: Source your RV32 compiler, build U-Boot's qemu-riscv32_defconfig and test with QEMU: ``` make clean make qemu-riscv32_defconfig && echo CONFIG_CMD_CLK=y >> .config make -j8 qemu-system-riscv32 -cpu rv32 -smp 4 -M virt,rpmi=on,dumpdtb=qemu.dtb dtc -O dts qemu.dtb | cat - ./overlay-mmode.dts | dtc -o qemu_mmode.dtb -I dts - qemu-system-riscv32 -cpu rv32 -smp 4 -M virt,rpmi=on -dtb qemu_mmode.dtb -nographic -bios u-boot.bin ``` `clk dump` should report 2 clocks. ## Test RV32 in S mode: Build OpenSBI for 32 bits, the instructions are the same as for 64 bits but with an rv32 toolchain in CROSS_COMPILE. Build U-Boot's qemu-riscv32_smode_defconfig and test with QEMU: ``` make clean make qemu-riscv32_smode_defconfig && echo CONFIG_CMD_CLK=y >> .config make -j8 qemu-system-riscv32 -cpu rv32 -smp 4 -M virt,rpmi=on,dumpdtb=qemu.dtb dtc -O dts qemu.dtb | cat - ./overlay-smode.dts | dtc -o qemu_smode.dtb -I dts - qemu-system-riscv32 -cpu rv32 -smp 4 -M virt,rpmi=on \ -dtb qemu_smode.dtb -nographic \ -bios fw_dynamic_rv32.bin \ -kernel u-boot.bin ``` `clk dump` should report 2 clocks. You can also use the `mpxy` command. # References [1]: https://github.com/riscv-non-isa/riscv-rpmi [2]: https://github.com/riscv-software-src/librpmi [3]: https://elixir.bootlin.com/linux/v7.0.10/source/drivers/mailbox/riscv-sbi-mpxy-mbox.c [4]: https://elixir.bootlin.com/opensbi/v1.8.1/source/lib/utils/mailbox/fdt_mailbox_rpmi_shmem.c [5]: https://elixir.bootlin.com/linux/v7.0.10/source/drivers/clk/clk-rpmi.c [6]: https://lore.kernel.org/all/[email protected]/ [7]: https://lore.kernel.org/all/[email protected]/ [8]: https://github.com/ch-perry/qemu/commits/rpmi_patches_with_clocks/ # Changelog Changes in v4: - I forgot to send patch 1 in v3, add it back. - Add patches 7 and 8 that add the relevant RPMI defconfig to qemu-riscv[32|64]_smode_defconfig and qemu-riscv[32|64]_defconfig - Add instructions on how to test on QEMU in the cover letter - Fix the default value of the doorbell from 0 to 1 in the MPXY driver - Force a device_probe() of all UCLASS_RPMI devices if g_mpxy is NULL in the mpxy command - Remove the unnecessary edit to "cmd/riscv/Makefile" (mpxy command) Changes in v3: - Added the "mpxy" command from Rahul. See [6]. Changes in v2: - Drop the device-power service group as the DT bindings for it are not mainlined (was patch 5 and 7). - Reorder headers in all .c files. - Don't null check pointers before free(). - Improve error messages in rpmi_check_versions() (patch 1). - Remove struct sbi_mpxy_rpmi_channel_attrs and struct sbi_mpxy_channel_attrs for simpler u32 arrays (patch 2). - Remove transition_latency from struct rpmi_clk_def as it's unused (patch 4). - Simplify last return path of _rpmi_clk_enable_disable() (patch 4). - Move the call to _rpmi_clk_get_rate() from _rpmi_clk_set_rate() to rpmi_clk_set_rate() (patch 4). Signed-off-by: Charles Perry <[email protected]> --- Charles Perry (7): firmware: add support for RPMI firmware: rpmi: add support for the SBI MPXY transport firmware: rpmi: add support for shared memory transport drivers: clk: add support for RPMI clocks firmware: rpmi: add a test and a sandbox driver configs: qemu-riscv[32|64]_smode_defconfig: add RPMI configs configs: qemu-riscv[32|64]_defconfig: add RPMI configs Rahul Pathak (1): drivers: firmware: rpmi: Add the mpxy command MAINTAINERS | 8 + arch/riscv/include/asm/sbi.h | 57 ++ arch/sandbox/dts/test.dts | 12 + configs/qemu-riscv32_defconfig | 3 + configs/qemu-riscv32_smode_defconfig | 4 + configs/qemu-riscv64_defconfig | 3 + configs/qemu-riscv64_smode_defconfig | 4 + configs/sandbox_defconfig | 2 + drivers/clk/Kconfig | 7 + drivers/clk/Makefile | 1 + drivers/clk/clk_rpmi.c | 344 ++++++++++++ drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/rpmi/Kconfig | 34 ++ drivers/firmware/rpmi/Makefile | 4 + drivers/firmware/rpmi/rpmi-sandbox-clock.c | 446 ++++++++++++++++ drivers/firmware/rpmi/rpmi-sandbox.c | 156 ++++++ drivers/firmware/rpmi/rpmi-sandbox.h | 47 ++ drivers/firmware/rpmi/rpmi-sbi-mpxy.c | 806 +++++++++++++++++++++++++++++ drivers/firmware/rpmi/rpmi-shmem.c | 473 +++++++++++++++++ drivers/firmware/rpmi/rpmi-uclass.c | 144 ++++++ include/dm/uclass-id.h | 1 + include/rpmi-uclass.h | 79 +++ include/rpmi.h | 159 ++++++ include/rpmi_proto.h | 125 +++++ test/dm/Makefile | 1 + test/dm/rpmi.c | 48 ++ 27 files changed, 2970 insertions(+) --- base-commit: fed92546960a92177d67c0b8d7b22385f50fed29 change-id: 20261012-rpmi_v4-811f5d688cbc Best regards, -- Charles Perry <[email protected]>
