This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.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 };