Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: SS_Interrupt.h | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | ||
24 | #ifndef __SS_Interrupt_h__ | |
25 | #define __SS_Interrupt_h__ | |
26 | ||
27 | #include "SS_Types.h" | |
28 | #include "SS_Trap.h" | |
29 | #include "SS_SnapShot.h" | |
30 | ||
31 | class SS_Strand; | |
32 | ||
33 | class SS_Interrupt | |
34 | { | |
35 | public: | |
36 | SS_Interrupt(); | |
37 | ||
38 | // The Bit enum is ordered on priority (highest priority has lowest index) | |
39 | // The priority is taken from the Sun Sparc architecture (trap section) | |
40 | // and repeated in the comment after the enum variable | |
41 | ||
42 | enum Bit | |
43 | { | |
44 | BIT_STORE_ERROR, // 2.1 | |
45 | BIT_TRAP_LEVEL_ZERO, // 2.2 | |
46 | BIT_NO_RETIRE, // 15.8 | |
47 | BIT_SIU_INBOUND_EXCEPTION, // 15.9 | |
48 | ||
49 | BIT_PERFORMANCE_EVENT, // 16.0 | |
50 | BIT_HSTICK_MATCH, // 16.1 | |
51 | BIT_INTERRUPT_VECTOR, // 16.3 | |
52 | BIT_MODULAR_ARITH_INT, // 16.4 | |
53 | ||
54 | BIT_CTRL_WORD_QUEUE_INT, // 16.5 | |
55 | BIT_HYPERPRIV_QUEUE_0, // 16.07 | |
56 | BIT_CPU_MONDO_TRAP, // 16.08 | |
57 | BIT_HYPERPRIV_QUEUE_1, // 16.10 | |
58 | ||
59 | BIT_DEV_MONDO_TRAP, // 16.11 | |
60 | BIT_INTERRUPT_LEVEL_15, // 17.0 | |
61 | BIT_INTERRUPT_LEVEL_14, // 18.0 | |
62 | BIT_INTERRUPT_LEVEL_13, // 19.0 | |
63 | ||
64 | BIT_INTERRUPT_LEVEL_12, // 20.0 | |
65 | BIT_INTERRUPT_LEVEL_11, // 21.0 | |
66 | BIT_INTERRUPT_LEVEL_10, // 22.0 | |
67 | BIT_INTERRUPT_LEVEL_9, // 23.0 | |
68 | ||
69 | BIT_INTERRUPT_LEVEL_8, // 24.0 | |
70 | BIT_INTERRUPT_LEVEL_7, // 25.0 | |
71 | BIT_INTERRUPT_LEVEL_6, // 26.0 | |
72 | BIT_INTERRUPT_LEVEL_5, // 27.0 | |
73 | ||
74 | BIT_INTERRUPT_LEVEL_4, // 28.0 | |
75 | BIT_INTERRUPT_LEVEL_3, // 29.0 | |
76 | BIT_INTERRUPT_LEVEL_2, // 30.0 | |
77 | BIT_INTERRUPT_LEVEL_1, // 31.0 | |
78 | ||
79 | BIT_SW_RECOVERABLE_ERROR, // 33.1 | |
80 | BIT_DATA_ACCESS_SIU_ERROR, // 32.0 | |
81 | BIT_HW_CORRECTED_ERROR, // 33.2 | |
82 | BIT_RESUMABLE_ERROR, // 33.3 | |
83 | ||
84 | BIT_NONRESUMABLE_ERROR, // 33.3 | |
85 | ||
86 | BIT_ASSERT_INDEX // To check our logic | |
87 | }; | |
88 | ||
89 | // enable() and disabled() are for hard enabling interrupts. | |
90 | // In some simulation situations we have to be carefull. These | |
91 | // enable disable allow us to block interrupts the hard way. | |
92 | ||
93 | void enable() { disabled = false; } | |
94 | void disable() { disabled = true; } | |
95 | ||
96 | // raise() is used to mark an interrupt pending, and check | |
97 | // if the strand is in the correct state to deal with the | |
98 | // interrupt on the next instruction. | |
99 | ||
100 | void raise( SS_Strand* strand, Bit b ) | |
101 | { | |
102 | if (!is_pending(b)) | |
103 | { | |
104 | mark_pending(b); | |
105 | _check(strand); | |
106 | } | |
107 | } | |
108 | ||
109 | // retract() is used to remove a pending interrupt. Note that | |
110 | // this means that the irq should be registered as manual_retract(); | |
111 | ||
112 | void retract( Bit b ) | |
113 | { | |
114 | pending &= ~(1ull << b); | |
115 | delivered &= ~(1ull << b); | |
116 | } | |
117 | ||
118 | // is_pending() can be used to test if a particular interrupt is | |
119 | // pending. True is returned when it is pending. | |
120 | ||
121 | bool is_pending( Bit b ) | |
122 | { | |
123 | return pending & (1ull << b); | |
124 | } | |
125 | ||
126 | // any_pending() can be used to see if any interrupt is pending. | |
127 | ||
128 | bool any_pending() | |
129 | { | |
130 | return pending; | |
131 | } | |
132 | ||
133 | // update_softint() is called whenever the SPARC softint register | |
134 | // changes. This is a kind of meta raise() | |
135 | ||
136 | void update_softint( SS_Strand* strand ); | |
137 | ||
138 | void check( SS_Strand* strand ) | |
139 | { | |
140 | if (pending) | |
141 | _check(strand); | |
142 | } | |
143 | ||
144 | void snapshot( SS_SnapShot& ss, const char* prefix ); | |
145 | ||
146 | // manual_retract() is used at simulator startup time to notify | |
147 | // the _check() routine that the simulater will call retract() | |
148 | // when the interrupt is no longer pending. The default is | |
149 | // to auto retract as soon as irq is delivered. | |
150 | ||
151 | void manual_retract( Bit b ) | |
152 | { | |
153 | auto_retract_mask &= ~(1ull << b); | |
154 | } | |
155 | ||
156 | // edge_triggered() is used at simulator startup time to notify | |
157 | // the _check() routine that the irq should be edge triggered | |
158 | // iso level triggered. This can only be used in conjunction with | |
159 | // manual_retract(). The default detection is level triggered. | |
160 | ||
161 | void edge_triggered( Bit b ) | |
162 | { | |
163 | assert((auto_retract_mask & (1ull << b)) == 0); // must be manual | |
164 | edge_triggered_mask |= 1ull << b; | |
165 | } | |
166 | ||
167 | protected: | |
168 | uint64_t pending; // Set bit means irq is pending. | |
169 | uint64_t auto_retract_mask; // The mask controls clearing the pending bit when the irq is delivered. | |
170 | uint64_t delivered; // Set bit means the irq has been delivered. | |
171 | uint64_t edge_triggered_mask; // Set bit means the irq is edge iso level triggered. | |
172 | bool disabled; // Really checking interrupts? | |
173 | ||
174 | void _check( SS_Strand* ); | |
175 | ||
176 | static SS_Trap::Type irq_trap_type[]; | |
177 | ||
178 | // mark_pending() is used to mark an interrupt pending. No action will | |
179 | // be taken on the interrupt. For action after mark_pending() call | |
180 | // check() or use raise(). | |
181 | ||
182 | void mark_pending( Bit b ) | |
183 | { | |
184 | pending |= 1ull << b; | |
185 | } | |
186 | }; | |
187 | ||
188 | #endif |