Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Interrupt.h
CommitLineData
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
31class SS_Strand;
32
33class 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