]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/services/diagnosis/v2_0/src/wdt/wdt.c
Initial revision
[karo-tx-redboot.git] / packages / services / diagnosis / v2_0 / src / wdt / wdt.c
1 #include <redboot.h>
2 #include <stdlib.h>
3 #include <cyg/diagnosis/diagnosis.h>
4 #include <cyg/hal/plf_io.h>
5
6 #include CYGHWR_MEMORY_LAYOUT_H
7
8 #define WDT_WCR         0x00
9 #define WDT_WSR         0x02
10
11 #define WDT_CNT_MASK    0xFF00
12 #define WDT_WCR_MASK    0xFF
13 #define WDT_CNT_OFF     8
14
15 #define WDT_WCR_WDW     (1 << 7)
16 #define WDT_WCR_WOE     (1 << 6)
17 #define WDT_WCR_WDA     (1 << 5)
18 #define WDT_WCR_SRS     (1 << 4)
19 #define WDT_WCR_WDT     (1 << 3)
20 #define WDT_WCR_WDE     (1 << 2)
21 #define WDT_WCR_WDBG    (1 << 1)
22 #define WDT_WCR_WDZST   (1)
23
24 #define WDT_MAGIC_1     (0x5555)
25 #define WDT_MAGIC_2     (0xAAAA)
26
27 local_cmd_entry("wdt",
28         "watchdog test:Warning after run test, please reboot",
29         "-s sleep_time -t timeout [-c ctrl_bits] -b\n"
30         "-b:Insert memory access during ping operation\n",
31         wdt_test,
32         DIAGNOSIS_cmds
33 );
34
35 static unsigned char wdt_wcr;
36
37 static unsigned int wdt_ping_mode;
38
39 static inline void wdt_setup(unsigned int timeout)
40 {
41         unsigned short int reg;
42         reg = readw(WDOG_BASE_ADDR + WDT_WCR) & WDT_WCR_MASK;   
43         reg |= (timeout * 2 << WDT_CNT_OFF) & WDT_CNT_MASK;
44
45         if (wdt_wcr)
46                 reg |= wdt_wcr & WDT_WCR_MASK;
47         else
48                 reg |= WDT_WCR_WOE | WDT_WCR_WDA | WDT_WCR_SRS|
49                         WDT_WCR_WDBG | WDT_WCR_WDZST;
50
51         diag_printf("WCR=%x\n", reg | WDT_WCR_WDE);     
52         writew(reg | WDT_WCR_WDE, WDOG_BASE_ADDR + WDT_WCR);
53 }
54
55 static inline void wdt_stop(void)
56 {
57         unsigned short int reg;
58         reg = readw(WDOG_BASE_ADDR + WDT_WCR) & (~WDT_WCR_WDE); 
59         reg |= WDT_CNT_MASK;
60         writew(reg, WDOG_BASE_ADDR + WDT_WCR);
61 }
62
63 static inline void wdt_keepalive(void)
64 {
65         int j;
66         volatile unsigned int i;
67
68         if (wdt_ping_mode) {
69                 writew(WDT_MAGIC_1, WDOG_BASE_ADDR + WDT_WSR);
70                 for (i = 0, j &= 0x7; i <= j; i++)
71                         asm("nop");
72         } else {
73                 writew(WDT_MAGIC_1, WDOG_BASE_ADDR + WDT_WSR);
74         }
75         writew(WDT_MAGIC_2, WDOG_BASE_ADDR + WDT_WSR);
76 }
77
78 static void wdt_sleep(int second)
79 {
80         int i;
81         unsigned int delayCount = 32000;
82
83         for ( i = 0; i < second; i++) { 
84                 writel(0x01, EPIT_BASE_ADDR + EPITSR);
85                 writel(delayCount, EPIT_BASE_ADDR + EPITLR);
86                 while ((0x1 & readl(EPIT_BASE_ADDR + EPITSR)) == 0);
87         }
88 }
89
90 static void wdt_test(int argc, char * argv[])
91 {
92         int opts_map[4];
93         struct option_info opts[4];
94         unsigned int sleep_timeout;
95         unsigned int wdt_timeout;
96
97         memset(opts_map, 0, sizeof(int)*4);
98
99         init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM,
100                  (void *)&sleep_timeout, (bool *)&opts_map[0], "sleep time");
101         init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_NUM,
102                  (void *)&wdt_timeout, (bool *)&opts_map[1], "watchdog timeout");
103         init_opts(&opts[2], 'c', true, OPTION_ARG_TYPE_NUM,
104                  (void *)&wdt_wcr, (bool *)&opts_map[2], "watchdog control bits");
105         init_opts(&opts[3], 'b', false, OPTION_ARG_TYPE_FLG,
106                  (void *)&wdt_ping_mode, (bool *)0, "Add nop between ping operation");
107
108         if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) {
109                 diagnosis_usage("invalid arguments");
110                 return;
111         }
112
113         if(!opts_map[0]) {
114                  sleep_timeout = 1;
115         } 
116
117         if(!opts_map[1]) {
118                 wdt_timeout = 2;
119         }
120
121         if(!opts_map[2]) {
122                 wdt_wcr = 0;
123         }
124
125         diag_printf("Watchdog sleeptime=%d timeout=%d %s in ping", 
126                         sleep_timeout, wdt_timeout,
127                         wdt_ping_mode?"Add memory access":"No memory access");
128         wdt_setup(wdt_timeout);
129         
130         while(1) {
131                 if(_rb_break(0)) {
132                         diag_printf("break Watchdog test\n");
133                         wdt_sleep(wdt_timeout*2);
134                         break;
135                 }
136                 wdt_keepalive();
137                 wdt_sleep(sleep_timeout);
138         }
139         wdt_stop(); 
140         diag_printf("Exit Watchdog test\n");
141 }