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); |