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