dv-mn103tim.c revision 1.1 1 1.1 christos /* This file is part of the program GDB, the GNU debugger.
2 1.1 christos
3 1.1 christos Copyright (C) 1998, 2003, 2007, 2008, 2009, 2010, 2011
4 1.1 christos Free Software Foundation, Inc.
5 1.1 christos Contributed by Cygnus Solutions.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>.
19 1.1 christos
20 1.1 christos */
21 1.1 christos
22 1.1 christos #include "sim-main.h"
23 1.1 christos #include "hw-main.h"
24 1.1 christos #include "sim-assert.h"
25 1.1 christos
26 1.1 christos /* DEVICE
27 1.1 christos
28 1.1 christos
29 1.1 christos mn103tim - mn103002 timers (8 and 16 bit)
30 1.1 christos
31 1.1 christos
32 1.1 christos DESCRIPTION
33 1.1 christos
34 1.1 christos Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide.
35 1.1 christos
36 1.1 christos
37 1.1 christos PROPERTIES
38 1.1 christos
39 1.1 christos reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size>
40 1.1 christos
41 1.1 christos
42 1.1 christos BUGS
43 1.1 christos
44 1.1 christos */
45 1.1 christos
46 1.1 christos
47 1.1 christos /* The timers' register address blocks */
48 1.1 christos
49 1.1 christos struct mn103tim_block {
50 1.1 christos unsigned_word base;
51 1.1 christos unsigned_word bound;
52 1.1 christos };
53 1.1 christos
54 1.1 christos enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
55 1.1 christos
56 1.1 christos enum timer_register_types {
57 1.1 christos FIRST_MODE_REG = 0,
58 1.1 christos TM0MD = FIRST_MODE_REG,
59 1.1 christos TM1MD,
60 1.1 christos TM2MD,
61 1.1 christos TM3MD,
62 1.1 christos TM4MD,
63 1.1 christos TM5MD,
64 1.1 christos TM6MD,
65 1.1 christos LAST_MODE_REG = TM6MD,
66 1.1 christos FIRST_BASE_REG,
67 1.1 christos TM0BR = FIRST_BASE_REG,
68 1.1 christos TM1BR,
69 1.1 christos TM2BR,
70 1.1 christos TM3BR,
71 1.1 christos TM4BR,
72 1.1 christos TM5BR,
73 1.1 christos LAST_BASE_REG = TM5BR,
74 1.1 christos FIRST_COUNTER,
75 1.1 christos TM0BC = FIRST_COUNTER,
76 1.1 christos TM1BC,
77 1.1 christos TM2BC,
78 1.1 christos TM3BC,
79 1.1 christos TM4BC,
80 1.1 christos TM5BC,
81 1.1 christos TM6BC,
82 1.1 christos LAST_COUNTER = TM6BC,
83 1.1 christos TM6MDA,
84 1.1 christos TM6MDB,
85 1.1 christos TM6CA,
86 1.1 christos TM6CB,
87 1.1 christos LAST_TIMER_REG = TM6BC,
88 1.1 christos };
89 1.1 christos
90 1.1 christos
91 1.1 christos /* Don't include timer 6 because it's handled specially. */
92 1.1 christos #define NR_8BIT_TIMERS 4
93 1.1 christos #define NR_16BIT_TIMERS 2
94 1.1 christos #define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
95 1.1 christos #define NR_TIMERS 7
96 1.1 christos
97 1.1 christos typedef struct _mn10300_timer_regs {
98 1.1 christos unsigned32 base;
99 1.1 christos unsigned8 mode;
100 1.1 christos } mn10300_timer_regs;
101 1.1 christos
102 1.1 christos typedef struct _mn10300_timer {
103 1.1 christos unsigned32 div_ratio, start;
104 1.1 christos struct hw_event *event;
105 1.1 christos } mn10300_timer;
106 1.1 christos
107 1.1 christos
108 1.1 christos struct mn103tim {
109 1.1 christos struct mn103tim_block block[NR_TIMER_BLOCKS];
110 1.1 christos mn10300_timer_regs reg[NR_REG_TIMERS];
111 1.1 christos mn10300_timer timer[NR_TIMERS];
112 1.1 christos
113 1.1 christos /* treat timer 6 registers specially. */
114 1.1 christos unsigned16 tm6md0, tm6md1, tm6bc, tm6ca, tm6cb;
115 1.1 christos unsigned8 tm6mda, tm6mdb; /* compare/capture mode regs for timer 6 */
116 1.1 christos };
117 1.1 christos
118 1.1 christos /* output port ID's */
119 1.1 christos
120 1.1 christos /* for mn103002 */
121 1.1 christos enum {
122 1.1 christos TIMER0_UFLOW,
123 1.1 christos TIMER1_UFLOW,
124 1.1 christos TIMER2_UFLOW,
125 1.1 christos TIMER3_UFLOW,
126 1.1 christos TIMER4_UFLOW,
127 1.1 christos TIMER5_UFLOW,
128 1.1 christos TIMER6_UFLOW,
129 1.1 christos TIMER6_CMPA,
130 1.1 christos TIMER6_CMPB,
131 1.1 christos };
132 1.1 christos
133 1.1 christos
134 1.1 christos static const struct hw_port_descriptor mn103tim_ports[] = {
135 1.1 christos
136 1.1 christos { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
137 1.1 christos { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
138 1.1 christos { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
139 1.1 christos { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
140 1.1 christos { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
141 1.1 christos { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
142 1.1 christos
143 1.1 christos { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
144 1.1 christos { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
145 1.1 christos { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
146 1.1 christos
147 1.1 christos { NULL, },
148 1.1 christos };
149 1.1 christos
150 1.1 christos #define bits2to5_mask 0x3c
151 1.1 christos #define bits0to2_mask 0x07
152 1.1 christos #define load_mask 0x40
153 1.1 christos #define count_mask 0x80
154 1.1 christos #define count_and_load_mask (load_mask | count_mask)
155 1.1 christos #define clock_mask 0x03
156 1.1 christos #define clk_ioclk 0x00
157 1.1 christos #define clk_cascaded 0x03
158 1.1 christos
159 1.1 christos
160 1.1 christos /* Finish off the partially created hw device. Attach our local
161 1.1 christos callbacks. Wire up our port names etc */
162 1.1 christos
163 1.1 christos static hw_io_read_buffer_method mn103tim_io_read_buffer;
164 1.1 christos static hw_io_write_buffer_method mn103tim_io_write_buffer;
165 1.1 christos
166 1.1 christos static void
167 1.1 christos attach_mn103tim_regs (struct hw *me,
168 1.1 christos struct mn103tim *timers)
169 1.1 christos {
170 1.1 christos int i;
171 1.1 christos if (hw_find_property (me, "reg") == NULL)
172 1.1 christos hw_abort (me, "Missing \"reg\" property");
173 1.1 christos for (i = 0; i < NR_TIMER_BLOCKS; i++)
174 1.1 christos {
175 1.1 christos unsigned_word attach_address;
176 1.1 christos int attach_space;
177 1.1 christos unsigned attach_size;
178 1.1 christos reg_property_spec reg;
179 1.1 christos if (!hw_find_reg_array_property (me, "reg", i, ®))
180 1.1 christos hw_abort (me, "\"reg\" property must contain three addr/size entries");
181 1.1 christos hw_unit_address_to_attach_address (hw_parent (me),
182 1.1 christos ®.address,
183 1.1 christos &attach_space,
184 1.1 christos &attach_address,
185 1.1 christos me);
186 1.1 christos timers->block[i].base = attach_address;
187 1.1 christos hw_unit_size_to_attach_size (hw_parent (me),
188 1.1 christos ®.size,
189 1.1 christos &attach_size, me);
190 1.1 christos timers->block[i].bound = attach_address + (attach_size - 1);
191 1.1 christos hw_attach_address (hw_parent (me),
192 1.1 christos 0,
193 1.1 christos attach_space, attach_address, attach_size,
194 1.1 christos me);
195 1.1 christos }
196 1.1 christos }
197 1.1 christos
198 1.1 christos static void
199 1.1 christos mn103tim_finish (struct hw *me)
200 1.1 christos {
201 1.1 christos struct mn103tim *timers;
202 1.1 christos int i;
203 1.1 christos
204 1.1 christos timers = HW_ZALLOC (me, struct mn103tim);
205 1.1 christos set_hw_data (me, timers);
206 1.1 christos set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
207 1.1 christos set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
208 1.1 christos set_hw_ports (me, mn103tim_ports);
209 1.1 christos
210 1.1 christos /* Attach ourself to our parent bus */
211 1.1 christos attach_mn103tim_regs (me, timers);
212 1.1 christos
213 1.1 christos /* Initialize the timers */
214 1.1 christos for ( i=0; i < NR_REG_TIMERS; ++i )
215 1.1 christos {
216 1.1 christos timers->reg[i].mode = 0x00;
217 1.1 christos timers->reg[i].base = 0;
218 1.1 christos }
219 1.1 christos for ( i=0; i < NR_TIMERS; ++i )
220 1.1 christos {
221 1.1 christos timers->timer[i].event = NULL;
222 1.1 christos timers->timer[i].div_ratio = 0;
223 1.1 christos timers->timer[i].start = 0;
224 1.1 christos }
225 1.1 christos timers->tm6md0 = 0x00;
226 1.1 christos timers->tm6md1 = 0x00;
227 1.1 christos timers->tm6bc = 0x0000;
228 1.1 christos timers->tm6ca = 0x0000;
229 1.1 christos timers->tm6cb = 0x0000;
230 1.1 christos timers->tm6mda = 0x00;
231 1.1 christos timers->tm6mdb = 0x00;
232 1.1 christos }
233 1.1 christos
234 1.1 christos
235 1.1 christos
236 1.1 christos /* read and write */
237 1.1 christos
238 1.1 christos static int
239 1.1 christos decode_addr (struct hw *me,
240 1.1 christos struct mn103tim *timers,
241 1.1 christos unsigned_word address)
242 1.1 christos {
243 1.1 christos unsigned_word offset;
244 1.1 christos offset = address - timers->block[0].base;
245 1.1 christos
246 1.1 christos switch (offset)
247 1.1 christos {
248 1.1 christos case 0x00: return TM0MD;
249 1.1 christos case 0x01: return TM1MD;
250 1.1 christos case 0x02: return TM2MD;
251 1.1 christos case 0x03: return TM3MD;
252 1.1 christos case 0x10: return TM0BR;
253 1.1 christos case 0x11: return TM1BR;
254 1.1 christos case 0x12: return TM2BR;
255 1.1 christos case 0x13: return TM3BR;
256 1.1 christos case 0x20: return TM0BC;
257 1.1 christos case 0x21: return TM1BC;
258 1.1 christos case 0x22: return TM2BC;
259 1.1 christos case 0x23: return TM3BC;
260 1.1 christos case 0x80: return TM4MD;
261 1.1 christos case 0x82: return TM5MD;
262 1.1 christos case 0x84: /* fall through */
263 1.1 christos case 0x85: return TM6MD;
264 1.1 christos case 0x90: return TM4BR;
265 1.1 christos case 0x92: return TM5BR;
266 1.1 christos case 0xa0: return TM4BC;
267 1.1 christos case 0xa2: return TM5BC;
268 1.1 christos case 0xa4: return TM6BC;
269 1.1 christos case 0xb4: return TM6MDA;
270 1.1 christos case 0xb5: return TM6MDB;
271 1.1 christos case 0xc4: return TM6CA;
272 1.1 christos case 0xd4: return TM6CB;
273 1.1 christos default:
274 1.1 christos {
275 1.1 christos hw_abort (me, "bad address");
276 1.1 christos return -1;
277 1.1 christos }
278 1.1 christos }
279 1.1 christos }
280 1.1 christos
281 1.1 christos static void
282 1.1 christos read_mode_reg (struct hw *me,
283 1.1 christos struct mn103tim *timers,
284 1.1 christos int timer_nr,
285 1.1 christos void *dest,
286 1.1 christos unsigned nr_bytes)
287 1.1 christos {
288 1.1 christos unsigned16 val16;
289 1.1 christos unsigned32 val32;
290 1.1 christos
291 1.1 christos switch ( nr_bytes )
292 1.1 christos {
293 1.1 christos case 1:
294 1.1 christos /* Accessing 1 byte is ok for all mode registers. */
295 1.1 christos if ( timer_nr == 6 )
296 1.1 christos {
297 1.1 christos *(unsigned8*)dest = timers->tm6md0;
298 1.1 christos }
299 1.1 christos else
300 1.1 christos {
301 1.1 christos *(unsigned8*)dest = timers->reg[timer_nr].mode;
302 1.1 christos }
303 1.1 christos break;
304 1.1 christos
305 1.1 christos case 2:
306 1.1 christos if ( timer_nr == 6 )
307 1.1 christos {
308 1.1 christos *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
309 1.1 christos }
310 1.1 christos else if ( timer_nr == 0 || timer_nr == 2 )
311 1.1 christos {
312 1.1 christos val16 = (timers->reg[timer_nr].mode << 8)
313 1.1 christos | timers->reg[timer_nr+1].mode;
314 1.1 christos *(unsigned16*)dest = val16;
315 1.1 christos }
316 1.1 christos else
317 1.1 christos {
318 1.1 christos hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
319 1.1 christos }
320 1.1 christos break;
321 1.1 christos
322 1.1 christos case 4:
323 1.1 christos if ( timer_nr == 0 )
324 1.1 christos {
325 1.1 christos val32 = (timers->reg[0].mode << 24 )
326 1.1 christos | (timers->reg[1].mode << 16)
327 1.1 christos | (timers->reg[2].mode << 8)
328 1.1 christos | timers->reg[3].mode;
329 1.1 christos *(unsigned32*)dest = val32;
330 1.1 christos }
331 1.1 christos else
332 1.1 christos {
333 1.1 christos hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
334 1.1 christos }
335 1.1 christos break;
336 1.1 christos
337 1.1 christos default:
338 1.1 christos hw_abort (me, "bad read size of %d bytes to TM%dMD.",
339 1.1 christos nr_bytes, timer_nr);
340 1.1 christos }
341 1.1 christos }
342 1.1 christos
343 1.1 christos
344 1.1 christos static void
345 1.1 christos read_base_reg (struct hw *me,
346 1.1 christos struct mn103tim *timers,
347 1.1 christos int timer_nr,
348 1.1 christos void *dest,
349 1.1 christos unsigned nr_bytes)
350 1.1 christos {
351 1.1 christos unsigned16 val16;
352 1.1 christos unsigned32 val32;
353 1.1 christos
354 1.1 christos /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
355 1.1 christos switch ( nr_bytes )
356 1.1 christos {
357 1.1 christos case 1:
358 1.1 christos /* Reading 1 byte is ok for all registers. */
359 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
360 1.1 christos {
361 1.1 christos *(unsigned8*)dest = timers->reg[timer_nr].base;
362 1.1 christos }
363 1.1 christos break;
364 1.1 christos
365 1.1 christos case 2:
366 1.1 christos if ( timer_nr == 1 || timer_nr == 3 )
367 1.1 christos {
368 1.1 christos hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
369 1.1 christos }
370 1.1 christos else
371 1.1 christos {
372 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
373 1.1 christos {
374 1.1 christos val16 = (timers->reg[timer_nr].base<<8)
375 1.1 christos | timers->reg[timer_nr+1].base;
376 1.1 christos }
377 1.1 christos else
378 1.1 christos {
379 1.1 christos val16 = timers->reg[timer_nr].base;
380 1.1 christos }
381 1.1 christos *(unsigned16*)dest = val16;
382 1.1 christos }
383 1.1 christos break;
384 1.1 christos
385 1.1 christos case 4:
386 1.1 christos if ( timer_nr == 0 )
387 1.1 christos {
388 1.1 christos val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
389 1.1 christos | (timers->reg[2].base << 8) | timers->reg[3].base;
390 1.1 christos *(unsigned32*)dest = val32;
391 1.1 christos }
392 1.1 christos else if ( timer_nr == 4 )
393 1.1 christos {
394 1.1 christos val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
395 1.1 christos *(unsigned32*)dest = val32;
396 1.1 christos }
397 1.1 christos else
398 1.1 christos {
399 1.1 christos hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
400 1.1 christos }
401 1.1 christos break;
402 1.1 christos
403 1.1 christos default:
404 1.1 christos hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
405 1.1 christos nr_bytes, timer_nr);
406 1.1 christos }
407 1.1 christos }
408 1.1 christos
409 1.1 christos
410 1.1 christos static void
411 1.1 christos read_counter (struct hw *me,
412 1.1 christos struct mn103tim *timers,
413 1.1 christos int timer_nr,
414 1.1 christos void *dest,
415 1.1 christos unsigned nr_bytes)
416 1.1 christos {
417 1.1 christos unsigned32 val;
418 1.1 christos
419 1.1 christos if ( NULL == timers->timer[timer_nr].event )
420 1.1 christos {
421 1.1 christos /* Timer is not counting, use value in base register. */
422 1.1 christos if ( timer_nr == 6 )
423 1.1 christos {
424 1.1 christos val = 0; /* timer 6 is an up counter */
425 1.1 christos }
426 1.1 christos else
427 1.1 christos {
428 1.1 christos val = timers->reg[timer_nr].base;
429 1.1 christos }
430 1.1 christos }
431 1.1 christos else
432 1.1 christos {
433 1.1 christos if ( timer_nr == 6 ) /* timer 6 is an up counter. */
434 1.1 christos {
435 1.1 christos val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
436 1.1 christos }
437 1.1 christos else
438 1.1 christos {
439 1.1 christos /* ticks left = start time + div ratio - curr time */
440 1.1 christos /* Cannot use base register because it can be written during counting and it
441 1.1 christos doesn't affect counter until underflow occurs. */
442 1.1 christos
443 1.1 christos val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
444 1.1 christos - hw_event_queue_time(me);
445 1.1 christos }
446 1.1 christos }
447 1.1 christos
448 1.1 christos switch (nr_bytes) {
449 1.1 christos case 1:
450 1.1 christos *(unsigned8 *)dest = val;
451 1.1 christos break;
452 1.1 christos
453 1.1 christos case 2:
454 1.1 christos *(unsigned16 *)dest = val;
455 1.1 christos break;
456 1.1 christos
457 1.1 christos case 4:
458 1.1 christos *(unsigned32 *)dest = val;
459 1.1 christos break;
460 1.1 christos
461 1.1 christos default:
462 1.1 christos hw_abort(me, "bad read size for reading counter");
463 1.1 christos }
464 1.1 christos
465 1.1 christos }
466 1.1 christos
467 1.1 christos
468 1.1 christos static void
469 1.1 christos read_special_timer6_reg (struct hw *me,
470 1.1 christos struct mn103tim *timers,
471 1.1 christos int timer_nr,
472 1.1 christos void *dest,
473 1.1 christos unsigned nr_bytes)
474 1.1 christos {
475 1.1 christos unsigned32 val;
476 1.1 christos
477 1.1 christos switch (nr_bytes) {
478 1.1 christos case 1:
479 1.1 christos {
480 1.1 christos switch ( timer_nr ) {
481 1.1 christos case TM6MDA:
482 1.1 christos *(unsigned8 *)dest = timers->tm6mda;
483 1.1 christos break;
484 1.1 christos
485 1.1 christos case TM6MDB:
486 1.1 christos *(unsigned8 *)dest = timers->tm6mdb;
487 1.1 christos break;
488 1.1 christos
489 1.1 christos case TM6CA:
490 1.1 christos *(unsigned8 *)dest = timers->tm6ca;
491 1.1 christos break;
492 1.1 christos
493 1.1 christos case TM6CB:
494 1.1 christos *(unsigned8 *)dest = timers->tm6cb;
495 1.1 christos break;
496 1.1 christos
497 1.1 christos default:
498 1.1 christos break;
499 1.1 christos }
500 1.1 christos break;
501 1.1 christos }
502 1.1 christos
503 1.1 christos case 2:
504 1.1 christos if ( timer_nr == TM6CA )
505 1.1 christos {
506 1.1 christos *(unsigned16 *)dest = timers->tm6ca;
507 1.1 christos }
508 1.1 christos else if ( timer_nr == TM6CB )
509 1.1 christos {
510 1.1 christos *(unsigned16 *)dest = timers->tm6cb;
511 1.1 christos }
512 1.1 christos else
513 1.1 christos {
514 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
515 1.1 christos }
516 1.1 christos break;
517 1.1 christos
518 1.1 christos default:
519 1.1 christos hw_abort(me, "bad read size for timer 6 register");
520 1.1 christos }
521 1.1 christos
522 1.1 christos }
523 1.1 christos
524 1.1 christos
525 1.1 christos static unsigned
526 1.1 christos mn103tim_io_read_buffer (struct hw *me,
527 1.1 christos void *dest,
528 1.1 christos int space,
529 1.1 christos unsigned_word base,
530 1.1 christos unsigned nr_bytes)
531 1.1 christos {
532 1.1 christos struct mn103tim *timers = hw_data (me);
533 1.1 christos enum timer_register_types timer_reg;
534 1.1 christos
535 1.1 christos HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
536 1.1 christos
537 1.1 christos timer_reg = decode_addr (me, timers, base);
538 1.1 christos
539 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
540 1.1 christos /* or a special timer 6 register. Check in that order. */
541 1.1 christos if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
542 1.1 christos {
543 1.1 christos read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
544 1.1 christos }
545 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
546 1.1 christos {
547 1.1 christos read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
548 1.1 christos }
549 1.1 christos else if ( timer_reg <= LAST_COUNTER )
550 1.1 christos {
551 1.1 christos read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
552 1.1 christos }
553 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
554 1.1 christos {
555 1.1 christos read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
556 1.1 christos }
557 1.1 christos else
558 1.1 christos {
559 1.1 christos hw_abort(me, "invalid timer register address.");
560 1.1 christos }
561 1.1 christos
562 1.1 christos return nr_bytes;
563 1.1 christos }
564 1.1 christos
565 1.1 christos
566 1.1 christos static void
567 1.1 christos do_counter_event (struct hw *me,
568 1.1 christos void *data)
569 1.1 christos {
570 1.1 christos struct mn103tim *timers = hw_data(me);
571 1.1 christos long timer_nr = (long) data;
572 1.1 christos int next_timer;
573 1.1 christos
574 1.1 christos /* Check if counting is still enabled. */
575 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
576 1.1 christos {
577 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
578 1.1 christos
579 1.1 christos /* Port event occurs on port of last cascaded timer. */
580 1.1 christos /* This works across timer range from 0 to NR_REG_TIMERS because */
581 1.1 christos /* the first 16 bit timer (timer 4) is not allowed to be set as */
582 1.1 christos /* a cascading timer. */
583 1.1 christos for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
584 1.1 christos {
585 1.1 christos if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
586 1.1 christos {
587 1.1 christos break;
588 1.1 christos }
589 1.1 christos }
590 1.1 christos hw_port_event (me, next_timer-1, 1);
591 1.1 christos
592 1.1 christos /* Schedule next timeout. */
593 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
594 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
595 1.1 christos timers->timer[timer_nr].event
596 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
597 1.1 christos do_counter_event, (void *)timer_nr);
598 1.1 christos }
599 1.1 christos else
600 1.1 christos {
601 1.1 christos timers->timer[timer_nr].event = NULL;
602 1.1 christos }
603 1.1 christos
604 1.1 christos }
605 1.1 christos
606 1.1 christos
607 1.1 christos static void
608 1.1 christos do_counter6_event (struct hw *me,
609 1.1 christos void *data)
610 1.1 christos {
611 1.1 christos struct mn103tim *timers = hw_data(me);
612 1.1 christos long timer_nr = (long) data;
613 1.1 christos int next_timer;
614 1.1 christos
615 1.1 christos /* Check if counting is still enabled. */
616 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
617 1.1 christos {
618 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
619 1.1 christos hw_port_event (me, timer_nr, 1);
620 1.1 christos
621 1.1 christos /* Schedule next timeout. */
622 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
623 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
624 1.1 christos timers->timer[timer_nr].event
625 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
626 1.1 christos do_counter6_event, (void *)timer_nr);
627 1.1 christos }
628 1.1 christos else
629 1.1 christos {
630 1.1 christos timers->timer[timer_nr].event = NULL;
631 1.1 christos }
632 1.1 christos
633 1.1 christos }
634 1.1 christos
635 1.1 christos static void
636 1.1 christos write_base_reg (struct hw *me,
637 1.1 christos struct mn103tim *timers,
638 1.1 christos int timer_nr,
639 1.1 christos const void *source,
640 1.1 christos unsigned nr_bytes)
641 1.1 christos {
642 1.1 christos unsigned i;
643 1.1 christos const unsigned8 *buf8 = source;
644 1.1 christos const unsigned16 *buf16 = source;
645 1.1 christos
646 1.1 christos /* If TMnCNE == 0 (counting is off), writing to the base register
647 1.1 christos (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
648 1.1 christos Else, the TMnBC is reloaded with the value from TMnBR when
649 1.1 christos underflow occurs. Since the counter register is not explicitly
650 1.1 christos maintained, this functionality is handled in read_counter. */
651 1.1 christos
652 1.1 christos /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
653 1.1 christos switch ( nr_bytes )
654 1.1 christos {
655 1.1 christos case 1:
656 1.1 christos /* Storing 1 byte is ok for all registers. */
657 1.1 christos timers->reg[timer_nr].base = buf8[0];
658 1.1 christos break;
659 1.1 christos
660 1.1 christos case 2:
661 1.1 christos if ( timer_nr == 1 || timer_nr == 3 )
662 1.1 christos {
663 1.1 christos hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
664 1.1 christos }
665 1.1 christos else
666 1.1 christos {
667 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
668 1.1 christos {
669 1.1 christos timers->reg[timer_nr].base = buf8[0];
670 1.1 christos timers->reg[timer_nr+1].base = buf8[1];
671 1.1 christos }
672 1.1 christos else
673 1.1 christos {
674 1.1 christos timers->reg[timer_nr].base = buf16[0];
675 1.1 christos }
676 1.1 christos }
677 1.1 christos break;
678 1.1 christos
679 1.1 christos case 4:
680 1.1 christos if ( timer_nr == 0 )
681 1.1 christos {
682 1.1 christos timers->reg[0].base = buf8[0];
683 1.1 christos timers->reg[1].base = buf8[1];
684 1.1 christos timers->reg[2].base = buf8[2];
685 1.1 christos timers->reg[3].base = buf8[3];
686 1.1 christos }
687 1.1 christos else if ( timer_nr == 4 )
688 1.1 christos {
689 1.1 christos timers->reg[4].base = buf16[0];
690 1.1 christos timers->reg[5].base = buf16[1];
691 1.1 christos }
692 1.1 christos else
693 1.1 christos {
694 1.1 christos hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
695 1.1 christos }
696 1.1 christos break;
697 1.1 christos
698 1.1 christos default:
699 1.1 christos hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
700 1.1 christos nr_bytes, timer_nr);
701 1.1 christos }
702 1.1 christos
703 1.1 christos }
704 1.1 christos
705 1.1 christos static void
706 1.1 christos write_mode_reg (struct hw *me,
707 1.1 christos struct mn103tim *timers,
708 1.1 christos long timer_nr,
709 1.1 christos const void *source,
710 1.1 christos unsigned nr_bytes)
711 1.1 christos /* for timers 0 to 5 */
712 1.1 christos {
713 1.1 christos unsigned i;
714 1.1 christos unsigned8 mode_val, next_mode_val;
715 1.1 christos unsigned32 div_ratio;
716 1.1 christos
717 1.1 christos if ( nr_bytes != 1 )
718 1.1 christos {
719 1.1 christos hw_abort (me, "bad write size of %d bytes to TM%ldMD.", nr_bytes,
720 1.1 christos timer_nr);
721 1.1 christos }
722 1.1 christos
723 1.1 christos mode_val = *(unsigned8 *)source;
724 1.1 christos timers->reg[timer_nr].mode = mode_val;
725 1.1 christos
726 1.1 christos if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
727 1.1 christos {
728 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
729 1.1 christos }
730 1.1 christos if ( ( mode_val & bits2to5_mask ) != 0 )
731 1.1 christos {
732 1.1 christos hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
733 1.1 christos }
734 1.1 christos
735 1.1 christos if ( mode_val & count_mask )
736 1.1 christos {
737 1.1 christos /* - de-schedule any previous event. */
738 1.1 christos /* - add new event to queue to start counting. */
739 1.1 christos /* - assert that counter == base reg? */
740 1.1 christos
741 1.1 christos /* For cascaded timers, */
742 1.1 christos if ( (mode_val & clock_mask) == clk_cascaded )
743 1.1 christos {
744 1.1 christos if ( timer_nr == 0 || timer_nr == 4 )
745 1.1 christos {
746 1.1 christos hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr);
747 1.1 christos }
748 1.1 christos }
749 1.1 christos else
750 1.1 christos {
751 1.1 christos div_ratio = timers->reg[timer_nr].base;
752 1.1 christos
753 1.1 christos /* Check for cascading. */
754 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
755 1.1 christos {
756 1.1 christos for ( i = timer_nr + 1; i <= 3; ++i )
757 1.1 christos {
758 1.1 christos next_mode_val = timers->reg[i].mode;
759 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
760 1.1 christos {
761 1.1 christos /* Check that CNE is on. */
762 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
763 1.1 christos {
764 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
765 1.1 christos }
766 1.1 christos ASSERT(timers->timer[i].event == NULL);
767 1.1 christos ASSERT(timers->timer[i].div_ratio == 0);
768 1.1 christos div_ratio = div_ratio
769 1.1 christos | (timers->reg[i].base << (8*(i-timer_nr)));
770 1.1 christos }
771 1.1 christos else
772 1.1 christos {
773 1.1 christos break;
774 1.1 christos }
775 1.1 christos }
776 1.1 christos }
777 1.1 christos else
778 1.1 christos {
779 1.1 christos /* Mode register for a 16 bit timer */
780 1.1 christos next_mode_val = timers->reg[timer_nr+1].mode;
781 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
782 1.1 christos {
783 1.1 christos /* Check that CNE is on. */
784 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
785 1.1 christos {
786 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
787 1.1 christos }
788 1.1 christos ASSERT(timers->timer[timer_nr+1].event == NULL);
789 1.1 christos ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
790 1.1 christos div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
791 1.1 christos }
792 1.1 christos }
793 1.1 christos
794 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
795 1.1 christos
796 1.1 christos if ( NULL != timers->timer[timer_nr].event )
797 1.1 christos {
798 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
799 1.1 christos timers->timer[timer_nr].event = NULL;
800 1.1 christos }
801 1.1 christos
802 1.1 christos if ( div_ratio > 0 )
803 1.1 christos {
804 1.1 christos /* Set start time. */
805 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
806 1.1 christos timers->timer[timer_nr].event
807 1.1 christos = hw_event_queue_schedule(me, div_ratio,
808 1.1 christos do_counter_event,
809 1.1 christos (void *)(timer_nr));
810 1.1 christos }
811 1.1 christos }
812 1.1 christos }
813 1.1 christos else
814 1.1 christos {
815 1.1 christos /* Turn off counting */
816 1.1 christos if ( NULL != timers->timer[timer_nr].event )
817 1.1 christos {
818 1.1 christos ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
819 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
820 1.1 christos timers->timer[timer_nr].event = NULL;
821 1.1 christos }
822 1.1 christos else
823 1.1 christos {
824 1.1 christos if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
825 1.1 christos {
826 1.1 christos ASSERT(timers->timer[timer_nr].event == NULL);
827 1.1 christos }
828 1.1 christos }
829 1.1 christos
830 1.1 christos }
831 1.1 christos
832 1.1 christos }
833 1.1 christos
834 1.1 christos static void
835 1.1 christos write_tm6md (struct hw *me,
836 1.1 christos struct mn103tim *timers,
837 1.1 christos unsigned_word address,
838 1.1 christos const void *source,
839 1.1 christos unsigned nr_bytes)
840 1.1 christos {
841 1.1 christos unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
842 1.1 christos unsigned32 div_ratio;
843 1.1 christos long timer_nr = 6;
844 1.1 christos
845 1.1 christos unsigned_word offset = address - timers->block[0].base;
846 1.1 christos
847 1.1 christos if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
848 1.1 christos {
849 1.1 christos hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
850 1.1 christos }
851 1.1 christos
852 1.1 christos if ( offset == 0x84 ) /* address of TM6MD */
853 1.1 christos {
854 1.1 christos /* Fill in first byte of mode */
855 1.1 christos mode_val0 = *(unsigned8 *)source;
856 1.1 christos timers->tm6md0 = mode_val0;
857 1.1 christos
858 1.1 christos if ( ( mode_val0 & 0x26 ) != 0 )
859 1.1 christos {
860 1.1 christos hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
861 1.1 christos }
862 1.1 christos }
863 1.1 christos
864 1.1 christos if ( offset == 0x85 || nr_bytes == 2 )
865 1.1 christos {
866 1.1 christos /* Fill in second byte of mode */
867 1.1 christos if ( nr_bytes == 2 )
868 1.1 christos {
869 1.1 christos mode_val1 = *(unsigned8 *)source+1;
870 1.1 christos }
871 1.1 christos else
872 1.1 christos {
873 1.1 christos mode_val1 = *(unsigned8 *)source;
874 1.1 christos }
875 1.1 christos
876 1.1 christos timers->tm6md1 = mode_val1;
877 1.1 christos
878 1.1 christos if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
879 1.1 christos {
880 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
881 1.1 christos }
882 1.1 christos if ( ( mode_val1 & bits0to2_mask ) != 0 )
883 1.1 christos {
884 1.1 christos hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
885 1.1 christos }
886 1.1 christos }
887 1.1 christos
888 1.1 christos if ( mode_val1 & count_mask )
889 1.1 christos {
890 1.1 christos /* - de-schedule any previous event. */
891 1.1 christos /* - add new event to queue to start counting. */
892 1.1 christos /* - assert that counter == base reg? */
893 1.1 christos
894 1.1 christos div_ratio = timers->tm6ca; /* binary counter for timer 6 */
895 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
896 1.1 christos if ( NULL != timers->timer[timer_nr].event )
897 1.1 christos {
898 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
899 1.1 christos timers->timer[timer_nr].event = NULL;
900 1.1 christos }
901 1.1 christos
902 1.1 christos if ( div_ratio > 0 )
903 1.1 christos {
904 1.1 christos /* Set start time. */
905 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
906 1.1 christos timers->timer[timer_nr].event
907 1.1 christos = hw_event_queue_schedule(me, div_ratio,
908 1.1 christos do_counter6_event,
909 1.1 christos (void *)(timer_nr));
910 1.1 christos }
911 1.1 christos }
912 1.1 christos else
913 1.1 christos {
914 1.1 christos /* Turn off counting */
915 1.1 christos if ( NULL != timers->timer[timer_nr].event )
916 1.1 christos {
917 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
918 1.1 christos timers->timer[timer_nr].event = NULL;
919 1.1 christos }
920 1.1 christos }
921 1.1 christos }
922 1.1 christos
923 1.1 christos
924 1.1 christos
925 1.1 christos static void
926 1.1 christos write_special_timer6_reg (struct hw *me,
927 1.1 christos struct mn103tim *timers,
928 1.1 christos int timer_nr,
929 1.1 christos const void *source,
930 1.1 christos unsigned nr_bytes)
931 1.1 christos {
932 1.1 christos unsigned32 val;
933 1.1 christos
934 1.1 christos switch (nr_bytes) {
935 1.1 christos case 1:
936 1.1 christos {
937 1.1 christos switch ( timer_nr ) {
938 1.1 christos case TM6MDA:
939 1.1 christos timers->tm6mda = *(unsigned8 *)source;
940 1.1 christos break;
941 1.1 christos
942 1.1 christos case TM6MDB:
943 1.1 christos timers->tm6mdb = *(unsigned8 *)source;
944 1.1 christos break;
945 1.1 christos
946 1.1 christos case TM6CA:
947 1.1 christos timers->tm6ca = *(unsigned8 *)source;
948 1.1 christos break;
949 1.1 christos
950 1.1 christos case TM6CB:
951 1.1 christos timers->tm6cb = *(unsigned8 *)source;
952 1.1 christos break;
953 1.1 christos
954 1.1 christos default:
955 1.1 christos break;
956 1.1 christos }
957 1.1 christos break;
958 1.1 christos }
959 1.1 christos
960 1.1 christos case 2:
961 1.1 christos if ( timer_nr == TM6CA )
962 1.1 christos {
963 1.1 christos timers->tm6ca = *(unsigned16 *)source;
964 1.1 christos }
965 1.1 christos else if ( timer_nr == TM6CB )
966 1.1 christos {
967 1.1 christos timers->tm6cb = *(unsigned16 *)source;
968 1.1 christos }
969 1.1 christos else
970 1.1 christos {
971 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
972 1.1 christos }
973 1.1 christos break;
974 1.1 christos
975 1.1 christos default:
976 1.1 christos hw_abort(me, "bad read size for timer 6 register");
977 1.1 christos }
978 1.1 christos
979 1.1 christos }
980 1.1 christos
981 1.1 christos
982 1.1 christos static unsigned
983 1.1 christos mn103tim_io_write_buffer (struct hw *me,
984 1.1 christos const void *source,
985 1.1 christos int space,
986 1.1 christos unsigned_word base,
987 1.1 christos unsigned nr_bytes)
988 1.1 christos {
989 1.1 christos struct mn103tim *timers = hw_data (me);
990 1.1 christos enum timer_register_types timer_reg;
991 1.1 christos
992 1.1 christos HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
993 1.1 christos (int) nr_bytes, *(unsigned32 *)source));
994 1.1 christos
995 1.1 christos timer_reg = decode_addr (me, timers, base);
996 1.1 christos
997 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
998 1.1 christos /* or a special timer 6 register. Check in that order. */
999 1.1 christos if ( timer_reg <= LAST_MODE_REG )
1000 1.1 christos {
1001 1.1 christos if ( timer_reg == 6 )
1002 1.1 christos {
1003 1.1 christos write_tm6md(me, timers, base, source, nr_bytes);
1004 1.1 christos }
1005 1.1 christos else
1006 1.1 christos {
1007 1.1 christos write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1008 1.1 christos source, nr_bytes);
1009 1.1 christos }
1010 1.1 christos }
1011 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
1012 1.1 christos {
1013 1.1 christos write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1014 1.1 christos }
1015 1.1 christos else if ( timer_reg <= LAST_COUNTER )
1016 1.1 christos {
1017 1.1 christos hw_abort(me, "cannot write to counter");
1018 1.1 christos }
1019 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
1020 1.1 christos {
1021 1.1 christos write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1022 1.1 christos }
1023 1.1 christos else
1024 1.1 christos {
1025 1.1 christos hw_abort(me, "invalid reg type");
1026 1.1 christos }
1027 1.1 christos
1028 1.1 christos return nr_bytes;
1029 1.1 christos }
1030 1.1 christos
1031 1.1 christos
1032 1.1 christos const struct hw_descriptor dv_mn103tim_descriptor[] = {
1033 1.1 christos { "mn103tim", mn103tim_finish, },
1034 1.1 christos { NULL },
1035 1.1 christos };
1036