interrupts.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* interrupts.h -- 68HC11 Interrupts Emulation
  2. Copyright 1999-2022 Free Software Foundation, Inc.
  3. Written by Stephane Carrez (stcarrez@worldnet.fr)
  4. This file is part of GDB, GAS, and the GNU binutils.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #ifndef _M6811_SIM_INTERRUPTS_H
  16. #define _M6811_SIM_INTERRUPTS_H
  17. /* Definition of 68HC11 interrupts. These enum are used as an index
  18. in the interrupt table. */
  19. enum M6811_INT
  20. {
  21. M6811_INT_RESERVED1 = 0,
  22. M6811_INT_RESERVED2,
  23. M6811_INT_RESERVED3,
  24. M6811_INT_RESERVED4,
  25. M6811_INT_RESERVED5,
  26. M6811_INT_RESERVED6,
  27. M6811_INT_RESERVED7,
  28. M6811_INT_RESERVED8,
  29. M6811_INT_RESERVED9,
  30. M6811_INT_RESERVED10,
  31. M6811_INT_RESERVED11,
  32. M6811_INT_SCI,
  33. M6811_INT_SPI,
  34. M6811_INT_AINPUT,
  35. M6811_INT_AOVERFLOW,
  36. M6811_INT_TCTN,
  37. M6811_INT_OUTCMP5,
  38. M6811_INT_OUTCMP4,
  39. M6811_INT_OUTCMP3,
  40. M6811_INT_OUTCMP2,
  41. M6811_INT_OUTCMP1,
  42. M6811_INT_INCMP3,
  43. M6811_INT_INCMP2,
  44. M6811_INT_INCMP1,
  45. M6811_INT_RT,
  46. M6811_INT_IRQ,
  47. M6811_INT_XIRQ,
  48. M6811_INT_SWI,
  49. M6811_INT_ILLEGAL,
  50. M6811_INT_COPRESET,
  51. M6811_INT_COPFAIL,
  52. M6811_INT_RESET,
  53. M6811_INT_NUMBER
  54. };
  55. /* Structure to describe how to recognize an interrupt in the
  56. 68hc11 IO regs. */
  57. struct interrupt_def
  58. {
  59. enum M6811_INT int_number;
  60. unsigned char int_paddr;
  61. unsigned char int_mask;
  62. unsigned char enable_paddr;
  63. unsigned char enabled_mask;
  64. };
  65. #define MAX_INT_HISTORY 64
  66. /* Structure used to keep track of interrupt history.
  67. This is used to understand in which order interrupts were
  68. raised and when. */
  69. struct interrupt_history
  70. {
  71. enum M6811_INT type;
  72. /* CPU cycle when interrupt handler is called. */
  73. int64_t taken_cycle;
  74. /* CPU cycle when the interrupt is first raised by the device. */
  75. int64_t raised_cycle;
  76. };
  77. #define SIM_STOP_WHEN_RAISED 1
  78. #define SIM_STOP_WHEN_TAKEN 2
  79. /* Information and control of pending interrupts. */
  80. struct interrupt
  81. {
  82. /* CPU cycle when the interrupt is raised by the device. */
  83. int64_t cpu_cycle;
  84. /* Number of times the interrupt was raised. */
  85. unsigned long raised_count;
  86. /* Controls whether we must stop the simulator. */
  87. int stop_mode;
  88. };
  89. /* Management of 68HC11 interrupts:
  90. - We use a table of 'interrupt_def' to describe the interrupts that must be
  91. raised depending on IO register flags (enable and present flags).
  92. - We keep a mask of pending interrupts. This mask is refreshed by
  93. calling 'interrupts_update_pending'. It must be refreshed each time
  94. an IO register is changed.
  95. - 'interrupts_process' must be called after each insn. It has two purposes:
  96. first it maintains a min/max count of CPU cycles between which interrupts
  97. are masked; second it checks for pending interrupts and raise one if
  98. interrupts are enabled. */
  99. struct interrupts {
  100. sim_cpu *cpu;
  101. /* Mask of current pending interrupts. */
  102. unsigned long pending_mask;
  103. /* Address of vector table. This is set depending on the
  104. 68hc11 init mode. */
  105. uint16_t vectors_addr;
  106. /* Priority order of interrupts. This is controlled by setting the HPRIO
  107. IO register. */
  108. enum M6811_INT interrupt_order[M6811_INT_NUMBER];
  109. struct interrupt interrupts[M6811_INT_NUMBER];
  110. /* Simulator statistics to report useful debug information to users. */
  111. /* - Max/Min number of CPU cycles executed with interrupts masked. */
  112. int64_t start_mask_cycle;
  113. int64_t min_mask_cycles;
  114. int64_t max_mask_cycles;
  115. int64_t last_mask_cycles;
  116. /* - Same for XIRQ. */
  117. int64_t xirq_start_mask_cycle;
  118. int64_t xirq_min_mask_cycles;
  119. int64_t xirq_max_mask_cycles;
  120. int64_t xirq_last_mask_cycles;
  121. /* - Total number of interrupts raised. */
  122. unsigned long nb_interrupts_raised;
  123. /* Interrupt history to help understand which interrupts
  124. were raised recently and in which order. */
  125. int history_index;
  126. struct interrupt_history interrupts_history[MAX_INT_HISTORY];
  127. };
  128. extern void interrupts_initialize (SIM_DESC sd, sim_cpu *cpu);
  129. extern void interrupts_reset (struct interrupts* interrupts);
  130. extern void interrupts_update_pending (struct interrupts* interrupts);
  131. extern int interrupts_get_current (struct interrupts* interrupts);
  132. extern int interrupts_process (struct interrupts* interrupts);
  133. extern void interrupts_raise (struct interrupts* interrupts,
  134. enum M6811_INT number);
  135. extern void interrupts_info (SIM_DESC sd,
  136. struct interrupts* interrupts);
  137. #endif