1 | This patch addresses the following issues: |
---|
2 | |
---|
3 | - _Watchdog_Ticks_since_boot should be a VOLATILE variable. |
---|
4 | - _Watchdog_Sync_count++ should be protected by _ISR_Disable |
---|
5 | (prevent corruption in case ISR calls watchdoginsert) |
---|
6 | - 'restart' algorithm needs to enforce reloading the list |
---|
7 | head in case a TICK interrupt during ISR_Flash() modified the list. |
---|
8 | This is achieved by a proper VOLATILE cast. |
---|
9 | |
---|
10 | NOTE: PowerPC BSPs using the new exception processing MUST BE UPDATED |
---|
11 | to maintain _ISR_Nest_level. See also PR288 which provides fixes |
---|
12 | for the affected BSPs distributed with RTEMS. |
---|
13 | |
---|
14 | Till Straumann <strauman@slac.stanford.edu>, 2003/7 |
---|
15 | |
---|
16 | Index: cpukit/score/include/rtems/score/watchdog.h |
---|
17 | =================================================================== |
---|
18 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src-20030128/cpukit/score/include/rtems/score/watchdog.h,v |
---|
19 | retrieving revision 1.1.1.3 |
---|
20 | retrieving revision 1.2 |
---|
21 | diff -c -r1.1.1.3 -r1.2 |
---|
22 | *** cpukit/score/include/rtems/score/watchdog.h 29 Jan 2003 22:59:29 -0000 1.1.1.3 |
---|
23 | --- cpukit/score/include/rtems/score/watchdog.h 12 Jul 2003 05:33:56 -0000 1.2 |
---|
24 | *************** |
---|
25 | *** 103,109 **** |
---|
26 | * system was booted. |
---|
27 | */ |
---|
28 | |
---|
29 | ! SCORE_EXTERN Watchdog_Interval _Watchdog_Ticks_since_boot; |
---|
30 | |
---|
31 | /* |
---|
32 | * The following defines the watchdog chains which are managed |
---|
33 | --- 103,109 ---- |
---|
34 | * system was booted. |
---|
35 | */ |
---|
36 | |
---|
37 | ! SCORE_EXTERN volatile Watchdog_Interval _Watchdog_Ticks_since_boot; |
---|
38 | |
---|
39 | /* |
---|
40 | * The following defines the watchdog chains which are managed |
---|
41 | Index: cpukit/score/src/watchdoginsert.c |
---|
42 | =================================================================== |
---|
43 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src-20030128/cpukit/score/src/watchdoginsert.c,v |
---|
44 | retrieving revision 1.1.1.2 |
---|
45 | retrieving revision 1.2 |
---|
46 | diff -c -r1.1.1.2 -r1.2 |
---|
47 | *** cpukit/score/src/watchdoginsert.c 29 Jan 2003 22:59:25 -0000 1.1.1.2 |
---|
48 | --- cpukit/score/src/watchdoginsert.c 12 Jul 2003 05:35:52 -0000 1.2 |
---|
49 | *************** |
---|
50 | *** 38,50 **** |
---|
51 | insert_isr_nest_level = _ISR_Nest_level; |
---|
52 | the_watchdog->state = WATCHDOG_BEING_INSERTED; |
---|
53 | |
---|
54 | _Watchdog_Sync_count++; |
---|
55 | restart: |
---|
56 | delta_interval = the_watchdog->initial; |
---|
57 | |
---|
58 | ! _ISR_Disable( level ); |
---|
59 | ! |
---|
60 | ! for ( after = _Watchdog_First( header ) ; |
---|
61 | ; |
---|
62 | after = _Watchdog_Next( after ) ) { |
---|
63 | |
---|
64 | --- 38,65 ---- |
---|
65 | insert_isr_nest_level = _ISR_Nest_level; |
---|
66 | the_watchdog->state = WATCHDOG_BEING_INSERTED; |
---|
67 | |
---|
68 | + _ISR_Disable( level ); |
---|
69 | + |
---|
70 | _Watchdog_Sync_count++; |
---|
71 | + |
---|
72 | restart: |
---|
73 | delta_interval = the_watchdog->initial; |
---|
74 | |
---|
75 | ! /* |
---|
76 | ! * We CANT use _Watchdog_First() here, because a TICK interrupt |
---|
77 | ! * could modify the chain during the _ISR_Flash() below. Hence, |
---|
78 | ! * the header is pointing to volatile data. The _Watchdog_First() |
---|
79 | ! * INLINE routine (but not the macro - note the subtle difference) |
---|
80 | ! * casts away the 'volatile'... |
---|
81 | ! * |
---|
82 | ! * Also, this is only necessary because we call no other routine |
---|
83 | ! * from this piece of code, hence the compiler thinks it's safe to |
---|
84 | ! * cache *header!! |
---|
85 | ! * |
---|
86 | ! * Till Straumann, 7/2003 (gcc-3.2.2 -O4 on powerpc) |
---|
87 | ! * |
---|
88 | ! */ |
---|
89 | ! for ( after = (Watchdog_Control *) ((volatile Chain_Control *)header)->first ; |
---|
90 | ; |
---|
91 | after = _Watchdog_Next( after ) ) { |
---|
92 | |
---|
93 | *************** |
---|
94 | *** 75,81 **** |
---|
95 | |
---|
96 | if ( _Watchdog_Sync_level > insert_isr_nest_level ) { |
---|
97 | _Watchdog_Sync_level = insert_isr_nest_level; |
---|
98 | - _ISR_Enable( level ); |
---|
99 | goto restart; |
---|
100 | } |
---|
101 | } |
---|
102 | --- 90,95 ---- |
---|