Commit | Line | Data |
---|---|---|
c906108c SS |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au> | |
4 | ||
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 | |
3fd725ef | 7 | the Free Software Foundation; either version 3 of the License, or |
c906108c SS |
8 | (at your option) any later version. |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
51b318de | 16 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
c906108c SS |
17 | |
18 | */ | |
19 | ||
20 | ||
21 | #ifndef _INTERRUPTS_H_ | |
22 | #define _INTERRUPTS_H_ | |
23 | ||
24 | /* Interrupts: | |
25 | ||
26 | The code below handles two different types of interrupts. | |
27 | Synchronous and Asynchronous. | |
28 | ||
29 | Synchronous: | |
30 | ||
31 | Interrupts that must immediately force either an abort or restart | |
32 | of a current instruction are implemented by forcing an instruction | |
33 | restart. (or to put it another way, long jump). In looking at the | |
34 | code it may occure to you that, for some interrupts, they could | |
35 | return instead of restarting the cpu (eg system_call). While true | |
36 | (it once was like that) I've decided to make the behavour of all | |
37 | interrupt routines roughly identical. | |
38 | ||
39 | Because, a cpu's recorded state (ie what is in the cpu structure) | |
40 | is allowed to lag behind the cpu's true current state (eg PC not | |
41 | updated) sycnronous interrupt handers are parameterized with the | |
42 | the cpu being interrupted so that, as part of moddeling the | |
43 | interrupt, the cpu's state can be updated. | |
44 | ||
45 | Asynchronous: | |
46 | ||
47 | Interrupts such as reset or external exception are delivered using | |
48 | more normal (returning) functions. It is assumed that these | |
49 | functions are called out side of the normal processor execution | |
50 | cycle. */ | |
51 | ||
52 | ||
53 | /* Software generated interrupts. | |
54 | ||
55 | The below are generated by software driven events. For instance, | |
56 | an invalid instruction or access (virtual or physical) to an | |
57 | invalid address */ | |
58 | ||
59 | typedef enum { | |
60 | direct_store_storage_interrupt, | |
61 | hash_table_miss_storage_interrupt, | |
62 | protection_violation_storage_interrupt, | |
63 | earwax_violation_storage_interrupt, | |
64 | segment_table_miss_storage_interrupt, | |
65 | earwax_disabled_storage_interrupt, | |
66 | vea_storage_interrupt, | |
67 | } storage_interrupt_reasons; | |
68 | ||
69 | ||
70 | INLINE_INTERRUPTS\ | |
71 | (void) data_storage_interrupt | |
72 | (cpu *processor, | |
73 | unsigned_word cia, | |
74 | unsigned_word ea, | |
75 | storage_interrupt_reasons reason, | |
76 | int is_store); | |
77 | ||
78 | INLINE_INTERRUPTS\ | |
79 | (void) instruction_storage_interrupt | |
80 | (cpu *processor, | |
81 | unsigned_word cia, | |
82 | storage_interrupt_reasons reason); | |
83 | ||
84 | INLINE_INTERRUPTS\ | |
85 | (void) alignment_interrupt | |
86 | (cpu *processor, | |
87 | unsigned_word cia, | |
88 | unsigned_word ra); | |
89 | ||
90 | typedef enum { | |
91 | floating_point_enabled_program_interrupt, | |
92 | illegal_instruction_program_interrupt, | |
93 | privileged_instruction_program_interrupt, | |
94 | trap_program_interrupt, | |
95 | optional_instruction_program_interrupt, /* subset of illegal instruction */ | |
c906108c | 96 | mpc860c0_instruction_program_interrupt, /* fwd br, taken but not predicted, near EO page */ |
c906108c SS |
97 | nr_program_interrupt_reasons |
98 | } program_interrupt_reasons; | |
99 | ||
100 | INLINE_INTERRUPTS\ | |
101 | (void) program_interrupt | |
102 | (cpu *processor, | |
103 | unsigned_word cia, | |
104 | program_interrupt_reasons reason); | |
105 | ||
106 | INLINE_INTERRUPTS\ | |
107 | (void) floating_point_unavailable_interrupt | |
108 | (cpu *processor, | |
109 | unsigned_word cia); | |
110 | ||
111 | INLINE_INTERRUPTS\ | |
112 | (void) system_call_interrupt | |
113 | (cpu *processor, | |
114 | unsigned_word cia); | |
115 | ||
116 | INLINE_INTERRUPTS\ | |
117 | (void) floating_point_assist_interrupt | |
118 | (cpu *processor, | |
119 | unsigned_word cia); | |
120 | ||
121 | INLINE_INTERRUPTS\ | |
122 | (void) machine_check_interrupt | |
123 | (cpu *processor, | |
124 | unsigned_word cia); | |
125 | ||
126 | /* Hardware generated interrupts: | |
127 | ||
128 | These asynchronous hardware generated interrupts may be called at | |
129 | any time. It is the responsibility of this (the interrupts) module | |
130 | to ensure that interrupts are delivered correctly (when possible). | |
131 | The delivery of these interrupts is controlled by the MSR's | |
132 | external interrupt enable bit. When ever the MSR's value is | |
133 | changed, the processor must call the check_masked_interrupts() | |
134 | function in case delivery has been made possible. | |
135 | ||
136 | decrementer_interrupt is `edge' sensitive. Multiple edges arriving | |
137 | before the first edge has been delivered result in only one | |
138 | interrupt. | |
139 | ||
140 | external_interrupt is `level' sensitive. An external interrupt | |
141 | will only be delivered when the external interrupt port is | |
142 | `asserted'. While interrupts are disabled, the external interrupt | |
143 | can be asserted and then de-asserted without an interrupt | |
144 | eventually being delivered. */ | |
145 | ||
146 | enum { | |
147 | external_interrupt_pending = 1, | |
148 | decrementer_interrupt_pending = 2, | |
149 | }; | |
150 | ||
151 | typedef struct _interrupts { | |
152 | event_entry_tag delivery_scheduled; | |
153 | int pending_interrupts; | |
154 | } interrupts; | |
155 | ||
156 | INLINE_INTERRUPTS\ | |
157 | (void) check_masked_interrupts | |
158 | (cpu *processor); | |
159 | ||
160 | INLINE_INTERRUPTS\ | |
161 | (void) decrementer_interrupt | |
162 | (cpu *processor); | |
163 | ||
164 | INLINE_INTERRUPTS\ | |
165 | (void) external_interrupt | |
166 | (cpu *processor, | |
167 | int is_asserted); | |
168 | ||
169 | #endif /* _INTERRUPTS_H_ */ |