1 /* dv-m68hc11tim.c -- Simulation of the 68HC11 timer devices.
2 Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
4 (From a driver model Contributed by Cygnus Solutions.)
6 This file is part of the program GDB, the GNU debugger.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either vertimn 2 of the License, or
11 (at your option) any later vertimn.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include "sim-assert.h"
32 m68hc11tim - m68hc11 timer devices
37 Implements the m68hc11 timer as described in Chapter 10
50 Reset the timer device. This port must be connected to
51 the cpu-reset output port.
55 Input capture. This port must be connected to the input
56 captures. It latches the current TCNT free running counter
57 into one of the three input capture registers.
72 static const struct hw_port_descriptor m68hc11tim_ports
[] =
74 { "reset", RESET_PORT
, 0, input_port
, },
75 { "capture", CAPTURE
, 0, input_port
, },
80 /* Timer Controller information. */
83 unsigned long cop_delay
;
84 unsigned long rti_delay
;
85 unsigned long ovf_delay
;
86 signed64 clock_prescaler
;
88 signed64 cop_prev_interrupt
;
89 signed64 rti_prev_interrupt
;
91 /* Periodic timers. */
92 struct hw_event
*rti_timer_event
;
93 struct hw_event
*cop_timer_event
;
94 struct hw_event
*tof_timer_event
;
95 struct hw_event
*cmp_timer_event
;
100 /* Finish off the partially created hw device. Attach our local
101 callbacks. Wire up our port names etc. */
103 static hw_io_read_buffer_method m68hc11tim_io_read_buffer
;
104 static hw_io_write_buffer_method m68hc11tim_io_write_buffer
;
105 static hw_port_event_method m68hc11tim_port_event
;
106 static hw_ioctl_method m68hc11tim_ioctl
;
108 #define M6811_TIMER_FIRST_REG (M6811_TCTN)
109 #define M6811_TIMER_LAST_REG (M6811_PACNT)
113 attach_m68hc11tim_regs (struct hw
*me
,
114 struct m68hc11tim
*controller
)
116 hw_attach_address (hw_parent (me
), M6811_IO_LEVEL
, io_map
,
117 M6811_TIMER_FIRST_REG
,
118 M6811_TIMER_LAST_REG
- M6811_TIMER_FIRST_REG
+ 1,
123 m68hc11tim_finish (struct hw
*me
)
125 struct m68hc11tim
*controller
;
127 controller
= HW_ZALLOC (me
, struct m68hc11tim
);
128 set_hw_data (me
, controller
);
129 set_hw_io_read_buffer (me
, m68hc11tim_io_read_buffer
);
130 set_hw_io_write_buffer (me
, m68hc11tim_io_write_buffer
);
131 set_hw_ports (me
, m68hc11tim_ports
);
132 set_hw_port_event (me
, m68hc11tim_port_event
);
134 set_hw_ioctl (me
, m68hc11tim_ioctl
);
136 me
->to_ioctl
= m68hc11tim_ioctl
;
139 /* Preset defaults. */
140 controller
->clock_prescaler
= 1;
141 controller
->tcnt_adjust
= 0;
143 /* Attach ourself to our parent bus. */
144 attach_m68hc11tim_regs (me
, controller
);
148 /* An event arrives on an interrupt port. */
151 m68hc11tim_port_event (struct hw
*me
,
158 struct m68hc11tim
*controller
;
163 controller
= hw_data (me
);
165 cpu
= STATE_CPU (sd
, 0);
170 HW_TRACE ((me
, "Timer reset"));
172 /* Cancel all timer events. */
173 if (controller
->rti_timer_event
)
175 hw_event_queue_deschedule (me
, controller
->rti_timer_event
);
176 controller
->rti_timer_event
= 0;
177 controller
->rti_prev_interrupt
= 0;
179 if (controller
->cop_timer_event
)
181 hw_event_queue_deschedule (me
, controller
->cop_timer_event
);
182 controller
->cop_timer_event
= 0;
183 controller
->cop_prev_interrupt
= 0;
185 if (controller
->tof_timer_event
)
187 hw_event_queue_deschedule (me
, controller
->tof_timer_event
);
188 controller
->tof_timer_event
= 0;
190 if (controller
->cmp_timer_event
)
192 hw_event_queue_deschedule (me
, controller
->cmp_timer_event
);
193 controller
->cmp_timer_event
= 0;
196 /* Reset the state of Timer registers. This also restarts
197 the timer events (overflow and RTI clock). The pending
198 flags (TFLG2) must be cleared explicitly here. */
200 cpu
->ios
[M6811_TFLG2
] = 0;
201 m68hc11tim_io_write_buffer (me
, &val
, io_map
,
202 (unsigned_word
) M6811_TMSK2
, 1);
203 m68hc11tim_io_write_buffer (me
, &val
, io_map
,
204 (unsigned_word
) M6811_PACTL
, 1);
209 tcnt
= (uint16
) ((cpu
->cpu_absolute_cycle
- controller
->tcnt_adjust
)
210 / controller
->clock_prescaler
);
216 cpu
->ios
[level
] = tcnt
>> 8;
217 cpu
->ios
[level
+ 1] = tcnt
;
221 hw_abort (me
, "Invalid event parameter %d", level
);
227 hw_abort (me
, "Event on unknown port %d", my_port
);
241 m68hc11tim_timer_event (struct hw
*me
, void *data
)
244 struct m68hc11tim
*controller
;
246 enum event_type type
;
248 struct hw_event
**eventp
;
249 int check_interrupt
= 0;
252 unsigned long tcnt_internal
;
257 controller
= hw_data (me
);
259 cpu
= STATE_CPU (sd
, 0);
260 type
= (enum event_type
) ((long) data
) & 0x0FF;
261 events
= STATE_EVENTS (sd
);
267 eventp
= &controller
->cop_timer_event
;
268 delay
= controller
->cop_delay
;
269 delay
= controller
->cop_prev_interrupt
+ controller
->cop_delay
;
270 controller
->cop_prev_interrupt
= delay
;
271 delay
= delay
- cpu
->cpu_absolute_cycle
;
273 delay
+= events
->nr_ticks_to_process
;
277 eventp
= &controller
->rti_timer_event
;
278 delay
= controller
->rti_prev_interrupt
+ controller
->rti_delay
;
280 if (((long) (data
) & 0x0100) == 0)
282 cpu
->ios
[M6811_TFLG2
] |= M6811_RTIF
;
284 controller
->rti_prev_interrupt
= delay
;
285 delay
+= controller
->rti_delay
;
287 delay
= delay
- cpu
->cpu_absolute_cycle
;
288 delay
+= events
->nr_ticks_to_process
;
292 /* Compute the 68HC11 internal free running counter.
293 There may be 'nr_ticks_to_process' pending cycles that are
294 not (yet) taken into account by 'sim_events_time'. */
295 tcnt_internal
= sim_events_time (sd
) - controller
->tcnt_adjust
;
296 tcnt_internal
+= events
->nr_ticks_to_process
;
298 /* We must take into account the prescaler that comes
299 before the counter (it's a power of 2). */
300 tcnt_internal
&= 0x0ffff * controller
->clock_prescaler
;
302 /* Compute the time when the overflow will occur. It occurs when
303 the counter increments from 0x0ffff to 0x10000 (and thus resets). */
304 delay
= (0x10000 * controller
->clock_prescaler
) - tcnt_internal
;
306 /* The 'nr_ticks_to_process' will be subtracted when the event
308 delay
+= events
->nr_ticks_to_process
;
310 eventp
= &controller
->tof_timer_event
;
311 if (((long) (data
) & 0x100) == 0)
313 cpu
->ios
[M6811_TFLG2
] |= M6811_TOF
;
319 eventp
= &controller
->cmp_timer_event
;
321 /* Compute the 68HC11 internal free running counter.
322 There may be 'nr_ticks_to_process' pending cycles that are
323 not (yet) taken into account by 'sim_events_time'. */
324 events
= STATE_EVENTS (sd
);
325 tcnt_internal
= sim_events_time (sd
) - controller
->tcnt_adjust
;
326 tcnt_internal
+= events
->nr_ticks_to_process
;
328 /* We must take into account the prescaler that comes
329 before the counter (it's a power of 2). */
330 tcnt_internal
&= 0x0ffff * controller
->clock_prescaler
;
332 /* Get current visible TCNT register value. */
333 tcnt
= tcnt_internal
/ controller
->clock_prescaler
;
335 flags
= cpu
->ios
[M6811_TMSK1
];
337 delay
= 65536 * controller
->clock_prescaler
;
339 /* Scan each output compare register to see if one matches
340 the free running counter. Set the corresponding OCi flag
341 if the output compare is enabled. */
342 for (i
= M6811_TOC1
; i
<= M6811_TOC5
; i
+= 2, mask
>>= 1)
344 unsigned long compare
;
346 compare
= (cpu
->ios
[i
] << 8) + cpu
->ios
[i
+1];
347 if (compare
== tcnt
&& (flags
& mask
))
349 cpu
->ios
[M6811_TFLG1
] |= mask
;
353 /* Compute how many times for the next match.
354 Use the internal counter value to take into account the
355 prescaler accurately. */
356 compare
= compare
* controller
->clock_prescaler
;
357 if (compare
> tcnt_internal
)
358 compare
= compare
- tcnt_internal
;
360 compare
= compare
- tcnt_internal
361 + 65536 * controller
->clock_prescaler
;
367 /* Deactivate the compare timer if no output compare is enabled. */
368 if ((flags
& 0xF0) == 0)
379 hw_event_queue_deschedule (me
, *eventp
);
385 *eventp
= hw_event_queue_schedule (me
, delay
,
386 m68hc11tim_timer_event
,
391 interrupts_update_pending (&cpu
->cpu_interrupts
);
395 /* Descriptions of the Timer I/O ports. These descriptions are only used to
396 give information of the Timer device under GDB. */
397 io_reg_desc tmsk1_desc
[] = {
398 { M6811_OC1I
, "OC1I ", "Timer Output Compare 1 Interrupt Enable" },
399 { M6811_OC2I
, "OC2I ", "Timer Output Compare 2 Interrupt Enable" },
400 { M6811_OC3I
, "OC3I ", "Timer Output Compare 3 Interrupt Enable" },
401 { M6811_OC4I
, "OC4I ", "Timer Output Compare 4 Interrupt Enable" },
402 { M6811_OC5I
, "OC5I ", "Timer Input Capture 4 / Output Compare 5 Enable" },
403 { M6811_IC1I
, "IC1I ", "Timer Input Capture 1 Interrupt Enable" },
404 { M6811_IC2I
, "IC2I ", "Timer Input Capture 2 Interrupt Enable" },
405 { M6811_IC3I
, "IC3I ", "Timer Input Capture 3 Interrupt Enable" },
409 io_reg_desc tflg1_desc
[] = {
410 { M6811_OC1F
, "OC1F ", "Timer Output Compare 1 Interrupt Flag" },
411 { M6811_OC2F
, "OC2F ", "Timer Output Compare 2 Interrupt Flag" },
412 { M6811_OC3F
, "OC3F ", "Timer Output Compare 3 Interrupt Flag" },
413 { M6811_OC4F
, "OC4F ", "Timer Output Compare 4 Interrupt Flag" },
414 { M6811_OC5F
, "OC5F ", "Timer Input Capture 4 / Output Compare 5 Flag" },
415 { M6811_IC1F
, "IC1F ", "Timer Input Capture 1 Interrupt Flag" },
416 { M6811_IC2F
, "IC2F ", "Timer Input Capture 2 Interrupt Flag" },
417 { M6811_IC3F
, "IC3F ", "Timer Input Capture 3 Interrupt Flag" },
421 io_reg_desc tmsk2_desc
[] = {
422 { M6811_TOI
, "TOI ", "Timer Overflow Interrupt Enable" },
423 { M6811_RTII
, "RTII ", "RTI Interrupt Enable" },
424 { M6811_PAOVI
, "PAOVI ", "Pulse Accumulator Overflow Interrupt Enable" },
425 { M6811_PAII
, "PAII ", "Pulse Accumulator Interrupt Enable" },
426 { M6811_PR1
, "PR1 ", "Timer prescaler (PR1)" },
427 { M6811_PR0
, "PR0 ", "Timer prescaler (PR0)" },
428 { M6811_TPR_1
, "TPR_1 ", "Timer prescaler div 1" },
429 { M6811_TPR_4
, "TPR_4 ", "Timer prescaler div 4" },
430 { M6811_TPR_8
, "TPR_8 ", "Timer prescaler div 8" },
431 { M6811_TPR_16
, "TPR_16", "Timer prescaler div 16" },
435 io_reg_desc tflg2_desc
[] = {
436 { M6811_TOF
, "TOF ", "Timer Overflow Bit" },
437 { M6811_RTIF
, "RTIF ", "Read Time Interrupt Flag" },
438 { M6811_PAOVF
, "PAOVF ", "Pulse Accumulator Overflow Interrupt Flag" },
439 { M6811_PAIF
, "PAIF ", "Pulse Accumulator Input Edge" },
443 io_reg_desc pactl_desc
[] = {
444 { M6811_DDRA7
, "DDRA7 ", "Data Direction for Port A bit-7" },
445 { M6811_PAEN
, "PAEN ", "Pulse Accumulator System Enable" },
446 { M6811_PAMOD
, "PAMOD ", "Pulse Accumulator Mode" },
447 { M6811_PEDGE
, "PEDGE ", "Pulse Accumulator Edge Control" },
448 { M6811_RTR1
, "RTR1 ", "RTI Interrupt rate select (RTR1)" },
449 { M6811_RTR0
, "RTR0 ", "RTI Interrupt rate select (RTR0)" },
454 to_realtime (sim_cpu
*cpu
, signed64 t
)
456 return (double) (t
) / (double) (cpu
->cpu_frequency
/ 4);
460 cycle_to_string (sim_cpu
*cpu
, signed64 t
)
466 dt
= to_realtime (cpu
, t
);
468 sprintf (tbuf
, "(%3.1f us)", dt
* 1000000.0);
470 sprintf (tbuf
, "(%3.1f ms)", dt
* 1000.0);
472 sprintf (tbuf
, "(%3.1f s)", dt
);
474 sprintf (buf
, "%llu cycle%s %10.10s", t
,
475 (t
> 1 ? "s" : ""), tbuf
);
480 m68hc11tim_print_timer (struct hw
*me
, const char *name
,
481 struct hw_event
*event
)
488 sim_io_printf (sd
, " No %s interrupt will be raised.\n", name
);
495 cpu
= STATE_CPU (sd
, 0);
497 t
= hw_event_remain_time (me
, event
);
498 sim_io_printf (sd
, " Next %s interrupt in %s\n",
499 name
, cycle_to_string (cpu
, t
));
504 m68hc11tim_info (struct hw
*me
)
509 struct m68hc11tim
*controller
;
514 cpu
= STATE_CPU (sd
, 0);
515 controller
= hw_data (me
);
517 sim_io_printf (sd
, "M68HC11 Timer:\n");
519 base
= cpu_get_io_base (cpu
);
522 val16
= (cpu
->ios
[M6811_TIC1_H
] << 8) + cpu
->ios
[M6811_TIC1_L
];
523 print_io_word (sd
, "TIC1 ", 0, val16
, base
+ M6811_TIC1
);
524 sim_io_printf (sd
, "\n");
527 val16
= (cpu
->ios
[M6811_TIC2_H
] << 8) + cpu
->ios
[M6811_TIC2_L
];
528 print_io_word (sd
, "TIC2 ", 0, val16
, base
+ M6811_TIC2
);
529 sim_io_printf (sd
, "\n");
532 val16
= (cpu
->ios
[M6811_TIC3_H
] << 8) + cpu
->ios
[M6811_TIC3_L
];
533 print_io_word (sd
, "TIC3 ", 0, val16
, base
+ M6811_TIC3
);
534 sim_io_printf (sd
, "\n");
537 val16
= (cpu
->ios
[M6811_TOC1_H
] << 8) + cpu
->ios
[M6811_TOC1_L
];
538 print_io_word (sd
, "TOC1 ", 0, val16
, base
+ M6811_TOC1
);
539 sim_io_printf (sd
, "\n");
542 val16
= (cpu
->ios
[M6811_TOC2_H
] << 8) + cpu
->ios
[M6811_TOC2_L
];
543 print_io_word (sd
, "TOC2 ", 0, val16
, base
+ M6811_TOC2
);
544 sim_io_printf (sd
, "\n");
547 val16
= (cpu
->ios
[M6811_TOC3_H
] << 8) + cpu
->ios
[M6811_TOC3_L
];
548 print_io_word (sd
, "TOC3 ", 0, val16
, base
+ M6811_TOC3
);
549 sim_io_printf (sd
, "\n");
552 val16
= (cpu
->ios
[M6811_TOC4_H
] << 8) + cpu
->ios
[M6811_TOC4_L
];
553 print_io_word (sd
, "TOC4 ", 0, val16
, base
+ M6811_TOC4
);
554 sim_io_printf (sd
, "\n");
557 val16
= (cpu
->ios
[M6811_TOC5_H
] << 8) + cpu
->ios
[M6811_TOC5_L
];
558 print_io_word (sd
, "TOC5 ", 0, val16
, base
+ M6811_TOC5
);
559 sim_io_printf (sd
, "\n");
562 val
= cpu
->ios
[M6811_TMSK1
];
563 print_io_byte (sd
, "TMSK1 ", tmsk1_desc
, val
, base
+ M6811_TMSK1
);
564 sim_io_printf (sd
, "\n");
567 val
= cpu
->ios
[M6811_TFLG1
];
568 print_io_byte (sd
, "TFLG1", tflg1_desc
, val
, base
+ M6811_TFLG1
);
569 sim_io_printf (sd
, "\n");
571 val
= cpu
->ios
[M6811_TMSK2
];
572 print_io_byte (sd
, "TMSK2 ", tmsk2_desc
, val
, base
+ M6811_TMSK2
);
573 sim_io_printf (sd
, "\n");
575 val
= cpu
->ios
[M6811_TFLG2
];
576 print_io_byte (sd
, "TFLG2", tflg2_desc
, val
, base
+ M6811_TFLG2
);
577 sim_io_printf (sd
, "\n");
579 val
= cpu
->ios
[M6811_PACTL
];
580 print_io_byte (sd
, "PACTL", pactl_desc
, val
, base
+ M6811_PACTL
);
581 sim_io_printf (sd
, "\n");
583 val
= cpu
->ios
[M6811_PACNT
];
584 print_io_byte (sd
, "PACNT", 0, val
, base
+ M6811_PACNT
);
585 sim_io_printf (sd
, "\n");
587 /* Give info about the next timer interrupts. */
588 m68hc11tim_print_timer (me
, "RTI", controller
->rti_timer_event
);
589 m68hc11tim_print_timer (me
, "COP", controller
->cop_timer_event
);
590 m68hc11tim_print_timer (me
, "OVERFLOW", controller
->tof_timer_event
);
591 m68hc11tim_print_timer (me
, "COMPARE", controller
->cmp_timer_event
);
595 m68hc11tim_ioctl (struct hw
*me
,
596 hw_ioctl_request request
,
599 m68hc11tim_info (me
);
603 /* generic read/write */
606 m68hc11tim_io_read_buffer (struct hw
*me
,
613 struct m68hc11tim
*controller
;
618 HW_TRACE ((me
, "read 0x%08lx %d", (long) base
, (int) nr_bytes
));
621 cpu
= STATE_CPU (sd
, 0);
622 controller
= hw_data (me
);
628 /* The cpu_absolute_cycle is updated after each instruction.
629 Reading in a 16-bit register will be split in two accesses
630 but this will be atomic within the simulator. */
632 val
= (uint8
) ((cpu
->cpu_absolute_cycle
- controller
->tcnt_adjust
)
633 / (controller
->clock_prescaler
* 256));
637 val
= (uint8
) ((cpu
->cpu_absolute_cycle
- controller
->tcnt_adjust
)
638 / controller
->clock_prescaler
);
642 val
= cpu
->ios
[base
];
645 *((unsigned8
*) dest
) = val
;
655 m68hc11tim_io_write_buffer (struct hw
*me
,
662 struct m68hc11tim
*controller
;
666 int reset_compare
= 0;
667 int reset_overflow
= 0;
670 HW_TRACE ((me
, "write 0x%08lx %d", (long) base
, (int) nr_bytes
));
673 cpu
= STATE_CPU (sd
, 0);
674 controller
= hw_data (me
);
678 val
= *((const unsigned8
*) source
);
681 /* Set the timer counter low part, trying to preserve the low part.
682 We compute the absolute cycle adjustment that we have to apply
683 to obtain the timer current value. Computation must be made
684 in 64-bit to avoid overflow problems. */
686 adj
= ((cpu
->cpu_absolute_cycle
- controller
->tcnt_adjust
)
687 / (controller
->clock_prescaler
* (signed64
) 256)) & 0x0FF;
688 adj
= cpu
->cpu_absolute_cycle
689 - (adj
* controller
->clock_prescaler
* (signed64
) 256)
690 - ((signed64
) adj
* controller
->clock_prescaler
);
691 controller
->tcnt_adjust
= adj
;
697 adj
= ((cpu
->cpu_absolute_cycle
- controller
->tcnt_adjust
)
698 / controller
->clock_prescaler
) & 0x0ff;
699 adj
= cpu
->cpu_absolute_cycle
700 - ((signed64
) val
* controller
->clock_prescaler
* (signed64
) 256)
701 - (adj
* controller
->clock_prescaler
);
702 controller
->tcnt_adjust
= adj
;
709 /* Timer prescaler cannot be changed after 64 bus cycles. */
710 if (cpu
->cpu_absolute_cycle
>= 64)
712 val
&= ~(M6811_PR1
| M6811_PR0
);
713 val
|= cpu
->ios
[M6811_TMSK2
] & (M6811_PR1
| M6811_PR0
);
715 switch (val
& (M6811_PR1
| M6811_PR0
))
727 case M6811_PR1
| M6811_PR0
:
731 if (cpu
->cpu_absolute_cycle
< 64)
734 controller
->clock_prescaler
= n
;
736 cpu
->ios
[base
] = val
;
737 interrupts_update_pending (&cpu
->cpu_interrupts
);
741 n
= (1 << ((val
& (M6811_RTR1
| M6811_RTR0
))));
742 cpu
->ios
[base
] = val
;
744 controller
->rti_delay
= (long) (n
) * 8192;
745 m68hc11tim_timer_event (me
, (void*) (RTI_EVENT
| 0x100));
749 val
&= cpu
->ios
[M6811_TFLG2
];
750 cpu
->ios
[M6811_TFLG2
] &= ~val
;
751 interrupts_update_pending (&cpu
->cpu_interrupts
);
755 cpu
->ios
[M6811_TMSK1
] = val
;
756 interrupts_update_pending (&cpu
->cpu_interrupts
);
760 val
&= cpu
->ios
[M6811_TFLG1
];
761 cpu
->ios
[M6811_TFLG1
] &= ~val
;
762 interrupts_update_pending (&cpu
->cpu_interrupts
);
770 cpu
->ios
[base
] = val
;
776 cpu
->ios
[base
] = val
;
780 cpu
->ios
[base
] = val
;
790 /* Re-compute the next timer compare event. */
793 m68hc11tim_timer_event (me
, (void*) (COMPARE_EVENT
));
797 m68hc11tim_timer_event (me
, (void*) (OVERFLOW_EVENT
| 0x100));
803 const struct hw_descriptor dv_m68hc11tim_descriptor
[] = {
804 { "m68hc11tim", m68hc11tim_finish
},
805 { "m68hc12tim", m68hc11tim_finish
},