OSDN Git Service

Updated copyright notices for most files.
[pf3gnuchains/pf3gnuchains3x.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 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 3 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, see <http://www.gnu.org/licenses/>.
18     
19     */
20
21 #include "sim-main.h"
22 #include "hw-main.h"
23 #include "sim-assert.h"
24
25 /* DEVICE
26
27    
28    mn103tim - mn103002 timers (8 and 16 bit)
29
30    
31    DESCRIPTION
32    
33    Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide.
34
35
36    PROPERTIES   
37
38    reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size>
39
40
41    BUGS
42
43    */
44
45
46 /* The timers' register address blocks */
47
48 struct mn103tim_block {
49   unsigned_word base;
50   unsigned_word bound;
51 };
52
53 enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
54
55 enum timer_register_types {
56   FIRST_MODE_REG = 0,
57   TM0MD = FIRST_MODE_REG,
58   TM1MD,
59   TM2MD,
60   TM3MD,
61   TM4MD,
62   TM5MD,
63   TM6MD,
64   LAST_MODE_REG = TM6MD,
65   FIRST_BASE_REG,
66   TM0BR = FIRST_BASE_REG,
67   TM1BR,
68   TM2BR,
69   TM3BR,
70   TM4BR,
71   TM5BR,
72   LAST_BASE_REG = TM5BR,
73   FIRST_COUNTER,
74   TM0BC = FIRST_COUNTER,
75   TM1BC,
76   TM2BC,
77   TM3BC,
78   TM4BC,
79   TM5BC,
80   TM6BC,
81   LAST_COUNTER = TM6BC,
82   TM6MDA,
83   TM6MDB,
84   TM6CA,
85   TM6CB,
86   LAST_TIMER_REG = TM6BC,
87 };
88
89
90 /* Don't include timer 6 because it's handled specially. */
91 #define NR_8BIT_TIMERS 4
92 #define NR_16BIT_TIMERS 2
93 #define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
94 #define NR_TIMERS 7
95
96 typedef struct _mn10300_timer_regs {
97   unsigned32 base;
98   unsigned8  mode;
99 } mn10300_timer_regs;
100
101 typedef struct _mn10300_timer {
102   unsigned32 div_ratio, start;
103   struct hw_event *event;
104 } mn10300_timer;
105
106
107 struct mn103tim {
108   struct mn103tim_block block[NR_TIMER_BLOCKS];
109   mn10300_timer_regs reg[NR_REG_TIMERS];
110   mn10300_timer timer[NR_TIMERS];
111
112   /* treat timer 6 registers specially. */
113   unsigned16   tm6md0, tm6md1, tm6bc, tm6ca, tm6cb; 
114   unsigned8  tm6mda, tm6mdb;  /* compare/capture mode regs for timer 6 */
115 };
116
117 /* output port ID's */
118
119 /* for mn103002 */
120 enum {
121   TIMER0_UFLOW,
122   TIMER1_UFLOW,
123   TIMER2_UFLOW,
124   TIMER3_UFLOW,
125   TIMER4_UFLOW,
126   TIMER5_UFLOW,
127   TIMER6_UFLOW,
128   TIMER6_CMPA,
129   TIMER6_CMPB,
130 };
131
132
133 static const struct hw_port_descriptor mn103tim_ports[] = {
134
135   { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
136   { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
137   { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
138   { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
139   { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
140   { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
141
142   { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
143   { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
144   { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
145
146   { NULL, },
147 };
148
149 #define bits2to5_mask 0x3c
150 #define bits0to2_mask 0x07
151 #define load_mask     0x40
152 #define count_mask    0x80
153 #define count_and_load_mask (load_mask | count_mask)
154 #define clock_mask    0x03
155 #define clk_ioclk    0x00
156 #define clk_cascaded 0x03
157
158
159 /* Finish off the partially created hw device.  Attach our local
160    callbacks.  Wire up our port names etc */
161
162 static hw_io_read_buffer_method mn103tim_io_read_buffer;
163 static hw_io_write_buffer_method mn103tim_io_write_buffer;
164
165 static void
166 attach_mn103tim_regs (struct hw *me,
167                       struct mn103tim *timers)
168 {
169   int i;
170   if (hw_find_property (me, "reg") == NULL)
171     hw_abort (me, "Missing \"reg\" property");
172   for (i = 0; i < NR_TIMER_BLOCKS; i++)
173     {
174       unsigned_word attach_address;
175       int attach_space;
176       unsigned attach_size;
177       reg_property_spec reg;
178       if (!hw_find_reg_array_property (me, "reg", i, &reg))
179         hw_abort (me, "\"reg\" property must contain three addr/size entries");
180       hw_unit_address_to_attach_address (hw_parent (me),
181                                          &reg.address,
182                                          &attach_space,
183                                          &attach_address,
184                                          me);
185       timers->block[i].base = attach_address;
186       hw_unit_size_to_attach_size (hw_parent (me),
187                                    &reg.size,
188                                    &attach_size, me);
189       timers->block[i].bound = attach_address + (attach_size - 1);
190       hw_attach_address (hw_parent (me),
191                          0,
192                          attach_space, attach_address, attach_size,
193                          me);
194     }
195 }
196
197 static void
198 mn103tim_finish (struct hw *me)
199 {
200   struct mn103tim *timers;
201   int i;
202
203   timers = HW_ZALLOC (me, struct mn103tim);
204   set_hw_data (me, timers);
205   set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
206   set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
207   set_hw_ports (me, mn103tim_ports);
208
209   /* Attach ourself to our parent bus */
210   attach_mn103tim_regs (me, timers);
211
212   /* Initialize the timers */
213   for ( i=0; i < NR_REG_TIMERS; ++i )
214     {
215       timers->reg[i].mode = 0x00;
216       timers->reg[i].base = 0;
217     }
218   for ( i=0; i < NR_TIMERS; ++i )
219     {
220       timers->timer[i].event = NULL;
221       timers->timer[i].div_ratio = 0;
222       timers->timer[i].start = 0;
223     }
224   timers->tm6md0 = 0x00;
225   timers->tm6md1 = 0x00;
226   timers->tm6bc = 0x0000;
227   timers->tm6ca = 0x0000;
228   timers->tm6cb = 0x0000;
229   timers->tm6mda = 0x00;
230   timers->tm6mdb = 0x00;
231 }
232
233
234
235 /* read and write */
236
237 static int
238 decode_addr (struct hw *me,
239              struct mn103tim *timers,
240              unsigned_word address)
241 {
242   unsigned_word offset;
243   offset = address - timers->block[0].base;
244
245   switch (offset)
246     {
247     case 0x00: return TM0MD;
248     case 0x01: return TM1MD;
249     case 0x02: return TM2MD;
250     case 0x03: return TM3MD;
251     case 0x10: return TM0BR;
252     case 0x11: return TM1BR;
253     case 0x12: return TM2BR;
254     case 0x13: return TM3BR;
255     case 0x20: return TM0BC;
256     case 0x21: return TM1BC;
257     case 0x22: return TM2BC;
258     case 0x23: return TM3BC;
259     case 0x80: return TM4MD;
260     case 0x82: return TM5MD;
261     case 0x84: /* fall through */
262     case 0x85: return TM6MD;
263     case 0x90: return TM4BR;
264     case 0x92: return TM5BR;
265     case 0xa0: return TM4BC;
266     case 0xa2: return TM5BC;
267     case 0xa4: return TM6BC;
268     case 0xb4: return TM6MDA;
269     case 0xb5: return TM6MDB;
270     case 0xc4: return TM6CA;
271     case 0xd4: return TM6CB;
272     default: 
273       {
274         hw_abort (me, "bad address");
275         return -1;
276       }
277     }
278 }
279
280 static void
281 read_mode_reg (struct hw *me,
282                struct mn103tim *timers,
283                int timer_nr,
284                void *dest,
285                unsigned nr_bytes)
286 {
287   unsigned16 val16;
288   unsigned32 val32;
289
290   switch ( nr_bytes )
291     {
292     case 1:
293       /* Accessing 1 byte is ok for all mode registers. */
294       if ( timer_nr == 6 )
295         {
296           *(unsigned8*)dest = timers->tm6md0;
297         }
298       else
299         {
300           *(unsigned8*)dest = timers->reg[timer_nr].mode;
301         }
302       break;
303
304     case 2:
305       if ( timer_nr == 6 )
306         {
307           *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
308         }
309       else if ( timer_nr == 0 || timer_nr == 2 )
310         {
311           val16 = (timers->reg[timer_nr].mode << 8)
312             | timers->reg[timer_nr+1].mode;
313           *(unsigned16*)dest = val16;
314         }
315       else
316         {
317           hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
318         }
319       break;
320
321     case 4:
322       if ( timer_nr == 0 )
323         {
324           val32 = (timers->reg[0].mode << 24 )
325             | (timers->reg[1].mode << 16)
326             | (timers->reg[2].mode << 8)
327             | timers->reg[3].mode;
328           *(unsigned32*)dest = val32;
329         }
330       else
331         {
332           hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
333         }
334       break;
335
336     default:
337       hw_abort (me, "bad read size of %d bytes to TM%dMD.",
338                 nr_bytes, timer_nr);
339     }
340 }
341
342
343 static void
344 read_base_reg (struct hw *me,
345                struct mn103tim *timers,
346                int timer_nr,
347                void *dest,
348                unsigned  nr_bytes)
349 {
350   unsigned16 val16;
351   unsigned32 val32;
352
353   /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
354   switch ( nr_bytes )
355     {
356     case 1:
357       /* Reading 1 byte is ok for all registers. */
358       if ( timer_nr < NR_8BIT_TIMERS )
359         {
360           *(unsigned8*)dest = timers->reg[timer_nr].base;
361         }
362       break;
363
364     case 2:
365       if ( timer_nr == 1 || timer_nr == 3 )
366         {
367           hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
368         }
369       else
370         {
371           if ( timer_nr < NR_8BIT_TIMERS )
372             {
373               val16 = (timers->reg[timer_nr].base<<8)
374                 | timers->reg[timer_nr+1].base;
375             }
376           else 
377             {
378               val16 = timers->reg[timer_nr].base;
379             }
380           *(unsigned16*)dest = val16;
381         }
382       break;
383
384     case 4:
385       if ( timer_nr == 0 )
386         {
387           val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
388             | (timers->reg[2].base << 8) | timers->reg[3].base;
389           *(unsigned32*)dest = val32;
390         }
391       else if ( timer_nr == 4 ) 
392         {
393           val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
394           *(unsigned32*)dest = val32;
395         }
396       else
397         {
398           hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
399         }
400       break;
401
402     default:
403       hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
404                 nr_bytes, timer_nr); 
405     }
406 }
407
408
409 static void
410 read_counter (struct hw *me,
411               struct mn103tim *timers,
412               int timer_nr,
413               void *dest,
414               unsigned  nr_bytes)
415 {
416   unsigned32 val;
417
418   if ( NULL == timers->timer[timer_nr].event )
419     {
420       /* Timer is not counting, use value in base register. */
421       if ( timer_nr == 6 )
422         {
423           val = 0;  /* timer 6 is an up counter */
424         }
425       else
426         {
427           val = timers->reg[timer_nr].base;
428         }
429     }
430   else
431     {
432       if ( timer_nr == 6 )  /* timer 6 is an up counter. */
433         {
434           val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
435         }
436       else
437         {
438           /* ticks left = start time + div ratio - curr time */
439           /* Cannot use base register because it can be written during counting and it
440              doesn't affect counter until underflow occurs. */
441           
442           val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
443             - hw_event_queue_time(me);
444         }
445     }
446
447   switch (nr_bytes) {
448   case 1:
449     *(unsigned8 *)dest = val;
450     break;
451     
452   case 2:
453     *(unsigned16 *)dest = val;
454     break;
455
456   case 4:
457     *(unsigned32 *)dest = val;
458     break;
459
460   default:
461     hw_abort(me, "bad read size for reading counter");
462   }
463       
464 }
465
466
467 static void
468 read_special_timer6_reg (struct hw *me,
469                          struct mn103tim *timers,
470                          int timer_nr,
471                          void *dest,
472                          unsigned  nr_bytes)
473 {
474   unsigned32 val;
475
476   switch (nr_bytes) {
477   case 1:
478     {
479       switch ( timer_nr ) {
480       case TM6MDA:
481         *(unsigned8 *)dest = timers->tm6mda;
482         break;
483     
484       case TM6MDB:
485         *(unsigned8 *)dest = timers->tm6mdb;
486         break;
487     
488       case TM6CA:
489         *(unsigned8 *)dest = timers->tm6ca;
490         break;
491     
492       case TM6CB:
493         *(unsigned8 *)dest = timers->tm6cb;
494         break;
495       
496       default:
497         break;
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   long timer_nr = (long) 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   long timer_nr = (long) 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                 long 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%ldMD.", nr_bytes,
719                 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 %ld 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   long 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 };