OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [mn10300/] [dv-mn103tim.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/*  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
#include "sim-assert.h"
25
 
26
/* DEVICE
27
 
28
 
29
   mn103tim - mn103002 timers (8 and 16 bit)
30
 
31
 
32
   DESCRIPTION
33
 
34
   Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide.
35
 
36
 
37
   PROPERTIES
38
 
39
   reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size>
40
 
41
 
42
   BUGS
43
 
44
   */
45
 
46
 
47
/* The timers' register address blocks */
48
 
49
struct mn103tim_block {
50
  unsigned_word base;
51
  unsigned_word bound;
52
};
53
 
54
enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
55
 
56
enum timer_register_types {
57
  FIRST_MODE_REG = 0,
58
  TM0MD = FIRST_MODE_REG,
59
  TM1MD,
60
  TM2MD,
61
  TM3MD,
62
  TM4MD,
63
  TM5MD,
64
  TM6MD,
65
  LAST_MODE_REG = TM6MD,
66
  FIRST_BASE_REG,
67
  TM0BR = FIRST_BASE_REG,
68
  TM1BR,
69
  TM2BR,
70
  TM3BR,
71
  TM4BR,
72
  TM5BR,
73
  LAST_BASE_REG = TM5BR,
74
  FIRST_COUNTER,
75
  TM0BC = FIRST_COUNTER,
76
  TM1BC,
77
  TM2BC,
78
  TM3BC,
79
  TM4BC,
80
  TM5BC,
81
  TM6BC,
82
  LAST_COUNTER = TM6BC,
83
  TM6MDA,
84
  TM6MDB,
85
  TM6CA,
86
  TM6CB,
87
  LAST_TIMER_REG = TM6BC,
88
};
89
 
90
 
91
/* Don't include timer 6 because it's handled specially. */
92
#define NR_8BIT_TIMERS 4
93
#define NR_16BIT_TIMERS 2
94
#define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
95
#define NR_TIMERS 7
96
 
97
typedef struct _mn10300_timer_regs {
98
  unsigned32 base;
99
  unsigned8  mode;
100
} mn10300_timer_regs;
101
 
102
typedef struct _mn10300_timer {
103
  unsigned32 div_ratio, start;
104
  struct hw_event *event;
105
} mn10300_timer;
106
 
107
 
108
struct mn103tim {
109
  struct mn103tim_block block[NR_TIMER_BLOCKS];
110
  mn10300_timer_regs reg[NR_REG_TIMERS];
111
  mn10300_timer timer[NR_TIMERS];
112
 
113
  /* treat timer 6 registers specially. */
114
  unsigned16   tm6md0, tm6md1, tm6bc, tm6ca, tm6cb;
115
  unsigned8  tm6mda, tm6mdb;  /* compare/capture mode regs for timer 6 */
116
};
117
 
118
/* output port ID's */
119
 
120
/* for mn103002 */
121
enum {
122
  TIMER0_UFLOW,
123
  TIMER1_UFLOW,
124
  TIMER2_UFLOW,
125
  TIMER3_UFLOW,
126
  TIMER4_UFLOW,
127
  TIMER5_UFLOW,
128
  TIMER6_UFLOW,
129
  TIMER6_CMPA,
130
  TIMER6_CMPB,
131
};
132
 
133
 
134
static const struct hw_port_descriptor mn103tim_ports[] = {
135
 
136
  { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
137
  { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
138
  { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
139
  { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
140
  { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
141
  { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
142
 
143
  { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
144
  { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
145
  { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
146
 
147
  { NULL, },
148
};
149
 
150
#define bits2to5_mask 0x3c
151
#define bits0to2_mask 0x07
152
#define load_mask     0x40
153
#define count_mask    0x80
154
#define count_and_load_mask (load_mask | count_mask)
155
#define clock_mask    0x03
156
#define clk_ioclk    0x00
157
#define clk_cascaded 0x03
158
 
159
 
160
/* Finish off the partially created hw device.  Attach our local
161
   callbacks.  Wire up our port names etc */
162
 
163
static hw_io_read_buffer_method mn103tim_io_read_buffer;
164
static hw_io_write_buffer_method mn103tim_io_write_buffer;
165
 
166
static void
167
attach_mn103tim_regs (struct hw *me,
168
                      struct mn103tim *timers)
169
{
170
  int i;
171
  if (hw_find_property (me, "reg") == NULL)
172
    hw_abort (me, "Missing \"reg\" property");
173
  for (i = 0; i < NR_TIMER_BLOCKS; i++)
174
    {
175
      unsigned_word attach_address;
176
      int attach_space;
177
      unsigned attach_size;
178
      reg_property_spec reg;
179
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
180
        hw_abort (me, "\"reg\" property must contain three addr/size entries");
181
      hw_unit_address_to_attach_address (hw_parent (me),
182
                                         &reg.address,
183
                                         &attach_space,
184
                                         &attach_address,
185
                                         me);
186
      timers->block[i].base = attach_address;
187
      hw_unit_size_to_attach_size (hw_parent (me),
188
                                   &reg.size,
189
                                   &attach_size, me);
190
      timers->block[i].bound = attach_address + (attach_size - 1);
191
      hw_attach_address (hw_parent (me),
192
                         0,
193
                         attach_space, attach_address, attach_size,
194
                         me);
195
    }
196
}
197
 
198
static void
199
mn103tim_finish (struct hw *me)
200
{
201
  struct mn103tim *timers;
202
  int i;
203
 
204
  timers = HW_ZALLOC (me, struct mn103tim);
205
  set_hw_data (me, timers);
206
  set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
207
  set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
208
  set_hw_ports (me, mn103tim_ports);
209
 
210
  /* Attach ourself to our parent bus */
211
  attach_mn103tim_regs (me, timers);
212
 
213
  /* Initialize the timers */
214
  for ( i=0; i < NR_REG_TIMERS; ++i )
215
    {
216
      timers->reg[i].mode = 0x00;
217
      timers->reg[i].base = 0;
218
    }
219
  for ( i=0; i < NR_TIMERS; ++i )
220
    {
221
      timers->timer[i].event = NULL;
222
      timers->timer[i].div_ratio = 0;
223
      timers->timer[i].start = 0;
224
    }
225
  timers->tm6md0 = 0x00;
226
  timers->tm6md1 = 0x00;
227
  timers->tm6bc = 0x0000;
228
  timers->tm6ca = 0x0000;
229
  timers->tm6cb = 0x0000;
230
  timers->tm6mda = 0x00;
231
  timers->tm6mdb = 0x00;
232
}
233
 
234
 
235
 
236
/* read and write */
237
 
238
static int
239
decode_addr (struct hw *me,
240
             struct mn103tim *timers,
241
             unsigned_word address)
242
{
243
  unsigned_word offset;
244
  offset = address - timers->block[0].base;
245
 
246
  switch (offset)
247
    {
248
    case 0x00: return TM0MD;
249
    case 0x01: return TM1MD;
250
    case 0x02: return TM2MD;
251
    case 0x03: return TM3MD;
252
    case 0x10: return TM0BR;
253
    case 0x11: return TM1BR;
254
    case 0x12: return TM2BR;
255
    case 0x13: return TM3BR;
256
    case 0x20: return TM0BC;
257
    case 0x21: return TM1BC;
258
    case 0x22: return TM2BC;
259
    case 0x23: return TM3BC;
260
    case 0x80: return TM4MD;
261
    case 0x82: return TM5MD;
262
    case 0x84: /* fall through */
263
    case 0x85: return TM6MD;
264
    case 0x90: return TM4BR;
265
    case 0x92: return TM5BR;
266
    case 0xa0: return TM4BC;
267
    case 0xa2: return TM5BC;
268
    case 0xa4: return TM6BC;
269
    case 0xb4: return TM6MDA;
270
    case 0xb5: return TM6MDB;
271
    case 0xc4: return TM6CA;
272
    case 0xd4: return TM6CB;
273
    default:
274
      {
275
        hw_abort (me, "bad address");
276
        return -1;
277
      }
278
    }
279
}
280
 
281
static void
282
read_mode_reg (struct hw *me,
283
               struct mn103tim *timers,
284
               int timer_nr,
285
               void *dest,
286
               unsigned nr_bytes)
287
{
288
  unsigned16 val16;
289
  unsigned32 val32;
290
 
291
  switch ( nr_bytes )
292
    {
293
    case 1:
294
      /* Accessing 1 byte is ok for all mode registers. */
295
      if ( timer_nr == 6 )
296
        {
297
          *(unsigned8*)dest = timers->tm6md0;
298
        }
299
      else
300
        {
301
          *(unsigned8*)dest = timers->reg[timer_nr].mode;
302
        }
303
      break;
304
 
305
    case 2:
306
      if ( timer_nr == 6 )
307
        {
308
          *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
309
        }
310
      else if ( timer_nr == 0 || timer_nr == 2 )
311
        {
312
          val16 = (timers->reg[timer_nr].mode << 8)
313
            | timers->reg[timer_nr+1].mode;
314
          *(unsigned16*)dest = val16;
315
        }
316
      else
317
        {
318
          hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
319
        }
320
      break;
321
 
322
    case 4:
323
      if ( timer_nr == 0 )
324
        {
325
          val32 = (timers->reg[0].mode << 24 )
326
            | (timers->reg[1].mode << 16)
327
            | (timers->reg[2].mode << 8)
328
            | timers->reg[3].mode;
329
          *(unsigned32*)dest = val32;
330
        }
331
      else
332
        {
333
          hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
334
        }
335
      break;
336
 
337
    default:
338
      hw_abort (me, "bad read size of %d bytes to TM%dMD.",
339
                nr_bytes, timer_nr);
340
    }
341
}
342
 
343
 
344
static void
345
read_base_reg (struct hw *me,
346
               struct mn103tim *timers,
347
               int timer_nr,
348
               void *dest,
349
               unsigned  nr_bytes)
350
{
351
  unsigned16 val16;
352
  unsigned32 val32;
353
 
354
  /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
355
  switch ( nr_bytes )
356
    {
357
    case 1:
358
      /* Reading 1 byte is ok for all registers. */
359
      if ( timer_nr < NR_8BIT_TIMERS )
360
        {
361
          *(unsigned8*)dest = timers->reg[timer_nr].base;
362
        }
363
      break;
364
 
365
    case 2:
366
      if ( timer_nr == 1 || timer_nr == 3 )
367
        {
368
          hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
369
        }
370
      else
371
        {
372
          if ( timer_nr < NR_8BIT_TIMERS )
373
            {
374
              val16 = (timers->reg[timer_nr].base<<8)
375
                | timers->reg[timer_nr+1].base;
376
            }
377
          else
378
            {
379
              val16 = timers->reg[timer_nr].base;
380
            }
381
          *(unsigned16*)dest = val16;
382
        }
383
      break;
384
 
385
    case 4:
386
      if ( timer_nr == 0 )
387
        {
388
          val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
389
            | (timers->reg[2].base << 8) | timers->reg[3].base;
390
          *(unsigned32*)dest = val32;
391
        }
392
      else if ( timer_nr == 4 )
393
        {
394
          val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
395
          *(unsigned32*)dest = val32;
396
        }
397
      else
398
        {
399
          hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
400
        }
401
      break;
402
 
403
    default:
404
      hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
405
                nr_bytes, timer_nr);
406
    }
407
}
408
 
409
 
410
static void
411
read_counter (struct hw *me,
412
              struct mn103tim *timers,
413
              int timer_nr,
414
              void *dest,
415
              unsigned  nr_bytes)
416
{
417
  unsigned32 val;
418
 
419
  if ( NULL == timers->timer[timer_nr].event )
420
    {
421
      /* Timer is not counting, use value in base register. */
422
      if ( timer_nr == 6 )
423
        {
424
          val = 0;  /* timer 6 is an up counter */
425
        }
426
      else
427
        {
428
          val = timers->reg[timer_nr].base;
429
        }
430
    }
431
  else
432
    {
433
      if ( timer_nr == 6 )  /* timer 6 is an up counter. */
434
        {
435
          val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
436
        }
437
      else
438
        {
439
          /* ticks left = start time + div ratio - curr time */
440
          /* Cannot use base register because it can be written during counting and it
441
             doesn't affect counter until underflow occurs. */
442
 
443
          val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
444
            - hw_event_queue_time(me);
445
        }
446
    }
447
 
448
  switch (nr_bytes) {
449
  case 1:
450
    *(unsigned8 *)dest = val;
451
    break;
452
 
453
  case 2:
454
    *(unsigned16 *)dest = val;
455
    break;
456
 
457
  case 4:
458
    *(unsigned32 *)dest = val;
459
    break;
460
 
461
  default:
462
    hw_abort(me, "bad read size for reading counter");
463
  }
464
 
465
}
466
 
467
 
468
static void
469
read_special_timer6_reg (struct hw *me,
470
                         struct mn103tim *timers,
471
                         int timer_nr,
472
                         void *dest,
473
                         unsigned  nr_bytes)
474
{
475
  unsigned32 val;
476
 
477
  switch (nr_bytes) {
478
  case 1:
479
    {
480
      switch ( timer_nr ) {
481
      case TM6MDA:
482
        *(unsigned8 *)dest = timers->tm6mda;
483
        break;
484
 
485
      case TM6MDB:
486
        *(unsigned8 *)dest = timers->tm6mdb;
487
        break;
488
 
489
      case TM6CA:
490
        *(unsigned8 *)dest = timers->tm6ca;
491
        break;
492
 
493
      case TM6CB:
494
        *(unsigned8 *)dest = timers->tm6cb;
495
        break;
496
 
497
      default:
498
      }
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
  int timer_nr = (int) 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
  int timer_nr = (int) 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
                int 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%dMD.", nr_bytes, timer_nr);
719
    }
720
 
721
  mode_val = *(unsigned8 *)source;
722
  timers->reg[timer_nr].mode = mode_val;
723
 
724
  if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
725
    {
726
      hw_abort(me, "Cannot load base reg and start counting simultaneously.");
727
    }
728
  if ( ( mode_val & bits2to5_mask ) != 0 )
729
    {
730
      hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
731
    }
732
 
733
  if ( mode_val & count_mask )
734
    {
735
      /* - de-schedule any previous event. */
736
      /* - add new event to queue to start counting. */
737
      /* - assert that counter == base reg? */
738
 
739
      /* For cascaded timers, */
740
      if ( (mode_val & clock_mask) == clk_cascaded )
741
        {
742
          if ( timer_nr == 0 || timer_nr == 4 )
743
            {
744
              hw_abort(me, "Timer %d cannot be cascaded.", timer_nr);
745
            }
746
        }
747
      else
748
        {
749
          div_ratio = timers->reg[timer_nr].base;
750
 
751
          /* Check for cascading. */
752
          if ( timer_nr < NR_8BIT_TIMERS )
753
            {
754
              for ( i = timer_nr + 1; i <= 3; ++i )
755
                {
756
                  next_mode_val = timers->reg[i].mode;
757
                  if ( ( next_mode_val & clock_mask ) == clk_cascaded )
758
                    {
759
                      /* Check that CNE is on. */
760
                      if ( ( next_mode_val & count_mask ) == 0 )
761
                        {
762
                          hw_abort (me, "cascaded timer not ready for counting");
763
                        }
764
                      ASSERT(timers->timer[i].event == NULL);
765
                      ASSERT(timers->timer[i].div_ratio == 0);
766
                      div_ratio = div_ratio
767
                        | (timers->reg[i].base << (8*(i-timer_nr)));
768
                    }
769
                  else
770
                    {
771
                      break;
772
                    }
773
                }
774
            }
775
          else
776
            {
777
              /* Mode register for a 16 bit timer */
778
              next_mode_val = timers->reg[timer_nr+1].mode;
779
              if ( ( next_mode_val & clock_mask ) == clk_cascaded )
780
                {
781
                  /* Check that CNE is on. */
782
                  if ( ( next_mode_val & count_mask ) == 0 )
783
                    {
784
                      hw_abort (me, "cascaded timer not ready for counting");
785
                    }
786
                  ASSERT(timers->timer[timer_nr+1].event == NULL);
787
                  ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
788
                  div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
789
                }
790
            }
791
 
792
          timers->timer[timer_nr].div_ratio = div_ratio;
793
 
794
          if ( NULL != timers->timer[timer_nr].event )
795
            {
796
              hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
797
              timers->timer[timer_nr].event = NULL;
798
            }
799
 
800
          if ( div_ratio > 0 )
801
            {
802
              /* Set start time. */
803
              timers->timer[timer_nr].start = hw_event_queue_time(me);
804
              timers->timer[timer_nr].event
805
                = hw_event_queue_schedule(me, div_ratio,
806
                                          do_counter_event,
807
                                          (void *)(timer_nr));
808
            }
809
        }
810
    }
811
  else
812
    {
813
      /* Turn off counting */
814
      if ( NULL != timers->timer[timer_nr].event )
815
        {
816
          ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
817
          hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
818
          timers->timer[timer_nr].event = NULL;
819
        }
820
      else
821
        {
822
          if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
823
            {
824
              ASSERT(timers->timer[timer_nr].event == NULL);
825
            }
826
        }
827
 
828
    }
829
 
830
}
831
 
832
static void
833
write_tm6md (struct hw *me,
834
             struct mn103tim *timers,
835
             unsigned_word address,
836
             const void *source,
837
             unsigned nr_bytes)
838
{
839
  unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
840
  unsigned32 div_ratio;
841
  int timer_nr = 6;
842
 
843
  unsigned_word offset = address - timers->block[0].base;
844
 
845
  if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
846
    {
847
      hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
848
    }
849
 
850
  if ( offset == 0x84 )  /* address of TM6MD */
851
    {
852
      /*  Fill in first byte of mode */
853
      mode_val0 = *(unsigned8 *)source;
854
      timers->tm6md0 = mode_val0;
855
 
856
      if ( ( mode_val0 & 0x26 ) != 0 )
857
        {
858
          hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
859
        }
860
    }
861
 
862
  if ( offset == 0x85 || nr_bytes == 2 )
863
    {
864
      /*  Fill in second byte of mode */
865
      if ( nr_bytes == 2 )
866
        {
867
          mode_val1 = *(unsigned8 *)source+1;
868
        }
869
      else
870
        {
871
          mode_val1 = *(unsigned8 *)source;
872
        }
873
 
874
      timers->tm6md1 = mode_val1;
875
 
876
      if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
877
        {
878
          hw_abort(me, "Cannot load base reg and start counting simultaneously.");
879
        }
880
      if ( ( mode_val1 & bits0to2_mask ) != 0 )
881
        {
882
          hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
883
        }
884
    }
885
 
886
  if ( mode_val1 & count_mask )
887
    {
888
      /* - de-schedule any previous event. */
889
      /* - add new event to queue to start counting. */
890
      /* - assert that counter == base reg? */
891
 
892
      div_ratio = timers->tm6ca;  /* binary counter for timer 6 */
893
      timers->timer[timer_nr].div_ratio = div_ratio;
894
      if ( NULL != timers->timer[timer_nr].event )
895
        {
896
          hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
897
          timers->timer[timer_nr].event = NULL;
898
        }
899
 
900
      if ( div_ratio > 0 )
901
        {
902
          /* Set start time. */
903
          timers->timer[timer_nr].start = hw_event_queue_time(me);
904
          timers->timer[timer_nr].event
905
            = hw_event_queue_schedule(me, div_ratio,
906
                                      do_counter6_event,
907
                                      (void *)(timer_nr));
908
        }
909
    }
910
  else
911
    {
912
      /* Turn off counting */
913
      if ( NULL != timers->timer[timer_nr].event )
914
        {
915
          hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
916
          timers->timer[timer_nr].event = NULL;
917
        }
918
    }
919
}
920
 
921
 
922
 
923
static void
924
write_special_timer6_reg (struct hw *me,
925
                          struct mn103tim *timers,
926
                          int timer_nr,
927
                          const void *source,
928
                          unsigned  nr_bytes)
929
{
930
  unsigned32 val;
931
 
932
  switch (nr_bytes) {
933
  case 1:
934
    {
935
      switch ( timer_nr ) {
936
      case TM6MDA:
937
        timers->tm6mda = *(unsigned8 *)source;
938
        break;
939
 
940
      case TM6MDB:
941
        timers->tm6mdb = *(unsigned8 *)source;
942
        break;
943
 
944
      case TM6CA:
945
        timers->tm6ca = *(unsigned8 *)source;
946
        break;
947
 
948
      case TM6CB:
949
        timers->tm6cb = *(unsigned8 *)source;
950
        break;
951
 
952
      default:
953
      }
954
      break;
955
    }
956
 
957
  case 2:
958
    if ( timer_nr == TM6CA )
959
      {
960
        timers->tm6ca = *(unsigned16 *)source;
961
      }
962
    else if ( timer_nr == TM6CB )
963
      {
964
        timers->tm6cb = *(unsigned16 *)source;
965
      }
966
    else
967
      {
968
        hw_abort(me, "bad read size for timer 6 mode A/B register");
969
      }
970
    break;
971
 
972
  default:
973
    hw_abort(me, "bad read size for timer 6 register");
974
  }
975
 
976
}
977
 
978
 
979
static unsigned
980
mn103tim_io_write_buffer (struct hw *me,
981
                          const void *source,
982
                          int space,
983
                          unsigned_word base,
984
                          unsigned nr_bytes)
985
{
986
  struct mn103tim *timers = hw_data (me);
987
  enum timer_register_types timer_reg;
988
 
989
  HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
990
             (int) nr_bytes, *(unsigned32 *)source));
991
 
992
  timer_reg = decode_addr (me, timers, base);
993
 
994
  /* It can be either a mode register, a base register, a binary counter, */
995
  /* or a special timer 6 register.  Check in that order. */
996
  if ( timer_reg <= LAST_MODE_REG )
997
    {
998
      if ( timer_reg == 6 )
999
        {
1000
          write_tm6md(me, timers, base, source, nr_bytes);
1001
        }
1002
      else
1003
        {
1004
          write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1005
                         source, nr_bytes);
1006
        }
1007
    }
1008
  else if ( timer_reg <= LAST_BASE_REG )
1009
    {
1010
      write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1011
    }
1012
  else if ( timer_reg <= LAST_COUNTER )
1013
    {
1014
      hw_abort(me, "cannot write to counter");
1015
    }
1016
  else if ( timer_reg <= LAST_TIMER_REG )
1017
    {
1018
      write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1019
    }
1020
  else
1021
    {
1022
      hw_abort(me, "invalid reg type");
1023
    }
1024
 
1025
  return nr_bytes;
1026
}
1027
 
1028
 
1029
const struct hw_descriptor dv_mn103tim_descriptor[] = {
1030
  { "mn103tim", mn103tim_finish, },
1031
  { NULL },
1032
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.