Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / test_utils / vera / niu_intr_setup.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_intr_setup.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_int_dev.vrh"
38#include "niu_int_mgr.vrh"
39#include "niu_ldgintr_utils.vrh"
40
41
42extern CNiuIntrMgr NiuIntrMgr;
43
44
45class CNiuIntrTest {
46
47 // variables
48
49 integer timer = 10; // Test can change this
50 integer random_intr_timer = 0;
51 integer sys_err_mask_prog=0;
52 integer dev68grp=0;
53 integer dev68grpbound=0;
54 bit[68:0] virt_on = 69'h0;
55 bit[4:0] sidTab[];
56 local bit[4:0] sids[32];
57 integer fixed_function_no = 0;
58
59 local bit[5:0] virt_rx_dma_binds[32];
60 local bit[5:0] virt_tx_dma_binds[32];
61 local integer dev_to_grp_bind[69];
62
63 local integer group_already_bound[64];
64 task InitDevice ( CNiuIntrDev dev, integer group_info, (integer mask = 0),(integer sid_from_test=-1) );
65 task RemoveDevice (integer device_id, (CNiuIntrDev dev=null) );
66 local function integer getFuncNo(integer g);
67 local task compute_random_sids();
68 local task compute_random_virt_grp_no();
69 local function bit [6:0] getSid(integer group,integer func);
70 local function integer getLdgNo(integer func);
71 task new( (integer tx_v = -1), (integer rx_v = -1) );
72 task use_alt_ldg(bit[63:0] groups);
73
74}
75
76task CNiuIntrTest::new( (integer tx_v = -1), (integer rx_v = -1) ) {
77 integer i;
78 for(i=0;i<64;i++) group_already_bound[i] = 0;
79 if(rx_v ==-1) {
80 virt_on[31:0] = random();
81 } else virt_on[31:0] = rx_v;
82 if(tx_v ==-1) {
83 virt_on[63:32] = random();
84 } else virt_on[63:32] = tx_v;
85 printf(" CNiuIntrTest::new Virtualization Vector - %x \n",virt_on);
86 compute_random_sids();
87 compute_random_virt_grp_no();
88 for(i=0;i<68;i++) dev_to_grp_bind[i] = -1;
89}
90
91task CNiuIntrTest::use_alt_ldg(bit[63:0] groups) {
92 integer i;
93 CNiuLdgEx ldgEx[64];
94 for(i=0;i<64;i++) {
95 if(groups[i]) {
96 ldgEx[i] = new(i);
97 NiuIntrMgr.ldg[i] = ldgEx[i];
98 }
99 }
100}
101
102task CNiuIntrTest::compute_random_virt_grp_no(){
103 bit[5:0] rand_rx_gids[];
104 bit[5:0] rand_tx_gids[];
105 integer func_binding_type = 0;
106 bit [3:0] rand_max_15;
107 integer i;
108 bit[5:0] r;
109
110 if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
111 func_binding_type = get_plus_arg( NUM, "RXTX_PIO_STRESS_BINDING=");
112 func_binding_type = func_binding_type % 4;
113 fixed_function_no = 1;
114 }
115 if(get_plus_arg( CHECK, "RANDOM_INTR_TIMER")) {
116 random_intr_timer = 1;
117 } else random_intr_timer = 0;
118
119 for(i=0;i<32;i++){
120 r = random();
121 if(assoc_index(CHECK,rand_rx_gids,r)) {
122 // recompute
123 i--;
124 } else {
125 rand_rx_gids[r] = r;
126 virt_rx_dma_binds[i] = r;
127 }
128
129 // Over write for stress testMatrix requirements
130 if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
131 // rand_max_15 = random();
132 virt_rx_dma_binds[i] = getLdgNo(func_binding_type);
133 printf(" virt_rx_dma_binds - %d i = %d\n",virt_rx_dma_binds[i],i);
134
135 }
136 }
137 for(i=0;i<32;i++){
138 r = random();
139 if(assoc_index(CHECK,rand_tx_gids,r)) {
140 // recompute
141 i--;
142 } else {
143 rand_tx_gids[r] = r;
144 virt_tx_dma_binds[i] = r;
145 }
146 // Over write for stress testMatrix requirements
147 if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
148 // rand_max_15 = random();
149 virt_tx_dma_binds[i] = getLdgNo(func_binding_type);
150 printf(" virt_tx_dma_binds - %d i = %d\n",virt_tx_dma_binds[i],i);
151 }
152 }
153}
154
155task CNiuIntrTest::compute_random_sids(){
156 bit[4:0] rand_sids[];
157 integer i;
158 bit[4:0] r;
159 for(i=0;i<32;i++){
160 r = random();
161 if(assoc_index(CHECK,rand_sids,r)) {
162 // recompute
163 i--;
164 } else {
165 rand_sids[r] = r;
166 sids[i] = r;
167 }
168 }
169}
170
171function bit[6:0] CNiuIntrTest::getSid(integer group,integer func){
172
173 bit[1:0] f;
174 bit[4:0] g;
175
176 f= func ;
177 g = group ;
178 getSid = {f,sids[g]};
179
180}
181function integer CNiuIntrTest::getLdgNo(integer func){
182 integer min, max;
183 min = 0 +16*func;
184 max = 15 +16*func;
185 getLdgNo = random() %16 +min;
186
187}
188function integer CNiuIntrTest::getFuncNo(integer g) {
189 if(g<=15) getFuncNo = 0;
190 else if(g<=31) getFuncNo = 1;
191 else if(g<=47) getFuncNo = 2;
192 else if(g<=63) getFuncNo = 3;
193 else { printf("CNiuIntrTest::getFuncNo TESTBENCH ERROR Incorrect Group Specified !!\n");}
194
195
196}
197
198task CNiuIntrTest::RemoveDevice (integer device_id, (CNiuIntrDev dev=null) ){
199 // if device class is specified that takes precedence
200 // else take the device_id
201
202 integer device_to_remove;
203 integer group_bound;
204
205 if(dev==null) {
206 device_to_remove = device_id;
207 } else {
208 device_to_remove = dev.dev_id;
209 }
210 group_bound = dev_to_grp_bind[device_to_remove];
211
212 if(group_bound ==-1) {
213 printf("CNiuIntrTest::RemoveDevice:ERROR Device ID - %d Not bound to any group \n",device_to_remove);
214 return;
215 }
216
217 NiuIntrMgr.ldg[group_bound].ldgunbind(device_to_remove);
218 group_already_bound[group_bound]--;
219 if(group_already_bound[group_bound]==0) {
220 // remove SID also from the table
221 NiuIntrMgr.invalidateSidTab(group_bound);
222 }
223
224
225}
226task CNiuIntrTest::InitDevice ( CNiuIntrDev dev, integer group_info, (integer mask = 0),(integer sid_from_test=-1) ){
227
228 integer func;
229 integer group;
230 bit[6:0] sid;
231 integer grp_num;
232 integer rx_or_tx;
233 integer id;
234 integer skip_virt;
235
236
237 // group determines the function to which this is going to be bound
238 // if virtualization is enabled this is determined by the dma-virtual bind
239 // if virtualization is not defined, this get determined by the ldg
240
241// ....
242// ....
243 id = dev.dev_id;
244 // compute dma id from device_id
245 if(dev.dev_id<32) {
246 rx_or_tx = 1; // 0 - Tx 1 - Rx
247 id = dev.dev_id;
248 skip_virt = 0;
249 } else if(dev.dev_id<63) {
250 rx_or_tx = 0; // 0 - Tx 1 - Rx
251 id = dev.dev_id - 32;
252 skip_virt = 0;
253 } else {
254 // This device is either MAC or one of the error device
255 // cannot do virtualization on these
256 skip_virt = 1;
257 }
258 if(fixed_function_no) {
259 if(rx_or_tx) {
260 grp_num = virt_rx_dma_binds[id];
261 } else {
262 grp_num = virt_tx_dma_binds[id];
263 }
264 group_info = grp_num;
265 printf("FIXED FUNCTION NO!! Group - %d \n",group_info);
266 skip_virt = 1;
267 }
268 if(virt_on[dev.dev_id] && (skip_virt==0) ) {
269 if(rx_or_tx) {
270 grp_num = virt_rx_dma_binds[id];
271 } else {
272 grp_num = virt_tx_dma_binds[id];
273 }
274 func = getFuncNo(grp_num);
275 dev.bind_to_group(grp_num);
276 group_info = getLdgNo(func);
277 }
278
279 if((dev.dev_id==68) && (dev68grpbound)) {
280 // override the group_info
281 group_info = dev68grp;
282 }
283 if(group_info ==-1) {
284 // pick up a random group for this device
285 group = random()%64;
286 func = getFuncNo(group);
287 } else {
288 group = group_info;
289 func = getFuncNo(group_info);
290 }
291 if(group_already_bound[group]!=0) {
292 printf(" Group - %d Already has members - Not programming SID for this group\n",group);
293 } else {
294 // bind this group
295 group_already_bound[group]++;
296
297 if(sid_from_test==-1)
298 sid = getSid(group,func);
299 else sid = sid_from_test;
300
301 printf("CNiuIntrTest::InitDevice - SID - %x Group - %d Func - %d \n",sid,group,func);
302 NiuIntrMgr.updateSidTab(group,sid);
303 // Arm the initial interrupt
304 if(random_intr_timer)
305 NiuIntrMgr.ldg[group].SetIntrMgm(1/*Arm*/,timer + random()%timer /*Timer*/); // Set up Arm bit
306 else
307 NiuIntrMgr.ldg[group].SetIntrMgm(1/*Arm*/,timer/*Timer*/); // Set up Arm bit
308 // Set up rearm flag - Need to be under test control
309 NiuIntrMgr.ldg[group].rearm = 1;
310 }
311 dev.pioSetMasks(mask);
312 dev_to_grp_bind [dev.dev_id] = group;
313 NiuIntrMgr.ldg[group].ldgbind(dev);
314 if(dev.dev_id==68) {
315 dev68grp = group;
316 if(sys_err_mask_prog==0) {
317 NiuIntrMgr.ldg[group].SetErrMask(0);// programs all 0s for now...
318 sys_err_mask_prog = 1;
319 }
320 }
321 if(virt_on[dev.dev_id] && (skip_virt==0) ) {
322 NiuIntrMgr.ldg[group].dis_pio_virt = 0;
323 }
324}