Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ios / vera / ras / ios_err_interrupt.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ios_err_interrupt.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#include <VeraListProgram.vrh>
37#include <ListMacros.vrh>
38#include "ios_err_packet.vrh"
39#include "ios_rasmon.if.vrh"
40#include "ios_rasmon_ports_binds.vrh"
41#include "std_display_class.vrh"
42#include "siu_common.vrh"
43
44// added this to exclude code for NIU
45#ifndef FC_NO_NIU_T2
46#include "niu_gen_pio.vrh"
47#endif
48#include "ios_ras_defines.vrh"
49#include "ios_injerr.vrh"
50
51extern StandardDisplay dbg;
52// for interrupt handler, not for FC
53
54#ifndef FC_NO_NIU_T2
55extern niu_gen_pio gen_pio_drv;
56#endif
57
58class ios_err_interrupt_mon {
59 local string myname;
60 integer timeout;
61 integer wait_for_report;
62 integer ios_ras_interrupt_mon_on;
63 integer interrupt_mon_running;
64 ios_ras_inj ras_injector;
65
66 task new(integer timeout = 100) {
67 this.myname = "IOS-RAS INTMON";
68 this.timeout = timeout;
69 this.wait_for_report = 100;
70 ios_ras_interrupt_mon_on = 1;
71 interrupt_mon_running = 0;
72 }
73
74 task monitor_err_interrupt(ios_ras_inj ras_injector, integer tout);
75 task handle_err_interrupt(var integer result);
76
77}
78
79task ios_err_interrupt_mon::monitor_err_interrupt(ios_ras_inj ras_injector, integer tout)
80{
81 bit [145:0] data;
82 bit not_match = 1;
83 integer counter = 0;
84 integer wait_time, pass_check;
85
86 this.ras_injector = ras_injector;
87 wait_time = (tout != 0) ? tout : this.timeout;
88
89 if (get_plus_arg(CHECK, "ios_ras_interrupt_chk_off"))
90 ios_ras_interrupt_mon_on = 0;
91 else
92 ios_ras_interrupt_mon_on = 1;
93
94 if (interrupt_mon_running)
95 dbg.dispmon(myname, MON_NORMAL, psprintf("user cannot activate more than one interrupt monitor!"));
96 else
97 fork {
98 dbg.dispmon(myname, MON_NORMAL, psprintf("wait for error interrupt timeout %0d", wait_time));
99 interrupt_mon_running = 1;
100 while (ios_ras_interrupt_mon_on)
101 {
102 if (!ras_injector.injected_err_list.empty())
103 {
104 counter = 0;
105 pass_check = 0;
106 not_match = 1;
107 while (not_match) {
108 @ (posedge ncu_cpx_err_mon.clk);
109 counter ++ ;
110 if (ncu_cpx_err_mon.req !== 8'h0) {
111 @ (posedge ncu_cpx_err_mon.clk);
112 data = ncu_cpx_err_mon.data[145:0];
113 //dbg.dispmon(myname, MON_NORMAL, psprintf("sample ncu cpx request %0h", data));
114 if (data[144:141] == 4'b1101) {
115 dbg.dispmon(myname, MON_NORMAL, psprintf("Got an error interrupt with data %0h", data[127:0]));
116 // call ras interrupt handler FC shall be different
117 this.handle_err_interrupt(pass_check);
118 if (!pass_check)
119 dbg.dispmon(myname, MON_ERR, psprintf("ras checking failed!"));
120 // end of interrupt checker
121 not_match = 0;
122 }
123 }
124 if (counter > wait_time && not_match)
125 {
126 dbg.dispmon(myname, MON_ERR, psprintf("interrupt timeout"));
127 not_match = 0;
128 }
129 } // search for the
130 } // injected_err_list not empty
131 else
132 @ (posedge ncu_cpx_err_mon.clk);
133 } // while(1)
134 } join none
135} // task
136
137task ios_err_interrupt_mon::handle_err_interrupt(var integer result) {
138 bit [63:0] tdata1 = 64'b0;
139 bit [63:0] syn_data = 64'b0;
140 bit [63:0] per_data = 64'b0;
141 bit [63:0] esr_data = 64'b0;
142 bit [63:0] expect_data = 64'b0;
143 bit [63:0] ncuele_value, ncueie_value;
144 bit [63:0] sii_syndrome = 64'b0;
145 bit [2:0] sii_etag = 3'b011;
146 bit check_sii_syndrome = 0;
147 bit [63:0] ncu_syndrome = 64'b0;
148 bit [4:0] ncu_etag = 5'b0;
149 bit check_ncu_syndrome = 0;
150 ios_err_packet ptr_pkt;
151 VeraListIterator_ios_err_packet list_ptr;
152
153 ras_injector.injector_on = 0;
154
155 // read whole injection list
156 list_ptr = ras_injector.injected_err_list.start();
157 ptr_pkt = list_ptr.data();
158 dbg.dispmon(myname, MON_NORMAL, psprintf("reading injection list size %0d", ras_injector.injected_err_list.size()));
159 while (ptr_pkt != null)
160 {
161 dbg.dispmon(myname, MON_NORMAL, psprintf("injection pkt tag=%x pa=%x type=%0d", ptr_pkt.ctag, ptr_pkt.pa, ptr_pkt.type));
162 case (ptr_pkt.type)
163 {
164#ifndef FC_NO_NIU_T2
165 NIUSII_CUE: { expect_data[siiNiuCtagUe] = 1'b1; sii_etag = 0; }
166 NIUSII_CCE: { expect_data[siiNiuCtagCe] = 1'b1; }
167 NIUSII_AP: { expect_data[siiNiuAPe] = 1'b1; sii_etag = 4; }
168 NIUSII_DP: { expect_data[siiNiuDPe] = 1'b1; sii_etag = 6; }
169 SIONIU_DP: { expect_data[niuDPe] = 1'b1; }
170 SIONIU_CUE: { expect_data[niuCtagUe] = 1'b1; }
171 SIONIU_CCE: { expect_data[niuCtagCe] = 1'b1; }
172#endif
173 DMUSII_CUE: { expect_data[siiDmuCtagUe] = 1'b1; sii_etag = 1; }
174 DMUSII_CCE: { expect_data[siiDmuCtagCe] = 1'b1; }
175 DMUSII_AP: { expect_data[siiDmuAPe] = 1'b1; sii_etag = 7; }
176 DMUSII_DP: { expect_data[siiDmuDPe] = 1'b1; sii_etag = 5; }
177 SIODMU_DP: { expect_data[dmuDPe] = 1'b1; }
178 SIODMU_CUE: { expect_data[dmuCtagUe] = 1'b1; }
179 SIODMU_CCE: { expect_data[dmuCtagCe] = 1'b1; }
180 L2SIO_DP: { expect_data[sioDPe] = 1'b1; }
181 L2SIO_EBIT:{}
182 L2SIO_CUE: { expect_data[sioCtagUe] = 1'b1; }
183 L2SIO_CCE: { expect_data[sioCtagCe] = 1'b1; }
184 SIINCU_DP: { expect_data[ncuDataParity] = 1'b1;}
185 SIINCU_CCE: { expect_data[ncuCtagCe] = 1'b1; }
186 SIINCU_CUE: { expect_data[ncuCtagUe] = 1'b1; }
187#ifndef FC_NO_NIU_T2
188 NIUSII_IOAE: {}
189 NIUSII_IOUE: {}
190 NIUSII_CMDP: {}
191#endif
192 DMUSII_TOUT: {}
193 DMUSII_IOAE: {}
194 DMUSII_IOUE: {}
195 DMUSII_CMDP: {}
196 DMUSII_BEP: {}
197 DMUNCU_WRACK_P: { expect_data[ncuDmuCr] = 1'b1; }
198 NCUDMU_MONDO_IDP: { expect_data[dmuNcuCrPe] = 1'b1; }
199 SIIDMU_WRACK_P: { expect_data[dmuSiiCrPe] = 1'b1; }
200 }
201 // only take first one on the list
202 if (!check_sii_syndrome)
203 {
204 if (sii_etag !== 3'b011)
205 {
206 check_sii_syndrome = 1;
207 sii_syndrome = {1'b1, 4'b0, sii_etag, ptr_pkt.ctag, ptr_pkt.pa};
208 }
209 }
210
211 list_ptr = ras_injector.injected_err_list.erase(list_ptr);
212 ptr_pkt = list_ptr.data();
213 }
214
215#ifdef N2_FC
216 // direct read from the ncu ras csr
217 per_data = 64'b0;
218 per_data[42:0] = ncu_ras_csr.per;
219 if (expect_data[42:0] !== per_data[42:0])
220 {
221 repeat (wait_for_report) @ (posedge ncu_cpx_err_mon.clk);
222 esr_data[42:0] = ncu_ras_csr.esr[42:0];
223 per_data = esr_data | per_data;
224 result = (expect_data[42:0] === per_data[42:0]) ? 1 : 0;
225 }
226 else
227 result = 1;
228
229 if (result)
230 dbg.dispmon(myname, MON_NORMAL, psprintf("direct read: error status register match get=%x exp=%x", per_data[42:0], expect_data[42:0]));
231 else
232 dbg.dispmon(myname, MON_ERR, psprintf("direct read: error status register mismatch get=%x exp=%x", per_data[42:0], expect_data[42:0]));
233
234 if (check_sii_syndrome)
235 {
236 repeat (30) @ (posedge ncu_cpx_err_mon.clk);
237 syn_data = 64'b0;
238 syn_data[58:0] = ncu_ras_csr.siisyn;
239 if (sii_syndrome[58:56] === 3'b0 || sii_syndrome[58:56] === 3'b001) sii_syndrome[55:40] = syn_data[55:40];
240 if (sii_syndrome[58:0] === syn_data[58:0])
241 {
242 dbg.dispmon(myname, MON_NORMAL, psprintf("direct read: sii error syndrome register match get=%x exp=%x", syn_data[58:0], sii_syndrome[58:0]));
243 result = 1;
244 }
245 else
246 {
247 dbg.dispmon(myname, MON_ERR, psprintf("direct read: sii error syndrome register mismatch get=%x exp=%x", syn_data[58:0], sii_syndrome[58:0]));
248 result = 0;
249 }
250 }
251 // end of direct read checking
252#else
253
254 // disable interrupt
255 gen_pio_drv.pio_rd(40'h80_0000_3010, ncueie_value);
256 gen_pio_drv.pio_wr(40'h80_0000_3010, 64'h0000_0000_0000_0000);
257 // read per,
258 gen_pio_drv.pio_rd(40'h80_0000_3028, tdata1);
259 per_data = {tdata1[7:0],tdata1[15:8],tdata1[23:16],tdata1[31:24],tdata1[39:32],tdata1[47:40],tdata1[55:48],tdata1[63:56]};
260 // if not matched, wait 100 cycles
261 if (expect_data[62:0] !== per_data[62:0])
262 {
263 repeat (wait_for_report) @ (posedge ncu_cpx_err_mon.clk);
264 gen_pio_drv.pio_rd(40'h80_0000_3000, tdata1);
265 esr_data = {tdata1[7:0],tdata1[15:8],tdata1[23:16],tdata1[31:24],tdata1[39:32],tdata1[47:40],tdata1[55:48],tdata1[63:56]};
266 per_data = esr_data | per_data;
267 result = (expect_data[62:0] === per_data[62:0]) ? 1 : 0;
268 }
269 else
270 result = 1;
271 if (result)
272 dbg.dispmon(myname, MON_NORMAL, psprintf("error status register match get=%x exp=%x", per_data, expect_data));
273 else
274 dbg.dispmon(myname, MON_ERR, psprintf("error status register mismatch get=%x exp=%x", per_data, expect_data));
275
276
277 // disable logging
278 gen_pio_drv.pio_rd(40'h80_0000_3008, ncuele_value);
279 gen_pio_drv.pio_wr(40'h80_0000_3008, 64'h0000_0000_0000_0000);
280
281
282 // check syndrome
283 if (check_sii_syndrome)
284 {
285 gen_pio_drv.pio_rd(40'h80_0000_3030, tdata1);
286 syn_data = {tdata1[7:0],tdata1[15:8],tdata1[23:16],tdata1[31:24],tdata1[39:32],tdata1[47:40],tdata1[55:48],tdata1[63:56]};
287 if (sii_syndrome[58:56] === 3'b0 || sii_syndrome[58:56] === 3'b001) sii_syndrome[55:40] = syn_data[55:40];
288 if (sii_syndrome === syn_data)
289 {
290 dbg.dispmon(myname, MON_NORMAL, psprintf("sii error syndrome register match get=%x exp=%x", syn_data, sii_syndrome));
291 result = 1;
292 }
293 else
294 {
295 dbg.dispmon(myname, MON_ERR, psprintf("sii error syndrome register mismatch get=%x exp=%x", syn_data, sii_syndrome));
296 result = 0;
297 }
298 }
299
300 gen_pio_drv.pio_wr(40'h80_0000_3028, 64'h0000_0000_0000_0000);
301 gen_pio_drv.pio_wr(40'h80_0000_3000, 64'h0000_0000_0000_0000);
302 gen_pio_drv.pio_wr(40'h80_0000_3030, 64'h0000_0000_0000_0000);
303 gen_pio_drv.pio_wr(40'h80_0000_3008, ncuele_value);
304 gen_pio_drv.pio_wr(40'h80_0000_3010, ncueie_value);
305#endif
306
307 ras_injector.injector_on = 1;
308}