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.
Like this:
static char *get_reset_cause(void)
{
u32 cause;
struct src *src_regs = (struct src *)SRC_BASE_ADDR;
cause = readl(&src_regs->srsr);
writel(cause, &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";
else
return "unknown reset";
}
int print_cpuinfo(void)
{
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);
setenv("reset_cause", reset_cause);
return 0;
}
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.
Thanks for all. Unfortunately, using setenv in 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 setenv on 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.
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?
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.
Ok.
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?
The variable reset_cause was created in the environment but wasn’t wrote to a non-volatile memory. So fw_printenv couldn’t read the variable reset_cause.
I’ve found out that using saveenv after setenv_hex on arch_misc_init function works. Take a look at the function below. That way I was able to read the reset_cause variable with fw_printenv.
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.