* am33.igen: Autoincrement loads/store fixes.
[deliverable/binutils-gdb.git] / sim / mn10300 / dv-mn103tim.c
1 /* 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
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 };
87
88
89 /* Don't include timer 6 because it's handled specially. */
90 #define NR_8BIT_TIMERS 4
91 #define NR_16BIT_TIMERS 2
92 #define NR_TIMERS 6
93
94 typedef struct _mn10300_timer {
95 unsigned32 div_ratio, start, base;
96 unsigned8 mode;
97 struct hw_event *event;
98 } mn10300_timer;
99
100
101 struct mn103tim {
102 struct mn103tim_block block[NR_TIMER_BLOCKS];
103 mn10300_timer timer[NR_TIMERS];
104
105 /* treat timer 6 registers specially. */
106 unsigned16 tm6md, tm6bc, tm6mca, tm6mcb;
107 unsigned8 tm6mda, tm6mdb; /* compare/capture mode regs for timer 6 */
108 struct hw_event *event6;
109 };
110
111 /* output port ID's */
112
113 /* for mn103002 */
114 enum {
115 TIMER0_UFLOW,
116 TIMER1_UFLOW,
117 TIMER2_UFLOW,
118 TIMER3_UFLOW,
119 TIMER4_UFLOW,
120 TIMER5_UFLOW,
121 TIMER6_UFLOW,
122 TIMER6_CMPA,
123 TIMER6_CMPB,
124 };
125
126
127 static const struct hw_port_descriptor mn103tim_ports[] = {
128
129 { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
130 { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
131 { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
132 { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
133 { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
134 { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
135
136 { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
137 { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
138 { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
139
140 { NULL, },
141 };
142
143 #define bits2to5_mask 0x3c
144 #define load_mask 0x40
145 #define count_mask 0x80
146 #define count_and_load_mask (load_mask | count_mask)
147 #define clock_mask 0x03
148 #define clk_ioclk 0x00
149 #define clk_cascaded 0x03
150
151
152 /* Finish off the partially created hw device. Attach our local
153 callbacks. Wire up our port names etc */
154
155 static hw_io_read_buffer_method mn103tim_io_read_buffer;
156 static hw_io_write_buffer_method mn103tim_io_write_buffer;
157
158 static void
159 attach_mn103tim_regs (struct hw *me,
160 struct mn103tim *timers)
161 {
162 int i;
163 if (hw_find_property (me, "reg") == NULL)
164 hw_abort (me, "Missing \"reg\" property");
165 for (i = 0; i < NR_TIMER_BLOCKS; i++)
166 {
167 unsigned_word attach_address;
168 int attach_space;
169 unsigned attach_size;
170 reg_property_spec reg;
171 if (!hw_find_reg_array_property (me, "reg", i, &reg))
172 hw_abort (me, "\"reg\" property must contain three addr/size entries");
173 hw_unit_address_to_attach_address (hw_parent (me),
174 &reg.address,
175 &attach_space,
176 &attach_address,
177 me);
178 timers->block[i].base = attach_address;
179 hw_unit_size_to_attach_size (hw_parent (me),
180 &reg.size,
181 &attach_size, me);
182 timers->block[i].bound = attach_address + (attach_size - 1);
183 hw_attach_address (hw_parent (me),
184 0,
185 attach_space, attach_address, attach_size,
186 me);
187 }
188 }
189
190 static void
191 mn103tim_finish (struct hw *me)
192 {
193 struct mn103tim *timers;
194 int i;
195
196 timers = HW_ZALLOC (me, struct mn103tim);
197 set_hw_data (me, timers);
198 set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
199 set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
200 set_hw_ports (me, mn103tim_ports);
201
202 /* Attach ourself to our parent bus */
203 attach_mn103tim_regs (me, timers);
204
205 /* Initialize the timers */
206 for ( i=0; i < NR_TIMERS; ++i )
207 {
208 timers->timer[i].event = NULL;
209 timers->timer[i].mode = 0x00;
210 timers->timer[i].base = 0;
211 timers->timer[i].div_ratio = 0;
212 timers->timer[i].start = 0;
213 }
214 timers->tm6md = 0x0000;
215 timers->tm6bc = 0x0000;
216 timers->tm6mca = 0x0000;
217 timers->tm6mcb = 0x0000;
218 timers->tm6mda = 0x00;
219 timers->tm6mdb = 0x00;
220 }
221
222
223
224 /* read and write */
225
226 static int
227 decode_addr (struct hw *me,
228 struct mn103tim *timers,
229 unsigned_word address)
230 {
231 unsigned_word offset;
232 offset = address - timers->block[0].base;
233
234 switch (offset)
235 {
236 case 0x00: return TM0MD;
237 case 0x01: return TM1MD;
238 case 0x02: return TM2MD;
239 case 0x03: return TM3MD;
240 case 0x10: return TM0BR;
241 case 0x11: return TM1BR;
242 case 0x12: return TM2BR;
243 case 0x13: return TM3BR;
244 case 0x20: return TM0BC;
245 case 0x21: return TM1BC;
246 case 0x22: return TM2BC;
247 case 0x23: return TM3BC;
248 case 0x80: return TM4MD;
249 case 0x82: return TM5MD;
250 case 0x84: return TM6MD;
251 case 0x90: return TM4BR;
252 case 0x92: return TM5BR;
253 case 0xa0: return TM4BC;
254 case 0xa2: return TM5BC;
255 case 0xa4: return TM6BC;
256 case 0xb4: return TM6MDA;
257 case 0xb5: return TM6MDB;
258 case 0xc4: return TM6CA;
259 case 0xd4: return TM6CB;
260 default:
261 {
262 hw_abort (me, "bad address");
263 return -1;
264 }
265 }
266 }
267
268 static void
269 read_mode_reg (struct hw *me,
270 struct mn103tim *timers,
271 int timer_nr,
272 void *dest,
273 unsigned nr_bytes)
274 {
275 unsigned16 val16;
276 unsigned32 val32;
277
278 switch ( nr_bytes )
279 {
280 case 1:
281 /* Accessing 1 byte is ok for all mode registers. */
282 *(unsigned8*)dest = timers->timer[timer_nr].mode;
283 break;
284
285 case 2:
286 if ( timer_nr == 6 )
287 {
288 *(unsigned16 *)dest = timers->tm6md;
289 }
290 else if ( timer_nr == 0 || timer_nr == 2 )
291 {
292 val16 = (timers->timer[timer_nr].mode << 8)
293 | timers->timer[timer_nr+1].mode;
294 *(unsigned16*)dest = val16;
295 }
296 else
297 {
298 hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
299 }
300 break;
301
302 case 4:
303 if ( timer_nr == 0 )
304 {
305 val32 = (timers->timer[0].mode << 24 )
306 | (timers->timer[1].mode << 16)
307 | (timers->timer[2].mode << 8)
308 | timers->timer[3].mode;
309 *(unsigned32*)dest = val32;
310 }
311 else
312 {
313 hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
314 }
315 break;
316
317 default:
318 hw_abort (me, "bad read size of %d bytes to TM%dMD.",
319 nr_bytes, timer_nr);
320 }
321 }
322
323
324 static void
325 read_base_reg (struct hw *me,
326 struct mn103tim *timers,
327 int timer_nr,
328 void *dest,
329 unsigned nr_bytes)
330 {
331 unsigned16 val16;
332 unsigned32 val32;
333
334 /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
335 switch ( nr_bytes )
336 {
337 case 1:
338 /* Reading 1 byte is ok for all registers. */
339 if ( timer_nr < NR_8BIT_TIMERS )
340 {
341 *(unsigned8*)dest = timers->timer[timer_nr].base;
342 }
343 break;
344
345 case 2:
346 if ( timer_nr == 1 || timer_nr == 3 )
347 {
348 hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
349 }
350 else
351 {
352 if ( timer_nr < NR_8BIT_TIMERS )
353 {
354 val16 = (timers->timer[timer_nr].base<<8)
355 | timers->timer[timer_nr+1].base;
356 }
357 else
358 {
359 val16 = timers->timer[timer_nr].base;
360 }
361 *(unsigned16*)dest = val16;
362 }
363 break;
364
365 case 4:
366 if ( timer_nr == 0 )
367 {
368 val32 = (timers->timer[0].base << 24) | (timers->timer[1].base << 16)
369 | (timers->timer[2].base << 8) | timers->timer[3].base;
370 *(unsigned32*)dest = val32;
371 }
372 else if ( timer_nr == 4 )
373 {
374 val32 = (timers->timer[4].base << 16) | timers->timer[5].base;
375 *(unsigned32*)dest = val32;
376 }
377 else
378 {
379 hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
380 }
381 break;
382
383 default:
384 hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
385 nr_bytes, timer_nr);
386 }
387 }
388
389
390 static void
391 read_counter (struct hw *me,
392 struct mn103tim *timers,
393 int timer_nr,
394 void *dest,
395 unsigned nr_bytes)
396 {
397 unsigned32 val;
398
399 if ( NULL == timers->timer[timer_nr].event )
400 {
401 /* Timer is not counting, use value in base register. */
402 val = timers->timer[timer_nr].base;
403 }
404 else
405 {
406 /* ticks left = start time + div ratio - curr time */
407 /* Cannot use base register because it can be written during counting and it
408 doesn't affect counter until underflow occurs. */
409
410 val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
411 - hw_event_queue_time(me);
412 }
413
414 switch (nr_bytes) {
415 case 1:
416 *(unsigned8 *)dest = val;
417 break;
418
419 case 2:
420 *(unsigned16 *)dest = val;
421 break;
422
423 case 4:
424 *(unsigned32 *)dest = val;
425 break;
426
427 default:
428 hw_abort(me, "bad read size for reading counter");
429 }
430
431 }
432
433
434 static unsigned
435 mn103tim_io_read_buffer (struct hw *me,
436 void *dest,
437 int space,
438 unsigned_word base,
439 unsigned nr_bytes)
440 {
441 struct mn103tim *timers = hw_data (me);
442 enum timer_register_types timer_reg;
443
444 HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
445
446 timer_reg = decode_addr (me, timers, base);
447
448 /* It can be either a mode register, a base register or a binary counter. */
449 /* Check in that order. */
450 if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
451 {
452 read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
453 }
454 else if ( timer_reg <= LAST_BASE_REG )
455 {
456 read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
457 }
458 else if ( timer_reg <= LAST_COUNTER )
459 {
460 read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
461 }
462 else
463 {
464 hw_abort(me, "invalid timer register address.");
465 }
466
467 return nr_bytes;
468 }
469
470
471 static void
472 do_counter_event (struct hw *me,
473 void *data)
474 {
475 struct mn103tim *timers = hw_data(me);
476 int timer_nr = (int) data;
477
478 /* Check if counting is still enabled. */
479 if ( (timers->timer[timer_nr].mode & count_mask) != 0 )
480 {
481 /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
482 hw_port_event (me, timer_nr /*uflow_port[timer_nr]*/, 1 /* level */);
483
484 /* Schedule next timeout. */
485
486 timers->timer[timer_nr].start = hw_event_queue_time(me);
487 /* FIX: Check if div_ ratio has changed and if it's now 0. */
488 timers->timer[timer_nr].event
489 = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
490 do_counter_event, (void *)timer_nr);
491 }
492
493 }
494
495 static void
496 write_base_reg (struct hw *me,
497 struct mn103tim *timers,
498 int timer_nr,
499 const void *source,
500 unsigned nr_bytes)
501 {
502 unsigned i;
503 const unsigned8 *buf8 = source;
504 const unsigned16 *buf16 = source;
505 unsigned8 mode_val;
506
507 /* If TMnCNE == 0 (counting is off), writing to the base register
508 (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
509 Else, the TMnBC is reloaded with the value from TMnBR when
510 underflow occurs. Since the counter register is not explicitly
511 maintained, this functionality is handled in read_counter. */
512
513 mode_val = timers->timer[timer_nr].mode;
514
515 /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
516 switch ( nr_bytes )
517 {
518 case 1:
519 /* Storing 1 byte is ok for all registers. */
520 timers->timer[timer_nr].base = buf8[0];
521 break;
522
523 case 2:
524 if ( timer_nr == 1 || timer_nr == 3 )
525 {
526 hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
527 }
528 else
529 {
530 if ( timer_nr < NR_8BIT_TIMERS )
531 {
532 timers->timer[timer_nr].base = buf8[0];
533 timers->timer[timer_nr+1].base = buf8[1];
534 }
535 else
536 {
537 timers->timer[timer_nr].base = buf16[0];
538 }
539 }
540 break;
541
542 case 4:
543 if ( timer_nr == 0 )
544 {
545 ASSERT(0);
546 timers->timer[0].base = buf8[0];
547 timers->timer[1].base = buf8[1];
548 timers->timer[2].base = buf8[2];
549 timers->timer[3].base = buf8[3];
550 }
551 else if ( timer_nr == 4 )
552 {
553 timers->timer[4].base = buf16[0];
554 timers->timer[5].base = buf16[1];
555 }
556 else
557 {
558 hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
559 }
560 break;
561
562 default:
563 hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
564 nr_bytes, timer_nr);
565 }
566
567 }
568
569 static void
570 write_8bit_mode_reg (struct hw *me,
571 struct mn103tim *timers,
572 int timer_nr,
573 const void *source,
574 unsigned nr_bytes)
575 /* for timers 0 to 3 */
576 {
577 unsigned i;
578 unsigned8 mode_val, next_mode_val;
579 unsigned32 div_ratio;
580
581 if ( nr_bytes != 1 )
582 {
583 hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
584 }
585
586 mode_val = *(unsigned8 *)source;
587 timers->timer[timer_nr].mode = mode_val;
588
589 if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
590 {
591 hw_abort(me, "Cannot load base reg and start counting simultaneously.");
592 }
593 if ( ( mode_val & bits2to5_mask ) != 0 )
594 {
595 hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
596 }
597
598 if ( mode_val & count_mask )
599 {
600 /* - de-schedule any previous event. */
601 /* - add new event to queue to start counting. */
602 /* - assert that counter == base reg? */
603
604 /* For cascaded timers, */
605 if ( (mode_val & clock_mask) == clk_cascaded )
606 {
607 if ( timer_nr == 0 )
608 {
609 hw_abort(me, "Timer 0 cannot be cascaded.");
610 }
611 }
612 else
613 {
614 div_ratio = timers->timer[timer_nr].base;
615
616 /* Check for cascading. */
617 next_mode_val = timers->timer[timer_nr+1].mode;
618 if ( ( next_mode_val & clock_mask ) == clk_cascaded )
619 {
620 /* Check that CNE is on. */
621 if ( ( next_mode_val & count_mask ) == 0 )
622 {
623 hw_abort (me, "cascaded timer not ready for counting");
624 }
625 ASSERT(timers->timer[timer_nr+1].event == NULL);
626 ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
627 div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 8);
628 }
629
630 timers->timer[timer_nr].div_ratio = div_ratio;
631
632 if ( NULL != timers->timer[timer_nr].event )
633 {
634 hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
635 timers->timer[timer_nr].event = NULL;
636 }
637
638 if ( div_ratio > 0 )
639 {
640 /* Set start time. */
641 timers->timer[timer_nr].start = hw_event_queue_time(me);
642
643 timers->timer[timer_nr].event
644 = hw_event_queue_schedule(me, div_ratio,
645 do_counter_event,
646 (void *)(timer_nr));
647 }
648 }
649 }
650 else
651 {
652 /* Turn off counting */
653 if ( NULL != timers->timer[timer_nr].event )
654 {
655 ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
656 hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
657 timers->timer[timer_nr].event = NULL;
658 }
659 else
660 {
661 if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
662 {
663 ASSERT(timers->timer[timer_nr].event == NULL);
664 }
665 }
666
667 }
668
669 }
670
671 static void
672 write_16bit_mode_reg (struct hw *me,
673 struct mn103tim *timers,
674 int timer_nr,
675 const void *source,
676 unsigned nr_bytes)
677 /* for timers 4 and 5, not 6 */
678 {
679 unsigned i;
680 unsigned8 mode_val, next_mode_val;
681 unsigned32 div_ratio;
682
683 if ( nr_bytes != 1 )
684 {
685 hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
686 }
687
688 mode_val = *(unsigned8 *)source;
689 timers->timer[timer_nr].mode = mode_val;
690
691 if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
692 {
693 hw_abort(me, "Cannot load base reg and start counting simultaneously.");
694 }
695 if ( ( mode_val & bits2to5_mask ) != 0 )
696 {
697 hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
698 }
699
700
701 if ( mode_val & count_mask )
702 {
703 /* - de-schedule any previous event. */
704 /* - add new event to queue to start counting. */
705 /* - assert that counter == base reg? */
706
707 /* For cascaded timers, */
708 if ( (mode_val & clock_mask) == clk_cascaded )
709 {
710 if ( timer_nr == 4 )
711 {
712 hw_abort(me, "Timer 4 cannot be cascaded.");
713 }
714 }
715 else
716 {
717 div_ratio = timers->timer[timer_nr].base;
718
719 /* Check for cascading. */
720 next_mode_val = timers->timer[timer_nr+1].mode;
721 if ( ( next_mode_val & clock_mask ) == clk_cascaded )
722 {
723 /* Check that CNE is on. */
724 if ( ( next_mode_val & count_mask ) == 0 )
725 {
726 hw_abort (me, "cascaded timer not ready for counting");
727 }
728 ASSERT(timers->timer[timer_nr+1].event == NULL);
729 ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
730 div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 16);
731 }
732
733 timers->timer[timer_nr].div_ratio = div_ratio;
734
735 if ( NULL != timers->timer[timer_nr].event )
736 {
737 hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
738 timers->timer[timer_nr].event = NULL;
739 }
740
741 if ( div_ratio > 0 )
742 {
743 /* Set start time. */
744 timers->timer[timer_nr].start = hw_event_queue_time(me);
745
746 timers->timer[timer_nr].event
747 = hw_event_queue_schedule(me, div_ratio, do_counter_event,
748 (void *)(timer_nr));
749 }
750 }
751 }
752 else
753 {
754 /* Turn off counting */
755 if ( NULL != timers->timer[timer_nr].event )
756 {
757 ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
758 hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
759 timers->timer[timer_nr].event = NULL;
760 }
761 else
762 {
763 if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
764 {
765 ASSERT(timers->timer[timer_nr].event == NULL);
766 }
767 }
768
769 }
770
771 }
772
773 static unsigned
774 mn103tim_io_write_buffer (struct hw *me,
775 const void *source,
776 int space,
777 unsigned_word base,
778 unsigned nr_bytes)
779 {
780 struct mn103tim *timers = hw_data (me);
781 enum timer_register_types timer_reg;
782
783 HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
784 (int) nr_bytes, *(unsigned32 *)source));
785
786 timer_reg = decode_addr (me, timers, base);
787
788 /* It can be either a mode register, a base register or a binary counter. */
789 /* Check in that order. */
790 if ( timer_reg <= LAST_MODE_REG )
791 {
792 if ( timer_reg > 3 )
793 {
794 write_16bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
795 source, nr_bytes);
796 }
797 else
798 {
799 write_8bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
800 source, nr_bytes);
801 }
802 }
803 else if ( timer_reg <= LAST_BASE_REG )
804 {
805 write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
806 }
807 else if ( timer_reg <= LAST_COUNTER )
808 {
809 hw_abort(me, "cannot write to counter");
810 }
811 else
812 {
813 hw_abort(me, "invalid reg type");
814 }
815
816 return nr_bytes;
817 }
818
819
820 const struct hw_descriptor dv_mn103tim_descriptor[] = {
821 { "mn103tim", mn103tim_finish, },
822 { NULL },
823 };
This page took 0.046851 seconds and 4 git commands to generate.