Is there any way to figure out Colibri-VF61 reset cause from user space?
There is a function on u-boot source code called “get_reset_cause” at “arch/arm/cpu/armv7/vf610/generic.c”. I’m planning to export an environment variable there with “setenv” and pass the variable to kernel command line through “defargs”. After that I will be able to read the file “/proc/cmdline” and get the reset cause. Do you think this is the right way to do this? Maybe there is another solution for that.
static char *get_reset_cause(void)
struct src *src_regs = (struct src *)SRC_BASE_ADDR;
cause = readl(&src_regs->srsr);
if (cause & SRC_SRSR_POR_RST)
return "POWER ON RESET";
else if (cause & SRC_SRSR_WDOG_A5)
return "WDOG A5";
else if (cause & SRC_SRSR_WDOG_M4)
return "WDOG M4";
else if (cause & SRC_SRSR_JTAG_RST)
return "JTAG HIGH-Z";
else if (cause & SRC_SRSR_SW_RST)
return "SW RESET";
else if (cause & SRC_SRSR_RESETB)
return "EXTERNAL RESET";
return "unknown reset";
printf("CPU: Freescale Vybrid VF%s at %d MHz\n",
soc_type, mxc_get_clock(MXC_ARM_CLK) / 1000000);
char *reset_cause = get_reset_cause();
printf("Reset cause: %s\n", reset_cause);
This seems to be good solution. Once you have written the Reset Cause in a U-Boot Variable, you could read this variable back by
fw_printenv variable from Linux.
Best regards, Jaski
Thanks for all. Unfortunately, using
print_cpuinfo function doesn’t work. Seems that the u-boot environment is not initialized at that point.
However, I’ve found out that using
arch_misc_init function works. The function is located at
arch/arm/cpu/armv7/vf610/generic.c. That way, the variable
reset_cause was created in the environment.
fw_printenv, I couldn’t read the u-boot variable. The command
fw_printenv reset_cause returns nothing. Furthermore, I couldn’t find the
reset_cause variable when I execute
fw_printenv command, without the argument. Do you have any idea what’s going on?
Sorry for the late response. I was busy with some other work.
Seems that the u-boot environment is not initialized at that point
You are right.
That way, the variable reset_cause was created in the environment.
Regarding fw_printenv, I couldn’t read the u-boot variable. The command fw_printenv reset_cause returns nothing. Furthermore, I couldn’t find the reset_cause variable when I execute fw_printenv command, without the argument. Do you have any idea what’s going on?
Was the variable created or not?
Best regards, Jaski
reset_cause was created in the environment but wasn’t wrote to a non-volatile memory. So
fw_printenv couldn’t read the variable
I’ve found out that using
arch_misc_init function works. Take a look at the function below. That way I was able to read the
reset_cause variable with
Thanks for all @jaski.tx.
I don’t like that solution to much. The environment is stored at a fixed location in NAND and no wear levelling algorithm is used.
So with each boot you add one erase/write cycle for the used block.
One improvement would be to first test if “reset_cause” has actually changed and only then do the setenv/saveenv calls.
Better still would be to write the reset cause into a device tree property and then read it out from the device tree. That way you do not need to write to NAND at all.
Have a look at ft_common_board_setup() in board/toradex/common/tdx-common.c on how to write a new property into the device-tree before passing it to the kernel. You would then get in Linux a file with the property name in /proc/device-tree/ with the content of the property.
ft_board_setup() in board/toradex/colibri_vf/colibri_vf.c would be the place to add the needed code.