Revision 84ceea57

b/hw/etraxfs_timer.c
45 45
#define R_MASKED_INTR 0x54
46 46

  
47 47
struct fs_timer_t {
48
	CPUState *env;
49
	qemu_irq *irq;
50
	qemu_irq *nmi;
51

  
52
	QEMUBH *bh_t0;
53
	QEMUBH *bh_t1;
54
	QEMUBH *bh_wd;
55
	ptimer_state *ptimer_t0;
56
	ptimer_state *ptimer_t1;
57
	ptimer_state *ptimer_wd;
58
	struct timeval last;
59

  
60
	int wd_hits;
61

  
62
	/* Control registers.  */
63
	uint32_t rw_tmr0_div;
64
	uint32_t r_tmr0_data;
65
	uint32_t rw_tmr0_ctrl;
66

  
67
	uint32_t rw_tmr1_div;
68
	uint32_t r_tmr1_data;
69
	uint32_t rw_tmr1_ctrl;
70

  
71
	uint32_t rw_wd_ctrl;
72

  
73
	uint32_t rw_intr_mask;
74
	uint32_t rw_ack_intr;
75
	uint32_t r_intr;
76
	uint32_t r_masked_intr;
48
    CPUState *env;
49
    qemu_irq *irq;
50
    qemu_irq *nmi;
51

  
52
    QEMUBH *bh_t0;
53
    QEMUBH *bh_t1;
54
    QEMUBH *bh_wd;
55
    ptimer_state *ptimer_t0;
56
    ptimer_state *ptimer_t1;
57
    ptimer_state *ptimer_wd;
58
    struct timeval last;
59

  
60
    int wd_hits;
61

  
62
    /* Control registers.  */
63
    uint32_t rw_tmr0_div;
64
    uint32_t r_tmr0_data;
65
    uint32_t rw_tmr0_ctrl;
66

  
67
    uint32_t rw_tmr1_div;
68
    uint32_t r_tmr1_data;
69
    uint32_t rw_tmr1_ctrl;
70

  
71
    uint32_t rw_wd_ctrl;
72

  
73
    uint32_t rw_intr_mask;
74
    uint32_t rw_ack_intr;
75
    uint32_t r_intr;
76
    uint32_t r_masked_intr;
77 77
};
78 78

  
79 79
static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
80 80
{
81
	struct fs_timer_t *t = opaque;
82
	uint32_t r = 0;
83

  
84
	switch (addr) {
85
	case R_TMR0_DATA:
86
		r = ptimer_get_count(t->ptimer_t0);
87
		break;
88
	case R_TMR1_DATA:
89
		r = ptimer_get_count(t->ptimer_t1);
90
		break;
91
	case R_TIME:
92
		r = qemu_get_clock(vm_clock) / 10;
93
		break;
94
	case RW_INTR_MASK:
95
		r = t->rw_intr_mask;
96
		break;
97
	case R_MASKED_INTR:
98
		r = t->r_intr & t->rw_intr_mask;
99
		break;
100
	default:
101
		D(printf ("%s %x\n", __func__, addr));
102
		break;
103
	}
104
	return r;
81
    struct fs_timer_t *t = opaque;
82
    uint32_t r = 0;
83

  
84
    switch (addr) {
85
    case R_TMR0_DATA:
86
        r = ptimer_get_count(t->ptimer_t0);
87
        break;
88
    case R_TMR1_DATA:
89
        r = ptimer_get_count(t->ptimer_t1);
90
        break;
91
    case R_TIME:
92
        r = qemu_get_clock(vm_clock) / 10;
93
        break;
94
    case RW_INTR_MASK:
95
        r = t->rw_intr_mask;
96
        break;
97
    case R_MASKED_INTR:
98
        r = t->r_intr & t->rw_intr_mask;
99
        break;
100
    default:
101
        D(printf ("%s %x\n", __func__, addr));
102
        break;
103
    }
104
    return r;
105 105
}
106 106

  
107 107
#define TIMER_SLOWDOWN 1
108 108
static void update_ctrl(struct fs_timer_t *t, int tnum)
109 109
{
110
	unsigned int op;
111
	unsigned int freq;
112
	unsigned int freq_hz;
113
	unsigned int div;
114
	uint32_t ctrl;
115

  
116
	ptimer_state *timer;
117

  
118
	if (tnum == 0) {
119
		ctrl = t->rw_tmr0_ctrl;
120
		div = t->rw_tmr0_div;
121
		timer = t->ptimer_t0;
122
	} else {
123
		ctrl = t->rw_tmr1_ctrl;
124
		div = t->rw_tmr1_div;
125
		timer = t->ptimer_t1;
126
	}
127

  
128

  
129
	op = ctrl & 3;
130
	freq = ctrl >> 2;
131
	freq_hz = 32000000;
132

  
133
	switch (freq)
134
	{
135
	case 0:
136
	case 1:
137
		D(printf ("extern or disabled timer clock?\n"));
138
		break;
139
	case 4: freq_hz =  29493000; break;
140
	case 5: freq_hz =  32000000; break;
141
	case 6: freq_hz =  32768000; break;
142
	case 7: freq_hz = 100000000; break;
143
	default:
144
		abort();
145
		break;
146
	}
147

  
148
	D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
149
	div = div * TIMER_SLOWDOWN;
150
	div /= 1000;
151
	freq_hz /= 1000;
152
	ptimer_set_freq(timer, freq_hz);
153
	ptimer_set_limit(timer, div, 0);
154

  
155
	switch (op)
156
	{
157
		case 0:
158
			/* Load.  */
159
			ptimer_set_limit(timer, div, 1);
160
			break;
161
		case 1:
162
			/* Hold.  */
163
			ptimer_stop(timer);
164
			break;
165
		case 2:
166
			/* Run.  */
167
			ptimer_run(timer, 0);
168
			break;
169
		default:
170
			abort();
171
			break;
172
	}
110
    unsigned int op;
111
    unsigned int freq;
112
    unsigned int freq_hz;
113
    unsigned int div;
114
    uint32_t ctrl;
115

  
116
    ptimer_state *timer;
117

  
118
    if (tnum == 0) {
119
        ctrl = t->rw_tmr0_ctrl;
120
        div = t->rw_tmr0_div;
121
        timer = t->ptimer_t0;
122
    } else {
123
        ctrl = t->rw_tmr1_ctrl;
124
        div = t->rw_tmr1_div;
125
        timer = t->ptimer_t1;
126
    }
127

  
128

  
129
    op = ctrl & 3;
130
    freq = ctrl >> 2;
131
    freq_hz = 32000000;
132

  
133
    switch (freq)
134
    {
135
    case 0:
136
    case 1:
137
        D(printf ("extern or disabled timer clock?\n"));
138
        break;
139
    case 4: freq_hz =  29493000; break;
140
    case 5: freq_hz =  32000000; break;
141
    case 6: freq_hz =  32768000; break;
142
    case 7: freq_hz = 100000000; break;
143
    default:
144
        abort();
145
        break;
146
    }
147

  
148
    D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
149
    div = div * TIMER_SLOWDOWN;
150
    div /= 1000;
151
    freq_hz /= 1000;
152
    ptimer_set_freq(timer, freq_hz);
153
    ptimer_set_limit(timer, div, 0);
154

  
155
    switch (op)
156
    {
157
        case 0:
158
            /* Load.  */
159
            ptimer_set_limit(timer, div, 1);
160
            break;
161
        case 1:
162
            /* Hold.  */
163
            ptimer_stop(timer);
164
            break;
165
        case 2:
166
            /* Run.  */
167
            ptimer_run(timer, 0);
168
            break;
169
        default:
170
            abort();
171
            break;
172
    }
173 173
}
174 174

  
175 175
static void timer_update_irq(struct fs_timer_t *t)
176 176
{
177
	t->r_intr &= ~(t->rw_ack_intr);
178
	t->r_masked_intr = t->r_intr & t->rw_intr_mask;
177
    t->r_intr &= ~(t->rw_ack_intr);
178
    t->r_masked_intr = t->r_intr & t->rw_intr_mask;
179 179

  
180
	D(printf("%s: masked_intr=%x\n", __func__, t->r_masked_intr));
181
	qemu_set_irq(t->irq[0], !!t->r_masked_intr);
180
    D(printf("%s: masked_intr=%x\n", __func__, t->r_masked_intr));
181
    qemu_set_irq(t->irq[0], !!t->r_masked_intr);
182 182
}
183 183

  
184 184
static void timer0_hit(void *opaque)
185 185
{
186
	struct fs_timer_t *t = opaque;
187
	t->r_intr |= 1;
188
	timer_update_irq(t);
186
    struct fs_timer_t *t = opaque;
187
    t->r_intr |= 1;
188
    timer_update_irq(t);
189 189
}
190 190

  
191 191
static void timer1_hit(void *opaque)
192 192
{
193
	struct fs_timer_t *t = opaque;
194
	t->r_intr |= 2;
195
	timer_update_irq(t);
193
    struct fs_timer_t *t = opaque;
194
    t->r_intr |= 2;
195
    timer_update_irq(t);
196 196
}
197 197

  
198 198
static void watchdog_hit(void *opaque)
199 199
{
200
	struct fs_timer_t *t = opaque;
201
	if (t->wd_hits == 0) {
202
		/* real hw gives a single tick before reseting but we are
203
		   a bit friendlier to compensate for our slower execution.  */
204
		ptimer_set_count(t->ptimer_wd, 10);
205
		ptimer_run(t->ptimer_wd, 1);
206
		qemu_irq_raise(t->nmi[0]);
207
	}
208
	else
209
		qemu_system_reset_request();
210

  
211
	t->wd_hits++;
200
    struct fs_timer_t *t = opaque;
201
    if (t->wd_hits == 0) {
202
        /* real hw gives a single tick before reseting but we are
203
           a bit friendlier to compensate for our slower execution.  */
204
        ptimer_set_count(t->ptimer_wd, 10);
205
        ptimer_run(t->ptimer_wd, 1);
206
        qemu_irq_raise(t->nmi[0]);
207
    }
208
    else
209
        qemu_system_reset_request();
210

  
211
    t->wd_hits++;
212 212
}
213 213

  
214 214
static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value)
215 215
{
216
	unsigned int wd_en = t->rw_wd_ctrl & (1 << 8);
217
	unsigned int wd_key = t->rw_wd_ctrl >> 9;
218
	unsigned int wd_cnt = t->rw_wd_ctrl & 511;
219
	unsigned int new_key = value >> 9 & ((1 << 7) - 1);
220
	unsigned int new_cmd = (value >> 8) & 1;
216
    unsigned int wd_en = t->rw_wd_ctrl & (1 << 8);
217
    unsigned int wd_key = t->rw_wd_ctrl >> 9;
218
    unsigned int wd_cnt = t->rw_wd_ctrl & 511;
219
    unsigned int new_key = value >> 9 & ((1 << 7) - 1);
220
    unsigned int new_cmd = (value >> 8) & 1;
221 221

  
222
	/* If the watchdog is enabled, they written key must match the
223
	   complement of the previous.  */
224
	wd_key = ~wd_key & ((1 << 7) - 1);
222
    /* If the watchdog is enabled, they written key must match the
223
       complement of the previous.  */
224
    wd_key = ~wd_key & ((1 << 7) - 1);
225 225

  
226
	if (wd_en && wd_key != new_key)
227
		return;
226
    if (wd_en && wd_key != new_key)
227
        return;
228 228

  
229
	D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", 
230
		 wd_en, new_key, wd_key, new_cmd, wd_cnt));
229
    D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", 
230
         wd_en, new_key, wd_key, new_cmd, wd_cnt));
231 231

  
232
	if (t->wd_hits)
233
		qemu_irq_lower(t->nmi[0]);
232
    if (t->wd_hits)
233
        qemu_irq_lower(t->nmi[0]);
234 234

  
235
	t->wd_hits = 0;
235
    t->wd_hits = 0;
236 236

  
237
	ptimer_set_freq(t->ptimer_wd, 760);
238
	if (wd_cnt == 0)
239
		wd_cnt = 256;
240
	ptimer_set_count(t->ptimer_wd, wd_cnt);
241
	if (new_cmd)
242
		ptimer_run(t->ptimer_wd, 1);
243
	else
244
		ptimer_stop(t->ptimer_wd);
237
    ptimer_set_freq(t->ptimer_wd, 760);
238
    if (wd_cnt == 0)
239
        wd_cnt = 256;
240
    ptimer_set_count(t->ptimer_wd, wd_cnt);
241
    if (new_cmd)
242
        ptimer_run(t->ptimer_wd, 1);
243
    else
244
        ptimer_stop(t->ptimer_wd);
245 245

  
246
	t->rw_wd_ctrl = value;
246
    t->rw_wd_ctrl = value;
247 247
}
248 248

  
249 249
static void
250 250
timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
251 251
{
252
	struct fs_timer_t *t = opaque;
253

  
254
	switch (addr)
255
	{
256
		case RW_TMR0_DIV:
257
			t->rw_tmr0_div = value;
258
			break;
259
		case RW_TMR0_CTRL:
260
			D(printf ("RW_TMR0_CTRL=%x\n", value));
261
			t->rw_tmr0_ctrl = value;
262
			update_ctrl(t, 0);
263
			break;
264
		case RW_TMR1_DIV:
265
			t->rw_tmr1_div = value;
266
			break;
267
		case RW_TMR1_CTRL:
268
			D(printf ("RW_TMR1_CTRL=%x\n", value));
269
			t->rw_tmr1_ctrl = value;
270
			update_ctrl(t, 1);
271
			break;
272
		case RW_INTR_MASK:
273
			D(printf ("RW_INTR_MASK=%x\n", value));
274
			t->rw_intr_mask = value;
275
			timer_update_irq(t);
276
			break;
277
		case RW_WD_CTRL:
278
			timer_watchdog_update(t, value);
279
			break;
280
		case RW_ACK_INTR:
281
			t->rw_ack_intr = value;
282
			timer_update_irq(t);
283
			t->rw_ack_intr = 0;
284
			break;
285
		default:
286
			printf ("%s " TARGET_FMT_plx " %x\n",
287
				__func__, addr, value);
288
			break;
289
	}
252
    struct fs_timer_t *t = opaque;
253

  
254
    switch (addr)
255
    {
256
        case RW_TMR0_DIV:
257
            t->rw_tmr0_div = value;
258
            break;
259
        case RW_TMR0_CTRL:
260
            D(printf ("RW_TMR0_CTRL=%x\n", value));
261
            t->rw_tmr0_ctrl = value;
262
            update_ctrl(t, 0);
263
            break;
264
        case RW_TMR1_DIV:
265
            t->rw_tmr1_div = value;
266
            break;
267
        case RW_TMR1_CTRL:
268
            D(printf ("RW_TMR1_CTRL=%x\n", value));
269
            t->rw_tmr1_ctrl = value;
270
            update_ctrl(t, 1);
271
            break;
272
        case RW_INTR_MASK:
273
            D(printf ("RW_INTR_MASK=%x\n", value));
274
            t->rw_intr_mask = value;
275
            timer_update_irq(t);
276
            break;
277
        case RW_WD_CTRL:
278
            timer_watchdog_update(t, value);
279
            break;
280
        case RW_ACK_INTR:
281
            t->rw_ack_intr = value;
282
            timer_update_irq(t);
283
            t->rw_ack_intr = 0;
284
            break;
285
        default:
286
            printf ("%s " TARGET_FMT_plx " %x\n",
287
                __func__, addr, value);
288
            break;
289
    }
290 290
}
291 291

  
292 292
static CPUReadMemoryFunc *timer_read[] = {
293
	NULL, NULL,
294
	&timer_readl,
293
    NULL, NULL,
294
    &timer_readl,
295 295
};
296 296

  
297 297
static CPUWriteMemoryFunc *timer_write[] = {
298
	NULL, NULL,
299
	&timer_writel,
298
    NULL, NULL,
299
    &timer_writel,
300 300
};
301 301

  
302 302
static void etraxfs_timer_reset(void *opaque)
303 303
{
304
	struct fs_timer_t *t = opaque;
305

  
306
	ptimer_stop(t->ptimer_t0);
307
	ptimer_stop(t->ptimer_t1);
308
	ptimer_stop(t->ptimer_wd);
309
	t->rw_wd_ctrl = 0;
310
	t->r_intr = 0;
311
	t->rw_intr_mask = 0;
312
	qemu_irq_lower(t->irq[0]);
304
    struct fs_timer_t *t = opaque;
305

  
306
    ptimer_stop(t->ptimer_t0);
307
    ptimer_stop(t->ptimer_t1);
308
    ptimer_stop(t->ptimer_wd);
309
    t->rw_wd_ctrl = 0;
310
    t->r_intr = 0;
311
    t->rw_intr_mask = 0;
312
    qemu_irq_lower(t->irq[0]);
313 313
}
314 314

  
315 315
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi,
316
			target_phys_addr_t base)
316
            target_phys_addr_t base)
317 317
{
318
	static struct fs_timer_t *t;
319
	int timer_regs;
318
    static struct fs_timer_t *t;
319
    int timer_regs;
320 320

  
321
	t = qemu_mallocz(sizeof *t);
321
    t = qemu_mallocz(sizeof *t);
322 322

  
323
	t->bh_t0 = qemu_bh_new(timer0_hit, t);
324
	t->bh_t1 = qemu_bh_new(timer1_hit, t);
325
	t->bh_wd = qemu_bh_new(watchdog_hit, t);
326
	t->ptimer_t0 = ptimer_init(t->bh_t0);
327
	t->ptimer_t1 = ptimer_init(t->bh_t1);
328
	t->ptimer_wd = ptimer_init(t->bh_wd);
329
	t->irq = irqs;
330
	t->nmi = nmi;
331
	t->env = env;
323
    t->bh_t0 = qemu_bh_new(timer0_hit, t);
324
    t->bh_t1 = qemu_bh_new(timer1_hit, t);
325
    t->bh_wd = qemu_bh_new(watchdog_hit, t);
326
    t->ptimer_t0 = ptimer_init(t->bh_t0);
327
    t->ptimer_t1 = ptimer_init(t->bh_t1);
328
    t->ptimer_wd = ptimer_init(t->bh_wd);
329
    t->irq = irqs;
330
    t->nmi = nmi;
331
    t->env = env;
332 332

  
333
	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t);
334
	cpu_register_physical_memory (base, 0x5c, timer_regs);
333
    timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t);
334
    cpu_register_physical_memory (base, 0x5c, timer_regs);
335 335

  
336
	qemu_register_reset(etraxfs_timer_reset, t);
336
    qemu_register_reset(etraxfs_timer_reset, t);
337 337
}

Also available in: Unified diff