Figure out VF61 Reset Reason

Hi!

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;
}

Regards,

Ives.

Hi @ives

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

Hi @jaski.tx.

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?

Best Regards,

Ives.

hii @ives

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?

Was the variable created or not?

Best regards, Jaski

Hi @jaski.tx.

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.

int arch_misc_init(void)
{
	char soc[6];

	strcpy(soc, "vf");
	strcat(soc, soc_type);
	setenv("soc", soc);

	setenv_hex("reset_cause", reset_cause);
	saveenv();

	return 0;
}

Thanks for all @jaski.tx.

Regards,

Ives.

Hi

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.

Regards
Max