[PATCH v2 0/2] arm64: zynqmp: Update zynqmp tcminit mode

When cpu is enabled, the zynqmp tcminit throws an error message when switching from r5-mode "split" to "lockstep". When cpu is disabled, the zynqmp tcminit switch from r5-mode "split" to "lockstep". The mode value is assigned based on string compare for "lockstep", "0" or "split", "1".
Changes in v2: - Update commit message of patch2
Padmarao Begari (2): arm64: zynqmp: Print an error for split to lock mode switch arm64: zynqmp: Fix tcminit mode value based on argv
arch/arm/mach-zynqmp/cpu.c | 16 ++++++++++--- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 1 + arch/arm/mach-zynqmp/mp.c | 24 +++++++++++++++++++ arch/arm/mach-zynqmp/zynqmp.c | 16 ++++++------- 4 files changed, 45 insertions(+), 12 deletions(-)

The zynqmp tcminit crashes the U-Boot when switching from r5-mode "split" to "lockstep" instead it should throw an error. When cpu is enabled, the check_tcm_mode() function checks if the previous mode is "split", switch mode is "lockstep" then it returns the error code and the initialize_tcm() function is not updating the global control register of the RPU instead it prints the error message. When cpu is disabled, the check_tcm_mode() function returns the success code for switch split to lockstep mode.
Signed-off-by: Padmarao Begari padmarao.begari@amd.com --- arch/arm/mach-zynqmp/cpu.c | 16 ++++++++++--- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 1 + arch/arm/mach-zynqmp/mp.c | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c index 07668c9468..b24c163147 100644 --- a/arch/arm/mach-zynqmp/cpu.c +++ b/arch/arm/mach-zynqmp/cpu.c @@ -115,9 +115,19 @@ u64 get_page_table_size(void) #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) void tcm_init(u8 mode) { - puts("WARNING: Initializing TCM overwrites TCM content\n"); - initialize_tcm(mode); - memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE); + int ret; + + ret = check_tcm_mode(mode); + if (!ret) { + puts("WARNING: Initializing TCM overwrites TCM content\n"); + initialize_tcm(mode); + memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE); + } + + if (ret == -EACCES) + printf("ERROR: Split to lockstep mode required reset/disable cpu\n"); + + /* Ignore if ret is -EAGAIN, trying to initialize same mode again */ } #endif
diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 15b69e7771..b3396db28f 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -48,6 +48,7 @@ enum {
unsigned int zynqmp_get_silicon_version(void);
+int check_tcm_mode(bool mode); void initialize_tcm(bool mode); void mem_map_fill(void); #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c index 9b46a25a1c..6e6da8008f 100644 --- a/arch/arm/mach-zynqmp/mp.c +++ b/arch/arm/mach-zynqmp/mp.c @@ -12,7 +12,9 @@ #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> +#include <linux/bitfield.h> #include <linux/delay.h> +#include <linux/errno.h> #include <linux/string.h>
#define LOCK 0 @@ -264,6 +266,28 @@ void initialize_tcm(bool mode) } }
+int check_tcm_mode(bool mode) +{ + u32 tmp, cpu_state; + bool mode_prev; + + tmp = readl(&rpu_base->rpu_glbl_ctrl); + mode_prev = FIELD_GET(ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK, tmp); + + tmp = readl(&crlapb_base->rst_lpd_top); + cpu_state = FIELD_GET(ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK, tmp); + cpu_state = cpu_state ? false : true; + + if ((mode_prev == SPLIT && mode == LOCK) && cpu_state) + return -EACCES; + + if (mode_prev == mode) + return -EAGAIN; + + return 0; +} + static void mark_r5_used(u32 nr, u8 mode) { u32 mask = 0;

The RPU pytest introduced by commit e894c10c040b ("test/py: zynqmp_rpu: Add test for loading RPU apps") expects 3rd parameter as string not a number that's why extend command to actually handle both. The issue with existing code is that when any non number string is passed hextoul returns 0. For backward compatibility zynqmp tcminit 0/1 can be still used but it is recommended to use strings instead.
Signed-off-by: Padmarao Begari padmarao.begari@amd.com --- arch/arm/mach-zynqmp/zynqmp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c index bf39c5472e..bea29bb4c6 100644 --- a/arch/arm/mach-zynqmp/zynqmp.c +++ b/arch/arm/mach-zynqmp/zynqmp.c @@ -151,14 +151,12 @@ static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc, if (argc != cmdtp->maxargs) return CMD_RET_USAGE;
- if (strcmp(argv[2], "lockstep") && strcmp(argv[2], "split")) { - printf("mode param should be lockstep or split\n"); - return CMD_RET_FAILURE; - } - - mode = hextoul(argv[2], NULL); - if (mode != TCM_LOCK && mode != TCM_SPLIT) { - printf("Mode should be either 0(lock)/1(split)\n"); + if (!strcmp(argv[2], "lockstep") || !strcmp(argv[2], "0")) { + mode = TCM_LOCK; + } else if (!strcmp(argv[2], "split") || !strcmp(argv[2], "1")) { + mode = TCM_SPLIT; + } else { + printf("Mode should be either lockstep/split\n"); return CMD_RET_FAILURE; }
@@ -403,7 +401,7 @@ U_BOOT_LONGHELP(zynqmp, " initialized before accessing to avoid ECC\n" " errors. mode specifies in which mode TCM has\n" " to be initialized. Supported modes will be\n" - " lock(0)/split(1)\n" + " lockstep(0)/split(1)\n" #endif "zynqmp pmufw address size - load PMU FW configuration object\n" "zynqmp pmufw node <id> - load PMU FW configuration object, <id> in dec\n"

On 9/30/24 06:38, Padmarao Begari wrote:
When cpu is enabled, the zynqmp tcminit throws an error message when switching from r5-mode "split" to "lockstep". When cpu is disabled, the zynqmp tcminit switch from r5-mode "split" to "lockstep". The mode value is assigned based on string compare for "lockstep", "0" or "split", "1".
Changes in v2:
- Update commit message of patch2
Padmarao Begari (2): arm64: zynqmp: Print an error for split to lock mode switch arm64: zynqmp: Fix tcminit mode value based on argv
arch/arm/mach-zynqmp/cpu.c | 16 ++++++++++--- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 1 + arch/arm/mach-zynqmp/mp.c | 24 +++++++++++++++++++ arch/arm/mach-zynqmp/zynqmp.c | 16 ++++++------- 4 files changed, 45 insertions(+), 12 deletions(-)
Applied. M
participants (2)
-
Michal Simek
-
Padmarao Begari