[U-Boot] [RFC] Detecting coldstart on kirkwood CPUs
Simon Kagstrom
simon.kagstrom at netinsight.net
Fri Sep 25 16:48:27 CEST 2009
Hi (mostly Prafulla)!
I'm looking at detecting cold starts on the OpenRD board (and also
maintain the bootcounter via this). I've come up with a slight hack
which works in practice for me, but which feels a bit unsafe.
What I do is basically to reset the SYSRST duration counter just before
doing the soft reset in reset_cpu() (see patch below, I do a similar
thing in Linux). I've then added the following function to the board
code:
#if defined(CONFIG_MISC_INIT_R)
# define MS_TO_COUNT(x) ( ((x) * 1000 * 1000) / 40)
int misc_init_r (void)
{
u32 rst_count = 0x1fffffff & readl(KW_REG_SYSRST_CNT);
struct uboot_com *p =
(struct uboot_com *)CONFIG_BOOTCOUNT_ADDR;
/* clear the counter for next valid read*/
writel(1 << 31, KW_REG_SYSRST_CNT);
/* If the reset has been held for over 20ms it's a cold-start,
* wait for 40 to be sure
*
* FIXME! This should rely one some more safe metric for the future
*/
if ( rst_count > MS_TO_COUNT(40) ) {
printf("Start type: cold\n");
p->bootcount_magic = 0x12345678; /* Clear the bootcount magic */
p->is_coldstart = is_coldstart = 1;
} else {
printf("Start type: warm\n");
p->is_coldstart = is_coldstart = 0;
}
return 0;
}
#endif
i.e., just check how long the reset was held at startup. If it's longer
than an empirically determined value (~40ms), then it's a cold start.
Pressing the reset button, I always get cold starts (even when tapping
as fast as I can), while soft resets are always warm.
But... Isn't there some better way of checking this on Kirkwood?
// Simon
[PATCH] Reset sysrst count before restarting
Signed-off-by: Simon Kagstrom <simon.kagstrom at netinsight.net>
---
cpu/arm926ejs/kirkwood/cpu.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
index bab5faf..d0cdaf6 100644
--- a/cpu/arm926ejs/kirkwood/cpu.c
+++ b/cpu/arm926ejs/kirkwood/cpu.c
@@ -37,6 +37,7 @@ void reset_cpu(unsigned long ignored)
writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
&cpureg->rstoutn_mask);
+ writel(1 << 31, KW_REG_SYSRST_CNT);
writel(readl(&cpureg->sys_soft_rst) | 1,
&cpureg->sys_soft_rst);
while (1) ;
--
1.6.0.4
More information about the U-Boot
mailing list