Fix 68hc11 timer device (accuracy, io, timer overflow)
[binutils-gdb.git] / sim / m68hc11 / dv-m68hc11tim.c
1 /* dv-m68hc11tim.c -- Simulation of the 68HC11 timer devices.
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
4 (From a driver model Contributed by Cygnus Solutions.)
5
6 This file is part of the program GDB, the GNU debugger.
7
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.
12
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.
17
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.
21
22 */
23
24
25 #include "sim-main.h"
26 #include "hw-main.h"
27 #include "sim-assert.h"
28
29
30 /* DEVICE
31
32 m68hc11tim - m68hc11 timer devices
33
34
35 DESCRIPTION
36
37 Implements the m68hc11 timer as described in Chapter 10
38 of the pink book.
39
40
41 PROPERTIES
42
43 none
44
45
46 PORTS
47
48 reset (input)
49
50 Reset the timer device. This port must be connected to
51 the cpu-reset output port.
52
53 */
54
55
56
57 /* port ID's */
58
59 enum
60 {
61 RESET_PORT
62 };
63
64
65 static const struct hw_port_descriptor m68hc11tim_ports[] =
66 {
67 { "reset", RESET_PORT, 0, input_port, },
68 { NULL, },
69 };
70
71
72 /* Timer Controller information. */
73 struct m68hc11tim
74 {
75 unsigned long cop_delay;
76 unsigned long rti_delay;
77 unsigned long ovf_delay;
78 signed64 clock_prescaler;
79 signed64 tcnt_adjust;
80 signed64 cop_prev_interrupt;
81 signed64 rti_prev_interrupt;
82
83 /* Periodic timers. */
84 struct hw_event *rti_timer_event;
85 struct hw_event *cop_timer_event;
86 struct hw_event *tof_timer_event;
87 struct hw_event *cmp_timer_event;
88 };
89
90
91
92 /* Finish off the partially created hw device. Attach our local
93 callbacks. Wire up our port names etc. */
94
95 static hw_io_read_buffer_method m68hc11tim_io_read_buffer;
96 static hw_io_write_buffer_method m68hc11tim_io_write_buffer;
97 static hw_port_event_method m68hc11tim_port_event;
98 static hw_ioctl_method m68hc11tim_ioctl;
99
100 #define M6811_TIMER_FIRST_REG (M6811_TCTN)
101 #define M6811_TIMER_LAST_REG (M6811_PACNT)
102
103
104 static void
105 attach_m68hc11tim_regs (struct hw *me,
106 struct m68hc11tim *controller)
107 {
108 hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
109 M6811_TIMER_FIRST_REG,
110 M6811_TIMER_LAST_REG - M6811_TIMER_FIRST_REG + 1,
111 me);
112 }
113
114
115 static void
116 m68hc11tim_finish (struct hw *me)
117 {
118 struct m68hc11tim *controller;
119
120 controller = HW_ZALLOC (me, struct m68hc11tim);
121 set_hw_data (me, controller);
122 set_hw_io_read_buffer (me, m68hc11tim_io_read_buffer);
123 set_hw_io_write_buffer (me, m68hc11tim_io_write_buffer);
124 set_hw_ports (me, m68hc11tim_ports);
125 set_hw_port_event (me, m68hc11tim_port_event);
126 #ifdef set_hw_ioctl
127 set_hw_ioctl (me, m68hc11tim_ioctl);
128 #else
129 me->to_ioctl = m68hc11tim_ioctl;
130 #endif
131
132 /* Preset defaults. */
133 controller->clock_prescaler = 1;
134 controller->tcnt_adjust = 0;
135
136 /* Attach ourself to our parent bus. */
137 attach_m68hc11tim_regs (me, controller);
138 }
139
140
141
142 /* An event arrives on an interrupt port. */
143
144 static void
145 m68hc11tim_port_event (struct hw *me,
146 int my_port,
147 struct hw *source,
148 int source_port,
149 int level)
150 {
151 SIM_DESC sd;
152 struct m68hc11tim *controller;
153 sim_cpu *cpu;
154 unsigned8 val;
155
156 controller = hw_data (me);
157 sd = hw_system (me);
158 cpu = STATE_CPU (sd, 0);
159 switch (my_port)
160 {
161 case RESET_PORT:
162 {
163 HW_TRACE ((me, "Timer reset"));
164
165 /* Cancel all timer events. */
166 if (controller->rti_timer_event)
167 {
168 hw_event_queue_deschedule (me, controller->rti_timer_event);
169 controller->rti_timer_event = 0;
170 controller->rti_prev_interrupt = 0;
171 }
172 if (controller->cop_timer_event)
173 {
174 hw_event_queue_deschedule (me, controller->cop_timer_event);
175 controller->cop_timer_event = 0;
176 controller->cop_prev_interrupt = 0;
177 }
178 if (controller->tof_timer_event)
179 {
180 hw_event_queue_deschedule (me, controller->tof_timer_event);
181 controller->tof_timer_event = 0;
182 }
183 if (controller->cmp_timer_event)
184 {
185 hw_event_queue_deschedule (me, controller->cmp_timer_event);
186 controller->cmp_timer_event = 0;
187 }
188
189 /* Reset the state of Timer registers. This also restarts
190 the timer events (overflow and RTI clock). */
191 val = 0;
192 m68hc11tim_io_write_buffer (me, &val, io_map,
193 (unsigned_word) M6811_TMSK2, 1);
194 m68hc11tim_io_write_buffer (me, &val, io_map,
195 (unsigned_word) M6811_TFLG2, 1);
196 m68hc11tim_io_write_buffer (me, &val, io_map,
197 (unsigned_word) M6811_PACTL, 1);
198 break;
199 }
200
201 default:
202 hw_abort (me, "Event on unknown port %d", my_port);
203 break;
204 }
205 }
206
207 enum event_type
208 {
209 COP_EVENT,
210 RTI_EVENT,
211 OVERFLOW_EVENT,
212 COMPARE_EVENT
213 };
214
215 void
216 m68hc11tim_timer_event (struct hw *me, void *data)
217 {
218 SIM_DESC sd;
219 struct m68hc11tim *controller;
220 sim_cpu *cpu;
221 enum event_type type;
222 unsigned long delay;
223 struct hw_event **eventp;
224 int check_interrupt = 0;
225 unsigned mask;
226 unsigned flags;
227 unsigned long tcnt_internal;
228 unsigned long tcnt;
229 int i;
230 sim_events *events;
231
232 controller = hw_data (me);
233 sd = hw_system (me);
234 cpu = STATE_CPU (sd, 0);
235 type = (enum event_type) ((long) data) & 0x0FF;
236 events = STATE_EVENTS (sd);
237
238 delay = 0;
239 switch (type)
240 {
241 case COP_EVENT:
242 eventp = &controller->cop_timer_event;
243 delay = controller->cop_delay;
244 delay = controller->cop_prev_interrupt + controller->cop_delay;
245 controller->cop_prev_interrupt = delay;
246 delay = delay - cpu->cpu_absolute_cycle;
247 check_interrupt = 1;
248 delay += events->nr_ticks_to_process;
249 break;
250
251 case RTI_EVENT:
252 eventp = &controller->rti_timer_event;
253 delay = controller->rti_prev_interrupt + controller->rti_delay;
254
255 if (((long) (data) & 0x0100) == 0)
256 {
257 cpu->ios[M6811_TFLG2] |= M6811_RTIF;
258 check_interrupt = 1;
259 controller->rti_prev_interrupt = delay;
260 delay += controller->rti_delay;
261 }
262 delay = delay - cpu->cpu_absolute_cycle;
263 delay += events->nr_ticks_to_process;
264 break;
265
266 case OVERFLOW_EVENT:
267 /* Compute the 68HC11 internal free running counter.
268 There may be 'nr_ticks_to_process' pending cycles that are
269 not (yet) taken into account by 'sim_events_time'. */
270 tcnt_internal = sim_events_time (sd) - controller->tcnt_adjust;
271 tcnt_internal += events->nr_ticks_to_process;
272
273 /* We must take into account the prescaler that comes
274 before the counter (it's a power of 2). */
275 tcnt_internal &= 0x0ffff * controller->clock_prescaler;
276
277 /* Compute the time when the overflow will occur. It occurs when
278 the counter increments from 0x0ffff to 0x10000 (and thus resets). */
279 delay = (0x10000 * controller->clock_prescaler) - tcnt_internal;
280
281 /* The 'nr_ticks_to_process' will be subtracted when the event
282 is scheduled. */
283 delay += events->nr_ticks_to_process;
284
285 eventp = &controller->tof_timer_event;
286 if (((long) (data) & 0x100) == 0)
287 {
288 cpu->ios[M6811_TFLG2] |= M6811_TOF;
289 check_interrupt = 1;
290 }
291 break;
292
293 case COMPARE_EVENT:
294 eventp = &controller->cmp_timer_event;
295
296 /* Compute the 68HC11 internal free running counter.
297 There may be 'nr_ticks_to_process' pending cycles that are
298 not (yet) taken into account by 'sim_events_time'. */
299 events = STATE_EVENTS (sd);
300 tcnt_internal = sim_events_time (sd) - controller->tcnt_adjust;
301 tcnt_internal += events->nr_ticks_to_process;
302
303 /* We must take into account the prescaler that comes
304 before the counter (it's a power of 2). */
305 tcnt_internal &= 0x0ffff * controller->clock_prescaler;
306
307 /* Get current visible TCNT register value. */
308 tcnt = tcnt_internal / controller->clock_prescaler;
309
310 flags = cpu->ios[M6811_TMSK1];
311 mask = 0x80;
312 delay = 65536 * controller->clock_prescaler;
313
314 /* Scan each output compare register to see if one matches
315 the free running counter. Set the corresponding OCi flag
316 if the output compare is enabled. */
317 for (i = M6811_TOC1; i <= M6811_TOC5; i += 2, mask >>= 1)
318 {
319 unsigned long compare;
320
321 compare = (cpu->ios[i] << 8) + cpu->ios[i+1];
322 if (compare == tcnt && (flags & mask))
323 {
324 cpu->ios[M6811_TFLG1] |= mask;
325 check_interrupt++;
326 }
327
328 /* Compute how many times for the next match.
329 Use the internal counter value to take into account the
330 prescaler accurately. */
331 compare = compare * controller->clock_prescaler;
332 if (compare > tcnt_internal)
333 compare = compare - tcnt_internal;
334 else
335 compare = compare - tcnt_internal
336 + 65536 * controller->clock_prescaler;
337
338 if (compare < delay)
339 delay = compare;
340 }
341
342 /* Deactivate the compare timer if no output compare is enabled. */
343 if ((flags & 0xF0) == 0)
344 delay = 0;
345 break;
346
347 default:
348 eventp = 0;
349 break;
350 }
351
352 if (*eventp)
353 {
354 hw_event_queue_deschedule (me, *eventp);
355 *eventp = 0;
356 }
357
358 if (delay != 0)
359 {
360 *eventp = hw_event_queue_schedule (me, delay,
361 m68hc11tim_timer_event,
362 (void*) type);
363 }
364
365 if (check_interrupt)
366 interrupts_update_pending (&cpu->cpu_interrupts);
367 }
368
369
370 /* Descriptions of the Timer I/O ports. These descriptions are only used to
371 give information of the Timer device under GDB. */
372 io_reg_desc tmsk2_desc[] = {
373 { M6811_TOI, "TOI ", "Timer Overflow Interrupt Enable" },
374 { M6811_RTII, "RTII ", "RTI Interrupt Enable" },
375 { M6811_PAOVI, "PAOVI ", "Pulse Accumulator Overflow Interrupt Enable" },
376 { M6811_PAII, "PAII ", "Pulse Accumulator Interrupt Enable" },
377 { M6811_PR1, "PR1 ", "Timer prescaler (PR1)" },
378 { M6811_PR0, "PR0 ", "Timer prescaler (PR0)" },
379 { M6811_TPR_1, "TPR_1 ", "Timer prescaler div 1" },
380 { M6811_TPR_4, "TPR_4 ", "Timer prescaler div 4" },
381 { M6811_TPR_8, "TPR_8 ", "Timer prescaler div 8" },
382 { M6811_TPR_16, "TPR_16", "Timer prescaler div 16" },
383 { 0, 0, 0 }
384 };
385
386 io_reg_desc tflg2_desc[] = {
387 { M6811_TOF, "TOF ", "Timer Overflow Bit" },
388 { M6811_RTIF, "RTIF ", "Read Time Interrupt Flag" },
389 { M6811_PAOVF, "PAOVF ", "Pulse Accumulator Overflow Interrupt Flag" },
390 { M6811_PAIF, "PAIF ", "Pulse Accumulator Input Edge" },
391 { 0, 0, 0 }
392 };
393
394 io_reg_desc pactl_desc[] = {
395 { M6811_DDRA7, "DDRA7 ", "Data Direction for Port A bit-7" },
396 { M6811_PAEN, "PAEN ", "Pulse Accumulator System Enable" },
397 { M6811_PAMOD, "PAMOD ", "Pulse Accumulator Mode" },
398 { M6811_PEDGE, "PEDGE ", "Pulse Accumulator Edge Control" },
399 { M6811_RTR1, "RTR1 ", "RTI Interrupt rate select (RTR1)" },
400 { M6811_RTR0, "RTR0 ", "RTI Interrupt rate select (RTR0)" },
401 { 0, 0, 0 }
402 };
403
404 static double
405 to_realtime (sim_cpu *cpu, signed64 t)
406 {
407 return (double) (t) / (double) (cpu->cpu_frequency / 4);
408 }
409
410 static void
411 m68hc11tim_print_timer (struct hw *me, const char *name,
412 struct hw_event *event)
413 {
414 SIM_DESC sd;
415
416 sd = hw_system (me);
417 if (event == 0)
418 {
419 sim_io_printf (sd, " No %s interrupt will be raised.\n", name);
420 }
421 else
422 {
423 signed64 t;
424 double dt;
425 sim_cpu* cpu;
426
427 cpu = STATE_CPU (sd, 0);
428
429 t = hw_event_remain_time (me, event);
430 dt = to_realtime (cpu, t) * 1000.0;
431 sim_io_printf (sd, " Next %s interrupt in %ld cycles (%3.3f ms)\n",
432 name, (long) t, dt);
433 }
434 }
435
436 static void
437 m68hc11tim_info (struct hw *me)
438 {
439 SIM_DESC sd;
440 uint16 base = 0;
441 sim_cpu *cpu;
442 struct m68hc11tim *controller;
443 uint8 val;
444
445 sd = hw_system (me);
446 cpu = STATE_CPU (sd, 0);
447 controller = hw_data (me);
448
449 sim_io_printf (sd, "M68HC11 Timer:\n");
450
451 base = cpu_get_io_base (cpu);
452
453 val = cpu->ios[M6811_TMSK2];
454 print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2);
455 sim_io_printf (sd, "\n");
456
457 val = cpu->ios[M6811_TFLG2];
458 print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2);
459 sim_io_printf (sd, "\n");
460
461 val = cpu->ios[M6811_PACTL];
462 print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL);
463 sim_io_printf (sd, "\n");
464
465 /* Give info about the next timer interrupts. */
466 m68hc11tim_print_timer (me, "RTI", controller->rti_timer_event);
467 m68hc11tim_print_timer (me, "COP", controller->cop_timer_event);
468 m68hc11tim_print_timer (me, "OVERFLOW", controller->tof_timer_event);
469 m68hc11tim_print_timer (me, "COMPARE", controller->cmp_timer_event);
470 }
471
472 static int
473 m68hc11tim_ioctl (struct hw *me,
474 hw_ioctl_request request,
475 va_list ap)
476 {
477 m68hc11tim_info (me);
478 return 0;
479 }
480
481 /* generic read/write */
482
483 static unsigned
484 m68hc11tim_io_read_buffer (struct hw *me,
485 void *dest,
486 int space,
487 unsigned_word base,
488 unsigned nr_bytes)
489 {
490 SIM_DESC sd;
491 struct m68hc11tim *controller;
492 sim_cpu *cpu;
493 unsigned8 val;
494 unsigned cnt = 0;
495
496 HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
497
498 sd = hw_system (me);
499 cpu = STATE_CPU (sd, 0);
500 controller = hw_data (me);
501
502 while (nr_bytes)
503 {
504 switch (base)
505 {
506 /* The cpu_absolute_cycle is updated after each instruction.
507 Reading in a 16-bit register will be split in two accesses
508 but this will be atomic within the simulator. */
509 case M6811_TCTN_H:
510 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
511 / (controller->clock_prescaler * 256));
512 break;
513
514 case M6811_TCTN_L:
515 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
516 / controller->clock_prescaler);
517 break;
518
519 default:
520 val = cpu->ios[base];
521 break;
522 }
523 *((unsigned8*) dest) = val;
524 dest++;
525 base++;
526 nr_bytes--;
527 cnt++;
528 }
529 return cnt;
530 }
531
532 static unsigned
533 m68hc11tim_io_write_buffer (struct hw *me,
534 const void *source,
535 int space,
536 unsigned_word base,
537 unsigned nr_bytes)
538 {
539 SIM_DESC sd;
540 struct m68hc11tim *controller;
541 sim_cpu *cpu;
542 unsigned8 val, n;
543 signed64 adj;
544 int reset_compare = 0;
545 int reset_overflow = 0;
546 int cnt = 0;
547
548 HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
549
550 sd = hw_system (me);
551 cpu = STATE_CPU (sd, 0);
552 controller = hw_data (me);
553
554 while (nr_bytes)
555 {
556 val = *((const unsigned8*) source);
557 switch (base)
558 {
559 /* Set the timer counter low part, trying to preserve the low part.
560 We compute the absolute cycle adjustment that we have to apply
561 to obtain the timer current value. Computation must be made
562 in 64-bit to avoid overflow problems. */
563 case M6811_TCTN_L:
564 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
565 / (controller->clock_prescaler * (signed64) 256)) & 0x0FF;
566 adj = cpu->cpu_absolute_cycle
567 - (adj * controller->clock_prescaler * (signed64) 256)
568 - ((signed64) adj * controller->clock_prescaler);
569 controller->tcnt_adjust = adj;
570 reset_compare = 1;
571 reset_overflow = 1;
572 break;
573
574 case M6811_TCTN_H:
575 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
576 / controller->clock_prescaler) & 0x0ff;
577 adj = cpu->cpu_absolute_cycle
578 - ((signed64) val * controller->clock_prescaler * (signed64) 256)
579 - (adj * controller->clock_prescaler);
580 controller->tcnt_adjust = adj;
581 reset_compare = 1;
582 reset_overflow = 1;
583 break;
584
585 case M6811_TMSK2:
586
587 /* Timer prescaler cannot be changed after 64 bus cycles. */
588 if (cpu->cpu_absolute_cycle >= 64)
589 {
590 val &= ~(M6811_PR1 | M6811_PR0);
591 val |= cpu->ios[M6811_TMSK2] & (M6811_PR1 | M6811_PR0);
592 }
593 switch (val & (M6811_PR1 | M6811_PR0))
594 {
595 case 0:
596 n = 1;
597 break;
598 case M6811_PR0:
599 n = 4;
600 break;
601 case M6811_PR1:
602 n = 8;
603 break;
604 default:
605 case M6811_PR1 | M6811_PR0:
606 n = 16;
607 break;
608 }
609 if (cpu->cpu_absolute_cycle < 64)
610 {
611 reset_overflow = 1;
612 controller->clock_prescaler = n;
613 }
614 cpu->ios[base] = val;
615 interrupts_update_pending (&cpu->cpu_interrupts);
616 break;
617
618 case M6811_PACTL:
619 n = (1 << ((val & (M6811_RTR1 | M6811_RTR0))));
620 cpu->ios[base] = val;
621
622 controller->rti_delay = (long) (n) * 8192;
623 m68hc11tim_timer_event (me, (void*) (RTI_EVENT| 0x100));
624 break;
625
626 case M6811_TFLG2:
627 if (val & M6811_TOF)
628 val &= ~M6811_TOF;
629 else
630 val |= cpu->ios[M6811_TFLG2] & M6811_TOF;
631
632 /* Clear the Real Time interrupt flag. */
633 if (val & M6811_RTIF)
634 val &= ~M6811_RTIF;
635 else
636 val |= cpu->ios[M6811_TFLG2] & M6811_RTIF;
637
638 cpu->ios[base] = val;
639 interrupts_update_pending (&cpu->cpu_interrupts);
640 break;
641
642 case M6811_TOC1:
643 case M6811_TOC2:
644 case M6811_TOC3:
645 case M6811_TOC4:
646 case M6811_TOC5:
647 cpu->ios[base] = val;
648 reset_compare = 1;
649 break;
650
651 default:
652 break;
653 }
654
655 base++;
656 nr_bytes--;
657 cnt++;
658 source++;
659 }
660
661 /* Re-compute the next timer compare event. */
662 if (reset_compare)
663 {
664 m68hc11tim_timer_event (me, (void*) (COMPARE_EVENT));
665 }
666 if (reset_overflow)
667 {
668 m68hc11tim_timer_event (me, (void*) (OVERFLOW_EVENT| 0x100));
669 }
670 return cnt;
671 }
672
673
674 const struct hw_descriptor dv_m68hc11tim_descriptor[] = {
675 { "m68hc11tim", m68hc11tim_finish, },
676 { NULL },
677 };
678