1/* interrupts.h -- 68HC11 Interrupts Emulation 2 Copyright 1999-2020 Free Software Foundation, Inc. 3 Written by Stephane Carrez (stcarrez@worldnet.fr) 4 5This file is part of GDB, GAS, and the GNU binutils. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 11 12This program is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along 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. */ 25enum 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. */ 72struct 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. */ 86struct interrupt_history 87{ 88 enum M6811_INT type; 89 90 /* CPU cycle when interrupt handler is called. */ 91 signed64 taken_cycle; 92 93 /* CPU cycle when the interrupt is first raised by the device. */ 94 signed64 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. */ 101struct interrupt 102{ 103 /* CPU cycle when the interrupt is raised by the device. */ 104 signed64 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. */ 124struct 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 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 signed64 start_mask_cycle; 143 signed64 min_mask_cycles; 144 signed64 max_mask_cycles; 145 signed64 last_mask_cycles; 146 147 /* - Same for XIRQ. */ 148 signed64 xirq_start_mask_cycle; 149 signed64 xirq_min_mask_cycles; 150 signed64 xirq_max_mask_cycles; 151 signed64 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 162extern void interrupts_initialize (SIM_DESC sd, sim_cpu *cpu); 163extern void interrupts_reset (struct interrupts* interrupts); 164extern void interrupts_update_pending (struct interrupts* interrupts); 165extern int interrupts_get_current (struct interrupts* interrupts); 166extern int interrupts_process (struct interrupts* interrupts); 167extern void interrupts_raise (struct interrupts* interrupts, 168 enum M6811_INT number); 169 170extern void interrupts_info (SIM_DESC sd, 171 struct interrupts* interrupts); 172 173#endif 174