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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [mn10300/] [dv-mn103tim.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/*  This file is part of the program GDB, the GNU debugger.
2
 
3
    Copyright (C) 1998, 2003, 2007, 2008, 2009, 2010
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
 
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
        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
 
525
static unsigned
526
mn103tim_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
 
566
static void
567
do_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
 
607
static void
608
do_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
 
635
static void
636
write_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
 
705
static void
706
write_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
 
834
static void
835
write_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
 
925
static void
926
write_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
 
982
static unsigned
983
mn103tim_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
 
1032
const struct hw_descriptor dv_mn103tim_descriptor[] = {
1033
  { "mn103tim", mn103tim_finish, },
1034
  { NULL },
1035
};

powered by: WebSVN 2.1.0

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