Rev 2107 | Rev 2634 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2107 | Rev 2633 | ||
---|---|---|---|
Line 87... | Line 87... | ||
87 | { |
87 | { |
88 | return cp0_status_read(); |
88 | return cp0_status_read(); |
89 | } |
89 | } |
90 | 90 | ||
91 | /* TODO: This is SMP unsafe!!! */ |
91 | /* TODO: This is SMP unsafe!!! */ |
- | 92 | uint32_t count_hi = 0; |
|
92 | static unsigned long nextcount; |
93 | static unsigned long nextcount; |
- | 94 | static unsigned long lastcount; |
|
- | 95 | ||
93 | /** Start hardware clock */ |
96 | /** Start hardware clock */ |
94 | static void timer_start(void) |
97 | static void timer_start(void) |
95 | { |
98 | { |
- | 99 | lastcount = cp0_count_read(); |
|
96 | nextcount = cp0_compare_value + cp0_count_read(); |
100 | nextcount = cp0_compare_value + cp0_count_read(); |
97 | cp0_compare_write(nextcount); |
101 | cp0_compare_write(nextcount); |
98 | } |
102 | } |
99 | 103 | ||
100 | static irq_ownership_t timer_claim(void) |
104 | static irq_ownership_t timer_claim(void) |
Line 103... | Line 107... | ||
103 | } |
107 | } |
104 | 108 | ||
105 | static void timer_irq_handler(irq_t *irq, void *arg, ...) |
109 | static void timer_irq_handler(irq_t *irq, void *arg, ...) |
106 | { |
110 | { |
107 | unsigned long drift; |
111 | unsigned long drift; |
108 | 112 | ||
- | 113 | if (cp0_count_read() < lastcount) { |
|
- | 114 | /* Count overflow detection */ |
|
- | 115 | count_hi++; |
|
- | 116 | lastcount = cp0_count_read(); |
|
- | 117 | } |
|
- | 118 | ||
109 | drift = cp0_count_read() - nextcount; |
119 | drift = cp0_count_read() - nextcount; |
110 | while (drift > cp0_compare_value) { |
120 | while (drift > cp0_compare_value) { |
111 | drift -= cp0_compare_value; |
121 | drift -= cp0_compare_value; |
112 | CPU->missed_clock_ticks++; |
122 | CPU->missed_clock_ticks++; |
113 | } |
123 | } |
114 | nextcount = cp0_count_read() + cp0_compare_value - drift; |
124 | nextcount = cp0_count_read() + cp0_compare_value - drift; |
115 | cp0_compare_write(nextcount); |
125 | cp0_compare_write(nextcount); |
116 | 126 | ||
117 | /* |
127 | /* |
118 | * We are holding a lock which prevents preemption. |
128 | * We are holding a lock which prevents preemption. |
119 | * Release the lock, call clock() and reacquire the lock again. |
129 | * Release the lock, call clock() and reacquire the lock again. |
120 | */ |
130 | */ |
121 | spinlock_unlock(&irq->lock); |
131 | spinlock_unlock(&irq->lock); |