Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / test_utils / vera / niu_txcintr_utils.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_txcintr_utils.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#include <vera_defines.vrh>
36
37#include "niu_tx_descp.vrh"
38
39#include "niu_int_dev.vrh"
40#include "niu_int_mgr.vrh"
41extern niu_gen_pio gen_pio_drv;
42#include "txc_memory_map.vri"
43
44#include "cMesg.vrh"
45
46extern Mesg be_msg;
47#include "tx_test_class_defines.vri"
48
49
50
51
52class CNiuIntrDevTxc extends CNiuIntrDev {
53
54 bit [63:0] rd_data;
55 // bit [63:0] wr_data;
56 bit [3:0] ports_active;
57 integer error_injection_type[4];
58 integer clear_pending_flag[4];
59 integer done=0;
60 integer sem_id = -1;
61 integer expect_error_interrupt[4];
62
63 task new(bit[3:0] p, integer dev_id) {
64 integer i;
65 super.new(dev_id);
66 SetErrId(7);// bit 7 in sys error stat
67 ports_active = p;
68 for(i=0;i<4;i++) clear_pending_flag[i] = 0;
69 for(i=0;i<4;i++) expect_error_interrupt[i] = 0;
70 sem_id = alloc(SEMAPHORE, 0, 1, 1);
71 }
72 function integer isr( ( bit[1:0] ldf_flags = 0) );
73 task unmask_intrs(bit [3:0] p);
74 task setPortIntMask(integer port_id);
75 task ReEnablePortInt(integer port_id);
76 task ClearPortInt(integer port_id);
77 function bit CheckPortIntStat(integer port_id);
78 task InjectTxcFifoError(bit[3:0] p);
79 task decode_txc_err_events(bit[5:0] data ,integer port_id) ;
80 task checkPendingStatus() ;
81
82
83}
84
85task CNiuIntrDevTxc::InjectTxcFifoError( bit[3:0] p) {
86
87 shadow integer pid;
88 for(pid = 0;pid<2;pid++) {
89 if(p[pid]) {
90 fork {
91 while(!done) {
92 // Inject Error here
93 ReEnablePortInt(pid);
94 clear_pending_flag[pid] = 1;
95 // Wait for clear from interrupt
96 while(clear_pending_flag[pid]) repeat(500)@(posedge CLOCK);
97 } // end while
98 } join none // endfork
99 }// endif
100 }// endfor
101}
102task CNiuIntrDevTxc::unmask_intrs(bit [3:0] p) {
103 integer i;
104 for(i=0;i<4;i++) {
105 if(p[i]){
106 setPortIntMask(i);
107 }
108 }
109}
110task CNiuIntrDevTxc::setPortIntMask(integer port_id) {
111
112 bit [63:0] address;
113 bit [63:0] data;
114 bit [63:0] wdata;
115 address = TXC_FZC_BASE + TXC_INT_MASK;
116
117 gen_pio_drv.pio_rd(address, data);
118 wdata = (6'h3f) <<(8*port_id);
119 wdata = wdata ^32'hffffffff;
120 /* read Modify bits based upon port id*/
121 data = data & wdata;
122 gen_pio_drv.pio_wr(address, data);
123}
124
125function bit CNiuIntrDevTxc::CheckPortIntStat(integer port_id) {
126// read status of the port
127// return 1 is any of the bits are set
128 bit [63:0] address;
129 bit [63:0] r_data;
130 integer interrupts_set;
131
132 address = TXC_FZC_BASE + TXC_INT_STAT;
133 gen_pio_drv.pio_rd(address,r_data);
134 if((r_data >> (port_id*8)) & 6'h3f ) {
135 interrupts_set = 1;
136 decode_txc_err_events( ( (r_data >> (port_id*8)) & 6'h3f ) ,port_id);
137 } else interrupts_set = 0;
138 // check for only bits related to - port_id
139 // check bits against error_interrupt_type;
140 if(interrupts_set) {
141 CheckPortIntStat = 1;
142 } else CheckPortIntStat = 0;
143
144}
145task CNiuIntrDevTxc::ClearPortInt(integer port_id) {
146 // clear interrupts for this port
147 bit [63:0] address;
148 bit [63:0] data;
149 bit [63:0] wdata;
150
151 semaphore_get(WAIT, sem_id, 1);
152
153 address = TXC_FZC_BASE + TXC_INT_STAT;
154 gen_pio_drv.pio_rd(address, data);
155
156 wdata = (6'h3f) << (8*port_id);
157 wdata = data | wdata;
158 gen_pio_drv.pio_wr(address, wdata);
159
160 clear_pending_flag[port_id] = 0;
161 semaphore_put(sem_id, 1);
162
163
164}
165task CNiuIntrDevTxc::ReEnablePortInt(integer port_id) {
166 // set interrupts for this port
167
168 integer error_type;
169 bit [63:0] address;
170 bit [63:0] data;
171
172
173
174 error_type = error_injection_type[port_id];
175
176// get the error code
177 data = error_type & 64'h3ffff; // {dblbit,snglbit,rsvd,all,alt,one,rsvd,last,second,first}
178
179
180// based upon error type set the appropriate bits
181 if(error_type & TxFIFO_SF_ERROR) {
182 address = TXC_FZC_BASE + TXC_SFECC_CTL +256 * port_id;
183 gen_pio_drv.pio_wr(address, data);
184 }
185
186 if(error_type & TxFIFO_RO_ERROR) {
187 address = TXC_FZC_BASE + TXC_ROECC_CTL+256 * port_id;
188 gen_pio_drv.pio_wr(address, data);
189 }
190 expect_error_interrupt[port_id] = error_type;
191
192
193
194
195}
196function integer CNiuIntrDevTxc::isr( ( bit[1:0] ldf_flags = 0) ) {
197 shadow integer i;
198 printf("Start In ISR id - %d LDF Flags - %x \n",super.dev_id,ldf_flags);
199 if(ldf_flags!==2'h2) {
200 printf("ERROR dev id - %d LDF Flags Incorrect - %x \n",super.dev_id,ldf_flags);
201 }
202
203 isr_done = 0;
204 SetPendingFlag();
205 for(i=0;i<4;i++) {
206 fork{
207 if(ports_active[i]) {
208 if(CheckPortIntStat(i))
209 ClearPortInt(i);
210 }
211 } join none
212 }
213 wait_child();
214 ClrPendingFlag();
215 isr_done = 1;
216 printf("End In ISR id - %d LDF Flags - %x \n",super.dev_id,ldf_flags);
217}
218
219
220task CNiuIntrDevTxc::decode_txc_err_events(bit[5:0] data ,integer port_id) {
221
222 bit [63:0] rd_data;
223 bit [63:0] wr_data;
224 bit [63:0] addr;
225 bit [11:0] port_offset;
226 integer error_type;
227 bit pktassydead,reordererror,ro_unco,ro_correct,sf_unco,sf_correct;
228 bit [5:0] expected_status;
229
230 port_offset = 256*port_id;
231
232
233 // This function can now check this integer to see what has been injected
234 error_type = expect_error_interrupt[port_id] ;
235 if(error_type ==0) {
236 printf("CNiuIntrDevTxC Port %d Not expected to generate interrupts!!ERROR: ErrorType Set to %x \n",port_id,error_type);
237 return;
238 } else {
239 // expected_status = {pktassydead,reordererror,ro_unco,ro_correct,sf_uncorrect,sf_correct};
240 pktassydead = 0; // Not injected in this case
241 reordererror = 0; // Not injected in this case
242 ro_unco = (error_type & TxFIFO_RO_ERROR) && ( error_type & TxFIFO_UnCorrectError) ;
243 sf_unco = (error_type & TxFIFO_SF_ERROR) && ( error_type & TxFIFO_UnCorrectError) ;
244 ro_correct = (error_type & TxFIFO_RO_ERROR) && ( error_type & TxFIFO_CorrectError) ;
245 sf_correct = (error_type & TxFIFO_SF_ERROR) && ( error_type & TxFIFO_CorrectError) ;
246 expected_status = {pktassydead,reordererror,ro_unco,ro_correct,sf_unco,sf_correct};
247 if(expected_status!==data) {
248 printf("CNiuIntrDevTxC Port %d ERROR Unexpected interrupts status expected %x received - %x\n",port_id,expected_status,data);
249 }
250 }
251
252 printf("CNiuIntrDevTxC Port %d has interrupted\n",port_id);
253 // check for store and forward fifo registers
254 if(data[0]) {
255 printf("CNiuIntrDevTxC Port %d SF_Correct_error status set\n",port_id);
256 addr = TXC_FZC_BASE + (TXC_SFECC_ST + port_offset);
257 gen_pio_drv.pio_rd(addr,rd_data);
258 if(rd_data[17] != 1'b1)
259 printf("ERROR SF_Correctable error bit not set for Port %d\n",port_id);
260 else
261 printf("INFO SF_Correctable error bit set for Port %d\n", port_id);
262 }
263
264 if(data[1]) {
265 printf("CNiuIntrDevTxC Port %d SF_UnCorrect_error status set\n",port_id);
266 addr = TXC_FZC_BASE + (TXC_SFECC_ST + port_offset);
267 gen_pio_drv.pio_rd(addr,rd_data);
268 if(rd_data[16] != 1'b1)
269 printf("ERROR SF_UnCorrectable error bit not set for Port %d\n",port_id);
270 else
271 printf("INFO SF_UnCorrectable error bit set for Port %d\n", port_id);
272 }
273
274 // check for RO fifo registers and functionality
275 if(data[2]) {
276 printf("CNiuIntrDevTxC Port %d RO_Correct_error status set\n",port_id);
277 addr = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
278 gen_pio_drv.pio_rd(addr,rd_data);
279 if(rd_data[17] != 1'b1)
280 printf("ERROR RO_Correctable error bit not set for Port %d\n",port_id);
281 else
282 printf("INFO RO_Correctable error bit set for Port %d\n", port_id);
283 }
284
285 if(data[3]) {
286 printf("CNiuIntrDevTxC Port %d RO_UnCorrect_error status set\n",port_id);
287 addr = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
288 gen_pio_drv.pio_rd(addr,rd_data);
289 if(rd_data[16] != 1'b1)
290 printf("ERROR RO_UnCorrectable error bit not set for Port %d\n",port_id);
291 else
292 printf("INFO RO_UnCorrectable error bit set for Port %d\n", port_id);
293 }
294
295
296 if(data[0] || data[1]) {
297 addr = TXC_FZC_BASE + (TXC_SFECC_ST + port_offset);
298 gen_pio_drv.pio_rd(addr,rd_data);
299 wr_data = 64'h8000_0000 | rd_data;
300 gen_pio_drv.pio_wr(addr,wr_data);
301
302 // read the sf_data & sf_ecc_st to check
303
304 gen_pio_drv.pio_rd(addr,rd_data);
305 if(rd_data != 64'h0)
306 printf("ERROR TXC_SFECC_ST not clrd for Port %d value %h\n",port_id,rd_data);
307 else
308 printf("INFO TXC_SFECC_ST clrd for Port %d value %h\n",port_id,rd_data);
309 }
310
311 if(data[2] || data[3]) {
312 addr = TXC_FZC_BASE + (TXC_ROECC_ST + port_offset);
313 gen_pio_drv.pio_rd(addr,rd_data);
314 wr_data = 64'h8000_0000 | rd_data;
315 gen_pio_drv.pio_wr(addr,wr_data);
316
317 // read the ro_data & ro_ecc_st to check
318
319 gen_pio_drv.pio_rd(addr,rd_data);
320 if(rd_data != 64'h0)
321 printf("ERROR TXC_ROECC_ST not clrd for Port %d value %h\n",port_id,rd_data);
322 else
323 printf("INFO TXC_ROECC_ST clrd for Port %d value %h\n",port_id,rd_data);
324 }
325
326
327 }
328
329task CNiuIntrDevTxc::checkPendingStatus() {
330 // final exit status check for TXC
331
332 bit [63:0] rd_data;
333 bit [63:0] wr_data;
334 bit [63:0] addr;
335 bit [11:0] port_offset;
336 integer port_id;
337
338
339 printf("CNiuIntrDevTxc::checkPendingStatus!!\n");
340 for(port_id=0;port_id<4;port_id++) {
341 if(ports_active[port_id]) {
342
343 port_offset = 256*port_id;
344
345
346 // clear sf_data
347
348 addr = TXC_FZC_BASE + (TXC_SF_DATA0 + port_offset);
349 gen_pio_drv.pio_rd(addr,rd_data);
350 if(rd_data != 64'h0)
351 printf("ERROR TXC_SF_ECC_DATA0 not clrd for Port %d value %h\n",port_id,rd_data);
352
353 addr = TXC_FZC_BASE + (TXC_SF_DATA1 + port_offset);
354 gen_pio_drv.pio_rd(addr,rd_data);
355 if(rd_data != 64'h0)
356 printf("ERROR TXC_SF_ECC_DATA1 not clrd for Port %d value %h\n",port_id,rd_data);
357
358 addr = TXC_FZC_BASE + (TXC_SF_DATA2 + port_offset);
359 gen_pio_drv.pio_rd(addr,rd_data);
360 if(rd_data != 64'h0)
361 printf("ERROR TXC_SF_ECC_DATA2 not clrd for Port %d value %h\n",port_id,rd_data);
362
363 addr = TXC_FZC_BASE + (TXC_SF_DATA3 + port_offset);
364 gen_pio_drv.pio_rd(addr,rd_data);
365 if(rd_data != 64'h0)
366 printf("ERROR TXC_SF_ECC_DATA3 not clrd for Port %d value %h\n",port_id,rd_data);
367
368 addr = TXC_FZC_BASE + (TXC_SF_DATA4 + port_offset);
369 gen_pio_drv.pio_rd(addr,rd_data);
370 if(rd_data != 64'h0)
371 printf("ERROR TXC_SF_ECC_DATA4 not clrd for Port %d value %h\n",port_id,rd_data);
372
373
374 // clear RO_data
375
376 addr = TXC_FZC_BASE + (TXC_RO_DATA0 + port_offset);
377 gen_pio_drv.pio_rd(addr,rd_data);
378 if(rd_data != 64'h0)
379 printf("ERROR TXC_RO_ECC_DATA0 not clrd for Port %d value %h\n",port_id,rd_data);
380
381 addr = TXC_FZC_BASE + (TXC_RO_DATA1 + port_offset);
382 gen_pio_drv.pio_rd(addr,rd_data);
383 if(rd_data != 64'h0)
384 printf("ERROR TXC_RO_ECC_DATA1 not clrd for Port %d value %h\n",port_id,rd_data);
385
386 addr = TXC_FZC_BASE + (TXC_RO_DATA2 + port_offset);
387 gen_pio_drv.pio_rd(addr,rd_data);
388 if(rd_data != 64'h0)
389 printf("ERROR TXC_RO_ECC_DATA2 not clrd for Port %d value %h\n",port_id,rd_data);
390
391 addr = TXC_FZC_BASE + (TXC_RO_DATA3 + port_offset);
392 gen_pio_drv.pio_rd(addr,rd_data);
393 if(rd_data != 64'h0)
394 printf("ERROR TXC_RO_ECC_DATA3 not clrd for Port %d value %h\n",port_id,rd_data);
395
396 addr = TXC_FZC_BASE + (TXC_RO_DATA4 + port_offset);
397 gen_pio_drv.pio_rd(addr,rd_data);
398 if(rd_data != 64'h0)
399 printf("ERROR TXC_RO_ECC_DATA4 not clrd for Port %d value %h\n",port_id,rd_data);
400
401 }// else if ports_valid
402 }// end for
403}