Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_ipp_intr_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 | #include "niu_int_dev.vrh" | |
37 | #include "niu_int_mgr.vrh" | |
38 | #include "mbox_class.vrh" | |
39 | #include "get_mbox_id.vrh" | |
40 | #include "neptune_memory_map.vri" | |
41 | #include "ipp_memory_map.vri" | |
42 | #include "mac_defines.vri" | |
43 | #include "pio_driver.vrh" | |
44 | #include "mac_pio_class.vrh" | |
45 | #include "xmac_util.vrh" | |
46 | #include "bmac_util.vrh" | |
47 | #include "mac_shadow_class.vrh" | |
48 | #include "xmac_shadow_class.vrh" | |
49 | #include "vega_shadow_class.vrh" | |
50 | #include "cMesg.vrh" | |
51 | #include "mac_defines.vri" | |
52 | ||
53 | extern Mesg be_msg; | |
54 | extern niu_gen_pio gen_pio_drv; | |
55 | extern CNiuIntrMgr NiuIntrMgr; | |
56 | extern pio_drv pio_driver_class; | |
57 | extern mac_pio_cl mac_pio_class; | |
58 | extern shadow_cl shadow_class; | |
59 | extern mac_util_class mac_util; | |
60 | extern bmac_util_class bmac_util; | |
61 | ||
62 | /* defined in ipp_memory_map.vri, listed here just for reference | |
63 | #define IPP_MASK_ECC_ERR_MX 7 | |
64 | #define IPP_MASK_DFIFO_EOP_SOP 6 | |
65 | #define IPP_MASK_DFIFO_UC 5 | |
66 | #define IPP_MASK_PFIFO_PAR 4 | |
67 | #define IPP_MASK_PFIFO_OVER 3 | |
68 | #define IPP_MASK_PFIFO_UND 2 | |
69 | #define IPP_MASK_BAD_CS 1 | |
70 | #define IPP_MASK_PKT_DIS_CNT 0 | |
71 | ||
72 | #define IPP_STAT_SOP_MISS 31 // corresponds to MASK 6 | |
73 | #define IPP_STAT_EOP_MISS 30 // corresponds to MASK 6 | |
74 | #define IPP_STAT_DFIFO_UE 29:28 // corresponds to MASK 5 | |
75 | #define IPP_STAT_DFIFO_CE 27:26 | |
76 | #define IPP_STAT_DFIFO_ECC 25:24 | |
77 | #define IPP_STAT_DFIFO_ECC_ID 22:12 | |
78 | #define IPP_STAT_PFIFO_PERR 11 // corresponds to MASK 4 | |
79 | #define IPP_STAT_ECC_ERR_MA 10 // corresponds to MASK 7 | |
80 | #define IPP_STAT_PFIFO_ERR_ID 9:4 | |
81 | #define IPP_STAT_PFIFO_OVER 3 // corresponds to MASK 3 | |
82 | #define IPP_STAT_PFIFO_UND 2 // corresponds to MASK 2 | |
83 | #define IPP_STAT_BAD_CS_MX 1 // corresponds to MASK 1 | |
84 | #define IPP_STAT_PKT_DIS_MX 0 // corresponds to MASK 0 | |
85 | */ | |
86 | ||
87 | class CNiuIntrDevIPPm extends CNiuIntrDev { | |
88 | integer isr_count = 0; | |
89 | integer lf_intr_cnt = 0; | |
90 | integer rf_intr_cnt = 0; | |
91 | bit [3:0] ports_vld = 0; | |
92 | ||
93 | task new(bit [3:0] ports_valid, integer dev_id) { | |
94 | super.new(dev_id); | |
95 | ports_vld = ports_valid; | |
96 | ErrId = 2; // for Interrupt Manager to Kick off the right Error Device's ISR | |
97 | // In the PIO_SYS_ERR_STAT, bit[2] is Interrupt for IPP, that is why. | |
98 | } | |
99 | task set_masks(bit [3:0] ports_valid); | |
100 | function integer isr( (bit[1:0] ldf_flags=0) ); | |
101 | task check_ipp_int(integer mac_id); | |
102 | } | |
103 | ||
104 | function integer CNiuIntrDevIPPm::isr( (bit[1:0] ldf_flags=0) ) { | |
105 | bit[31:0] rd_data, rd_status, rd_mask; | |
106 | bit[39:0] base_addr; | |
107 | bit [63:0] address; | |
108 | integer i; | |
109 | ||
110 | printf("Start in CNiuIntrDevIPP ISR DevId time=%0d\n", super.dev_id, get_time(LO)); | |
111 | isr_done = 0; | |
112 | SetPendingFlag(); | |
113 | ||
114 | if(ldf_flags!=2) printf("ERROR ldf_flags is not set to the correct value of 2\n"); | |
115 | ||
116 | for(i=0;i<4;i++){ | |
117 | if (ports_vld[i]) { | |
118 | printf("CNiuIntrDevIPP Kicking off PerPort-ISR IntrDevId=%0d ipp_num=%0d LDF_flags=%0d time=%0d\n", | |
119 | super.dev_id, i, ldf_flags, get_time(LO)); | |
120 | check_ipp_int(i); | |
121 | } | |
122 | } | |
123 | ||
124 | ClrPendingFlag(); | |
125 | isr_done=1; | |
126 | printf("End in CNiuIntrDevIPP ISR DevId time=%0d\n", super.dev_id, get_time(LO)); | |
127 | } | |
128 | ||
129 | task CNiuIntrDevIPPm::check_ipp_int(integer mac_id) { | |
130 | bit[31:0] rd_data, rd_status, rd_mask; | |
131 | bit[39:0] base_addr; | |
132 | bit[63:0] rd_data64; | |
133 | bit[63:0] address; | |
134 | ||
135 | case(mac_id){ | |
136 | 0:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_0_RANGE; | |
137 | 1:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_1_RANGE; | |
138 | 2:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_2_RANGE; | |
139 | 3:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_3_RANGE; | |
140 | default: {} | |
141 | } | |
142 | ||
143 | gen_pio_drv.pio_rd(address, rd_data64, 1'b0); | |
144 | printf("CNiuIntrDevIPP INT_STAT id=%0d status=0x%0x for ipp %0d\n", super.dev_id, rd_data64, mac_id); | |
145 | ||
146 | /**** Each Bit ISR Response ****/ | |
147 | if(rd_data64[IPP_STAT_ECC_ERR_MA]) { | |
148 | printf("CNiuIntrDevIPP IPP_INT_STAT IPP_MASK_ECC_ERR_MX is set\n"); | |
149 | // write 0 to ECC_CNTR to clear this bit | |
150 | case(mac_id){ | |
151 | 0:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_0_RANGE; | |
152 | 1:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_1_RANGE; | |
153 | 2:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_2_RANGE; | |
154 | 3:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_3_RANGE; | |
155 | default: {} | |
156 | } | |
157 | gen_pio_drv.pio_rd(address, rd_data64, 1'b0); // Read to Clear the ECC Error Counter | |
158 | // Now, read the IPP_INT_STAT again to make sure it is really cleared | |
159 | case(mac_id){ | |
160 | 0:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_0_RANGE; | |
161 | 1:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_1_RANGE; | |
162 | 2:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_2_RANGE; | |
163 | 3:address = FZC_IPP_BASE_ADDRESS+IPP_INT_STATUS+IPP_3_RANGE; | |
164 | default: {} | |
165 | } | |
166 | gen_pio_drv.pio_rd(address, rd_data64, 1'b0); | |
167 | if (rd_data64[IPP_STAT_ECC_ERR_MA]) | |
168 | be_msg.print(e_mesg_error, "CNiuIntrDevIPP::check_ipp_int", "ISR", | |
169 | "Could not get IPP_STAT_ECC_ERR_MA bit cleared in the ISR\n"); | |
170 | else | |
171 | printf("IPP_STAT_ECC_ERR_MA bit is just cleared in the ISR\n"); | |
172 | ||
173 | // pre-program IPP_ECC_ERR_COUNTER to an almost-full value to get the next intr sooner | |
174 | case(mac_id){ | |
175 | 0:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_0_RANGE; | |
176 | 1:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_1_RANGE; | |
177 | 2:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_2_RANGE; | |
178 | 3:address = FZC_IPP_BASE_ADDRESS+IPP_ECC_ERR_COUNTER+IPP_3_RANGE; | |
179 | default: {} | |
180 | } | |
181 | gen_pio_drv.pio_wr(address, rd_data64); // Write 8'hf0 to IPP_ECC_ERR_COUNTER | |
182 | } | |
183 | /**** Each Bit ISR Response ****/ | |
184 | if(rd_data64[IPP_STAT_SOP_MISS] | rd_data64[IPP_STAT_EOP_MISS]) { | |
185 | } | |
186 | /**** Each Bit ISR Response ****/ | |
187 | if(rd_data64[IPP_STAT_DFIFO_UE]) { | |
188 | } | |
189 | /**** Each Bit ISR Response ****/ | |
190 | if(rd_data64[IPP_STAT_PFIFO_PERR]) { | |
191 | } | |
192 | /**** Each Bit ISR Response ****/ | |
193 | if(rd_data64[IPP_STAT_PFIFO_OVER]) { | |
194 | } | |
195 | /**** Each Bit ISR Response ****/ | |
196 | if(rd_data64[IPP_STAT_PFIFO_UND]) { | |
197 | } | |
198 | /**** Each Bit ISR Response ****/ | |
199 | if(rd_data64[IPP_STAT_BAD_CS_MX]) { | |
200 | } | |
201 | /**** Each Bit ISR Response ****/ | |
202 | if(rd_data64[IPP_STAT_PKT_DIS_MX]) { | |
203 | } | |
204 | } | |
205 | ||
206 | task CNiuIntrDevIPPm::set_masks (bit [3:0] ports_vld) { | |
207 | bit[39:0] base_addr; | |
208 | bit[31:0] rd_data; | |
209 | bit[63:0] address; | |
210 | integer i; | |
211 | ||
212 | for (i=0;i<4;i++) { | |
213 | if (ports_vld[i]) { | |
214 | printf("CNiuIntrDevIPP setting masks=0 mac_id=%0d\n", i); | |
215 | case(i){ | |
216 | 0:address = FZC_IPP_BASE_ADDRESS+IPP_INT_MASK+IPP_0_RANGE; | |
217 | 1:address = FZC_IPP_BASE_ADDRESS+IPP_INT_MASK+IPP_1_RANGE; | |
218 | 2:address = FZC_IPP_BASE_ADDRESS+IPP_INT_MASK+IPP_2_RANGE; | |
219 | 3:address = FZC_IPP_BASE_ADDRESS+IPP_INT_MASK+IPP_3_RANGE; | |
220 | default: {} | |
221 | } | |
222 | gen_pio_drv.pio_wr(address, 64'h0); // Enable all the 8 interrupts | |
223 | } | |
224 | } | |
225 | } |