Revision ca87d03b hw/etraxfs_timer.c

b/hw/etraxfs_timer.c
28 28

  
29 29
#define D(x)
30 30

  
31
#define R_TIME 0xb001e038
32
#define RW_TMR0_DIV 0xb001e000
33
#define R_TMR0_DATA 0xb001e004
34
#define RW_TMR0_CTRL 0xb001e008
35
#define RW_TMR1_DIV 0xb001e010
36
#define R_TMR1_DATA 0xb001e014
37
#define RW_TMR1_CTRL 0xb001e018
38

  
39
#define RW_WD_CTRL 0xb001e040
40
#define RW_INTR_MASK 0xb001e048
41
#define RW_ACK_INTR 0xb001e04c
42
#define R_INTR 0xb001e050
43
#define R_MASKED_INTR 0xb001e054
31
#define RW_TMR0_DIV   0x00
32
#define R_TMR0_DATA   0x04
33
#define RW_TMR0_CTRL  0x08
34
#define RW_TMR1_DIV   0x10
35
#define R_TMR1_DATA   0x14
36
#define RW_TMR1_CTRL  0x18
37
#define R_TIME        0x38
38
#define RW_WD_CTRL    0x40
39
#define RW_INTR_MASK  0x48
40
#define RW_ACK_INTR   0x4c
41
#define R_INTR        0x50
42
#define R_MASKED_INTR 0x54
44 43

  
45 44
struct fs_timer_t {
45
	CPUState *env;
46
	qemu_irq *irq;
47
	target_phys_addr_t base;
48

  
46 49
	QEMUBH *bh;
50
	ptimer_state *ptimer;
47 51
	unsigned int limit;
48 52
	int scale;
49
	ptimer_state *ptimer;
50
	CPUState *env;
51
	qemu_irq *irq;
52 53
	uint32_t mask;
53 54
	struct timeval last;
54 55

  
......
57 58
	uint32_t r_intr;
58 59
};
59 60

  
60
static struct fs_timer_t timer[2];
61

  
62
static inline int timer_index(target_phys_addr_t addr)
63
{
64
	int t = 0;
65
	if (addr >= 0xb005e000)
66
		t = 1;
67
	return t;
68
}
69

  
70 61
/* diff two timevals.  Return a single int in us. */
71 62
int diff_timeval_us(struct timeval *a, struct timeval *b)
72 63
{
......
78 69
        return diff;
79 70
}
80 71

  
81
static uint32_t timer_readb (void *opaque, target_phys_addr_t addr)
72
static uint32_t timer_rinvalid (void *opaque, target_phys_addr_t addr)
82 73
{
83
	CPUState *env;
84
	uint32_t r = 0;
85

  
86
	env = opaque;
87
	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc));
88
	return r;
89
}
90
static uint32_t timer_readw (void *opaque, target_phys_addr_t addr)
91
{
92
	CPUState *env;
93
	uint32_t r = 0;
94

  
95
	env = opaque;
96
	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc));
97
	return r;
74
	struct fs_timer_t *t = opaque;
75
	CPUState *env = t->env;
76
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
77
		  addr, env->pc);
78
	return 0;
98 79
}
99 80

  
100 81
static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
101 82
{
102
	CPUState *env = opaque;
83
	struct fs_timer_t *t = opaque;
84
	D(CPUState *env = t->env);
103 85
	uint32_t r = 0;
104
	int t = timer_index(addr);
105 86

  
87
	/* Make addr relative to this instances base.  */
88
	addr -= t->base;
106 89
	switch (addr) {
107 90
	case R_TMR0_DATA:
108 91
		break;
......
113 96
	{
114 97
		struct timeval now;
115 98
		gettimeofday(&now, NULL);
116
		if (!(timer[t].last.tv_sec == 0 
117
		      && timer[t].last.tv_usec == 0)) {
118
			r = diff_timeval_us(&now, &timer[t].last);
99
		if (!(t->last.tv_sec == 0 
100
		      && t->last.tv_usec == 0)) {
101
			r = diff_timeval_us(&now, &t->last);
119 102
			r *= 1000; /* convert to ns.  */
120 103
			r++; /* make sure we increase for each call.  */
121 104
		}
122
		timer[t].last = now;
105
		t->last = now;
123 106
		break;
124 107
	}
125 108

  
126 109
	case RW_INTR_MASK:
127
		r = timer[t].rw_intr_mask;
110
		r = t->rw_intr_mask;
128 111
		break;
129 112
	case R_MASKED_INTR:
130
		r = timer[t].r_intr & timer[t].rw_intr_mask;
113
		r = t->r_intr & t->rw_intr_mask;
131 114
		break;
132 115
	default:
133 116
		D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
......
137 120
}
138 121

  
139 122
static void
140
timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
123
timer_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value)
141 124
{
142
	CPUState *env;
143
	env = opaque;
144
	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc));
145
}
146
static void
147
timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
148
{
149
	CPUState *env;
150
	env = opaque;
151
	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc));
125
	struct fs_timer_t *t = opaque;
126
	CPUState *env = t->env;
127
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
128
		  addr, env->pc);
152 129
}
153 130

  
154 131
static void write_ctrl(struct fs_timer_t *t, uint32_t v)
......
212 189
static void
213 190
timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
214 191
{
215
	CPUState *env = opaque;
216
	int t = timer_index(addr);
192
	struct fs_timer_t *t = opaque;
193
	CPUState *env = t->env;
217 194

  
218 195
	D(printf ("%s %x %x pc=%x\n",
219 196
		__func__, addr, value, env->pc));
197
	/* Make addr relative to this instances base.  */
198
	addr -= t->base;
220 199
	switch (addr)
221 200
	{
222 201
		case RW_TMR0_DIV:
223 202
			D(printf ("RW_TMR0_DIV=%x\n", value));
224
			timer[t].limit = value;
203
			t->limit = value;
225 204
			break;
226 205
		case RW_TMR0_CTRL:
227 206
			D(printf ("RW_TMR0_CTRL=%x\n", value));
228
			write_ctrl(&timer[t], value);
207
			write_ctrl(t, value);
229 208
			break;
230 209
		case RW_TMR1_DIV:
231 210
			D(printf ("RW_TMR1_DIV=%x\n", value));
......
235 214
			break;
236 215
		case RW_INTR_MASK:
237 216
			D(printf ("RW_INTR_MASK=%x\n", value));
238
			timer[t].rw_intr_mask = value;
217
			t->rw_intr_mask = value;
239 218
			break;
240 219
		case RW_WD_CTRL:
241 220
			D(printf ("RW_WD_CTRL=%x\n", value));
242 221
			break;
243 222
		case RW_ACK_INTR:
244
			timer[t].r_intr &= ~value;
245
			timer_ack_irq(&timer[t]);
223
			t->r_intr &= ~value;
224
			timer_ack_irq(t);
246 225
			break;
247 226
		default:
248 227
			printf ("%s %x %x pc=%x\n",
......
252 231
}
253 232

  
254 233
static CPUReadMemoryFunc *timer_read[] = {
255
    &timer_readb,
256
    &timer_readw,
234
    &timer_rinvalid,
235
    &timer_rinvalid,
257 236
    &timer_readl,
258 237
};
259 238

  
260 239
static CPUWriteMemoryFunc *timer_write[] = {
261
    &timer_writeb,
262
    &timer_writew,
240
    &timer_winvalid,
241
    &timer_winvalid,
263 242
    &timer_writel,
264 243
};
265 244

  
......
273 252
	}
274 253
}
275 254

  
276
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
255
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, 
256
			target_phys_addr_t base)
277 257
{
258
	static struct fs_timer_t *t;
278 259
	int timer_regs;
279 260

  
280
	timer[0].bh = qemu_bh_new(timer_irq, &timer[0]);
281
	timer[0].ptimer = ptimer_init(timer[0].bh);
282
	timer[0].irq = irqs + 26;
283
	timer[0].mask = 1;
284
	timer[0].env = env;
261
	t = qemu_mallocz(sizeof *t);
262
	if (!t)
263
		return;
285 264

  
286
	timer[1].bh = qemu_bh_new(timer_irq, &timer[1]);
287
	timer[1].ptimer = ptimer_init(timer[1].bh);
288
	timer[1].irq = irqs + 26;
289
	timer[1].mask = 1;
290
	timer[1].env = env;
265
	t->bh = qemu_bh_new(timer_irq, t);
266
	t->ptimer = ptimer_init(t->bh);
267
	t->irq = irqs + 26;
268
	t->mask = 1;
269
	t->env = env;
270
	t->base = base;
291 271

  
292
	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env);
293
	cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs);
294
	cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs);
272
	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t);
273
	cpu_register_physical_memory (base, 0x5c, timer_regs);
295 274
}

Also available in: Unified diff