Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_int_mgr.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 "niu_int_dev.vrh" | |
37 | #include "niu_int_ldg.vrh" | |
38 | #include "niu_int_qmgr.vrh" | |
39 | #include "niu_int_sidmgr.vrh" | |
40 | #include "pio_driver.vrh" | |
41 | #ifdef NEPTUNE | |
42 | #include "Pcie_defines.vri" | |
43 | #include "Pcie_intr_util.vrh" | |
44 | #else | |
45 | #endif | |
46 | ||
47 | extern niu_gen_pio gen_pio_drv; | |
48 | #define DEASSERT_SEEN 100 | |
49 | ||
50 | ||
51 | ||
52 | #ifdef NEPTUNE | |
53 | extern Pcie_intr_util pcie_intr_util; | |
54 | #else | |
55 | #endif | |
56 | ||
57 | extern CNiuIntrQMgr NiuIntrQ; | |
58 | ||
59 | class CNiuIntrMgr { | |
60 | ||
61 | CSidShadowTab SidTab; | |
62 | CNiuLdg ldg[64]; | |
63 | bit [63:0] active_ldg; | |
64 | ||
65 | // Neptune Specific | |
66 | // event intx_sync[4]; | |
67 | integer INTX_BUG_FIX=0; | |
68 | integer intx_sync[4]; | |
69 | bit[63:0] ldg_func_map[4]; | |
70 | local integer deasset_mbox[4]; | |
71 | integer masks_before_isrs=0; | |
72 | ||
73 | task new(); | |
74 | task initLdg(bit [63:0] active_list); | |
75 | task SetTmrRes(bit[63:0] wdata); | |
76 | local task spGetIntMsg(); | |
77 | local task parseIntx(bit[3:0] assert_msg, bit[3:0] deassert_msg,CniuGenIntrMsg IntrMsg) ; | |
78 | local task procIntDevId(CniuGenIntrMsg IntrMsg) ; | |
79 | local task procIntMsi(CniuGenIntrMsg IntrMsg) ; | |
80 | local task procIntx(integer func,CniuGenIntrMsg IntrMsg) ; | |
81 | local task spawnprocIntx(integer func,CniuGenIntrMsg IntrMsg) ; | |
82 | function integer getFuncionNo(bit[3:0] msg); | |
83 | task bindLdgFunc(bit [63:0] list,integer func); | |
84 | task updateSidTab(integer gid, bit[6:0] sid); | |
85 | task invalidateSidTab(integer gid ); | |
86 | function integer get_DevIsr_Cnt(integer group_bind_no, integer dev_id) ; | |
87 | task CheckPendingFlags(); | |
88 | function integer CheckDevPendingFlag(integer device_no) ; | |
89 | } | |
90 | ||
91 | // Set up Tasks | |
92 | task CNiuIntrMgr::SetTmrRes(bit[63:0] wdata) { | |
93 | bit[63:0] address; | |
94 | address = LDGITMRES; | |
95 | gen_pio_drv.pio_wr(address,wdata); | |
96 | } | |
97 | ||
98 | ||
99 | task CNiuIntrMgr::new() { | |
100 | integer i; | |
101 | active_ldg = 0; | |
102 | SidTab = new(); | |
103 | for(i=0;i<4;i++) { | |
104 | // trigger(ON,intx_sync[i]); | |
105 | intx_sync[i] = alloc(SEMAPHORE,0,1,0); | |
106 | semaphore_put(intx_sync[i],1); | |
107 | ||
108 | ldg_func_map[i] = 0; | |
109 | deasset_mbox[i] = alloc(MAILBOX,0,1); | |
110 | } | |
111 | fork { | |
112 | spGetIntMsg(); | |
113 | } join none | |
114 | ||
115 | if(get_plus_arg(CHECK,"MASK_BEFORE_ISR")) { | |
116 | masks_before_isrs = 1; | |
117 | } | |
118 | if(get_plus_arg(CHECK,"INTX_BUG_FIX")) { | |
119 | INTX_BUG_FIX = 1; | |
120 | } | |
121 | } | |
122 | ||
123 | ||
124 | // SID Setup Tasks | |
125 | // LDG Setup Tasks | |
126 | task CNiuIntrMgr::initLdg(bit [63:0] active_list) { | |
127 | integer i; | |
128 | #ifdef NEPTUNE | |
129 | pcie_intr_util.setup_neptune_interrupts(); | |
130 | #else | |
131 | #endif | |
132 | for(i=0;i<64;i++) { | |
133 | if(active_list[i]) { | |
134 | ldg[i] = new(i); | |
135 | active_ldg[i] = 1; | |
136 | } | |
137 | } | |
138 | // bindLdgFunc(active_list,0); // TMP | |
139 | } | |
140 | task CNiuIntrMgr::invalidateSidTab(integer gid ){ | |
141 | SidTab.RemoveSidTab(gid); | |
142 | } | |
143 | ||
144 | task CNiuIntrMgr::updateSidTab(integer gid, bit[6:0] sid){ | |
145 | integer func; | |
146 | func = sid[6:5]; | |
147 | ldg_func_map[func] =ldg_func_map[func] | ( 1<<gid); | |
148 | if(ldg[gid]==null){ | |
149 | printf("ERROR ldg- %d Not active!! Cannot update SID for this group\n",gid); | |
150 | } else { | |
151 | ldg[gid].setSid(sid); | |
152 | } | |
153 | SidTab.pio_writeSidTab(gid,sid); | |
154 | ||
155 | } | |
156 | task CNiuIntrMgr::bindLdgFunc(bit [63:0] list,integer func){ | |
157 | ldg_func_map[func] = list; | |
158 | printf("CNiuIntrMgr::bindLdgFunc: list - %x function - %d \n",ldg_func_map[func],func); | |
159 | } | |
160 | ||
161 | // Queue Management tasks | |
162 | // - SID Look up tasks | |
163 | // - Get LDG Number | |
164 | // - Call LDG's ISR | |
165 | ||
166 | task CNiuIntrMgr::spGetIntMsg() { | |
167 | ||
168 | CniuGenIntrMsg IntrMsg; | |
169 | shadow integer status,gid; | |
170 | shadow bit [6:0] sid; | |
171 | integer message; | |
172 | bit[3:0] assert_msg,deassert_msg; | |
173 | shadow integer i; | |
174 | integer nep_msi_intr; | |
175 | /* free running task */ | |
176 | ||
177 | ||
178 | while(1) { | |
179 | /*Wait for a message in the intrQueue*/ | |
180 | ||
181 | while(NiuIntrQ.isQEmpty() ) { | |
182 | repeat(10) @(posedge CLOCK); | |
183 | } | |
184 | IntrMsg = NiuIntrQ.getIntrMsg(status); | |
185 | if(status ==0) { | |
186 | printf("spGetIntMsg TB ERROR \n"); | |
187 | return; | |
188 | } | |
189 | ||
190 | // Parse the message and get the SID information from this | |
191 | assert_msg = 0; | |
192 | deassert_msg = 0; | |
193 | nep_msi_intr =0; | |
194 | #ifdef NEPTUNE | |
195 | // First get the type of message | |
196 | message = IntrMsg.int_message; | |
197 | printf(" Message - %x \n",message); | |
198 | if(message == -1) { | |
199 | // not an intx message | |
200 | } else { | |
201 | assert_msg = 0; | |
202 | deassert_msg = 0; | |
203 | nep_msi_intr = 0; | |
204 | ||
205 | if(message== PCIE_MSG_CODE_INTX_ASSERT_A) { | |
206 | assert_msg[0] = 1; | |
207 | } else if(message == PCIE_MSG_CODE_INTX_DEASSERT_A) { | |
208 | deassert_msg[0] = 1; | |
209 | } else if(message== PCIE_MSG_CODE_INTX_ASSERT_B) { | |
210 | assert_msg[1] = 1; | |
211 | } else if(message == PCIE_MSG_CODE_INTX_DEASSERT_B) { | |
212 | deassert_msg[1] = 1; | |
213 | } else if(message== PCIE_MSG_CODE_INTX_ASSERT_C) { | |
214 | assert_msg[2] = 1; | |
215 | } else if(message == PCIE_MSG_CODE_INTX_DEASSERT_C) { | |
216 | deassert_msg[2] = 1; | |
217 | } else if(message== PCIE_MSG_CODE_INTX_ASSERT_D) { | |
218 | assert_msg[3] = 1; | |
219 | } else if(message == PCIE_MSG_CODE_INTX_DEASSERT_D) { | |
220 | deassert_msg[3] = 1; | |
221 | } else if(message== PCIE_MSI) { | |
222 | printf("CNiuIntrMgr::spGetIntMsg Received PCIE_MSI Message Vector - %x NoOfIntrs - %d \n",IntrMsg.int_message,IntrMsg.no_of_intr_alloc); | |
223 | nep_msi_intr = 1; | |
224 | } else if(message== PCIE_MSIX) { | |
225 | printf("CNiuIntrMgr::spGetIntMsg Received PCIE_MSIX Message Vector - %x NoOfIntrs - %d \n",IntrMsg.int_message,IntrMsg.no_of_intr_alloc); | |
226 | } | |
227 | ||
228 | } | |
229 | #else | |
230 | #endif | |
231 | ||
232 | if(assert_msg|deassert_msg) { | |
233 | // any Intx Message seen | |
234 | parseIntx(assert_msg,deassert_msg,IntrMsg); | |
235 | } else if(nep_msi_intr) { | |
236 | procIntMsi(IntrMsg); | |
237 | } else { | |
238 | procIntDevId(IntrMsg); | |
239 | } | |
240 | } // end while | |
241 | } | |
242 | function integer CNiuIntrMgr::getFuncionNo(bit[3:0] msg) { | |
243 | // According to Babu - IntA is for function0 , IntB for funtion 1 and so on | |
244 | ||
245 | if(msg[0]) | |
246 | getFuncionNo = 0; | |
247 | else if(msg[1]) | |
248 | getFuncionNo = 1; | |
249 | else if(msg[2]) | |
250 | getFuncionNo = 2; | |
251 | else if(msg[3]) | |
252 | getFuncionNo = 3; | |
253 | else getFuncionNo = -1; | |
254 | } | |
255 | ||
256 | ||
257 | task CNiuIntrMgr:: parseIntx(bit[3:0] assert_msg, bit[3:0] deassert_msg,CniuGenIntrMsg IntrMsg) { | |
258 | ||
259 | integer func; | |
260 | // get function number based upon the msg | |
261 | func = getFuncionNo(assert_msg | deassert_msg); | |
262 | if(deassert_msg!=0) { | |
263 | mailbox_put(deasset_mbox[func],DEASSERT_SEEN); | |
264 | } else { | |
265 | fork{ | |
266 | spawnprocIntx(func,IntrMsg); | |
267 | } join none | |
268 | } | |
269 | } | |
270 | ||
271 | task CNiuIntrMgr:: spawnprocIntx(integer func,CniuGenIntrMsg IntrMsg) { | |
272 | ||
273 | integer status, message,end_Intx; | |
274 | end_Intx = 0; | |
275 | while(end_Intx == 0) { | |
276 | procIntx(func,IntrMsg); | |
277 | printf("Done with assert - all Waiting for deassert Function - %d Time - %d\n",func, {get_time(HI), get_time(LO)}); | |
278 | repeat(50)@(posedge CLOCK); | |
279 | // Wait for some time to see if deasset was seen, if not continue | |
280 | status = mailbox_get(NO_WAIT, deasset_mbox[func], message); | |
281 | if((status!=0) && (message == DEASSERT_SEEN)) { | |
282 | printf("Done with deassert - Killing spawnprocIntx Function - %d Time - %d\n",func,{get_time(HI), get_time(LO)}); | |
283 | end_Intx = 1; | |
284 | } | |
285 | } | |
286 | } | |
287 | task CNiuIntrMgr:: procIntx(integer func,CniuGenIntrMsg IntrMsg) { | |
288 | ||
289 | integer blanket_interrupt; | |
290 | integer fixed_group_no; | |
291 | shadow integer i; | |
292 | // sync(ALL, intx_sync[func]); | |
293 | // trigger(OFF,intx_sync[func]); | |
294 | semaphore_get(WAIT,intx_sync[func],1); | |
295 | ||
296 | ||
297 | // | |
298 | /* Do we need to disable any more generation of interrupts here*/ | |
299 | // | |
300 | blanket_interrupt = 1; | |
301 | printf("CNiuIntrMgr:: procIntx Start Function - %d Time - %d\n",func,{get_time(HI), get_time(LO)}); | |
302 | ||
303 | if(INTX_BUG_FIX) { | |
304 | fixed_group_no = 16*func; | |
305 | if(masks_before_isrs) { | |
306 | if(active_ldg[fixed_group_no] && ldg_func_map[func][fixed_group_no] && (ldg[fixed_group_no].active_devices!=0) ) { | |
307 | ldg[fixed_group_no].mask_all_devices(); | |
308 | } | |
309 | } | |
310 | if(active_ldg[fixed_group_no] && ldg_func_map[func][fixed_group_no] && (ldg[fixed_group_no].active_devices!=0) ) { | |
311 | printf("Start ldgIsr Group - %d \n",fixed_group_no); | |
312 | ldg[fixed_group_no].ldgIsr(blanket_interrupt,IntrMsg); | |
313 | } | |
314 | if(masks_before_isrs) { | |
315 | if(active_ldg[fixed_group_no] && ldg_func_map[func][fixed_group_no] && (ldg[fixed_group_no].active_devices!=0) ) { | |
316 | ldg[fixed_group_no].unmask_all_devices(); | |
317 | } | |
318 | } | |
319 | } else { | |
320 | if(masks_before_isrs) { | |
321 | for(i=0;i<64;i++) { | |
322 | if(active_ldg[i] && ldg_func_map[func][i] && (ldg[i].active_devices!=0) ) { | |
323 | ldg[i].mask_all_devices(); | |
324 | } | |
325 | } | |
326 | } | |
327 | fork { | |
328 | for(i=0;i<64;i++) { | |
329 | //printf("Start ldgIsr Group xxxxx %d, %d, %d, %d\n", i, active_ldg[i], ldg_func_map[func][i], ldg[i].active_devices); | |
330 | if(active_ldg[i] && ldg_func_map[func][i] && (ldg[i].active_devices!=0) ) { | |
331 | printf("Start ldgIsr Group - %d \n",i); | |
332 | ldg[i].ldgIsr(blanket_interrupt,IntrMsg); | |
333 | } | |
334 | } | |
335 | } join all | |
336 | if(masks_before_isrs) { | |
337 | for(i=0;i<64;i++) { | |
338 | if(active_ldg[i] && ldg_func_map[func][i] && (ldg[i].active_devices!=0) ) { | |
339 | ldg[i].unmask_all_devices(); | |
340 | } | |
341 | } | |
342 | } | |
343 | } | |
344 | printf("Done with assert - all Waiting for deassert Time - %d\n",{get_time(HI), get_time(LO)}); | |
345 | // trigger(ON,intx_sync[func]); | |
346 | semaphore_put(intx_sync[func],1); | |
347 | ||
348 | ||
349 | } | |
350 | task CNiuIntrMgr::procIntMsi(CniuGenIntrMsg IntrMsg) { | |
351 | ||
352 | bit[6:0] device_id; | |
353 | bit[1:0] function_no; | |
354 | bit[4:0] sid; | |
355 | integer no_of_in_masked; | |
356 | bit[6:0] valid_sids[*]; | |
357 | integer valid_gids[*]; | |
358 | integer mask,no_of_gids,status; | |
359 | integer no_of_bits_valid; | |
360 | integer no_of_bits_masked; | |
361 | shadow integer gid,i,n; | |
362 | integer blanket_interrupt; | |
363 | integer no_of_intr_alloc; | |
364 | integer no_of_possible_intr; | |
365 | ||
366 | // In this case, the message contains the no_of_possible interrupts along with the device_id | |
367 | // first get the device_id and no_of_interrupts_allocated from this | |
368 | ||
369 | /* notes: | |
370 | no_of_intr_alloc = 32 - means all bits are valid | |
371 | no_of_intr_alloc = 16 - only 4 lsb are valid, 1 msb is masked out and hence there are 2 possible intr | |
372 | no_of_intr_alloc = 8 - only 3 lsb are valid, 2 msb is masked out and hence there are 4 possible intr | |
373 | no_of_intr_alloc = 4 - only 2 lsb are valid, 3 msb is masked out and hence there are 8 possible intr | |
374 | no_of_intr_alloc = 2 - only 1 lsb are valid, 4 msb is masked out and hence there are 16 possible intr | |
375 | no_of_intr_alloc = 1 - only 0 lsb are valid, 5 msb is masked out and hence there are 32 possible intr | |
376 | no_of_intr_alloc = 0 - illegal case | |
377 | ||
378 | ||
379 | */ | |
380 | device_id = IntrMsg.device_id; | |
381 | no_of_intr_alloc = IntrMsg.no_of_intr_alloc; | |
382 | function_no = device_id[6:5]; | |
383 | sid = device_id[4:0]; | |
384 | valid_sids = new[32]; | |
385 | valid_gids = new[32]; | |
386 | ||
387 | printf("CNiuIntrMgr::procIntMsi IntrMsg.no_of_intr_alloc - %d IntrMsg.device_id - %x \n",IntrMsg.no_of_intr_alloc,IntrMsg.device_id); | |
388 | ||
389 | // from the no_of_intr_alloc, there are lot more possible SIDs. The top bits from this SID would have been masked | |
390 | // off and therefore they need to be tested for valid SID | |
391 | no_of_bits_valid = -1; | |
392 | while(no_of_intr_alloc) { | |
393 | no_of_bits_valid++; | |
394 | no_of_intr_alloc = no_of_intr_alloc>>1; | |
395 | } | |
396 | ||
397 | if(( no_of_bits_valid > 5) ) { | |
398 | printf("ERROR CNiuIntrMgr::procIntMsi Incorrect value for IntrMsg.no_of_intr_alloc!! FIX THIS!! - %d\n",IntrMsg.no_of_intr_alloc); | |
399 | } | |
400 | no_of_intr_alloc = IntrMsg.no_of_intr_alloc; | |
401 | if(no_of_intr_alloc==0) { | |
402 | no_of_bits_valid = 0; | |
403 | } | |
404 | ||
405 | mask = 0; | |
406 | no_of_bits_masked = 5 - no_of_bits_valid ; | |
407 | no_of_possible_intr = 1<<no_of_bits_masked ; | |
408 | ||
409 | for(n=0;n<no_of_bits_valid;n++) | |
410 | mask = mask | (1<<n); | |
411 | ||
412 | ||
413 | no_of_gids = 0; | |
414 | for(n=0;n<no_of_possible_intr;n++) { | |
415 | valid_sids[n] = ((sid & mask) | ( n << no_of_bits_valid)) | (function_no<<5) ; | |
416 | status = SidTab.getGid(gid,valid_sids[n]); | |
417 | if(status!=0) { | |
418 | valid_gids[no_of_gids++] = gid; | |
419 | } | |
420 | printf("CNiuIntrMgr::procIntMsi n - %d valid_sid - %x valid_gid - %d \n",n,valid_sids[n] ,gid); | |
421 | } | |
422 | ||
423 | // now that we have all the possible SIDs from where this interrupt would have originated, check for various gids | |
424 | // some of these may be invalids too so look for those and spawn off the various ISRs | |
425 | ||
426 | if(masks_before_isrs) { | |
427 | for(i=0;i<no_of_gids;i++) { | |
428 | gid = valid_gids[i]; | |
429 | if(active_ldg[gid] && (ldg[gid].active_devices!=0) ) { | |
430 | ldg[gid].mask_all_devices(); | |
431 | } | |
432 | } | |
433 | } | |
434 | blanket_interrupt = 1; | |
435 | fork { | |
436 | for(i=0;i<no_of_gids;i++) { | |
437 | gid = valid_gids[i]; | |
438 | if(active_ldg[gid] && /*ldg_func_map[func][igid] &&*/ (ldg[gid].active_devices!=0) ) { | |
439 | ldg[gid].ldgIsr(blanket_interrupt,IntrMsg); | |
440 | } | |
441 | } | |
442 | } join all | |
443 | ||
444 | if(masks_before_isrs) { | |
445 | for(i=0;i<no_of_gids;i++) { | |
446 | gid = valid_gids[i]; | |
447 | if(active_ldg[gid] && (ldg[gid].active_devices!=0) ) { | |
448 | ldg[gid].unmask_all_devices(); | |
449 | } | |
450 | } | |
451 | } | |
452 | ||
453 | ||
454 | } | |
455 | ||
456 | task CNiuIntrMgr::procIntDevId(CniuGenIntrMsg IntrMsg) { | |
457 | ||
458 | integer status,gid; | |
459 | bit [6:0] sid; | |
460 | ||
461 | ||
462 | sid = IntrMsg.device_id[6:0]; | |
463 | printf("CNiuIntrMgr::spGetIntMsg: IntrMsg.device_id %x Time - %d \n",IntrMsg.device_id[6:0],{get_time(HI), get_time(LO)}); | |
464 | status = SidTab.getGid(gid,sid); | |
465 | printf("CNiuIntrMgr::spGetIntMsg: IntrMsg.sid - %x gid - %x status - %d active - %d Time - %d \n",sid,gid,status,active_ldg[gid],{get_time(HI), get_time(LO)}); | |
466 | if(status ==0) { | |
467 | printf("CNiuIntrMgr::spGetIntMsg: Illegal SID from Hardware ERROR \n"); | |
468 | return; | |
469 | } | |
470 | // check if this gid is an active one | |
471 | // if not flag errors | |
472 | if(active_ldg[gid]!==1) { | |
473 | printf("CNiuIntrMgr::procIntDevId: LDG Num - %d Not bound TB ERROR \n",gid); | |
474 | return; | |
475 | } | |
476 | // spawn task with ldg to check all the interrupting devices so that | |
477 | // they can run their ISRs | |
478 | ||
479 | fork { | |
480 | ||
481 | if(masks_before_isrs) | |
482 | ldg[gid].mask_all_devices(); | |
483 | ||
484 | ldg[gid].ldgIsr(0,IntrMsg); | |
485 | ||
486 | if(masks_before_isrs) | |
487 | ldg[gid].unmask_all_devices(); | |
488 | ||
489 | } join none | |
490 | } | |
491 | ||
492 | function integer CNiuIntrMgr :: get_DevIsr_Cnt(integer group_bind_no, integer dev_id) { | |
493 | ||
494 | integer isr_count = 0; | |
495 | ||
496 | if(active_ldg[group_bind_no]) { | |
497 | isr_count = ldg[group_bind_no].getDevIsrCnt(dev_id); | |
498 | } else { | |
499 | isr_count = -1; | |
500 | printf("CNiuIntrMgr :: get_DevIsr_Cnt TEST ERROR - Group - %d Not Active!!\n",group_bind_no); | |
501 | } | |
502 | ||
503 | get_DevIsr_Cnt = isr_count; | |
504 | } | |
505 | ||
506 | task CNiuIntrMgr :: CheckPendingFlags(){ | |
507 | shadow integer i; | |
508 | bit[63:0] done; | |
509 | shadow integer pending_flags; | |
510 | bit[63:0] restart_pending_flags; | |
511 | bit[63:0] active_grps; | |
512 | ||
513 | ||
514 | for(i=0;i<64;i++) | |
515 | active_grps[i] = (active_ldg[i] & (ldg[i].active_devices!=0)) ; | |
516 | ||
517 | restart_pending_flags = 0; | |
518 | while(restart_pending_flags!= active_grps) { | |
519 | done = 64'h0; | |
520 | for(i=0;i<64;i++) { | |
521 | if(active_ldg[i] & (ldg[i].active_devices!=0)) { | |
522 | fork { | |
523 | printf("CNiuIntrMgr :: CheckPendingFlags Checking LDG# - %d for pending interrupts \n",i); | |
524 | pending_flags = ldg[i].isPending(); | |
525 | if(pending_flags==-1) { | |
526 | printf("CNiuIntrMgr :: CheckPendingFlags Group - %d Returned ERROR!!! \n",i); | |
527 | } | |
528 | done[i] = 1; | |
529 | } join none | |
530 | }else done[i] = 1; | |
531 | } | |
532 | wait_child(); | |
533 | printf(" CNiuIntrMgr :: CheckPendingFlags! Exiting, All Interrupts done!! first Iteration \n"); | |
534 | // check to see if anything is stillpending | |
535 | for(i=0;i<64;i++) { | |
536 | if(active_grps[i]) { | |
537 | restart_pending_flags[i] = (ldg[i].pending_flag==0); | |
538 | } | |
539 | } | |
540 | printf("CNiuIntrMgr :: CheckPendingFlags restart_pending_flags - %x \n",restart_pending_flags); | |
541 | ||
542 | }// while | |
543 | ||
544 | } | |
545 | ||
546 | function integer CNiuIntrMgr:: CheckDevPendingFlag(integer device_no) { | |
547 | // first get the group to which this is bound | |
548 | integer i; | |
549 | integer pending_flags; | |
550 | i=0; | |
551 | while(i<64) { | |
552 | if(active_ldg[i] & (ldg[i].active_devices[device_no])) { | |
553 | break; | |
554 | } else i++; | |
555 | } | |
556 | if(i==64) { | |
557 | printf("CNiuIntrMgr:: CheckDevPendingFlag device_no - %d Not bound to any group!! ERROR \n",device_no); | |
558 | return; | |
559 | } | |
560 | pending_flags = ldg[i].isPending(); | |
561 | if(pending_flags==-1) { | |
562 | printf("CNiuIntrMgr :: CheckDevPendingFlag Group - %d Returned ERROR!!! \n",i); | |
563 | } | |
564 | CheckDevPendingFlag = pending_flags; | |
565 | } |