This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / mn10300 / dv-mn103tim.c
1 /*  This file is part of the program GDB, the GNU debugger.
2     
3     Copyright (C) 1998 Free Software Foundation, Inc.
4     Contributed by Cygnus Solutions.
5     
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10     
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15     
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     
20     */
21
22 #include "sim-main.h"
23 #include "hw-main.h"
24
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 };
87
88
89 /* Don't include timer 6 because it's handled specially. */
90 #define NR_8BIT_TIMERS 4
91 #define NR_16BIT_TIMERS 2
92 #define NR_TIMERS 6
93
94 typedef struct _mn10300_timer {
95   unsigned32 div_ratio, start, base;
96   unsigned8  mode;
97   struct hw_event *event;
98 } mn10300_timer;
99
100
101 struct mn103tim {
102   struct mn103tim_block block[NR_TIMER_BLOCKS];
103   mn10300_timer timer[NR_TIMERS];
104
105   /* treat timer 6 registers specially. */
106   unsigned16   tm6md, tm6bc, tm6mca, tm6mcb; 
107   unsigned8  tm6mda, tm6mdb;  /* compare/capture mode regs for timer 6 */
108   struct hw_event *event6;
109 };
110
111 /* output port ID's */
112
113 /* for mn103002 */
114 enum {
115   TIMER0_UFLOW,
116   TIMER1_UFLOW,
117   TIMER2_UFLOW,
118   TIMER3_UFLOW,
119   TIMER4_UFLOW,
120   TIMER5_UFLOW,
121   TIMER6_UFLOW,
122   TIMER6_CMPA,
123   TIMER6_CMPB,
124 };
125
126
127 static const struct hw_port_descriptor mn103tim_ports[] = {
128
129   { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
130   { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
131   { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
132   { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
133   { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
134   { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
135
136   { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
137   { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
138   { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
139
140   { NULL, },
141 };
142
143 #define bits2to5_mask 0x3c
144 #define load_mask     0x40
145 #define count_mask    0x80
146 #define count_and_load_mask (load_mask | count_mask)
147 #define clock_mask    0x03
148 #define clk_ioclk    0x00
149 #define clk_cascaded 0x03
150
151
152 /* Finish off the partially created hw device.  Attach our local
153    callbacks.  Wire up our port names etc */
154
155 static hw_io_read_buffer_method mn103tim_io_read_buffer;
156 static hw_io_write_buffer_method mn103tim_io_write_buffer;
157
158 static void
159 attach_mn103tim_regs (struct hw *me,
160                       struct mn103tim *timers)
161 {
162   int i;
163   if (hw_find_property (me, "reg") == NULL)
164     hw_abort (me, "Missing \"reg\" property");
165   for (i = 0; i < NR_TIMER_BLOCKS; i++)
166     {
167       unsigned_word attach_address;
168       int attach_space;
169       unsigned attach_size;
170       reg_property_spec reg;
171       if (!hw_find_reg_array_property (me, "reg", i, &reg))
172         hw_abort (me, "\"reg\" property must contain three addr/size entries");
173       hw_unit_address_to_attach_address (hw_parent (me),
174                                          &reg.address,
175                                          &attach_space,
176                                          &attach_address,
177                                          me);
178       timers->block[i].base = attach_address;
179       hw_unit_size_to_attach_size (hw_parent (me),
180                                    &reg.size,
181                                    &attach_size, me);
182       timers->block[i].bound = attach_address + (attach_size - 1);
183       hw_attach_address (hw_parent (me),
184                          0,
185                          attach_space, attach_address, attach_size,
186                          me);
187     }
188 }
189
190 static void
191 mn103tim_finish (struct hw *me)
192 {
193   struct mn103tim *timers;
194   int i;
195
196   timers = HW_ZALLOC (me, struct mn103tim);
197   set_hw_data (me, timers);
198   set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
199   set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
200   set_hw_ports (me, mn103tim_ports);
201
202   /* Attach ourself to our parent bus */
203   attach_mn103tim_regs (me, timers);
204
205   /* Initialize the timers */
206   for ( i=0; i < NR_TIMERS; ++i )
207     {
208       timers->timer[i].event = NULL;
209       timers->timer[i].mode = 0x00;
210       timers->timer[i].base = 0;
211       timers->timer[i].div_ratio = 0;
212       timers->timer[i].start = 0;
213     }
214   timers->tm6md = 0x0000;
215   timers->tm6bc = 0x0000;
216   timers->tm6mca = 0x0000;
217   timers->tm6mcb = 0x0000;
218   timers->tm6mda = 0x00;
219   timers->tm6mdb = 0x00;
220 }
221
222
223
224 /* read and write */
225
226 static int
227 decode_addr (struct hw *me,
228              struct mn103tim *timers,
229              unsigned_word address)
230 {
231   unsigned_word offset;
232   offset = address - timers->block[0].base;
233
234   switch (offset)
235     {
236     case 0x00: return TM0MD;
237     case 0x01: return TM1MD;
238     case 0x02: return TM2MD;
239     case 0x03: return TM3MD;
240     case 0x10: return TM0BR;
241     case 0x11: return TM1BR;
242     case 0x12: return TM2BR;
243     case 0x13: return TM3BR;
244     case 0x20: return TM0BC;
245     case 0x21: return TM1BC;
246     case 0x22: return TM2BC;
247     case 0x23: return TM3BC;
248     case 0x80: return TM4MD;
249     case 0x82: return TM5MD;
250     case 0x84: return TM6MD;
251     case 0x90: return TM4BR;
252     case 0x92: return TM5BR;
253     case 0xa0: return TM4BC;
254     case 0xa2: return TM5BC;
255     case 0xa4: return TM6BC;
256     case 0xb4: return TM6MDA;
257     case 0xb5: return TM6MDB;
258     case 0xc4: return TM6CA;
259     case 0xd4: return TM6CB;
260     default: 
261       {
262         hw_abort (me, "bad address");
263         return -1;
264       }
265     }
266 }
267
268 static void
269 read_mode_reg (struct hw *me,
270                struct mn103tim *timers,
271                int timer_nr,
272                void *dest,
273                unsigned nr_bytes)
274 {
275   unsigned16 val16;
276   unsigned32 val32;
277
278   switch ( nr_bytes )
279     {
280     case 1:
281       /* Accessing 1 byte is ok for all mode registers. */
282       *(unsigned8*)dest = timers->timer[timer_nr].mode;
283       break;
284
285     case 2:
286       if ( timer_nr == 6 )
287         {
288           *(unsigned16 *)dest = timers->tm6md;
289         }
290       else if ( timer_nr == 0 || timer_nr == 2 )
291         {
292           val16 = (timers->timer[timer_nr].mode << 8)
293             | timers->timer[timer_nr+1].mode;
294           *(unsigned16*)dest = val16;
295         }
296       else
297         {
298           hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
299         }
300       break;
301
302     case 4:
303       if ( timer_nr == 0 )
304         {
305           val32 = (timers->timer[0].mode << 24 )
306             | (timers->timer[1].mode << 16)
307             | (timers->timer[2].mode << 8)
308             | timers->timer[3].mode;
309           *(unsigned32*)dest = val32;
310         }
311       else
312         {
313           hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
314         }
315       break;
316
317     default:
318       hw_abort (me, "bad read size of %d bytes to TM%dMD.",
319                 nr_bytes, timer_nr);
320     }
321 }
322
323
324 static void
325 read_base_reg (struct hw *me,
326                struct mn103tim *timers,
327                int timer_nr,
328                void *dest,
329                unsigned  nr_bytes)
330 {
331   unsigned16 val16;
332   unsigned32 val32;
333
334   /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
335   switch ( nr_bytes )
336     {
337     case 1:
338       /* Reading 1 byte is ok for all registers. */
339       if ( timer_nr < NR_8BIT_TIMERS )
340         {
341           *(unsigned8*)dest = timers->timer[timer_nr].base;
342         }
343       break;
344
345     case 2:
346       if ( timer_nr == 1 || timer_nr == 3 )
347         {
348           hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
349         }
350       else
351         {
352           if ( timer_nr < NR_8BIT_TIMERS )
353             {
354               val16 = (timers->timer[timer_nr].base<<8)
355                 | timers->timer[timer_nr+1].base;
356             }
357           else 
358             {
359               val16 = timers->timer[timer_nr].base;
360             }
361           *(unsigned16*)dest = val16;
362         }
363       break;
364
365     case 4:
366       if ( timer_nr == 0 )
367         {
368           val32 = (timers->timer[0].base << 24) | (timers->timer[1].base << 16)
369             | (timers->timer[2].base << 8) | timers->timer[3].base;
370           *(unsigned32*)dest = val32;
371         }
372       else if ( timer_nr == 4 ) 
373         {
374           val32 = (timers->timer[4].base << 16) | timers->timer[5].base;
375           *(unsigned32*)dest = val32;
376         }
377       else
378         {
379           hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
380         }
381       break;
382
383     default:
384       hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
385                 nr_bytes, timer_nr); 
386     }
387 }
388
389
390 static void
391 read_counter (struct hw *me,
392               struct mn103tim *timers,
393               int timer_nr,
394               void *dest,
395               unsigned  nr_bytes)
396 {
397   unsigned32 val;
398
399   if ( NULL == timers->timer[timer_nr].event )
400     {
401       /* Timer is not counting, use value in base register. */
402       val = timers->timer[timer_nr].base;
403     }
404   else
405     {
406       /* ticks left = start time + div ratio - curr time */
407       /* Cannot use base register because it can be written during counting and it
408          doesn't affect counter until underflow occurs. */
409
410       val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
411         - hw_event_queue_time(me);
412     }
413
414   switch (nr_bytes) {
415   case 1:
416     *(unsigned8 *)dest = val;
417     break;
418     
419   case 2:
420     *(unsigned16 *)dest = val;
421     break;
422
423   case 4:
424     *(unsigned32 *)dest = val;
425     break;
426
427   default:
428     hw_abort(me, "bad read size for reading counter");
429   }
430       
431 }
432
433
434 static unsigned
435 mn103tim_io_read_buffer (struct hw *me,
436                          void *dest,
437                          int space,
438                          unsigned_word base,
439                          unsigned nr_bytes)
440 {
441   struct mn103tim *timers = hw_data (me);
442   enum timer_register_types timer_reg;
443
444   HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
445
446   timer_reg = decode_addr (me, timers, base);
447
448   /* It can be either a mode register, a base register or a binary counter. */
449   /* Check in that order. */
450   if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
451     {
452       read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
453     }
454   else if ( timer_reg <= LAST_BASE_REG )
455     {
456       read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
457     }
458   else if ( timer_reg <= LAST_COUNTER )
459     {
460       read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
461     }
462   else
463     {
464       hw_abort(me, "invalid timer register address.");
465     }
466
467   return nr_bytes;
468 }     
469
470
471 static void
472 do_counter_event (struct hw *me,
473                   void *data)
474 {
475   struct mn103tim *timers = hw_data(me);
476   int timer_nr = (int) data;
477
478   /* Check if counting is still enabled. */
479   if ( (timers->timer[timer_nr].mode & count_mask) != 0 )
480     {
481       /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
482       hw_port_event (me, timer_nr /*uflow_port[timer_nr]*/, 1 /* level */);
483
484       /* Schedule next timeout.  */
485
486       timers->timer[timer_nr].start = hw_event_queue_time(me);
487       /* FIX: Check if div_ ratio has changed and if it's now 0. */
488       timers->timer[timer_nr].event
489         = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
490                                    do_counter_event, (void *)timer_nr);
491     }
492
493 }
494
495 static void
496 write_base_reg (struct hw *me,
497                 struct mn103tim *timers,
498                 int timer_nr,
499                 const void *source,
500                 unsigned  nr_bytes)
501 {
502   unsigned i;
503   const unsigned8 *buf8 = source;
504   const unsigned16 *buf16 = source;
505   unsigned8 mode_val;
506
507   /* If TMnCNE == 0 (counting is off),  writing to the base register
508      (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
509      Else, the TMnBC is reloaded with the value from TMnBR when
510      underflow occurs.  Since the counter register is not explicitly
511      maintained, this functionality is handled in read_counter. */
512
513   mode_val = timers->timer[timer_nr].mode;
514
515   /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
516   switch ( nr_bytes )
517     {
518     case 1:
519       /* Storing 1 byte is ok for all registers. */
520       timers->timer[timer_nr].base = buf8[0];
521       break;
522
523     case 2:
524       if ( timer_nr == 1 || timer_nr == 3 )
525         {
526           hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
527         }
528       else
529         {
530           if ( timer_nr < NR_8BIT_TIMERS )
531             {
532               timers->timer[timer_nr].base = buf8[0];
533               timers->timer[timer_nr+1].base = buf8[1];
534             }
535           else 
536             {
537               timers->timer[timer_nr].base = buf16[0];
538             }
539         }
540       break;
541
542     case 4:
543       if ( timer_nr == 0 )
544         {
545           ASSERT(0);
546           timers->timer[0].base = buf8[0];
547           timers->timer[1].base = buf8[1];
548           timers->timer[2].base = buf8[2];
549           timers->timer[3].base = buf8[3];
550         }
551       else if ( timer_nr == 4 )
552         {
553           timers->timer[4].base = buf16[0];
554           timers->timer[5].base = buf16[1];
555         }
556       else
557         {
558           hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
559         }
560       break;
561
562     default:
563       hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
564                 nr_bytes, timer_nr);
565     }
566      
567 }
568
569 static void
570 write_8bit_mode_reg (struct hw *me,
571                      struct mn103tim *timers,
572                      int timer_nr,
573                      const void *source,
574                      unsigned nr_bytes)
575      /* for timers 0 to 3 */
576 {
577   unsigned i;
578   unsigned8 mode_val, next_mode_val;
579   unsigned32 div_ratio;
580
581   if ( nr_bytes != 1 )
582     {
583       hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
584     }
585
586   mode_val = *(unsigned8 *)source;
587   timers->timer[timer_nr].mode = mode_val;
588       
589   if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
590     {
591       hw_abort(me, "Cannot load base reg and start counting simultaneously.");
592     }
593   if ( ( mode_val & bits2to5_mask ) != 0 )
594     {
595       hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
596     }
597       
598   if ( mode_val & count_mask )
599     {
600       /* - de-schedule any previous event. */
601       /* - add new event to queue to start counting. */
602       /* - assert that counter == base reg? */
603
604       /* For cascaded timers, */
605       if ( (mode_val & clock_mask) == clk_cascaded )
606         {
607           if ( timer_nr == 0 )
608             {
609               hw_abort(me, "Timer 0 cannot be cascaded.");
610             }
611         }
612       else
613         {
614           div_ratio = timers->timer[timer_nr].base;
615
616           /* Check for cascading. */
617           next_mode_val = timers->timer[timer_nr+1].mode;
618           if ( ( next_mode_val & clock_mask ) == clk_cascaded )
619             {
620               /* Check that CNE is on. */
621               if ( ( next_mode_val & count_mask ) == 0 ) 
622                 {
623                   hw_abort (me, "cascaded timer not ready for counting");
624                 }
625               ASSERT(timers->timer[timer_nr+1].event == NULL);
626               ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
627               div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 8);
628             }
629
630           timers->timer[timer_nr].div_ratio = div_ratio;
631
632           if ( NULL != timers->timer[timer_nr].event )
633             {
634               hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
635               timers->timer[timer_nr].event = NULL;
636             }
637
638           if ( div_ratio > 0 )
639             {
640               /* Set start time. */
641               timers->timer[timer_nr].start = hw_event_queue_time(me);
642               
643               timers->timer[timer_nr].event
644                 = hw_event_queue_schedule(me, div_ratio,
645                                           do_counter_event,
646                                           (void *)(timer_nr)); 
647             }
648         }
649     }
650   else
651     {
652       /* Turn off counting */
653       if ( NULL != timers->timer[timer_nr].event )
654         {
655           ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
656           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
657           timers->timer[timer_nr].event = NULL;
658         }
659       else
660         {
661           if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
662             {
663               ASSERT(timers->timer[timer_nr].event == NULL);
664             }
665         }
666       
667     }
668
669 }
670
671 static void
672 write_16bit_mode_reg (struct hw *me,
673                       struct mn103tim *timers,
674                       int timer_nr,
675                       const void *source,
676                       unsigned nr_bytes)
677      /* for timers 4 and 5, not 6 */
678 {
679   unsigned i;
680   unsigned8 mode_val, next_mode_val;
681   unsigned32 div_ratio;
682
683   if ( nr_bytes != 1 )
684     {
685       hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
686     }
687
688   mode_val = *(unsigned8 *)source;
689   timers->timer[timer_nr].mode = mode_val;
690       
691   if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
692     {
693       hw_abort(me, "Cannot load base reg and start counting simultaneously.");
694     }
695   if ( ( mode_val & bits2to5_mask ) != 0 )
696     {
697       hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
698     }
699
700      
701   if ( mode_val & count_mask )
702     {
703       /* - de-schedule any previous event. */
704       /* - add new event to queue to start counting. */
705       /* - assert that counter == base reg? */
706
707       /* For cascaded timers, */
708       if ( (mode_val & clock_mask) == clk_cascaded )
709         {
710           if ( timer_nr == 4 )
711             {
712               hw_abort(me, "Timer 4 cannot be cascaded.");
713             }
714         }
715       else
716         {
717           div_ratio = timers->timer[timer_nr].base;
718           
719           /* Check for cascading. */
720           next_mode_val = timers->timer[timer_nr+1].mode;
721           if ( ( next_mode_val & clock_mask ) == clk_cascaded )
722             {
723               /* Check that CNE is on. */
724               if ( ( next_mode_val & count_mask ) == 0 ) 
725                 {
726                   hw_abort (me, "cascaded timer not ready for counting");
727                 }
728               ASSERT(timers->timer[timer_nr+1].event == NULL);
729               ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
730               div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 16);
731             }
732
733           timers->timer[timer_nr].div_ratio = div_ratio;
734       
735           if ( NULL != timers->timer[timer_nr].event )
736             {
737               hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
738               timers->timer[timer_nr].event = NULL;
739             }
740
741           if ( div_ratio > 0 )
742             {
743               /* Set start time. */
744               timers->timer[timer_nr].start = hw_event_queue_time(me);
745               
746               timers->timer[timer_nr].event
747                 = hw_event_queue_schedule(me, div_ratio, do_counter_event,
748                                           (void *)(timer_nr));
749             }
750         }
751     }
752   else
753     {
754       /* Turn off counting */
755       if ( NULL != timers->timer[timer_nr].event )
756         {
757           ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
758           hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
759           timers->timer[timer_nr].event = NULL;
760         }
761       else
762         {
763           if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
764             {
765               ASSERT(timers->timer[timer_nr].event == NULL);
766             }
767         }
768       
769     }
770
771 }
772
773 static unsigned
774 mn103tim_io_write_buffer (struct hw *me,
775                           const void *source,
776                           int space,
777                           unsigned_word base,
778                           unsigned nr_bytes)
779 {
780   struct mn103tim *timers = hw_data (me);
781   enum timer_register_types timer_reg;
782
783   HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
784              (int) nr_bytes, *(unsigned32 *)source));
785
786   timer_reg = decode_addr (me, timers, base);
787
788   /* It can be either a mode register, a base register or a binary counter. */
789   /* Check in that order. */
790   if ( timer_reg <= LAST_MODE_REG )
791     {
792       if ( timer_reg > 3 )
793         {
794           write_16bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
795                                source, nr_bytes);
796         }
797       else
798         {
799           write_8bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
800                                source, nr_bytes);
801         }
802     }
803   else if ( timer_reg <= LAST_BASE_REG )
804     {
805       write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
806     }
807   else if ( timer_reg <= LAST_COUNTER )
808     {
809       hw_abort(me, "cannot write to counter");
810     }
811   else
812     {
813       hw_abort(me, "invalid reg type");
814     }
815
816   return nr_bytes;
817 }     
818
819
820 const struct hw_descriptor dv_mn103tim_descriptor[] = {
821   { "mn103tim", mn103tim_finish, },
822   { NULL },
823 };