dv-mn103tim.c revision 1.1.1.9
1130803Smarcel/*  This file is part of the program GDB, the GNU debugger.
2130803Smarcel
3130803Smarcel    Copyright (C) 1998-2023 Free Software Foundation, Inc.
4130803Smarcel    Contributed by Cygnus Solutions.
5130803Smarcel
6130803Smarcel    This program is free software; you can redistribute it and/or modify
7130803Smarcel    it under the terms of the GNU General Public License as published by
8130803Smarcel    the Free Software Foundation; either version 3 of the License, or
9130803Smarcel    (at your option) any later version.
10130803Smarcel
11130803Smarcel    This program is distributed in the hope that it will be useful,
12130803Smarcel    but WITHOUT ANY WARRANTY; without even the implied warranty of
13130803Smarcel    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14130803Smarcel    GNU General Public License for more details.
15130803Smarcel
16130803Smarcel    You should have received a copy of the GNU General Public License
17130803Smarcel    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18130803Smarcel
19130803Smarcel    */
20130803Smarcel
21130803Smarcel/* This must come before any other includes.  */
22130803Smarcel#include "defs.h"
23130803Smarcel
24130803Smarcel#include "sim-main.h"
25130803Smarcel#include "hw-main.h"
26130803Smarcel#include "sim-assert.h"
27130803Smarcel
28130803Smarcel/* DEVICE
29130803Smarcel
30130803Smarcel
31130803Smarcel   mn103tim - mn103002 timers (8 and 16 bit)
32130803Smarcel
33130803Smarcel
34130803Smarcel   DESCRIPTION
35130803Smarcel
36130803Smarcel   Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide.
37130803Smarcel
38130803Smarcel
39130803Smarcel   PROPERTIES
40130803Smarcel
41130803Smarcel   reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size>
42130803Smarcel
43130803Smarcel
44130803Smarcel   BUGS
45130803Smarcel
46130803Smarcel   */
47130803Smarcel
48130803Smarcel
49130803Smarcel/* The timers' register address blocks */
50130803Smarcel
51130803Smarcelstruct mn103tim_block {
52  unsigned_word base;
53  unsigned_word bound;
54};
55
56enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
57
58enum timer_register_types {
59  FIRST_MODE_REG = 0,
60  TM0MD = FIRST_MODE_REG,
61  TM1MD,
62  TM2MD,
63  TM3MD,
64  TM4MD,
65  TM5MD,
66  TM6MD,
67  LAST_MODE_REG = TM6MD,
68  FIRST_BASE_REG,
69  TM0BR = FIRST_BASE_REG,
70  TM1BR,
71  TM2BR,
72  TM3BR,
73  TM4BR,
74  TM5BR,
75  LAST_BASE_REG = TM5BR,
76  FIRST_COUNTER,
77  TM0BC = FIRST_COUNTER,
78  TM1BC,
79  TM2BC,
80  TM3BC,
81  TM4BC,
82  TM5BC,
83  TM6BC,
84  LAST_COUNTER = TM6BC,
85  TM6MDA,
86  TM6MDB,
87  TM6CA,
88  TM6CB,
89  LAST_TIMER_REG = TM6BC,
90};
91
92
93/* Don't include timer 6 because it's handled specially. */
94#define NR_8BIT_TIMERS 4
95#define NR_16BIT_TIMERS 2
96#define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
97#define NR_TIMERS 7
98
99typedef struct _mn10300_timer_regs {
100  uint32_t base;
101  uint8_t  mode;
102} mn10300_timer_regs;
103
104typedef struct _mn10300_timer {
105  uint32_t div_ratio, start;
106  struct hw_event *event;
107} mn10300_timer;
108
109
110struct mn103tim {
111  struct mn103tim_block block[NR_TIMER_BLOCKS];
112  mn10300_timer_regs reg[NR_REG_TIMERS];
113  mn10300_timer timer[NR_TIMERS];
114
115  /* treat timer 6 registers specially. */
116  uint16_t   tm6md0, tm6md1, tm6bc, tm6ca, tm6cb;
117  uint8_t  tm6mda, tm6mdb;  /* compare/capture mode regs for timer 6 */
118};
119
120/* output port ID's */
121
122/* for mn103002 */
123enum {
124  TIMER0_UFLOW,
125  TIMER1_UFLOW,
126  TIMER2_UFLOW,
127  TIMER3_UFLOW,
128  TIMER4_UFLOW,
129  TIMER5_UFLOW,
130  TIMER6_UFLOW,
131  TIMER6_CMPA,
132  TIMER6_CMPB,
133};
134
135
136static const struct hw_port_descriptor mn103tim_ports[] = {
137
138  { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
139  { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
140  { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
141  { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
142  { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
143  { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
144
145  { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
146  { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
147  { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
148
149  { NULL, },
150};
151
152#define bits2to5_mask 0x3c
153#define bits0to2_mask 0x07
154#define load_mask     0x40
155#define count_mask    0x80
156#define count_and_load_mask (load_mask | count_mask)
157#define clock_mask    0x03
158#define clk_ioclk    0x00
159#define clk_cascaded 0x03
160
161
162/* Finish off the partially created hw device.  Attach our local
163   callbacks.  Wire up our port names etc */
164
165static hw_io_read_buffer_method mn103tim_io_read_buffer;
166static hw_io_write_buffer_method mn103tim_io_write_buffer;
167
168static void
169attach_mn103tim_regs (struct hw *me,
170		      struct mn103tim *timers)
171{
172  int i;
173  if (hw_find_property (me, "reg") == NULL)
174    hw_abort (me, "Missing \"reg\" property");
175  for (i = 0; i < NR_TIMER_BLOCKS; i++)
176    {
177      unsigned_word attach_address;
178      int attach_space;
179      unsigned attach_size;
180      reg_property_spec reg;
181      if (!hw_find_reg_array_property (me, "reg", i, &reg))
182	hw_abort (me, "\"reg\" property must contain three addr/size entries");
183      hw_unit_address_to_attach_address (hw_parent (me),
184					 &reg.address,
185					 &attach_space,
186					 &attach_address,
187					 me);
188      timers->block[i].base = attach_address;
189      hw_unit_size_to_attach_size (hw_parent (me),
190				   &reg.size,
191				   &attach_size, me);
192      timers->block[i].bound = attach_address + (attach_size - 1);
193      hw_attach_address (hw_parent (me),
194			 0,
195			 attach_space, attach_address, attach_size,
196			 me);
197    }
198}
199
200static void
201mn103tim_finish (struct hw *me)
202{
203  struct mn103tim *timers;
204  int i;
205
206  timers = HW_ZALLOC (me, struct mn103tim);
207  set_hw_data (me, timers);
208  set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
209  set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
210  set_hw_ports (me, mn103tim_ports);
211
212  /* Attach ourself to our parent bus */
213  attach_mn103tim_regs (me, timers);
214
215  /* Initialize the timers */
216  for ( i=0; i < NR_REG_TIMERS; ++i )
217    {
218      timers->reg[i].mode = 0x00;
219      timers->reg[i].base = 0;
220    }
221  for ( i=0; i < NR_TIMERS; ++i )
222    {
223      timers->timer[i].event = NULL;
224      timers->timer[i].div_ratio = 0;
225      timers->timer[i].start = 0;
226    }
227  timers->tm6md0 = 0x00;
228  timers->tm6md1 = 0x00;
229  timers->tm6bc = 0x0000;
230  timers->tm6ca = 0x0000;
231  timers->tm6cb = 0x0000;
232  timers->tm6mda = 0x00;
233  timers->tm6mdb = 0x00;
234}
235
236
237
238/* read and write */
239
240static int
241decode_addr (struct hw *me,
242	     struct mn103tim *timers,
243	     unsigned_word address)
244{
245  unsigned_word offset;
246  offset = address - timers->block[0].base;
247
248  switch (offset)
249    {
250    case 0x00: return TM0MD;
251    case 0x01: return TM1MD;
252    case 0x02: return TM2MD;
253    case 0x03: return TM3MD;
254    case 0x10: return TM0BR;
255    case 0x11: return TM1BR;
256    case 0x12: return TM2BR;
257    case 0x13: return TM3BR;
258    case 0x20: return TM0BC;
259    case 0x21: return TM1BC;
260    case 0x22: return TM2BC;
261    case 0x23: return TM3BC;
262    case 0x80: return TM4MD;
263    case 0x82: return TM5MD;
264    case 0x84: /* fall through */
265    case 0x85: return TM6MD;
266    case 0x90: return TM4BR;
267    case 0x92: return TM5BR;
268    case 0xa0: return TM4BC;
269    case 0xa2: return TM5BC;
270    case 0xa4: return TM6BC;
271    case 0xb4: return TM6MDA;
272    case 0xb5: return TM6MDB;
273    case 0xc4: return TM6CA;
274    case 0xd4: return TM6CB;
275    default:
276      {
277	hw_abort (me, "bad address");
278	return -1;
279      }
280    }
281}
282
283static void
284read_mode_reg (struct hw *me,
285	       struct mn103tim *timers,
286	       int timer_nr,
287	       void *dest,
288	       unsigned nr_bytes)
289{
290  uint16_t val16;
291  uint32_t val32;
292
293  switch ( nr_bytes )
294    {
295    case 1:
296      /* Accessing 1 byte is ok for all mode registers. */
297      if ( timer_nr == 6 )
298	{
299	  *(uint8_t*)dest = timers->tm6md0;
300	}
301      else
302	{
303	  *(uint8_t*)dest = timers->reg[timer_nr].mode;
304	}
305      break;
306
307    case 2:
308      if ( timer_nr == 6 )
309	{
310	  *(uint16_t *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
311	}
312      else if ( timer_nr == 0 || timer_nr == 2 )
313	{
314	  val16 = (timers->reg[timer_nr].mode << 8)
315	    | timers->reg[timer_nr+1].mode;
316	  *(uint16_t*)dest = val16;
317	}
318      else
319	{
320	  hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
321	}
322      break;
323
324    case 4:
325      if ( timer_nr == 0 )
326	{
327	  val32 = (timers->reg[0].mode << 24 )
328	    | (timers->reg[1].mode << 16)
329	    | (timers->reg[2].mode << 8)
330	    | timers->reg[3].mode;
331	  *(uint32_t*)dest = val32;
332	}
333      else
334	{
335	  hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
336	}
337      break;
338
339    default:
340      hw_abort (me, "bad read size of %d bytes to TM%dMD.",
341		nr_bytes, timer_nr);
342    }
343}
344
345
346static void
347read_base_reg (struct hw *me,
348	       struct mn103tim *timers,
349	       int timer_nr,
350	       void *dest,
351	       unsigned  nr_bytes)
352{
353  uint16_t val16;
354  uint32_t val32;
355
356  /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
357  switch ( nr_bytes )
358    {
359    case 1:
360      /* Reading 1 byte is ok for all registers. */
361      if ( timer_nr < NR_8BIT_TIMERS )
362	{
363	  *(uint8_t*)dest = timers->reg[timer_nr].base;
364	}
365      break;
366
367    case 2:
368      if ( timer_nr == 1 || timer_nr == 3 )
369	{
370	  hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
371	}
372      else
373	{
374	  if ( timer_nr < NR_8BIT_TIMERS )
375	    {
376	      val16 = (timers->reg[timer_nr].base<<8)
377		| timers->reg[timer_nr+1].base;
378	    }
379	  else
380	    {
381	      val16 = timers->reg[timer_nr].base;
382	    }
383	  *(uint16_t*)dest = val16;
384	}
385      break;
386
387    case 4:
388      if ( timer_nr == 0 )
389	{
390	  val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
391	    | (timers->reg[2].base << 8) | timers->reg[3].base;
392	  *(uint32_t*)dest = val32;
393	}
394      else if ( timer_nr == 4 )
395	{
396	  val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
397	  *(uint32_t*)dest = val32;
398	}
399      else
400	{
401	  hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
402	}
403      break;
404
405    default:
406      hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
407		nr_bytes, timer_nr);
408    }
409}
410
411
412static void
413read_counter (struct hw *me,
414	      struct mn103tim *timers,
415	      int timer_nr,
416	      void *dest,
417	      unsigned  nr_bytes)
418{
419  uint32_t val;
420
421  if ( NULL == timers->timer[timer_nr].event )
422    {
423      /* Timer is not counting, use value in base register. */
424      if ( timer_nr == 6 )
425	{
426	  val = 0;  /* timer 6 is an up counter */
427	}
428      else
429	{
430	  val = timers->reg[timer_nr].base;
431	}
432    }
433  else
434    {
435      if ( timer_nr == 6 )  /* timer 6 is an up counter. */
436	{
437	  val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
438	}
439      else
440	{
441	  /* ticks left = start time + div ratio - curr time */
442	  /* Cannot use base register because it can be written during counting and it
443	     doesn't affect counter until underflow occurs. */
444
445	  val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
446	    - hw_event_queue_time(me);
447	}
448    }
449
450  switch (nr_bytes) {
451  case 1:
452    *(uint8_t *)dest = val;
453    break;
454
455  case 2:
456    *(uint16_t *)dest = val;
457    break;
458
459  case 4:
460    *(uint32_t *)dest = val;
461    break;
462
463  default:
464    hw_abort(me, "bad read size for reading counter");
465  }
466
467}
468
469
470static void
471read_special_timer6_reg (struct hw *me,
472			 struct mn103tim *timers,
473			 int timer_nr,
474			 void *dest,
475			 unsigned  nr_bytes)
476{
477  uint32_t val;
478
479  switch (nr_bytes) {
480  case 1:
481    {
482      switch ( timer_nr ) {
483      case TM6MDA:
484	*(uint8_t *)dest = timers->tm6mda;
485	break;
486
487      case TM6MDB:
488	*(uint8_t *)dest = timers->tm6mdb;
489	break;
490
491      case TM6CA:
492	*(uint8_t *)dest = timers->tm6ca;
493	break;
494
495      case TM6CB:
496	*(uint8_t *)dest = timers->tm6cb;
497	break;
498
499      default:
500	break;
501      }
502      break;
503    }
504
505  case 2:
506    if ( timer_nr == TM6CA )
507      {
508	*(uint16_t *)dest = timers->tm6ca;
509      }
510    else if ( timer_nr == TM6CB )
511      {
512	*(uint16_t *)dest = timers->tm6cb;
513      }
514    else
515      {
516	hw_abort(me, "bad read size for timer 6 mode A/B register");
517      }
518    break;
519
520  default:
521    hw_abort(me, "bad read size for timer 6 register");
522  }
523
524}
525
526
527static unsigned
528mn103tim_io_read_buffer (struct hw *me,
529			 void *dest,
530			 int space,
531			 unsigned_word base,
532			 unsigned nr_bytes)
533{
534  struct mn103tim *timers = hw_data (me);
535  enum timer_register_types timer_reg;
536
537  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
538
539  timer_reg = decode_addr (me, timers, base);
540
541  /* It can be either a mode register, a base register, a binary counter, */
542  /* or a special timer 6 register.  Check in that order. */
543  if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
544    {
545      read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
546    }
547  else if ( timer_reg <= LAST_BASE_REG )
548    {
549      read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
550    }
551  else if ( timer_reg <= LAST_COUNTER )
552    {
553      read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
554    }
555  else if ( timer_reg <= LAST_TIMER_REG )
556    {
557      read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
558    }
559  else
560    {
561      hw_abort(me, "invalid timer register address.");
562    }
563
564  return nr_bytes;
565}
566
567
568static void
569do_counter_event (struct hw *me,
570		  void *data)
571{
572  struct mn103tim *timers = hw_data(me);
573  long timer_nr = (uintptr_t) data;
574  int next_timer;
575
576  /* Check if counting is still enabled. */
577  if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
578    {
579      /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
580
581      /* Port event occurs on port of last cascaded timer. */
582      /* This works across timer range from 0 to NR_REG_TIMERS because */
583      /* the first 16 bit timer (timer 4) is not allowed to be set as  */
584      /* a cascading timer. */
585      for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
586	{
587	  if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
588	    {
589	      break;
590	    }
591	}
592      hw_port_event (me, next_timer-1, 1);
593
594      /* Schedule next timeout.  */
595      timers->timer[timer_nr].start = hw_event_queue_time(me);
596      /* FIX: Check if div_ratio has changed and if it's now 0. */
597      timers->timer[timer_nr].event
598	= hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
599				   do_counter_event, (void *)(uintptr_t)timer_nr);
600    }
601  else
602    {
603      timers->timer[timer_nr].event = NULL;
604    }
605
606}
607
608
609static void
610do_counter6_event (struct hw *me,
611		  void *data)
612{
613  struct mn103tim *timers = hw_data(me);
614  long timer_nr = (uintptr_t) data;
615  int next_timer;
616
617  /* Check if counting is still enabled. */
618  if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
619    {
620      /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
621      hw_port_event (me, timer_nr, 1);
622
623      /* Schedule next timeout.  */
624      timers->timer[timer_nr].start = hw_event_queue_time(me);
625      /* FIX: Check if div_ratio has changed and if it's now 0. */
626      timers->timer[timer_nr].event
627	= hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
628				   do_counter6_event, (void *)(uintptr_t)timer_nr);
629    }
630  else
631    {
632      timers->timer[timer_nr].event = NULL;
633    }
634
635}
636
637static void
638write_base_reg (struct hw *me,
639		struct mn103tim *timers,
640		int timer_nr,
641		const void *source,
642		unsigned  nr_bytes)
643{
644  unsigned i;
645  const uint8_t *buf8 = source;
646  const uint16_t *buf16 = source;
647
648  /* If TMnCNE == 0 (counting is off),  writing to the base register
649     (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
650     Else, the TMnBC is reloaded with the value from TMnBR when
651     underflow occurs.  Since the counter register is not explicitly
652     maintained, this functionality is handled in read_counter. */
653
654  /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
655  switch ( nr_bytes )
656    {
657    case 1:
658      /* Storing 1 byte is ok for all registers. */
659      timers->reg[timer_nr].base = buf8[0];
660      break;
661
662    case 2:
663      if ( timer_nr == 1 || timer_nr == 3 )
664	{
665	  hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
666	}
667      else
668	{
669	  if ( timer_nr < NR_8BIT_TIMERS )
670	    {
671	      timers->reg[timer_nr].base = buf8[0];
672	      timers->reg[timer_nr+1].base = buf8[1];
673	    }
674	  else
675	    {
676	      timers->reg[timer_nr].base = buf16[0];
677	    }
678	}
679      break;
680
681    case 4:
682      if ( timer_nr == 0 )
683	{
684	  timers->reg[0].base = buf8[0];
685	  timers->reg[1].base = buf8[1];
686	  timers->reg[2].base = buf8[2];
687	  timers->reg[3].base = buf8[3];
688	}
689      else if ( timer_nr == 4 )
690	{
691	  timers->reg[4].base = buf16[0];
692	  timers->reg[5].base = buf16[1];
693	}
694      else
695	{
696	  hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
697	}
698      break;
699
700    default:
701      hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
702		nr_bytes, timer_nr);
703    }
704
705}
706
707static void
708write_mode_reg (struct hw *me,
709		struct mn103tim *timers,
710		long timer_nr,
711		const void *source,
712		unsigned nr_bytes)
713     /* for timers 0 to 5 */
714{
715  unsigned i;
716  uint8_t mode_val, next_mode_val;
717  uint32_t div_ratio;
718
719  if ( nr_bytes != 1 )
720    {
721      hw_abort (me, "bad write size of %d bytes to TM%ldMD.", nr_bytes,
722		timer_nr);
723    }
724
725  mode_val = *(uint8_t *)source;
726  timers->reg[timer_nr].mode = mode_val;
727
728  if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
729    {
730      hw_abort(me, "Cannot load base reg and start counting simultaneously.");
731    }
732  if ( ( mode_val & bits2to5_mask ) != 0 )
733    {
734      hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
735    }
736
737  if ( mode_val & count_mask )
738    {
739      /* - de-schedule any previous event. */
740      /* - add new event to queue to start counting. */
741      /* - assert that counter == base reg? */
742
743      /* For cascaded timers, */
744      if ( (mode_val & clock_mask) == clk_cascaded )
745	{
746	  if ( timer_nr == 0 || timer_nr == 4 )
747	    {
748	      hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr);
749	    }
750	}
751      else
752	{
753	  div_ratio = timers->reg[timer_nr].base;
754
755	  /* Check for cascading. */
756	  if ( timer_nr < NR_8BIT_TIMERS )
757	    {
758	      for ( i = timer_nr + 1; i <= 3; ++i )
759		{
760		  next_mode_val = timers->reg[i].mode;
761		  if ( ( next_mode_val & clock_mask ) == clk_cascaded )
762		    {
763		      /* Check that CNE is on. */
764		      if ( ( next_mode_val & count_mask ) == 0 )
765			{
766			  hw_abort (me, "cascaded timer not ready for counting");
767			}
768		      ASSERT(timers->timer[i].event == NULL);
769		      ASSERT(timers->timer[i].div_ratio == 0);
770		      div_ratio = div_ratio
771			| (timers->reg[i].base << (8*(i-timer_nr)));
772		    }
773		  else
774		    {
775		      break;
776		    }
777		}
778	    }
779	  else
780	    {
781	      /* Mode register for a 16 bit timer */
782	      next_mode_val = timers->reg[timer_nr+1].mode;
783	      if ( ( next_mode_val & clock_mask ) == clk_cascaded )
784		{
785		  /* Check that CNE is on. */
786		  if ( ( next_mode_val & count_mask ) == 0 )
787		    {
788		      hw_abort (me, "cascaded timer not ready for counting");
789		    }
790		  ASSERT(timers->timer[timer_nr+1].event == NULL);
791		  ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
792		  div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
793		}
794	    }
795
796	  timers->timer[timer_nr].div_ratio = div_ratio;
797
798	  if ( NULL != timers->timer[timer_nr].event )
799	    {
800	      hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
801	      timers->timer[timer_nr].event = NULL;
802	    }
803
804	  if ( div_ratio > 0 )
805	    {
806	      /* Set start time. */
807	      timers->timer[timer_nr].start = hw_event_queue_time(me);
808	      timers->timer[timer_nr].event
809		= hw_event_queue_schedule(me, div_ratio,
810					  do_counter_event,
811					  (void *)(uintptr_t)timer_nr);
812	    }
813	}
814    }
815  else
816    {
817      /* Turn off counting */
818      if ( NULL != timers->timer[timer_nr].event )
819	{
820	  ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
821	  hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
822	  timers->timer[timer_nr].event = NULL;
823	}
824      else
825	{
826	  if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
827	    {
828	      ASSERT(timers->timer[timer_nr].event == NULL);
829	    }
830	}
831
832    }
833
834}
835
836static void
837write_tm6md (struct hw *me,
838	     struct mn103tim *timers,
839	     unsigned_word address,
840	     const void *source,
841	     unsigned nr_bytes)
842{
843  uint8_t mode_val0 = 0x00, mode_val1 = 0x00;
844  uint32_t div_ratio;
845  long timer_nr = 6;
846
847  unsigned_word offset = address - timers->block[0].base;
848
849  if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
850    {
851      hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
852    }
853
854  if ( offset == 0x84 )  /* address of TM6MD */
855    {
856      /*  Fill in first byte of mode */
857      mode_val0 = *(uint8_t *)source;
858      timers->tm6md0 = mode_val0;
859
860      if ( ( mode_val0 & 0x26 ) != 0 )
861	{
862	  hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
863	}
864    }
865
866  if ( offset == 0x85 || nr_bytes == 2 )
867    {
868      /*  Fill in second byte of mode */
869      if ( nr_bytes == 2 )
870	{
871	  mode_val1 = *(uint8_t *)source+1;
872	}
873      else
874	{
875	  mode_val1 = *(uint8_t *)source;
876	}
877
878      timers->tm6md1 = mode_val1;
879
880      if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
881	{
882	  hw_abort(me, "Cannot load base reg and start counting simultaneously.");
883	}
884      if ( ( mode_val1 & bits0to2_mask ) != 0 )
885	{
886	  hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
887	}
888    }
889
890  if ( mode_val1 & count_mask )
891    {
892      /* - de-schedule any previous event. */
893      /* - add new event to queue to start counting. */
894      /* - assert that counter == base reg? */
895
896      div_ratio = timers->tm6ca;  /* binary counter for timer 6 */
897      timers->timer[timer_nr].div_ratio = div_ratio;
898      if ( NULL != timers->timer[timer_nr].event )
899	{
900	  hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
901	  timers->timer[timer_nr].event = NULL;
902	}
903
904      if ( div_ratio > 0 )
905	{
906	  /* Set start time. */
907	  timers->timer[timer_nr].start = hw_event_queue_time(me);
908	  timers->timer[timer_nr].event
909	    = hw_event_queue_schedule(me, div_ratio,
910				      do_counter6_event,
911				      (void *)(uintptr_t)timer_nr);
912	}
913    }
914  else
915    {
916      /* Turn off counting */
917      if ( NULL != timers->timer[timer_nr].event )
918	{
919	  hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
920	  timers->timer[timer_nr].event = NULL;
921	}
922    }
923}
924
925
926
927static void
928write_special_timer6_reg (struct hw *me,
929			  struct mn103tim *timers,
930			  int timer_nr,
931			  const void *source,
932			  unsigned  nr_bytes)
933{
934  uint32_t val;
935
936  switch (nr_bytes) {
937  case 1:
938    {
939      switch ( timer_nr ) {
940      case TM6MDA:
941	timers->tm6mda = *(uint8_t *)source;
942	break;
943
944      case TM6MDB:
945	timers->tm6mdb = *(uint8_t *)source;
946	break;
947
948      case TM6CA:
949	timers->tm6ca = *(uint8_t *)source;
950	break;
951
952      case TM6CB:
953	timers->tm6cb = *(uint8_t *)source;
954	break;
955
956      default:
957	break;
958      }
959      break;
960    }
961
962  case 2:
963    if ( timer_nr == TM6CA )
964      {
965	timers->tm6ca = *(uint16_t *)source;
966      }
967    else if ( timer_nr == TM6CB )
968      {
969	timers->tm6cb = *(uint16_t *)source;
970      }
971    else
972      {
973	hw_abort(me, "bad read size for timer 6 mode A/B register");
974      }
975    break;
976
977  default:
978    hw_abort(me, "bad read size for timer 6 register");
979  }
980
981}
982
983
984static unsigned
985mn103tim_io_write_buffer (struct hw *me,
986			  const void *source,
987			  int space,
988			  unsigned_word base,
989			  unsigned nr_bytes)
990{
991  struct mn103tim *timers = hw_data (me);
992  enum timer_register_types timer_reg;
993
994  HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
995	     (int) nr_bytes, *(uint32_t *)source));
996
997  timer_reg = decode_addr (me, timers, base);
998
999  /* It can be either a mode register, a base register, a binary counter, */
1000  /* or a special timer 6 register.  Check in that order. */
1001  if ( timer_reg <= LAST_MODE_REG )
1002    {
1003      if ( timer_reg == 6 )
1004	{
1005	  write_tm6md(me, timers, base, source, nr_bytes);
1006	}
1007      else
1008	{
1009	  write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1010			 source, nr_bytes);
1011	}
1012    }
1013  else if ( timer_reg <= LAST_BASE_REG )
1014    {
1015      write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1016    }
1017  else if ( timer_reg <= LAST_COUNTER )
1018    {
1019      hw_abort(me, "cannot write to counter");
1020    }
1021  else if ( timer_reg <= LAST_TIMER_REG )
1022    {
1023      write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1024    }
1025  else
1026    {
1027      hw_abort(me, "invalid reg type");
1028    }
1029
1030  return nr_bytes;
1031}
1032
1033
1034const struct hw_descriptor dv_mn103tim_descriptor[] = {
1035  { "mn103tim", mn103tim_finish, },
1036  { NULL },
1037};
1038