Remove building with NOCRYPTO option
[minix.git] / minix / kernel / watchdog.c
blob65bb9ff030511b6f7320e4106cc86913f44eca3d
1 /*
2 * This is arch independent NMI watchdog implementation part. It is used to
3 * detect kernel lockups and help debugging. each architecture must add its own
4 * low level code that triggers periodic checks
5 */
7 #include "watchdog.h"
8 #include "arch/i386/glo.h"
10 unsigned watchdog_local_timer_ticks = 0U;
11 struct arch_watchdog *watchdog;
12 int watchdog_enabled;
14 static void lockup_check(struct nmi_frame * frame)
16 /* FIXME this should be CPU local */
17 static unsigned no_ticks;
18 static unsigned last_tick_count = (unsigned) -1;
21 * when debugging on serial console, printing takes a lot of time some
22 * times while the kernel is certainly not locked up. We don't want to
23 * report a lockup in such situation
25 if (serial_debug_active)
26 return;
28 if (last_tick_count != watchdog_local_timer_ticks) {
29 if (no_ticks == 1) {
30 printf("watchdog : kernel unlocked\n");
31 no_ticks = 0;
33 /* we are still ticking, everything seems good */
34 last_tick_count = watchdog_local_timer_ticks;
35 return;
39 * if watchdog_local_timer_ticks didn't changed since last time, give it
40 * some more time and only if it still dead, trigger the watchdog alarm
42 if (++no_ticks < 10) {
43 if (no_ticks == 1)
44 printf("WARNING watchdog : possible kernel lockup\n");
45 return;
48 /* if we get this far, the kernel is locked up */
49 arch_watchdog_lockup(frame);
52 void nmi_watchdog_handler(struct nmi_frame * frame)
54 #if SPROFILE
56 * Do not check for lockups while profiling, it is extremely likely that
57 * a false positive is detected if the frequency is high
59 if (watchdog_enabled && !sprofiling)
60 lockup_check(frame);
61 if (sprofiling)
62 nmi_sprofile_handler(frame);
64 if ((watchdog_enabled || sprofiling) && watchdog->reinit)
65 watchdog->reinit(cpuid);
66 #else
67 if (watchdog_enabled) {
68 lockup_check(frame);
69 if (watchdog->reinit)
70 watchdog->reinit(cpuid);
72 #endif
75 int nmi_watchdog_start_profiling(const unsigned freq)
77 int err;
79 /* if watchdog hasn't been enabled, we must enable it now */
80 if (!watchdog_enabled) {
81 if (arch_watchdog_init())
82 return ENODEV;
85 if (!watchdog->profile_init) {
86 printf("WARNING NMI watchdog profiling not supported\n");
87 nmi_watchdog_stop_profiling();
88 return ENODEV;
91 err = watchdog->profile_init(freq);
92 if (err != OK)
93 return err;
95 watchdog->resetval = watchdog->profile_resetval;
97 return OK;
100 void nmi_watchdog_stop_profiling(void)
103 * if we do not rearm the NMI source, we are done, if we want to keep
104 * the watchdog running, we reset is to its normal value
107 if (watchdog)
108 watchdog->resetval = watchdog->watchdog_resetval;
110 if (!watchdog_enabled)
111 arch_watchdog_stop();