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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [mn10300/] [dv-mn103tim.c] - Blame information for rev 819

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

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

powered by: WebSVN 2.1.0

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