dv-mn103tim.c revision 1.1.1.1
1/*  This file is part of the program GDB, the GNU debugger.
2
3    Copyright (C) 1998, 2003, 2007, 2008, 2009, 2010, 2011
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
49struct mn103tim_block {
50  unsigned_word base;
51  unsigned_word bound;
52};
53
54enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
55
56enum 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
97typedef struct _mn10300_timer_regs {
98  unsigned32 base;
99  unsigned8  mode;
100} mn10300_timer_regs;
101
102typedef struct _mn10300_timer {
103  unsigned32 div_ratio, start;
104  struct hw_event *event;
105} mn10300_timer;
106
107
108struct 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 */
121enum {
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
134static 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
163static hw_io_read_buffer_method mn103tim_io_read_buffer;
164static hw_io_write_buffer_method mn103tim_io_write_buffer;
165
166static void
167attach_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
198static void
199mn103tim_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
238static int
239decode_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
281static void
282read_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
344static void
345read_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
410static void
411read_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
468static void
469read_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
525static unsigned
526mn103tim_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
566static void
567do_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
607static void
608do_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
635static void
636write_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
705static void
706write_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
834static void
835write_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
925static void
926write_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
982static unsigned
983mn103tim_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
1032const struct hw_descriptor dv_mn103tim_descriptor[] = {
1033  { "mn103tim", mn103tim_finish, },
1034  { NULL },
1035};
1036