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