From: Chao-ying Fu <c...@mips.com> Introduce the 'startharts' command for RISC-V targets, which prints or executes commands to power up and reset all harts and jump to 0x80000000. The command supports optional cluster/core count and immediate execution via the 'g' argument.
Signed-off-by: Chao-ying Fu <c...@mips.com> Signed-off-by: Uros Stajic <uros.sta...@htecgroup.com> --- arch/riscv/include/asm/arch-p8700/p8700.h | 3 + board/mips/boston-riscv/MAINTAINERS | 1 + cmd/Kconfig | 6 ++ cmd/Makefile | 1 + cmd/start_harts.c | 103 ++++++++++++++++++++++ configs/boston-p8700_defconfig | 1 + 6 files changed, 115 insertions(+) create mode 100644 cmd/start_harts.c diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h index 6c47de9a633..20868eee419 100644 --- a/arch/riscv/include/asm/arch-p8700/p8700.h +++ b/arch/riscv/include/asm/arch-p8700/p8700.h @@ -77,8 +77,11 @@ #define CPC_SYS_CONFIG 0x0140 #define CPC_Cx_CMD 0x0000 +#define CPC_Cx_CMD_PWRUP 0x3 #define CPC_Cx_CMD_RESET 0x4 +#define CPC_Cx_VP_RUN 0x0028 + /* GCR_CONFIG */ #define GCR_CONFIG 0x0000 #define GCR_REV 0x0030 diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS index b04dcde943a..0e2f4c277d3 100644 --- a/board/mips/boston-riscv/MAINTAINERS +++ b/board/mips/boston-riscv/MAINTAINERS @@ -12,3 +12,4 @@ F: arch/riscv/lib/mips_gic.c F: cmd/display.c F: include/led-display.h F: doc/README.LED_display +F: cmd/start_harts.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 3be6459acf6..3cfc6bcc7e7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2334,6 +2334,12 @@ config CMD_DISPLAY displayed on a simple board-specific display. Implement display_putc() to use it. +config CMD_START_HARTS + bool "Start harts" + depends on RISCV + help + This prints commands to start all harts and go 0x80000000. + config CMD_EFIDEBUG bool "efidebug - display/configure UEFI environment" depends on EFI_LOADER diff --git a/cmd/Makefile b/cmd/Makefile index e1bdb7f05e8..afe10e92291 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_CMD_SOUND) += sound.o ifdef CONFIG_POST obj-$(CONFIG_CMD_DIAG) += diag.o endif +obj-$(CONFIG_CMD_START_HARTS) += start_harts.o obj-$(CONFIG_CMD_DISPLAY) += display.o obj-$(CONFIG_CMD_ADTIMG) += adtimg.o obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o diff --git a/cmd/start_harts.c b/cmd/start_harts.c new file mode 100644 index 00000000000..0d074778b6d --- /dev/null +++ b/cmd/start_harts.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2005 + * Wolfgang Denk, DENX Software Engineering, w...@denx.de. + */ + +#include <command.h> +#include <asm/arch-p8700/p8700.h> + +int start_harts(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int n_cluster = 1; + int n_core = 1; + int run = 0; + int cl, co; + long cmd_reg; + + if (argc > 1 && argv[1][0] > '0' && argv[1][0] <= '9') + n_cluster = argv[1][0] - '0'; + if (argc > 2 && argv[2][0] > '0' && argv[2][0] <= '9') + n_core = argv[2][0] - '0'; + if (argc > 3) + run = (argv[3][0] == 'g'); + + for (cl = 1; cl < n_cluster; cl++) { + cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + + CPC_OFF_LOCAL + CPC_Cx_CMD; + printf("# Start cluster %d core 0 hart 0\n", cl); + printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_PWRUP); + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_PWRUP), "r"(cmd_reg)); + asm volatile("fence"); + } + + printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_RESET); + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_RESET), "r"(cmd_reg)); + asm volatile("fence"); + } + + cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + CPC_OFF_LOCAL + CPC_Cx_VP_RUN; + printf("mw.q 0x%lx 1\n", cmd_reg); + + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(1), "r"(cmd_reg)); + asm volatile("fence"); + } + } + + for (cl = 0; cl < n_cluster; cl++) { + for (co = 1; co < n_core; co++) { + cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + + (co << CM_BASE_CORE_SHIFT) + + CPC_OFF_LOCAL + CPC_Cx_CMD; + printf("# Start cluster %d core %d hart 0\n", cl, co); + printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_RESET); + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_RESET), "r"(cmd_reg)); + asm volatile("fence"); + } + + cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + + (co << CM_BASE_CORE_SHIFT) + + CPC_OFF_LOCAL + CPC_Cx_VP_RUN; + printf("mw.q 0x%lx 1\n", cmd_reg); + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(1), "r"(cmd_reg)); + asm volatile("fence"); + } + } + } + + for (cl = 0; cl < n_cluster; cl++) { + for (co = 0; co < n_core; co++) { + printf("# Start cluster %d core %d all harts\n", cl, co); + cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + + (co << CM_BASE_CORE_SHIFT) + + CPC_OFF_LOCAL + CPC_Cx_VP_RUN; + printf("mw.q 0x%lx 0xff\n", cmd_reg); + if (run == 1) { + asm volatile("sd %0, 0(%1)"::"r"(0xff), "r"(cmd_reg)); + asm volatile("fence"); + } + } + } + + printf("go 0x80000000\n"); + if (run == 1) { + void (*addr)(void) = (void (*)(void))0x80000000; + (*addr)(); + } + + return 0; +} + +/***************************************************/ + +U_BOOT_CMD(startharts, CONFIG_SYS_MAXARGS, 1, start_harts, + "print commands to start all harts and go 0x80000000", + "[<#clusters:1-9>] [<#cores_per_cluster:1-9>] [g]\n" + " - print commands to start all harts and go 0x80000000\n" + " If the 3rd parameter is 'g', execute all comamnds." +); diff --git a/configs/boston-p8700_defconfig b/configs/boston-p8700_defconfig index 3df7ffe50b3..85ed687107e 100644 --- a/configs/boston-p8700_defconfig +++ b/configs/boston-p8700_defconfig @@ -72,6 +72,7 @@ CONFIG_OF_EMBED=y CONFIG_CPU=y CONFIG_MMC_SDHCI=y CONFIG_MMC_PCI=y +CONFIG_CMD_START_HARTS=y CONFIG_UNIT_TEST=y CONFIG_UT_LIB=n -- 2.34.1