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