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