1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <stdio.h>
25: #include <sys/time.h>
26: #include "hw.h"
27: #include "qemu-timer.h"
28:
29: void etrax_ack_irq(CPUState *env, uint32_t mask);
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_INTR_MASK 0xb001e048
40: #define RW_ACK_INTR 0xb001e04c
41: #define R_INTR 0xb001e050
42: #define R_MASKED_INTR 0xb001e054
43:
44:
45: uint32_t rw_intr_mask;
46: uint32_t rw_ack_intr;
47: uint32_t r_intr;
48:
49: struct fs_timer_t {
50: QEMUBH *bh;
51: unsigned int limit;
52: int scale;
53: ptimer_state *ptimer;
54: CPUState *env;
55: qemu_irq *irq;
56: uint32_t mask;
57: };
58:
59: static struct fs_timer_t timer0;
60:
61:
62: int diff_timeval_us(struct timeval *a, struct timeval *b)
63: {
64: int diff;
65:
66:
67: diff = (a->tv_sec - b->tv_sec) * 1000 * 1000;
68: diff += (a->tv_usec - b->tv_usec);
69: return diff;
70: }
71:
72: static uint32_t timer_readb (void *opaque, target_phys_addr_t addr)
73: {
74: CPUState *env = opaque;
75: uint32_t r = 0;
76: printf ("%s %x pc=%x\n", __func__, addr, env->pc);
77: return r;
78: }
79: static uint32_t timer_readw (void *opaque, target_phys_addr_t addr)
80: {
81: CPUState *env = opaque;
82: uint32_t r = 0;
83: printf ("%s %x pc=%x\n", __func__, addr, env->pc);
84: return r;
85: }
86:
87: static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
88: {
89: CPUState *env = opaque;
90: uint32_t r = 0;
91:
92: switch (addr) {
93: case R_TMR0_DATA:
94: break;
95: case R_TMR1_DATA:
96: printf ("R_TMR1_DATA\n");
97: break;
98: case R_TIME:
99: {
100: static struct timeval last;
101: struct timeval now;
102: gettimeofday(&now, NULL);
103: if (!(last.tv_sec == 0 && last.tv_usec == 0)) {
104: r = diff_timeval_us(&now, &last);
105: r *= 1000;
106: r++;
107: }
108: last = now;
109: break;
110: }
111:
112: case RW_INTR_MASK:
113: r = rw_intr_mask;
114: break;
115: case R_MASKED_INTR:
116: r = r_intr & rw_intr_mask;
117: break;
118: default:
119: printf ("%s %x p=%x\n", __func__, addr, env->pc);
120: break;
121: }
122: return r;
123: }
124:
125: static void
126: timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
127: {
128: CPUState *env = opaque;
129: printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
130: }
131: static void
132: timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
133: {
134: CPUState *env = opaque;
135: printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
136: }
137:
138: static void write_ctrl(struct fs_timer_t *t, uint32_t v)
139: {
140: int op;
141: int freq;
142: int freq_hz;
143:
144: op = v & 3;
145: freq = v >> 2;
146: freq_hz = 32000000;
147:
148: switch (freq)
149: {
150: case 0:
151: case 1:
152: printf ("extern or disabled timer clock?\n");
153: break;
154: case 4: freq_hz = 29493000; break;
155: case 5: freq_hz = 32000000; break;
156: case 6: freq_hz = 32768000; break;
157: case 7: freq_hz = 100000000; break;
158: default:
159: abort();
160: break;
161: }
162:
163: printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit);
164: t->scale = 0;
165: if (t->limit > 2048)
166: {
167: t->scale = 2048;
168: ptimer_set_period(timer0.ptimer, freq_hz / t->scale);
169: }
170:
171: printf ("op=%d\n", op);
172: switch (op)
173: {
174: case 0:
175: printf ("limit=%d %d\n", t->limit, t->limit/t->scale);
176: ptimer_set_limit(t->ptimer, t->limit / t->scale, 1);
177: break;
178: case 1:
179: ptimer_stop(t->ptimer);
180: break;
181: case 2:
182: ptimer_run(t->ptimer, 0);
183: break;
184: default:
185: abort();
186: break;
187: }
188: }
189:
190: static void timer_ack_irq(void)
191: {
192: if (!(r_intr & timer0.mask & rw_intr_mask)) {
193: qemu_irq_lower(timer0.irq[0]);
194: etrax_ack_irq(timer0.env, 1 << 0x1b);
195: }
196: }
197:
198: static void
199: timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
200: {
201: CPUState *env = opaque;
202: printf ("%s %x %x pc=%x\n",
203: __func__, addr, value, env->pc);
204: switch (addr)
205: {
206: case RW_TMR0_DIV:
207: printf ("RW_TMR0_DIV=%x\n", value);
208: timer0.limit = value;
209: break;
210: case RW_TMR0_CTRL:
211: printf ("RW_TMR0_CTRL=%x\n", value);
212: write_ctrl(&timer0, value);
213: break;
214: case RW_TMR1_DIV:
215: printf ("RW_TMR1_DIV=%x\n", value);
216: break;
217: case RW_TMR1_CTRL:
218: printf ("RW_TMR1_CTRL=%x\n", value);
219: break;
220: case RW_INTR_MASK:
221: printf ("RW_INTR_MASK=%x\n", value);
222: rw_intr_mask = value;
223: break;
224: case RW_ACK_INTR:
225: r_intr &= ~value;
226: timer_ack_irq();
227: break;
228: default:
229: printf ("%s %x %x pc=%x\n",
230: __func__, addr, value, env->pc);
231: break;
232: }
233: }
234:
235: static CPUReadMemoryFunc *timer_read[] = {
236: &timer_readb,
237: &timer_readw,
238: &timer_readl,
239: };
240:
241: static CPUWriteMemoryFunc *timer_write[] = {
242: &timer_writeb,
243: &timer_writew,
244: &timer_writel,
245: };
246:
247: static void timer_irq(void *opaque)
248: {
249: struct fs_timer_t *t = opaque;
250:
251: r_intr |= t->mask;
252: if (t->mask & rw_intr_mask) {
253: qemu_irq_raise(t->irq[0]);
254: }
255: }
256:
257: void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
258: {
259: int timer_regs;
260:
261: timer0.bh = qemu_bh_new(timer_irq, &timer0);
262: timer0.ptimer = ptimer_init(timer0.bh);
263: timer0.irq = irqs + 0x1b;
264: timer0.mask = 1;
265: timer0.env = env;
266:
267: timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env);
268: cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs);
269: }