Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: N2DMAPEUCtx.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 DMAPEUCtx extends PEUCtxBase | |
36 | { | |
37 | public string f_mode; // To allow non 'random' noise | |
38 | // local integer f_index; | |
39 | integer f_index; | |
40 | local bit[3:0] f_first; | |
41 | local bit[3:0] f_last; | |
42 | local bit[2:0] f_rc; | |
43 | local integer f_len; | |
44 | ||
45 | integer f_rdWeight; // Relative # of memory-reads | |
46 | integer f_wrWeight; // Relative # of memory-writes | |
47 | integer f_msgWeight; // Relative # of messages | |
48 | integer f_poisonPct; // % of memory-reads w bad data | |
49 | integer f_maxPayloadPct; // % of memory-writes w max data | |
50 | ||
51 | task new( string a_name, PEUTestEnv a_env, string a_mode ) | |
52 | { | |
53 | super.new(a_name,a_env); | |
54 | f_mode = a_mode; | |
55 | f_index = 0; | |
56 | f_first = 0; | |
57 | f_last = 0; | |
58 | f_len = 0; | |
59 | f_rc = 0; | |
60 | f_rdWeight = 0; | |
61 | f_wrWeight = 0; | |
62 | f_msgWeight = 0; | |
63 | f_poisonPct = 0; | |
64 | f_maxPayloadPct = -1; | |
65 | } | |
66 | ||
67 | task Execute() | |
68 | { | |
69 | super.Execute(); | |
70 | } | |
71 | ||
72 | protected function CTStrategyBase ProvideStrategy() | |
73 | { | |
74 | PEUStrBase nullStr; | |
75 | DmaWrPEUStr dmaWr; | |
76 | DmaRdPEUStr dmaRd; | |
77 | DmaMsgPEUStr dmaMsg; | |
78 | integer dwbe; | |
79 | integer maxLen; | |
80 | ||
81 | // If the "StratStop" (within the base | |
82 | // context class) has been set, then | |
83 | // just return a base context which | |
84 | // does nothing. | |
85 | if ( this.StratStop ) | |
86 | { | |
87 | nullStr = new( f_env ); | |
88 | ProvideStrategy = nullStr; | |
89 | } | |
90 | ||
91 | // The directed (memory) write test | |
92 | // does every possible DWBE. That's | |
93 | // any "firstDWBE" for 1-DW payloads | |
94 | // (including zero), and any non-zero | |
95 | // DWBE (first and last) for 2-DWs on | |
96 | // a quad-word boundary, and any of the | |
97 | // four contiguous DWBE values for all | |
98 | // other payloads. | |
99 | else if ( f_mode == "write" ) | |
100 | { | |
101 | dmaWr = new( f_env ); | |
102 | // len=1... any firstDWBE value | |
103 | if ( f_index == 0 ) | |
104 | { | |
105 | dmaWr.SetLen(1); | |
106 | dmaWr.SetFirstDWBE(f_first); | |
107 | f_first = f_first + 1; | |
108 | if ( f_first == 0 ) f_index = f_index + 1; | |
109 | } | |
110 | ||
111 | // len=2 on QW boundary... any non-zero | |
112 | // firstDWBE and lastDWBE value | |
113 | else if ( f_index == 1 ) | |
114 | { | |
115 | if ( f_first == 0 ) f_first = 1; | |
116 | if ( f_last == 0 ) f_last = 1; | |
117 | dmaWr.SetLen(2); | |
118 | dmaWr.SetAddrBndy( 8 * (urandom()%8) ); | |
119 | dmaWr.SetLastDWBE( f_last ); | |
120 | dmaWr.SetFirstDWBE( f_first ); | |
121 | f_last = f_last + 1; | |
122 | if ( f_last == 0 ) f_first = f_first + 1; | |
123 | if ( f_first == 0 ) f_index = f_index + 1; | |
124 | } | |
125 | ||
126 | // Otherwise, hit every length and every | |
127 | // contiguous first/lastDWBE value | |
128 | else if ( f_index <= 16 ) | |
129 | { | |
130 | if ( f_first == 0 ) f_first = 4'hf; | |
131 | if ( f_last == 0 ) f_last = 4'hf; | |
132 | dmaWr.SetLen( f_index ); | |
133 | if ( f_index == 2 ) dmaWr.SetAddrBndy( 4 ); | |
134 | dmaWr.SetLastDWBE( f_last ); | |
135 | dmaWr.SetFirstDWBE( f_first ); | |
136 | f_last = f_last >> 1; | |
137 | if ( f_last == 0 ) f_first = f_first << 1; | |
138 | if ( f_first == 0 ) f_index = f_index + 1; | |
139 | } | |
140 | ||
141 | // If we fell through, then anything will do. | |
142 | ProvideStrategy = dmaWr; | |
143 | } | |
144 | ||
145 | // The directed memory-read test | |
146 | // does every possible length and | |
147 | // offset through a 64-byte cache line. | |
148 | else if ( f_mode == "read" || f_mode == "readUC" ) | |
149 | { | |
150 | dmaRd = new( f_env ); | |
151 | ||
152 | if ( f_len == 0 || f_len + f_index >= 16 ) | |
153 | { | |
154 | f_len = f_len + 1; | |
155 | f_index = 0; | |
156 | } | |
157 | else | |
158 | { | |
159 | f_index = f_index + 1; | |
160 | } | |
161 | if ( f_len > 16 ) | |
162 | { | |
163 | f_len = 1; | |
164 | } | |
165 | ||
166 | dmaRd.SetLen( f_len ); | |
167 | dmaRd.SetAddrBndy( 4*f_index ); | |
168 | if ( f_mode == "readUC" ) dmaRd.SetUC( f_index % 2 ); | |
169 | ||
170 | ProvideStrategy = dmaRd; | |
171 | } | |
172 | ||
173 | // The "max read" is used for injected | |
174 | // retry parity errors. It just does | |
175 | // reads of the maximum size allowed | |
176 | else if ( f_mode == "max read" ) | |
177 | { | |
178 | dmaRd = new( f_env ); | |
179 | dmaRd.SetLen( 512 ); | |
180 | ProvideStrategy = dmaRd; | |
181 | } | |
182 | ||
183 | // The "bulk write" test makes sure that | |
184 | // the lengths up to the maximum are | |
185 | // supported, and that the ILU can | |
186 | // handle cases where the IDB wraps. | |
187 | else if ( f_mode == "bulk write" ) | |
188 | { | |
189 | dmaWr = new( f_env ); | |
190 | maxLen = f_env.getMaxPayloadSize(); | |
191 | ||
192 | f_index = f_index + 1; | |
193 | if ( f_index*4 < maxLen ) | |
194 | dmaWr.SetLen( f_index + 1 ); | |
195 | ||
196 | ProvideStrategy = dmaWr; | |
197 | } | |
198 | ||
199 | // The "bulk read" test makes sure that | |
200 | // the ILU wraps around the DOU. | |
201 | else if ( f_mode == "bulk read" ) | |
202 | { | |
203 | dmaRd = new( f_env ); | |
204 | maxLen = f_env.getMaxPayloadSize(); | |
205 | ||
206 | // The first strategy will perform a | |
207 | // 2DW read which crosses the DOU | |
208 | // block boundary (or RCB). | |
209 | f_index = f_index + 1; | |
210 | // if ( f_index == 1 ) | |
211 | // { | |
212 | // dmaRd.SetLen( f_index + 1 ); | |
213 | ||
214 | // } | |
215 | ||
216 | // Try max request-size | |
217 | if ( f_index == 1 ) | |
218 | { | |
219 | dmaRd.SetLen( f_env.getMaxRequestSize() / 4 ); | |
220 | } | |
221 | // else if ( f_index < 64 && f_index*4 < maxLen ) | |
222 | // dmaRd.SetLen( f_index + 1 ); | |
223 | else if( f_index < (f_env.getMaxRequestSize()/4) ) | |
224 | { | |
225 | dmaRd.SetLen( f_index ); | |
226 | } | |
227 | else | |
228 | { | |
229 | dmaRd.SetLen( (f_env.getMaxRequestSize()/4) % f_index ); | |
230 | } | |
231 | ||
232 | ProvideStrategy = dmaRd; | |
233 | } | |
234 | ||
235 | // The "bulk read" test makes sure that | |
236 | // the ILU wraps around the DOU. | |
237 | else if ( f_mode == "err read" ) | |
238 | { | |
239 | dmaRd = new( f_env ); | |
240 | maxLen = f_env.getMaxRequestSize(); | |
241 | ||
242 | // A multiple of 3, 5, or 7? A single | |
243 | // DOU-block request. | |
244 | f_index = f_index + 1; | |
245 | if ( f_index % 3 == 0 || f_index % 5 == 0 || f_index % 7 == 0 ) | |
246 | { | |
247 | dmaRd.SetLen( (f_index % 16) + 1 ); | |
248 | } | |
249 | ||
250 | // Try every request-size up to the max. | |
251 | else if ( f_index < 64 && f_index*4 < maxLen ) | |
252 | dmaRd.SetLen( f_index + 1 ); | |
253 | else if ( (f_index-63)*16 <= maxLen ) | |
254 | dmaRd.SetLen( (f_index-63)*16 ); | |
255 | ||
256 | // Not every request is poisoned. | |
257 | if ( urandom()%100 < f_poisonPct ) dmaRd.f_poison = 1; | |
258 | ||
259 | ProvideStrategy = dmaRd; | |
260 | } | |
261 | ||
262 | // The directed message test | |
263 | // does every valid message code and | |
264 | // every valid routing code. | |
265 | // N2 - Since each message type only has | |
266 | // one valid routing code - change this | |
267 | // test | |
268 | else if ( f_mode == "message" ) | |
269 | { | |
270 | dmaMsg = new( f_env ); | |
271 | dmaMsg.SetRoutingCode( f_rc ); | |
272 | case( f_index ) | |
273 | { | |
274 | 0: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ASSERT_INTA ); | |
275 | 1: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ASSERT_INTB ); | |
276 | 2: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ASSERT_INTC ); | |
277 | 3: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ASSERT_INTD ); | |
278 | 4: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_DEASSERT_INTA ); | |
279 | 5: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_DEASSERT_INTB ); | |
280 | 6: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_DEASSERT_INTC ); | |
281 | 7: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_DEASSERT_INTD ); | |
282 | 8: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_PM_PME ); | |
283 | 9: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_PM_TO_ACK ); | |
284 | 10: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ERR_COR ); | |
285 | 11: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ERR_NONFATAL ); | |
286 | 12: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_ERR_FATAL ); | |
287 | 13: dmaMsg.SetMsgCode( PEC_PCI__MSG_CODE_VENDOR_TYPE_1 ); | |
288 | // PEC_PCI__MSG_CODE_ATTN is not supported by FIRE | |
289 | } | |
290 | ||
291 | if( f_index <= 7 ){ | |
292 | dmaMsg.SetRoutingCode( 3'b100 ); | |
293 | } | |
294 | else if( f_index == 8 ){ | |
295 | dmaMsg.SetRoutingCode( 3'b000 ); | |
296 | } | |
297 | else if( f_index == 9 ){ | |
298 | dmaMsg.SetRoutingCode( 3'b101 ); | |
299 | } | |
300 | else if( f_index >= 10 && f_index <= 12 ){ | |
301 | dmaMsg.SetRoutingCode( 3'b000 ); | |
302 | } | |
303 | //N2 review else if( f_index == 13 ){ | |
304 | //N2 review dmaMsg.SetRoutingCode( 3'b000 ); | |
305 | //N2 review dmaMsg.SetRoutingCode( 3'b010 ); | |
306 | //N2 review dmaMsg.SetRoutingCode( 3'b011 ); | |
307 | //N2 review dmaMsg.SetRoutingCode( 3'b100 ); | |
308 | //N2 review } | |
309 | f_index = f_index + 1; | |
310 | //N2 review VENDOR_TYPE_1 if ( f_index > 13 ) | |
311 | if ( f_index > 12 ) | |
312 | { | |
313 | f_index = 0; | |
314 | //N2 f_rc = f_rc + 1; | |
315 | } | |
316 | ||
317 | ProvideStrategy = dmaMsg; | |
318 | } | |
319 | ||
320 | // A random test? Then just supply any | |
321 | // legit request or message. | |
322 | else | |
323 | { | |
324 | if ( f_wrWeight < 0 ) f_wrWeight = 0; | |
325 | if ( f_rdWeight < 0 ) f_rdWeight = 0; | |
326 | if ( f_msgWeight < 0 ) f_msgWeight = 0; | |
327 | if ( f_wrWeight + f_rdWeight + f_msgWeight == 0 ) | |
328 | { | |
329 | f_wrWeight = 10; | |
330 | f_rdWeight = 10; | |
331 | f_msgWeight = 5; | |
332 | } | |
333 | randcase | |
334 | { | |
335 | f_wrWeight: { | |
336 | dmaWr = new( f_env ); | |
337 | ProvideStrategy = dmaWr; | |
338 | if ( f_maxPayloadPct >= 0 | |
339 | && urandom()%100 < f_maxPayloadPct ) | |
340 | { | |
341 | dmaWr.SetLen( f_env.getMaxPayloadSize() / 4 ); | |
342 | } | |
343 | } | |
344 | f_rdWeight: { | |
345 | dmaRd = new( f_env ); | |
346 | if ( urandom()%100 < f_poisonPct ) dmaRd.f_poison = 1; | |
347 | ProvideStrategy = dmaRd; | |
348 | } | |
349 | f_msgWeight:{ | |
350 | dmaMsg = new( f_env ); | |
351 | ProvideStrategy = dmaMsg; | |
352 | } | |
353 | } | |
354 | } | |
355 | } /* end ProvideStrategy */ | |
356 | ||
357 | protected function CTStrategyBase FinalizeParms( CTStrategyBase a_strategy ) | |
358 | { | |
359 | FinalizeParms = a_strategy; | |
360 | } /* end FinalizeParms */ | |
361 | ||
362 | } /* end DMAPECCtx */ |