Revision 5ef98b47 hw/etraxfs_timer.c

b/hw/etraxfs_timer.c
46 46
struct fs_timer_t {
47 47
	CPUState *env;
48 48
	qemu_irq *irq;
49
	qemu_irq *nmi;
49 50
	target_phys_addr_t base;
50 51

  
51 52
	QEMUBH *bh_t0;
......
56 57
	ptimer_state *ptimer_wd;
57 58
	struct timeval last;
58 59

  
60
	int wd_hits;
61

  
59 62
	/* Control registers.  */
60 63
	uint32_t rw_tmr0_div;
61 64
	uint32_t r_tmr0_data;
......
129 132
	unsigned int freq_hz;
130 133
	unsigned int div;
131 134
	uint32_t ctrl;
135

  
132 136
	ptimer_state *timer;
133 137

  
134 138
	if (tnum == 0) {
......
163 167

  
164 168
	D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
165 169
	div = div * TIMER_SLOWDOWN;
166
	div >>= 15;
167
	freq_hz >>= 15;
170
	div >>= 10;
171
	freq_hz >>= 10;
168 172
	ptimer_set_freq(timer, freq_hz);
169 173
	ptimer_set_limit(timer, div, 0);
170 174

  
......
216 220

  
217 221
static void watchdog_hit(void *opaque)
218 222
{
219
	qemu_system_reset_request();
223
	struct fs_timer_t *t = opaque;
224
	if (t->wd_hits == 0) {
225
		/* real hw gives a single tick before reseting but we are
226
		   a bit friendlier to compensate for our slower execution.  */
227
		ptimer_set_count(t->ptimer_wd, 10);
228
		ptimer_run(t->ptimer_wd, 1);
229
		qemu_irq_raise(t->nmi[0]);
230
	}
231
	else
232
		qemu_system_reset_request();
233

  
234
	t->wd_hits++;
220 235
}
221 236

  
222 237
static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value)
......
237 252
	D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", 
238 253
		 wd_en, new_key, wd_key, new_cmd, wd_cnt));
239 254

  
255
	if (t->wd_hits)
256
		qemu_irq_lower(t->nmi[0]);
257

  
258
	t->wd_hits = 0;
259

  
240 260
	ptimer_set_freq(t->ptimer_wd, 760);
241 261
	if (wd_cnt == 0)
242 262
		wd_cnt = 256;
......
320 340
	qemu_irq_lower(t->irq[0]);
321 341
}
322 342

  
323
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, 
343
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi,
324 344
			target_phys_addr_t base)
325 345
{
326 346
	static struct fs_timer_t *t;
......
337 357
	t->ptimer_t1 = ptimer_init(t->bh_t1);
338 358
	t->ptimer_wd = ptimer_init(t->bh_wd);
339 359
	t->irq = irqs;
360
	t->nmi = nmi;
340 361
	t->env = env;
341 362
	t->base = base;
342 363

  

Also available in: Unified diff