Update copyright notices to add year 2010.
[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, 2007, 2008, 2009, 2010
4     Free Software Foundation, Inc.
5     Contributed by Cygnus Solutions.
6     
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 3 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
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   long timer_nr = (long) 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   long timer_nr = (long) 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                 long 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%ldMD.", nr_bytes,
720                 timer_nr);
721     }
722
723   mode_val = *(unsigned8 *)source;
724   timers->reg[timer_nr].mode = mode_val;
725       
726   if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
727     {
728       hw_abort(me, "Cannot load base reg and start counting simultaneously.");
729     }
730   if ( ( mode_val & bits2to5_mask ) != 0 )
731     {
732       hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
733     }
734
735   if ( mode_val & count_mask )
736     {
737       /* - de-schedule any previous event. */
738       /* - add new event to queue to start counting. */
739       /* - assert that counter == base reg? */
740
741       /* For cascaded timers, */
742       if ( (mode_val & clock_mask) == clk_cascaded )
743         {
744           if ( timer_nr == 0 || timer_nr == 4 )
745             {
746               hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr);
747             }
748         }
749       else
750         {
751           div_ratio = timers->reg[timer_nr].base;
752
753           /* Check for cascading. */
754           if ( timer_nr < NR_8BIT_TIMERS )
755             {
756               for ( i = timer_nr + 1; i <= 3; ++i ) 
757                 {
758                   next_mode_val = timers->reg[i].mode;
759                   if ( ( next_mode_val & clock_mask ) == clk_cascaded )
760                     {
761                       /* Check that CNE is on. */
762                       if ( ( next_mode_val & count_mask ) == 0 ) 
763                         {
764                           hw_abort (me, "cascaded timer not ready for counting");
765                         }
766                       ASSERT(timers->timer[i].event == NULL);
767                       ASSERT(timers->timer[i].div_ratio == 0);
768                       div_ratio = div_ratio
769                         | (timers->reg[i].base << (8*(i-timer_nr)));
770                     }
771                   else
772                     {
773                       break;
774                     }
775                 }
776             }
777           else
778             {
779               /* Mode register for a 16 bit timer */
780               next_mode_val = timers->reg[timer_nr+1].mode;
781               if ( ( next_mode_val & clock_mask ) == clk_cascaded )
782                 {
783                   /* Check that CNE is on. */
784                   if ( ( next_mode_val & count_mask ) == 0 ) 
785                     {
786                       hw_abort (me, "cascaded timer not ready for counting");
787                     }
788                   ASSERT(timers->timer[timer_nr+1].event == NULL);
789                   ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
790                   div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
791                 }
792             }
793
794           timers->timer[timer_nr].div_ratio = div_ratio;
795
796           if ( NULL != timers->timer[timer_nr].event )
797             {
798               hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
799               timers->timer[timer_nr].event = NULL;
800             }
801
802           if ( div_ratio > 0 )
803             {
804               /* Set start time. */
805               timers->timer[timer_nr].start = hw_event_queue_time(me);
806               timers->timer[timer_nr].event
807                 = hw_event_queue_schedule(me, div_ratio,
808                                           do_counter_event,
809                                           (void *)(timer_nr)); 
810             }
811         }
812     }
813   else
814     {
815       /* Turn off counting */
816       if ( NULL != timers->timer[timer_nr].event )
817         {
818           ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
819           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
820           timers->timer[timer_nr].event = NULL;
821         }
822       else
823         {
824           if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
825             {
826               ASSERT(timers->timer[timer_nr].event == NULL);
827             }
828         }
829       
830     }
831
832 }
833
834 static void
835 write_tm6md (struct hw *me,
836              struct mn103tim *timers,
837              unsigned_word address,
838              const void *source,
839              unsigned nr_bytes)
840 {
841   unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
842   unsigned32 div_ratio;
843   long timer_nr = 6;
844
845   unsigned_word offset = address - timers->block[0].base;
846   
847   if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
848     {
849       hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
850     }
851
852   if ( offset == 0x84 )  /* address of TM6MD */
853     {
854       /*  Fill in first byte of mode */
855       mode_val0 = *(unsigned8 *)source;
856       timers->tm6md0 = mode_val0;
857     
858       if ( ( mode_val0 & 0x26 ) != 0 )
859         {
860           hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
861         }
862     }
863   
864   if ( offset == 0x85 || nr_bytes == 2 )
865     {
866       /*  Fill in second byte of mode */
867       if ( nr_bytes == 2 )
868         {
869           mode_val1 = *(unsigned8 *)source+1;
870         }
871       else
872         {
873           mode_val1 = *(unsigned8 *)source;
874         }
875
876       timers->tm6md1 = mode_val1;
877
878       if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
879         {
880           hw_abort(me, "Cannot load base reg and start counting simultaneously.");
881         }
882       if ( ( mode_val1 & bits0to2_mask ) != 0 )
883         {
884           hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
885         }
886     }
887
888   if ( mode_val1 & count_mask )
889     {
890       /* - de-schedule any previous event. */
891       /* - add new event to queue to start counting. */
892       /* - assert that counter == base reg? */
893
894       div_ratio = timers->tm6ca;  /* binary counter for timer 6 */
895       timers->timer[timer_nr].div_ratio = div_ratio;
896       if ( NULL != timers->timer[timer_nr].event )
897         {
898           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
899           timers->timer[timer_nr].event = NULL;
900         }
901
902       if ( div_ratio > 0 )
903         {
904           /* Set start time. */
905           timers->timer[timer_nr].start = hw_event_queue_time(me);
906           timers->timer[timer_nr].event
907             = hw_event_queue_schedule(me, div_ratio,
908                                       do_counter6_event,
909                                       (void *)(timer_nr)); 
910         }
911     }
912   else
913     {
914       /* Turn off counting */
915       if ( NULL != timers->timer[timer_nr].event )
916         {
917           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
918           timers->timer[timer_nr].event = NULL;
919         }
920     }
921 }
922
923
924
925 static void
926 write_special_timer6_reg (struct hw *me,
927                           struct mn103tim *timers,
928                           int timer_nr,
929                           const void *source,
930                           unsigned  nr_bytes)
931 {
932   unsigned32 val;
933
934   switch (nr_bytes) {
935   case 1:
936     {
937       switch ( timer_nr ) {
938       case TM6MDA:
939         timers->tm6mda = *(unsigned8 *)source;
940         break;
941     
942       case TM6MDB:
943         timers->tm6mdb = *(unsigned8 *)source;
944         break;
945     
946       case TM6CA:
947         timers->tm6ca = *(unsigned8 *)source;
948         break;
949     
950       case TM6CB:
951         timers->tm6cb = *(unsigned8 *)source;
952         break;
953       
954       default:
955         break;
956       }
957       break;
958     }
959     
960   case 2:
961     if ( timer_nr == TM6CA )
962       {
963         timers->tm6ca = *(unsigned16 *)source;
964       }
965     else if ( timer_nr == TM6CB )
966       {
967         timers->tm6cb = *(unsigned16 *)source;
968       }
969     else
970       {
971         hw_abort(me, "bad read size for timer 6 mode A/B register");
972       }
973     break;
974
975   default:
976     hw_abort(me, "bad read size for timer 6 register");
977   }
978       
979 }
980
981
982 static unsigned
983 mn103tim_io_write_buffer (struct hw *me,
984                           const void *source,
985                           int space,
986                           unsigned_word base,
987                           unsigned nr_bytes)
988 {
989   struct mn103tim *timers = hw_data (me);
990   enum timer_register_types timer_reg;
991
992   HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
993              (int) nr_bytes, *(unsigned32 *)source));
994
995   timer_reg = decode_addr (me, timers, base);
996
997   /* It can be either a mode register, a base register, a binary counter, */
998   /* or a special timer 6 register.  Check in that order. */
999   if ( timer_reg <= LAST_MODE_REG )
1000     {
1001       if ( timer_reg == 6 ) 
1002         {
1003           write_tm6md(me, timers, base, source, nr_bytes);
1004         }
1005       else
1006         {
1007           write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1008                          source, nr_bytes);
1009         }
1010     }
1011   else if ( timer_reg <= LAST_BASE_REG )
1012     {
1013       write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1014     }
1015   else if ( timer_reg <= LAST_COUNTER )
1016     {
1017       hw_abort(me, "cannot write to counter");
1018     }
1019   else if ( timer_reg <= LAST_TIMER_REG )
1020     {
1021       write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1022     }
1023   else
1024     {
1025       hw_abort(me, "invalid reg type");
1026     }
1027
1028   return nr_bytes;
1029 }     
1030
1031
1032 const struct hw_descriptor dv_mn103tim_descriptor[] = {
1033   { "mn103tim", mn103tim_finish, },
1034   { NULL },
1035 };