2003-02-26 David Carlton <carlton@math.stanford.edu>
[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, 2003 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         break;
499       }
500       break;
501     }
502     
503   case 2:
504     if ( timer_nr == TM6CA )
505       {
506         *(unsigned16 *)dest = timers->tm6ca;
507       }
508     else if ( timer_nr == TM6CB )
509       {
510         *(unsigned16 *)dest = timers->tm6cb;
511       }
512     else
513       {
514         hw_abort(me, "bad read size for timer 6 mode A/B register");
515       }
516     break;
517
518   default:
519     hw_abort(me, "bad read size for timer 6 register");
520   }
521       
522 }
523
524
525 static unsigned
526 mn103tim_io_read_buffer (struct hw *me,
527                          void *dest,
528                          int space,
529                          unsigned_word base,
530                          unsigned nr_bytes)
531 {
532   struct mn103tim *timers = hw_data (me);
533   enum timer_register_types timer_reg;
534
535   HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
536
537   timer_reg = decode_addr (me, timers, base);
538
539   /* It can be either a mode register, a base register, a binary counter, */
540   /* or a special timer 6 register.  Check in that order. */
541   if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
542     {
543       read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
544     }
545   else if ( timer_reg <= LAST_BASE_REG )
546     {
547       read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
548     }
549   else if ( timer_reg <= LAST_COUNTER )
550     {
551       read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
552     }
553   else if ( timer_reg <= LAST_TIMER_REG )
554     {
555       read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
556     }
557   else
558     {
559       hw_abort(me, "invalid timer register address.");
560     }
561
562   return nr_bytes;
563 }     
564
565
566 static void
567 do_counter_event (struct hw *me,
568                   void *data)
569 {
570   struct mn103tim *timers = hw_data(me);
571   int timer_nr = (int) data;
572   int next_timer;
573
574   /* Check if counting is still enabled. */
575   if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
576     {
577       /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
578
579       /* Port event occurs on port of last cascaded timer. */
580       /* This works across timer range from 0 to NR_REG_TIMERS because */
581       /* the first 16 bit timer (timer 4) is not allowed to be set as  */
582       /* a cascading timer. */
583       for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
584         {
585           if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
586             {
587               break;
588             }
589         }
590       hw_port_event (me, next_timer-1, 1);
591
592       /* Schedule next timeout.  */
593       timers->timer[timer_nr].start = hw_event_queue_time(me);
594       /* FIX: Check if div_ratio has changed and if it's now 0. */
595       timers->timer[timer_nr].event
596         = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
597                                    do_counter_event, (void *)timer_nr);
598     }
599   else
600     {
601       timers->timer[timer_nr].event = NULL;
602     }
603
604 }
605
606
607 static void
608 do_counter6_event (struct hw *me,
609                   void *data)
610 {
611   struct mn103tim *timers = hw_data(me);
612   int timer_nr = (int) data;
613   int next_timer;
614
615   /* Check if counting is still enabled. */
616   if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
617     {
618       /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
619       hw_port_event (me, timer_nr, 1);
620
621       /* Schedule next timeout.  */
622       timers->timer[timer_nr].start = hw_event_queue_time(me);
623       /* FIX: Check if div_ratio has changed and if it's now 0. */
624       timers->timer[timer_nr].event
625         = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
626                                    do_counter6_event, (void *)timer_nr);
627     }
628   else
629     {
630       timers->timer[timer_nr].event = NULL;
631     }
632
633 }
634
635 static void
636 write_base_reg (struct hw *me,
637                 struct mn103tim *timers,
638                 int timer_nr,
639                 const void *source,
640                 unsigned  nr_bytes)
641 {
642   unsigned i;
643   const unsigned8 *buf8 = source;
644   const unsigned16 *buf16 = source;
645
646   /* If TMnCNE == 0 (counting is off),  writing to the base register
647      (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
648      Else, the TMnBC is reloaded with the value from TMnBR when
649      underflow occurs.  Since the counter register is not explicitly
650      maintained, this functionality is handled in read_counter. */
651
652   /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
653   switch ( nr_bytes )
654     {
655     case 1:
656       /* Storing 1 byte is ok for all registers. */
657       timers->reg[timer_nr].base = buf8[0];
658       break;
659
660     case 2:
661       if ( timer_nr == 1 || timer_nr == 3 )
662         {
663           hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
664         }
665       else
666         {
667           if ( timer_nr < NR_8BIT_TIMERS )
668             {
669               timers->reg[timer_nr].base = buf8[0];
670               timers->reg[timer_nr+1].base = buf8[1];
671             }
672           else 
673             {
674               timers->reg[timer_nr].base = buf16[0];
675             }
676         }
677       break;
678
679     case 4:
680       if ( timer_nr == 0 )
681         {
682           timers->reg[0].base = buf8[0];
683           timers->reg[1].base = buf8[1];
684           timers->reg[2].base = buf8[2];
685           timers->reg[3].base = buf8[3];
686         }
687       else if ( timer_nr == 4 )
688         {
689           timers->reg[4].base = buf16[0];
690           timers->reg[5].base = buf16[1];
691         }
692       else
693         {
694           hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
695         }
696       break;
697
698     default:
699       hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
700                 nr_bytes, timer_nr);
701     }
702      
703 }
704
705 static void
706 write_mode_reg (struct hw *me,
707                 struct mn103tim *timers,
708                 int timer_nr,
709                 const void *source,
710                 unsigned nr_bytes)
711      /* for timers 0 to 5 */
712 {
713   unsigned i;
714   unsigned8 mode_val, next_mode_val;
715   unsigned32 div_ratio;
716
717   if ( nr_bytes != 1 )
718     {
719       hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
720     }
721
722   mode_val = *(unsigned8 *)source;
723   timers->reg[timer_nr].mode = mode_val;
724       
725   if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
726     {
727       hw_abort(me, "Cannot load base reg and start counting simultaneously.");
728     }
729   if ( ( mode_val & bits2to5_mask ) != 0 )
730     {
731       hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
732     }
733
734   if ( mode_val & count_mask )
735     {
736       /* - de-schedule any previous event. */
737       /* - add new event to queue to start counting. */
738       /* - assert that counter == base reg? */
739
740       /* For cascaded timers, */
741       if ( (mode_val & clock_mask) == clk_cascaded )
742         {
743           if ( timer_nr == 0 || timer_nr == 4 )
744             {
745               hw_abort(me, "Timer %d cannot be cascaded.", timer_nr);
746             }
747         }
748       else
749         {
750           div_ratio = timers->reg[timer_nr].base;
751
752           /* Check for cascading. */
753           if ( timer_nr < NR_8BIT_TIMERS )
754             {
755               for ( i = timer_nr + 1; i <= 3; ++i ) 
756                 {
757                   next_mode_val = timers->reg[i].mode;
758                   if ( ( next_mode_val & clock_mask ) == clk_cascaded )
759                     {
760                       /* Check that CNE is on. */
761                       if ( ( next_mode_val & count_mask ) == 0 ) 
762                         {
763                           hw_abort (me, "cascaded timer not ready for counting");
764                         }
765                       ASSERT(timers->timer[i].event == NULL);
766                       ASSERT(timers->timer[i].div_ratio == 0);
767                       div_ratio = div_ratio
768                         | (timers->reg[i].base << (8*(i-timer_nr)));
769                     }
770                   else
771                     {
772                       break;
773                     }
774                 }
775             }
776           else
777             {
778               /* Mode register for a 16 bit timer */
779               next_mode_val = timers->reg[timer_nr+1].mode;
780               if ( ( next_mode_val & clock_mask ) == clk_cascaded )
781                 {
782                   /* Check that CNE is on. */
783                   if ( ( next_mode_val & count_mask ) == 0 ) 
784                     {
785                       hw_abort (me, "cascaded timer not ready for counting");
786                     }
787                   ASSERT(timers->timer[timer_nr+1].event == NULL);
788                   ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
789                   div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
790                 }
791             }
792
793           timers->timer[timer_nr].div_ratio = div_ratio;
794
795           if ( NULL != timers->timer[timer_nr].event )
796             {
797               hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
798               timers->timer[timer_nr].event = NULL;
799             }
800
801           if ( div_ratio > 0 )
802             {
803               /* Set start time. */
804               timers->timer[timer_nr].start = hw_event_queue_time(me);
805               timers->timer[timer_nr].event
806                 = hw_event_queue_schedule(me, div_ratio,
807                                           do_counter_event,
808                                           (void *)(timer_nr)); 
809             }
810         }
811     }
812   else
813     {
814       /* Turn off counting */
815       if ( NULL != timers->timer[timer_nr].event )
816         {
817           ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
818           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
819           timers->timer[timer_nr].event = NULL;
820         }
821       else
822         {
823           if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
824             {
825               ASSERT(timers->timer[timer_nr].event == NULL);
826             }
827         }
828       
829     }
830
831 }
832
833 static void
834 write_tm6md (struct hw *me,
835              struct mn103tim *timers,
836              unsigned_word address,
837              const void *source,
838              unsigned nr_bytes)
839 {
840   unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
841   unsigned32 div_ratio;
842   int timer_nr = 6;
843
844   unsigned_word offset = address - timers->block[0].base;
845   
846   if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
847     {
848       hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
849     }
850
851   if ( offset == 0x84 )  /* address of TM6MD */
852     {
853       /*  Fill in first byte of mode */
854       mode_val0 = *(unsigned8 *)source;
855       timers->tm6md0 = mode_val0;
856     
857       if ( ( mode_val0 & 0x26 ) != 0 )
858         {
859           hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
860         }
861     }
862   
863   if ( offset == 0x85 || nr_bytes == 2 )
864     {
865       /*  Fill in second byte of mode */
866       if ( nr_bytes == 2 )
867         {
868           mode_val1 = *(unsigned8 *)source+1;
869         }
870       else
871         {
872           mode_val1 = *(unsigned8 *)source;
873         }
874
875       timers->tm6md1 = mode_val1;
876
877       if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
878         {
879           hw_abort(me, "Cannot load base reg and start counting simultaneously.");
880         }
881       if ( ( mode_val1 & bits0to2_mask ) != 0 )
882         {
883           hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
884         }
885     }
886
887   if ( mode_val1 & count_mask )
888     {
889       /* - de-schedule any previous event. */
890       /* - add new event to queue to start counting. */
891       /* - assert that counter == base reg? */
892
893       div_ratio = timers->tm6ca;  /* binary counter for timer 6 */
894       timers->timer[timer_nr].div_ratio = div_ratio;
895       if ( NULL != timers->timer[timer_nr].event )
896         {
897           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
898           timers->timer[timer_nr].event = NULL;
899         }
900
901       if ( div_ratio > 0 )
902         {
903           /* Set start time. */
904           timers->timer[timer_nr].start = hw_event_queue_time(me);
905           timers->timer[timer_nr].event
906             = hw_event_queue_schedule(me, div_ratio,
907                                       do_counter6_event,
908                                       (void *)(timer_nr)); 
909         }
910     }
911   else
912     {
913       /* Turn off counting */
914       if ( NULL != timers->timer[timer_nr].event )
915         {
916           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
917           timers->timer[timer_nr].event = NULL;
918         }
919     }
920 }
921
922
923
924 static void
925 write_special_timer6_reg (struct hw *me,
926                           struct mn103tim *timers,
927                           int timer_nr,
928                           const void *source,
929                           unsigned  nr_bytes)
930 {
931   unsigned32 val;
932
933   switch (nr_bytes) {
934   case 1:
935     {
936       switch ( timer_nr ) {
937       case TM6MDA:
938         timers->tm6mda = *(unsigned8 *)source;
939         break;
940     
941       case TM6MDB:
942         timers->tm6mdb = *(unsigned8 *)source;
943         break;
944     
945       case TM6CA:
946         timers->tm6ca = *(unsigned8 *)source;
947         break;
948     
949       case TM6CB:
950         timers->tm6cb = *(unsigned8 *)source;
951         break;
952       
953       default:
954         break;
955       }
956       break;
957     }
958     
959   case 2:
960     if ( timer_nr == TM6CA )
961       {
962         timers->tm6ca = *(unsigned16 *)source;
963       }
964     else if ( timer_nr == TM6CB )
965       {
966         timers->tm6cb = *(unsigned16 *)source;
967       }
968     else
969       {
970         hw_abort(me, "bad read size for timer 6 mode A/B register");
971       }
972     break;
973
974   default:
975     hw_abort(me, "bad read size for timer 6 register");
976   }
977       
978 }
979
980
981 static unsigned
982 mn103tim_io_write_buffer (struct hw *me,
983                           const void *source,
984                           int space,
985                           unsigned_word base,
986                           unsigned nr_bytes)
987 {
988   struct mn103tim *timers = hw_data (me);
989   enum timer_register_types timer_reg;
990
991   HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
992              (int) nr_bytes, *(unsigned32 *)source));
993
994   timer_reg = decode_addr (me, timers, base);
995
996   /* It can be either a mode register, a base register, a binary counter, */
997   /* or a special timer 6 register.  Check in that order. */
998   if ( timer_reg <= LAST_MODE_REG )
999     {
1000       if ( timer_reg == 6 ) 
1001         {
1002           write_tm6md(me, timers, base, source, nr_bytes);
1003         }
1004       else
1005         {
1006           write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1007                          source, nr_bytes);
1008         }
1009     }
1010   else if ( timer_reg <= LAST_BASE_REG )
1011     {
1012       write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1013     }
1014   else if ( timer_reg <= LAST_COUNTER )
1015     {
1016       hw_abort(me, "cannot write to counter");
1017     }
1018   else if ( timer_reg <= LAST_TIMER_REG )
1019     {
1020       write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1021     }
1022   else
1023     {
1024       hw_abort(me, "invalid reg type");
1025     }
1026
1027   return nr_bytes;
1028 }     
1029
1030
1031 const struct hw_descriptor dv_mn103tim_descriptor[] = {
1032   { "mn103tim", mn103tim_finish, },
1033   { NULL },
1034 };