[PATCH 36] LEON3: GPTIMER timer watchdog driver

Daniel Hellstrom daniel at gaisler.com
Thu Apr 19 10:32:12 UTC 2012


On 04/18/2012 06:35 PM, Joel Sherrill wrote:
> On 04/18/2012 10:53 AM, Joel Sherrill wrote:
>> + Looks like tabs on indentation in the new C file
ok
>> + 2011 date
ok
>> + You are proposing new bsp_watchdog methods. I am
>> not opposed to them but they shouldn't go in your bsp.h.
ok, will add watchdog.h temporarily and resubmit patch. I agree a common API would benefit all, and I'm ready to convert the LEON3 watchdog code for the new API when it is available.

>> It would be better to add this as a possible API for all BSPs.
>> This would have to be reconciled with the following existing
>> code in the tree:
>>
>> ./cpukit/libcsupport/include/rtems/watchdogdrv.h
>> ./c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
>> ./c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start-watchdog.c
>>
>> And I did some work on a prototype which never got the
>> attention it deserved. Chris and I discussed this as a libchip
>> framework where you could have multiple reset watchdogs
>> for different pieces of hardware.
>>
>> I prototyped a simple one based upon a test fixture reset
>> driver and a some code for the Intel ich4 chipset watchdog.
>> Longer term, we envisioned a library of watchdog management
>> code which helped the application. Say reset from timer or
>> a special task.
> http://www.rtems.org/ftp/pub/rtems/people/joel/watchdog/
>> I would like to take this as an opportunity to discuss this
>> all again and get on the right path long term. Your
>> "bsp_watchdog_xxx" could be the names for the
>> main board reset and the framework could be
>> layered on top of it.

I have read your code, and I have detected some coding-style issues... ;) ... anyway, one thing that that came to my mind was that the watchdog functionality may be initialized early in the BSP 
already to detect a lock-up during boot, or perhaps we need to access the watchdog routines on shutdown after RTEMS has been closed down. But at that time the IO layer is perhaps not available, my 
point is that it is perhaps better to avoid depend on the IO layer? On the other hand, it may be the bootloader that sets up the watchdog the first time to detect a RTEMS boot hang.

The reboot returns to bootcard.c, then bsp_clean(), then to the BSP. In the LEON case the CPU is forced into a trap/debug-mode. It would perhaps be better to have to option to reset the system also 
instead of always stopping the CPU. That is something I need to think about.

Daniel


>> You seem to be the lucky guy who asks the questions which
>> need to be answered. :)
>>
>> On 04/18/2012 10:19 AM, Daniel Hellstrom wrote:
>>> Last timer instance of GPTIMER is sometimes a watchdog timer that
>>> can reset the system on timer underflow.
>>>
>>> Signed-off-by: Daniel Hellstrom<daniel at gaisler.com>
>>> ---
>>>    c/src/lib/libbsp/sparc/leon3/Makefile.am      |    1 +
>>>    c/src/lib/libbsp/sparc/leon3/include/bsp.h    |   25 +++++++
>>>    c/src/lib/libbsp/sparc/leon3/timer/watchdog.c |   89 +++++++++++++++++++++++++
>>>    3 files changed, 115 insertions(+), 0 deletions(-)
>>>    create mode 100644 c/src/lib/libbsp/sparc/leon3/timer/watchdog.c
>>>
>>> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>>> index cc25993..9b8af4b 100644
>>> --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
>>> +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>>> @@ -115,6 +115,7 @@ libbsp_a_SOURCES += ../../sparc/shared/i2c/i2cmst.c
>>>
>>>    # timer
>>>    libbsp_a_SOURCES += timer/timer.c
>>> +libbsp_a_SOURCES += timer/watchdog.c
>>>
>>>    if HAS_SMP
>>>    libbsp_a_SOURCES += smp/getcpuid.c
>>> diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>>> index d883064..32407dd 100644
>>> --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>>> +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>>> @@ -192,6 +192,31 @@ extern void BSP_shared_interrupt_unmask(int irq);
>>>     */
>>>    extern void BSP_shared_interrupt_mask(int irq);
>>>
>>> +/* Initialize BSP watchdog routines. Returns number of watchdog timers found.
>>> + * Currently only one is supported.
>>> + */
>>> +extern int bsp_watchdog_init(void);
>>> +
>>> +/* Reload watchdog (last timer on the first GPTIMER core), all systems does not
>>> + * feature a watchdog, it is expected that if this function is called the
>>> + * user knows that there is a watchdog available.
>>> + *
>>> + * The prescaler is normally set to number of MHz of system, this is to
>>> + * make the system clock tick be stable.
>>> + *
>>> + * Arguments
>>> + *  watchdog       - Always 0 for now
>>> + *  reload_value   - Number of timer clocks (after prescaler) to count before
>>> + *                   watchdog is woken.
>>> + */
>>> +extern void bsp_watchdog_reload(int watchdog, unsigned int reload_value);
>>> +
>>> +/* Stop watchdog timer */
>>> +extern void bsp_watchdog_stop(int watchdog);
>>> +
>>> +/* Use watchdog0 timer to reset the system */
>>> +extern void bsp_watchdog_system_reset(void);
>>> +
>>>    #ifdef __cplusplus
>>>    }
>>>    #endif
>>> diff --git a/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c b/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c
>>> new file mode 100644
>>> index 0000000..d3a9c15
>>> --- /dev/null
>>> +++ b/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c
>>> @@ -0,0 +1,89 @@
>>> +/*  GPTIMER Watchdog timer routines. On some systems the first GPTIMER
>>> + *  core's last Timer instance underflow signal is connected to system
>>> + *  reset.
>>> + *
>>> + *  COPYRIGHT (c) 2011
>>> + *  Aeroflex Gaisler
>>> + *
>>> + *  The license and distribution terms for this file may be
>>> + *  found in the file LICENSE in this distribution or at
>>> + *http://www.rtems.com/license/LICENSE.
>>> + */
>>> +
>>> +#include<bsp.h>
>>> +#include<grlib.h>
>>> +
>>> +extern volatile struct gptimer_regs *LEON3_Timer_Regs;
>>> +
>>> +struct gptimer_watchdog_priv {
>>> +	struct gptimer_regs *regs;
>>> +	struct gptimer_timer_regs *timer;
>>> +	int timerno;
>>> +};
>>> +
>>> +struct gptimer_watchdog_priv bsp_watchdogs[1];
>>> +int bsp_watchdog_count = 0;
>>> +
>>> +int bsp_watchdog_init(void)
>>> +{
>>> +	int timercnt;
>>> +
>>> +	if (!LEON3_Timer_Regs)
>>> +		return 0;
>>> +
>>> +	/* Get Watchdogs in system, this is implemented for one GPTIMER core
>>> +	 * only.
>>> +	 *
>>> +	 * First watchdog is a special case, we can get the first timer core by
>>> +	 * looking at LEON3_Timer_Regs, the watchdog within a timer core is
>>> +	 * always the last timer. Unfortunately we can not know it the watchdog
>>> +	 * functionality is available or not, we assume that it is if we
>>> +	 * reached this function.
>>> +	 */
>>> +	bsp_watchdogs[0].regs = (struct gptimer_regs *)LEON3_Timer_Regs;
>>> +
>>> +	/* Find Timer that has watchdog functionality */
>>> +	timercnt = bsp_watchdogs[0].regs->cfg&   0x7;
>>> +	if (timercnt<   2) /* First timer system clock timer */
>>> +		return 0;
>>> +
>>> +	bsp_watchdogs[0].timerno = timercnt - 1;
>>> +	bsp_watchdogs[0].timer =&bsp_watchdogs[0].regs->timer[bsp_watchdogs[0].timerno];
>>> +
>>> +	bsp_watchdog_count = 1;
>>> +	return bsp_watchdog_count;
>>> +}
>>> +
>>> +void bsp_watchdog_reload(int watchdog, unsigned int reload_value)
>>> +{
>>> +	if (bsp_watchdog_count == 0)
>>> +		bsp_watchdog_init();
>>> +
>>> +	if (bsp_watchdog_count<= watchdog)
>>> +		return;
>>> +
>>> +	/* Kick watchdog, and clear interrupt pending bit */
>>> +	bsp_watchdogs[watchdog].timer->reload = reload_value;
>>> +	bsp_watchdogs[watchdog].timer->ctrl =
>>> +		(LEON3_GPTIMER_LD | LEON3_GPTIMER_EN) |
>>> +		(bsp_watchdogs[watchdog].timer->ctrl&   ~(1<<4));
>>> +}
>>> +
>>> +void bsp_watchdog_stop(int watchdog)
>>> +{
>>> +	if (bsp_watchdog_count == 0)
>>> +		bsp_watchdog_init();
>>> +
>>> +	if (bsp_watchdog_count<= watchdog)
>>> +		return;
>>> +
>>> +	/* Stop watchdog timer */
>>> +	bsp_watchdogs[watchdog].timer->ctrl = 0;
>>> +}
>>> +
>>> +/* Use watchdog timer to reset system */
>>> +void bsp_watchdog_system_reset(void)
>>> +{
>>> +	sparc_disable_interrupts();
>>> +	bsp_watchdog_reload(0, 1);
>>> +}
>
>
> -- 
> Joel Sherrill, Ph.D.             Director of Research&   Development
> joel.sherrill at OARcorp.com         On-Line Applications Research
> Ask me about RTEMS: a free RTOS  Huntsville AL 35805
>      Support Available             (256) 722-9985
>




More information about the devel mailing list