Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: N2ExceptionPEUCtx.vr | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | class ExceptionPEUCtx extends PEUCtxBase | |
36 | { | |
37 | bit f_expectInterrupt; | |
38 | ||
39 | local string f_mode; | |
40 | local integer f_index; | |
41 | local integer f_errQueue; | |
42 | local integer f_offset; | |
43 | ||
44 | static bit[4:0] f_badType = PEC_PCI__TYPE_MEM; | |
45 | static PEC_ERRtype f_lpuErr = e_ERR_none; | |
46 | static integer f_count = 0; | |
47 | static bit [1:0] f_injectType = 0; | |
48 | ||
49 | task new( string a_name, PEUTestEnv a_env, string a_mode ) | |
50 | { | |
51 | super.new(a_name,a_env); | |
52 | f_mode = a_mode; | |
53 | f_index = 0; | |
54 | f_offset = 0; | |
55 | f_errQueue = 0; | |
56 | f_expectInterrupt = 1; | |
57 | } | |
58 | ||
59 | task Execute() | |
60 | { | |
61 | super.Execute(); | |
62 | } | |
63 | ||
64 | task SetOffset( integer a_offs ) | |
65 | { | |
66 | f_offset = a_offs; | |
67 | } | |
68 | ||
69 | protected function CTStrategyBase ProvideStrategy() | |
70 | { | |
71 | integer seed; | |
72 | PEUStrBase nullStr; | |
73 | ErrChkPEUStr errChk; // The guy who checks error state | |
74 | EdbErrPEUStr edbErr; // Generate an EDB parity error | |
75 | EhbErrPEUStr ehbErr; // Generate an EHB parity error | |
76 | IhbErrPEUStr ihbErr; // Generate an IHB parity error | |
77 | LinkErrPEUStr linkErr; // Pull down the "link up" signal | |
78 | LpuErrPEUStr lpuErr; // Present an LPU-detected error | |
79 | TimeOutPEUStr timeOut; // Let a non-posted PIO request time out | |
80 | ReplayPEUStr replay; // Cause a replay to take place by a nak or timeout | |
81 | InErrPEUStr ingressErr; // Provide bad parity for an ingress TLP | |
82 | EgrParErrStr egrParErr; // Egress Injected Parity Errors | |
83 | IngParErrStr ingParErr; // Ingress Injected Parity Errors | |
84 | ||
85 | // If the "StratStop" (within the base | |
86 | // context class) has been set, then | |
87 | // just return a base context which | |
88 | // does nothing. | |
89 | if ( this.StratStop ) | |
90 | { | |
91 | nullStr = new( f_env ); | |
92 | ProvideStrategy = nullStr; | |
93 | } | |
94 | ||
95 | // The first strategy? Build a | |
96 | // mailbox and fire up the guy | |
97 | // who'll check interrupt status | |
98 | // after it's all over. | |
99 | // The test uses "NumStrat" to tell us | |
100 | // how many errors to generate. | |
101 | // Every error-generating strategy will | |
102 | // add something to the "f_errQueue". | |
103 | else if ( f_index == 0 ) | |
104 | { | |
105 | f_index = 1; | |
106 | f_errQueue = alloc( MAILBOX, 0, 1 ); | |
107 | errChk = new( f_env, f_errQueue, this.NumStrat-1 ); | |
108 | ||
109 | // The "errChk" strategy will enable | |
110 | // interrupt checking when it's done. | |
111 | if ( f_expectInterrupt ) f_env.disableInterrupt(); | |
112 | ProvideStrategy = errChk; | |
113 | } | |
114 | ||
115 | // The directed "EDB parity" test | |
116 | // injects a parity error for some | |
117 | // request type (or completion). | |
118 | else if ( f_mode == "EDB" ) | |
119 | { | |
120 | edbErr = new( f_env ); | |
121 | edbErr.SetErrQueue( f_errQueue ); | |
122 | edbErr.SetType( f_badType ); | |
123 | ProvideStrategy = edbErr; | |
124 | } | |
125 | ||
126 | // The directed "EHB parity" test | |
127 | // injects a parity error for some | |
128 | // request type (or completion). | |
129 | else if ( f_mode == "EHB" ) | |
130 | { | |
131 | ehbErr = new( f_env ); | |
132 | ehbErr.SetErrQueue( f_errQueue ); | |
133 | ehbErr.SetType( f_badType ); | |
134 | ProvideStrategy = ehbErr; | |
135 | } | |
136 | ||
137 | // The directed "IHB parity" test | |
138 | // injects a parity error for some | |
139 | // request type (or completion). | |
140 | else if ( f_mode == "IHB" ) | |
141 | { | |
142 | ihbErr = new( f_env ); | |
143 | ihbErr.SetErrQueue( f_errQueue ); | |
144 | ihbErr.SetType( f_badType ); | |
145 | ProvideStrategy = ihbErr; | |
146 | } | |
147 | ||
148 | // injects a parity error | |
149 | // on a egress PIO packet | |
150 | else if ( f_mode == "EgrPar" ) | |
151 | { | |
152 | egrParErr = new( f_env ); | |
153 | egrParErr.SetErrQueue( f_errQueue ); | |
154 | egrParErr.SetInjectType( f_injectType ); | |
155 | ProvideStrategy = egrParErr; | |
156 | } | |
157 | ||
158 | // injects a parity error | |
159 | // on a ingress packet | |
160 | else if ( f_mode == "IngPar" ) | |
161 | { | |
162 | ingParErr = new( f_env ); | |
163 | ingParErr.SetErrQueue( f_errQueue ); | |
164 | ingParErr.SetInjectType( f_injectType ); | |
165 | ProvideStrategy = ingParErr; | |
166 | } | |
167 | ||
168 | ||
169 | // The directed "link down" test | |
170 | // just pulls down the "link up" signal. | |
171 | else if ( f_mode == "Link" ) | |
172 | { | |
173 | linkErr = new( f_env ); | |
174 | linkErr.SetErrQueue( f_errQueue ); | |
175 | ProvideStrategy = linkErr; | |
176 | } | |
177 | ||
178 | // A LPU-detected error? Find the next | |
179 | // one and use it! | |
180 | else if ( f_mode == "LPU" ) | |
181 | { | |
182 | lpuErr = new( f_env ); | |
183 | lpuErr.SetErrQueue( f_errQueue ); | |
184 | f_lpuErr++; | |
185 | while( lpuErr.SetError(f_lpuErr) ) f_lpuErr++; | |
186 | ProvideStrategy = lpuErr; | |
187 | } | |
188 | ||
189 | // An ingress parity error? | |
190 | // A "header" error is one which appears | |
191 | // in the first 4DWs of the TLP. | |
192 | else if ( f_mode == "ITP data" ) | |
193 | { | |
194 | ingressErr = new( f_env ); | |
195 | ingressErr.SetErrQueue( f_errQueue ); | |
196 | f_count = f_count + 1; | |
197 | if ( f_offset > 0 ) | |
198 | ingressErr.SetOffset( f_offset + 16 ); | |
199 | else if ( f_offset < 0 ) | |
200 | ingressErr.SetOffset( f_offset ); | |
201 | else | |
202 | ingressErr.SetOffset( f_count + 16 ); | |
203 | ProvideStrategy = ingressErr; | |
204 | } | |
205 | ||
206 | else if ( f_mode == "ITP hdr" ) | |
207 | { | |
208 | ingressErr = new( f_env ); | |
209 | ingressErr.SetErrQueue( f_errQueue ); | |
210 | f_count = f_count + 1; | |
211 | ingressErr.SetOffset( (f_count % 16) + 1); | |
212 | ProvideStrategy = ingressErr; | |
213 | } | |
214 | ||
215 | // A PIO request times out? | |
216 | else if ( f_mode == "Time-out" ) | |
217 | { | |
218 | timeOut = new( f_env ); | |
219 | timeOut.SetErrQueue( f_errQueue ); | |
220 | ProvideStrategy = timeOut; | |
221 | } | |
222 | ||
223 | // A replay caused by a timeout | |
224 | else if ( f_mode == "Replay-Timeout" ) | |
225 | { | |
226 | replay = new( f_env ); | |
227 | replay.SetErrQueue( f_errQueue ); | |
228 | replay.SetType( "timeout" ); | |
229 | ProvideStrategy = replay; | |
230 | } | |
231 | // A replay count rollover caused by a timeout | |
232 | else if ( f_mode == "Replay-Timeout-Rollover" ) | |
233 | { | |
234 | replay = new( f_env ); | |
235 | replay.SetErrQueue( f_errQueue ); | |
236 | replay.SetType( "timeout" ); | |
237 | replay.SetNmbrReplays( 4 ); | |
238 | ProvideStrategy = replay; | |
239 | } | |
240 | // A replay count rollover caused by NAKs | |
241 | else if ( f_mode == "Replay-Nak-Rollover" ) | |
242 | { | |
243 | replay = new( f_env ); | |
244 | replay.SetErrQueue( f_errQueue ); | |
245 | replay.SetType( "nak" ); | |
246 | replay.SetNmbrReplays( 4 ); | |
247 | ProvideStrategy = replay; | |
248 | } | |
249 | // A random drain-state test? | |
250 | // Then just supply any nasty exception. | |
251 | else if ( f_mode == "Drain" ) | |
252 | { | |
253 | if ( get_plus_arg( CHECK, "vera_random_seed=" ) ) | |
254 | seed = get_plus_arg( NUM, "vera_random_seed=" ); | |
255 | else | |
256 | seed = 0; | |
257 | ||
258 | if ( seed >= 1 && seed <= 4 ) | |
259 | { | |
260 | printf( "Exception: An EHB parity error... DW-%0d\n", seed-1 ); | |
261 | ehbErr = new( f_env ); | |
262 | ehbErr.SetErrQueue( f_errQueue ); | |
263 | if ( f_env.nonpostedWriteStalled() ) | |
264 | ehbErr.SetType( PEC_PCI__TYPE_CPL ); | |
265 | ehbErr.SetMask( 1 << (seed-1) ); | |
266 | ProvideStrategy = ehbErr; | |
267 | } | |
268 | else if ( seed >= 5 && seed <= 8 ) | |
269 | { | |
270 | printf( "Exception: An IHB parity error... DW-%0d\n", seed-5 ); | |
271 | ihbErr = new( f_env ); | |
272 | ihbErr.SetErrQueue( f_errQueue ); | |
273 | ihbErr.SetMask( 1 << (seed-5) ); | |
274 | ProvideStrategy = ihbErr; | |
275 | } | |
276 | else if ( seed >= 9 && seed <= 15 ) | |
277 | { | |
278 | printf( "Exception: An EDB parity error... DW-%0d\n", seed-9 ); | |
279 | edbErr = new( f_env ); | |
280 | edbErr.SetErrQueue( f_errQueue ); | |
281 | if ( f_env.nonpostedWriteStalled() ) | |
282 | edbErr.SetType( PEC_PCI__TYPE_CPL ); | |
283 | edbErr.SetMask( 1 << (seed-9) ); | |
284 | edbErr.SetLength( 8 ); | |
285 | if ( seed <= 12 ) edbErr.SetBndy( 0 ); | |
286 | ProvideStrategy = edbErr; | |
287 | } | |
288 | else if ( seed == 16 ) | |
289 | { | |
290 | printf( "Exception: An EDB parity error... only DW\n" ); | |
291 | edbErr = new( f_env ); | |
292 | edbErr.SetErrQueue( f_errQueue ); | |
293 | if ( f_env.nonpostedWriteStalled() ) | |
294 | edbErr.SetType( PEC_PCI__TYPE_CPL ); | |
295 | edbErr.SetLength( 1 ); | |
296 | edbErr.SetMask( 4'b1111 ); | |
297 | ProvideStrategy = edbErr; | |
298 | } | |
299 | else randcase | |
300 | { | |
301 | 1: { /* ITP header parity */ | |
302 | printf( "Exception: An ITP (header) parity error\n" ); | |
303 | ingressErr = new( f_env ); | |
304 | ingressErr.SetErrQueue( f_errQueue ); | |
305 | ingressErr.SetOffset( urandom() % 16 + 1 ); | |
306 | ProvideStrategy = ingressErr; | |
307 | } | |
308 | ||
309 | 1: { /* Link down */ | |
310 | printf( "Exception: The link drops\n" ); | |
311 | linkErr = new( f_env ); | |
312 | linkErr.SetErrQueue( f_errQueue ); | |
313 | ProvideStrategy = linkErr; | |
314 | } | |
315 | ||
316 | 1: { /* IHB parity */ | |
317 | printf( "Exception: An IHB parity error\n" ); | |
318 | ihbErr = new( f_env ); | |
319 | ihbErr.SetErrQueue( f_errQueue ); | |
320 | ProvideStrategy = ihbErr; | |
321 | } | |
322 | ||
323 | 1: { /* EDB parity */ | |
324 | printf( "Exception: An EDB parity error\n" ); | |
325 | edbErr = new( f_env ); | |
326 | edbErr.SetErrQueue( f_errQueue ); | |
327 | if ( f_env.nonpostedWriteStalled() ) | |
328 | edbErr.SetType( PEC_PCI__TYPE_CPL ); | |
329 | ProvideStrategy = edbErr; | |
330 | } | |
331 | ||
332 | 1: { /* EHB parity */ | |
333 | printf( "Exception: An EHB parity error\n" ); | |
334 | ehbErr = new( f_env ); | |
335 | ehbErr.SetErrQueue( f_errQueue ); | |
336 | if ( f_env.nonpostedWriteStalled() ) | |
337 | ehbErr.SetType( PEC_PCI__TYPE_CPL ); | |
338 | ProvideStrategy = ehbErr; | |
339 | } | |
340 | } | |
341 | } | |
342 | ||
343 | // None of the above? A null strategy | |
344 | // does nothing. | |
345 | else | |
346 | { | |
347 | nullStr = new( f_env ); | |
348 | ProvideStrategy = nullStr; | |
349 | } | |
350 | } /* end ProvideStrategy */ | |
351 | ||
352 | protected function CTStrategyBase FinalizeParms( CTStrategyBase a_strategy ) | |
353 | { | |
354 | FinalizeParms = a_strategy; | |
355 | } /* end FinalizeParms */ | |
356 | ||
357 | } /* end ExceptionPEUCtx */ |