Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: pl_consumer.cpp | |
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 "dll_top.hpp" | |
36 | ||
37 | namespace pcie { | |
38 | ||
39 | /** This function gets packets from PL and processes them **/ | |
40 | void dll_top::pl_consumer() | |
41 | { | |
42 | LOG_DEBUG<<"DLL: pl_consumer begins..."; | |
43 | try { | |
44 | RefPciePacket rx_pkt; | |
45 | RefPciePacket tx_ack_nack_pkt; | |
46 | int i,rx_pkt_size; | |
47 | sc_uint<16> rx_pkt_dllp_crc,tx_pkt_dllp_crc; | |
48 | sc_uint<12> rx_pkt_seq_num; | |
49 | sc_uint<8> byte_seq_num; | |
50 | sc_uint<12> tx_pkt_seq_num; | |
51 | sc_uint<12> check_seq_num; | |
52 | sc_uint<32> rx_pkt_calc_lcrc; | |
53 | sc_uint<8> HdrFC; | |
54 | sc_uint<12> DataFC; | |
55 | sc_uint<16> dllp_crc_unmapped; | |
56 | sc_uint<8> SDP_byte1; | |
57 | sc_uint<8> SDP_byte2; | |
58 | sc_uint<8> SDP_byte3; | |
59 | sc_uint<8> SDP_byte4; | |
60 | sc_uint<8> SDP_byte5; | |
61 | sc_uint<8> SDP_byte6; | |
62 | sc_uint<64> tlu_ecl_hw_reg,tlu_ecc_hw_reg ; | |
63 | ||
64 | time_last_ack_nak_received=0; | |
65 | ||
66 | while (true) { | |
67 | //Receive packet from PL | |
68 | pl_dll_in.get_packet(rx_pkt); | |
69 | //rx_pkt->display_packet(); | |
70 | ||
71 | if(rx_pkt->get_byte(0) == STP && rx_pkt->get_control() != DLLP_NAK && rx_pkt->get_control() != DLLP_NAK_FRAMING){ | |
72 | //cout << sc_time_stamp() << " DLL: Received TLP " << rx_pkt->getPacketId() << " from PL." << endl; | |
73 | rx_pkt_size = rx_pkt->get_size(); | |
74 | byte_seq_num = rx_pkt->get_byte(1); | |
75 | rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0); | |
76 | byte_seq_num = rx_pkt->get_byte(2); | |
77 | rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0); | |
78 | //rx_pkt->pl2dll_display_stp_packet(); | |
79 | ||
80 | rx_pkt_calc_lcrc=calculate_lcrc(rx_pkt,1,rx_pkt_size-5); | |
81 | ||
82 | if((rx_pkt->get_byte(rx_pkt_size - 2) == rx_pkt_calc_lcrc.range(7,0)) && | |
83 | (rx_pkt->get_byte(rx_pkt_size - 3) == rx_pkt_calc_lcrc.range(15,8)) && | |
84 | (rx_pkt->get_byte(rx_pkt_size - 4) == rx_pkt_calc_lcrc.range(23,16)) && | |
85 | (rx_pkt->get_byte(rx_pkt_size - 5) == rx_pkt_calc_lcrc.range(31,24))) | |
86 | { | |
87 | LCRC_MATCHED = 1; | |
88 | } | |
89 | else { | |
90 | LCRC_MATCHED = 0; | |
91 | LOG_DEBUG << "_DLL_ : LCRC MIS-MATCH => Calculated: " << rx_pkt_calc_lcrc << " Received: " << rx_pkt->get_byte(rx_pkt_size-5) << rx_pkt->get_byte(rx_pkt_size-4) << rx_pkt->get_byte(rx_pkt_size-3) << rx_pkt->get_byte(rx_pkt_size-2); | |
92 | ||
93 | sc_uint<64> peu_lnk_bit_err_cnt1 = csr_port.read_csr(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR); | |
94 | sc_uint<8> btc = peu_lnk_bit_err_cnt1.range(23,16); | |
95 | if(btc!=ALLONES) | |
96 | { | |
97 | btc++; | |
98 | peu_lnk_bit_err_cnt1.range(23,16) = btc; | |
99 | csr_port.write_csr_mask(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR,peu_lnk_bit_err_cnt1,PEU_CSR_LNK_BIT_ERR_CNT_1_READ_MASK); | |
100 | } | |
101 | } | |
102 | ||
103 | if((rx_pkt->get_byte(rx_pkt_size-1)==EDB)){ | |
104 | LOG_DEBUG <<" _DLL_ : LCRC matches, but EDB is present. Discarding and sending NAK..."; | |
105 | EDB_DETECTED = 1; | |
106 | } | |
107 | else | |
108 | EDB_DETECTED = 0; | |
109 | ||
110 | LOG_DEBUG << "_DLL_ : rx_pkt_seq_num: " << rx_pkt_seq_num << " NEXT_RECEIVE_SEQ: " << NEXT_RECEIVE_SEQ ; | |
111 | ||
112 | DO_NAK_SCHEDULED_CHECK = 0; | |
113 | check_seq_num = (NEXT_RECEIVE_SEQ - rx_pkt_seq_num ); //% (sc_uint<12>)(4096) ; | |
114 | ||
115 | tx_ack_nack_pkt = new pciePacket(6); | |
116 | if(EDB_DETECTED){ | |
117 | if((rx_pkt->get_byte( rx_pkt_size - 2) == ~rx_pkt_calc_lcrc.range(7,0)) && | |
118 | (rx_pkt->get_byte( rx_pkt_size - 3) == ~rx_pkt_calc_lcrc.range(15,8)) && | |
119 | (rx_pkt->get_byte( rx_pkt_size - 4) == ~rx_pkt_calc_lcrc.range(23,16)) && | |
120 | (rx_pkt->get_byte( rx_pkt_size - 5) == ~rx_pkt_calc_lcrc.range(31,24))) | |
121 | { | |
122 | // Discard tlp | |
123 | LOG_DEBUG << "EDB_DETECTED, LCRC LOGICAL NOT, seqnum: " << rx_pkt_seq_num ; | |
124 | continue; | |
125 | } | |
126 | else { | |
127 | DO_NAK_SCHEDULED_CHECK = 1; | |
128 | LOG_DEBUG << "EDB_DETECTED, LCRC UNINVERTED, seqnum: " << rx_pkt_seq_num ; | |
129 | } | |
130 | } | |
131 | else if(!LCRC_MATCHED){ | |
132 | DO_NAK_SCHEDULED_CHECK = 1; | |
133 | LOG_DEBUG << "LCRC DID NOT MATCH. seqnum: " << rx_pkt_seq_num ; | |
134 | } | |
135 | else if(LCRC_MATCHED && !EDB_DETECTED && rx_pkt->get_control() != DLLP_NAK) { | |
136 | LOG_DEBUG << "LCRC OK and NO EDB FOUND. seqnum: " << rx_pkt_seq_num ; | |
137 | ||
138 | if(rx_pkt_seq_num == NEXT_RECEIVE_SEQ ){ | |
139 | LOG_DEBUG << "rx_pkt_seq_num == NEXT_RECEIVE_SEQ seqnum " << rx_pkt_seq_num ; | |
140 | ||
141 | NEXT_RECEIVE_SEQ++; | |
142 | queueTL.push(rx_pkt); | |
143 | eventTlPktRdy.notify(); | |
144 | ||
145 | tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1; | |
146 | tx_ack_nack_pkt->set_control(SDP_CONTROL); | |
147 | tx_ack_nack_pkt->modify_byte(0,DLLP_ACK); | |
148 | tx_ack_nack_pkt->modify_byte(1,DATA0); | |
149 | tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8)); | |
150 | tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0)); | |
151 | tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4); | |
152 | tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8)); | |
153 | tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0)); | |
154 | //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1); | |
155 | ||
156 | queue_DLLP.push(tx_ack_nack_pkt); | |
157 | eventPlPktRdy.notify(); | |
158 | ||
159 | NAK_SCHEDULED=0; | |
160 | LOG_DEBUG << "CLEAR NAK SCHEDULED. seqnum: " << rx_pkt_seq_num ; | |
161 | DO_NAK_SCHEDULED_CHECK = 0; | |
162 | LOG_DEBUG << "Send ACK - rx_pkt_seq_num == NEXT_RECEIVE_SEQ " << rx_pkt_seq_num ; | |
163 | } | |
164 | //else if ( rx_pkt_seq_num < NEXT_RECEIVE_SEQ ) | |
165 | else { | |
166 | if( ((NEXT_RECEIVE_SEQ-rx_pkt_seq_num)%4096) <= 2048 ) { | |
167 | LOG_DEBUG << "(NEXT_RECEIVE_SEQ - rx_pkt_seq_num) mod 4096 smaller then 2048 seqnum " << rx_pkt_seq_num ; | |
168 | NAK_SCHEDULED=0; //Why was this not there? | |
169 | DO_NAK_SCHEDULED_CHECK = 0; | |
170 | ||
171 | tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1; | |
172 | tx_ack_nack_pkt->set_control(SDP_CONTROL); | |
173 | tx_ack_nack_pkt->modify_byte(0,DLLP_ACK); | |
174 | tx_ack_nack_pkt->modify_byte(1,DATA0); | |
175 | tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8)); | |
176 | tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0)); | |
177 | tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4); | |
178 | tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8)); | |
179 | tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0)); | |
180 | //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1); | |
181 | queue_DLLP.push(tx_ack_nack_pkt); | |
182 | eventPlPktRdy.notify(); | |
183 | LOG_DEBUG<<"Send ACK - rx_pkt_seq_num < NEXT_RECEIVE_SEQ " << rx_pkt_seq_num ; | |
184 | } | |
185 | else { | |
186 | LOG_DEBUG<<"TLP Out of Sequence: Recvd: "<<rx_pkt_seq_num<<" NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ<<" value: "<<check_seq_num ; | |
187 | DO_NAK_SCHEDULED_CHECK = 1; | |
188 | } | |
189 | } | |
190 | } | |
191 | } | |
192 | if(DO_NAK_SCHEDULED_CHECK) | |
193 | { | |
194 | LOG_DEBUG << "RAS: DO_NAK_SCHEDULED_CHECK seqnum " << rx_pkt_seq_num ; | |
195 | if ( !NAK_SCHEDULED/* || rx_pkt->get_control() == DLLP_NAK*/) | |
196 | { | |
197 | LOG_DEBUG << "RAS: NAK SCHEDULED is CLEAR seqnum " << rx_pkt_seq_num ; | |
198 | ||
199 | write_error_csr(CE,6,38,"btp"); | |
200 | /////////////////////////////////////////// | |
201 | tx_ack_nack_pkt->set_control(SDP_CONTROL); | |
202 | tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1; | |
203 | tx_ack_nack_pkt->modify_byte(0,DLLP_NAK); | |
204 | tx_ack_nack_pkt->modify_byte(1,DATA0); | |
205 | tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8)); | |
206 | tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0)); | |
207 | ||
208 | tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4); | |
209 | tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8)); | |
210 | tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0)); | |
211 | //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1); | |
212 | queue_DLLP.push(tx_ack_nack_pkt); | |
213 | eventPlPktRdy.notify(); | |
214 | LOG_DEBUG << " Send NAK - LCRC Mis-match and/or EDB caused by seqnum " << rx_pkt_seq_num ; | |
215 | ||
216 | NAK_SCHEDULED = 1; | |
217 | DO_NAK_SCHEDULED_CHECK = 0; //WHY was this not there? | |
218 | } | |
219 | } | |
220 | else{ | |
221 | if(!NAK_SCHEDULED && rx_pkt->get_byte(0) == STP && rx_pkt->get_control() == DLLP_NAK){ | |
222 | ||
223 | write_error_csr(CE,0,32,"re"); | |
224 | byte_seq_num = rx_pkt->get_byte(1); | |
225 | rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0); | |
226 | byte_seq_num = rx_pkt->get_byte(2); | |
227 | rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0); | |
228 | ||
229 | LOG_WARNING << "DLL: Receive Error, seqnum: " << rx_pkt_seq_num << ", scheduling NAK... NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ; | |
230 | ||
231 | tx_ack_nack_pkt->set_control(SDP_CONTROL); | |
232 | tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1; | |
233 | tx_ack_nack_pkt->modify_byte(0,DLLP_NAK); | |
234 | tx_ack_nack_pkt->modify_byte(1,DATA0); | |
235 | tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8)); | |
236 | tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0)); | |
237 | ||
238 | tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4); | |
239 | tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8)); | |
240 | tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0)); | |
241 | //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1); | |
242 | queue_DLLP.push(tx_ack_nack_pkt); | |
243 | eventPlPktRdy.notify(); | |
244 | NAK_SCHEDULED = 1; | |
245 | } | |
246 | else if(!NAK_SCHEDULED && rx_pkt->get_byte(0) == STP && rx_pkt->get_control() == DLLP_NAK_FRAMING){ | |
247 | //rx_pkt_size = rx_pkt->get_size(); | |
248 | //rx_pkt_calc_lcrc=calculate_lcrc(rx_pkt,1,rx_pkt_size-5); | |
249 | write_error_csr(OE,11,11,"lin"); | |
250 | byte_seq_num = rx_pkt->get_byte(1); | |
251 | rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0); | |
252 | byte_seq_num = rx_pkt->get_byte(2); | |
253 | rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0); | |
254 | ||
255 | LOG_WARNING << "DLL: Framing Receive Error, seqnum: " << rx_pkt_seq_num << ", scheduling NAK... NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ; | |
256 | ||
257 | tx_ack_nack_pkt->set_control(SDP_CONTROL); | |
258 | tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1; | |
259 | tx_ack_nack_pkt->modify_byte(0,DLLP_NAK); | |
260 | tx_ack_nack_pkt->modify_byte(1,DATA0); | |
261 | tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8)); | |
262 | tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0)); | |
263 | ||
264 | tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4); | |
265 | tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8)); | |
266 | tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0)); | |
267 | //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1); | |
268 | queue_DLLP.push(tx_ack_nack_pkt); | |
269 | eventPlPktRdy.notify(); | |
270 | NAK_SCHEDULED = 1; | |
271 | } | |
272 | } | |
273 | ||
274 | ||
275 | // DLLP Processing | |
276 | if ( rx_pkt->get_byte(0) == SDP ) | |
277 | { | |
278 | if((rx_pkt->get_byte(1) == DLLP_ACK )||(rx_pkt->get_byte(1) == DLLP_NAK)) | |
279 | time_last_ack_nak_received = dll_timer; | |
280 | ||
281 | //cout << sc_time_stamp() << " DLL: Received DLLP " << rx_pkt->getPacketId() << " from PL." << endl; | |
282 | //rx_pkt->pl2dll_display_sdp_packet(0); | |
283 | ||
284 | if ( (rx_pkt->get_byte(1) != DLLP_ACK ) && | |
285 | (rx_pkt->get_byte(1) != DLLP_NAK ) && | |
286 | (rx_pkt->get_byte(1) != DLLP_PM_ENTER_L1 ) && | |
287 | (rx_pkt->get_byte(1) != DLLP_PM_ENTER_L23 ) && | |
288 | (rx_pkt->get_byte(1) != DLLP_PM_ACT_SR_L1 ) && | |
289 | (rx_pkt->get_byte(1) != DLLP_PM_REQ_ACK ) && | |
290 | (rx_pkt->get_byte(1) != DLLP_VENDOR ) && | |
291 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_P_NOVC ) && | |
292 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_NP_NOVC ) && | |
293 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_CPL_NOVC ) && | |
294 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_P_NOVC ) && | |
295 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_NP_NOVC ) && | |
296 | (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_CPL_NOVC ) && | |
297 | (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_P_NOVC ) && | |
298 | (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_NP_NOVC ) && | |
299 | (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_CPL_NOVC ) | |
300 | ) | |
301 | { | |
302 | write_error_csr2(OE,2,2,"xxx"); | |
303 | } | |
304 | else if(rx_pkt->get_byte(rx_pkt->get_size() - 1) == EDB){ | |
305 | LOG_DEBUG << "SDP PKT with EDB"; | |
306 | } | |
307 | else { | |
308 | SDP_byte1=rx_pkt->get_byte(1); | |
309 | SDP_byte2=rx_pkt->get_byte(2); | |
310 | SDP_byte3=rx_pkt->get_byte(3); | |
311 | SDP_byte4=rx_pkt->get_byte(4); | |
312 | SDP_byte5=rx_pkt->get_byte(5); | |
313 | SDP_byte6=rx_pkt->get_byte(6); | |
314 | ||
315 | if ( SDP_byte1.range(7,4) == 0 ) | |
316 | { | |
317 | rx_pkt_seq_num.range(11,8) = SDP_byte3.range(3,0); | |
318 | rx_pkt_seq_num.range(7,0) = SDP_byte4.range(7,0); | |
319 | } | |
320 | ||
321 | if ( SDP_byte1 == DLLP_NAK ) { | |
322 | rx_pkt_seq_num.range(11,8) = SDP_byte3.range(3,0); | |
323 | rx_pkt_seq_num.range(7,0) = SDP_byte4.range(7,0); | |
324 | LOG_DEBUG << "REPLAY_BUFFER: Received NAK with seqid = " << rx_pkt_seq_num ; | |
325 | //buffer_replay_single(rx_pkt_seq_num); | |
326 | buffer_replay(rx_pkt_seq_num); | |
327 | ACKD_SEQ=rx_pkt_seq_num; | |
328 | } | |
329 | ||
330 | // if ACK, then remove the corresponding TLP entry in the retry buffer | |
331 | if ( SDP_byte1 == DATA0 ) { | |
332 | rx_pkt_seq_num.range(11,8)=SDP_byte3.range(3,0); | |
333 | rx_pkt_seq_num.range(7,0)=SDP_byte4.range(7,0); | |
334 | LOG_DEBUG << "REPLAY_BUFFER: Received ACK with seqid = " << rx_pkt_seq_num ; | |
335 | buffer_remove(rx_pkt_seq_num); | |
336 | REPLAY_NUM=0; | |
337 | REPLAY_TIMER=0; | |
338 | ACKD_SEQ=rx_pkt_seq_num; | |
339 | } | |
340 | ||
341 | rx_pkt_dllp_crc.range(15,8)=SDP_byte5.range(7,0); | |
342 | rx_pkt_dllp_crc.range(7,0)=SDP_byte6.range(7,0); | |
343 | ||
344 | if ( rx_pkt_dllp_crc != calculate_dllp_crc(rx_pkt,1,5) ) { | |
345 | LOG_DEBUG << " _DLL_: DLLP CRC MIS-MATCH : Calculated DLLP CRC " << calculate_dllp_crc(rx_pkt,1,5) << " Received DLLP CRC" << rx_pkt_dllp_crc ; | |
346 | write_error_csr(CE,7,39,"bdp"); | |
347 | sc_uint<64> peu_lnk_bit_err_cnt1 = csr_port.read_csr(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR); | |
348 | sc_uint<8> bdc = peu_lnk_bit_err_cnt1.range(31,24); | |
349 | if(bdc!=ALLONES) { | |
350 | bdc++; | |
351 | peu_lnk_bit_err_cnt1.range(31,24) = bdc; | |
352 | csr_port.write_csr_mask(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR,peu_lnk_bit_err_cnt1,PEU_CSR_LNK_BIT_ERR_CNT_1_READ_MASK); | |
353 | } | |
354 | continue; | |
355 | } | |
356 | else { | |
357 | HdrFC.range(7,2)=SDP_byte2.range(5,0); | |
358 | HdrFC.range(1,0)=SDP_byte3.range(7,6); | |
359 | ||
360 | DataFC.range(11,8)=SDP_byte3.range(3,0); | |
361 | DataFC.range(7,0)=SDP_byte4; | |
362 | ||
363 | sc_uint<64> peu_diag_csr = csr_port.read_csr(PEU_CSR_A_TLU_DIAG_HW_ADDR); | |
364 | ||
365 | tlu_ecc_hw_reg = csr_port.read_csr(PEU_CSR_A_TLU_ECC_HW_ADDR); | |
366 | tlu_ecl_hw_reg = csr_port.read_csr(PEU_CSR_A_TLU_ECL_HW_ADDR); | |
367 | LOG_DEBUG << "ECL: " << tlu_ecl_hw_reg << " ECC: " << tlu_ecc_hw_reg ; | |
368 | ||
369 | sc_uint<64> old_ecc = tlu_ecc_hw_reg; | |
370 | ||
371 | switch(SDP_byte1.range(7,4)){ | |
372 | case 4: // init fc1 p | |
373 | if ( (HdrFC== 0 ) ) | |
374 | tlu_ecc_hw_reg.range(60,60) = 1; | |
375 | else | |
376 | tlu_ecc_hw_reg.range(60,60) = 0; | |
377 | ||
378 | if ( (DataFC== 0 ) ) | |
379 | tlu_ecl_hw_reg.range(60,60) = 1; | |
380 | else | |
381 | tlu_ecl_hw_reg.range(60,60) = 0; | |
382 | ||
383 | tlu_ecl_hw_reg.range(19,12) = HdrFC; | |
384 | tlu_ecl_hw_reg.range(11,0) = DataFC; | |
385 | ||
386 | LOG_DEBUG << " initfc1P ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
387 | LOG_DEBUG << " initfc1P ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
388 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
389 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
390 | break; | |
391 | ||
392 | case 5: // init fc1 np | |
393 | if ( (HdrFC== 0 ) ) | |
394 | tlu_ecc_hw_reg.range(61,61) = 1; | |
395 | else | |
396 | tlu_ecc_hw_reg.range(61,61) = 0; | |
397 | ||
398 | if ( (DataFC== 0 ) ) | |
399 | tlu_ecl_hw_reg.range(61,61) = 1; | |
400 | else | |
401 | tlu_ecl_hw_reg.range(61,61) = 0; | |
402 | ||
403 | tlu_ecl_hw_reg.range(39,32) = HdrFC; | |
404 | tlu_ecl_hw_reg.range(31,20) = DataFC; | |
405 | ||
406 | LOG_DEBUG << " initfc1NP ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
407 | LOG_DEBUG << " initfc1NP ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
408 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
409 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
410 | break; | |
411 | ||
412 | case 6: // init fc1 cpl | |
413 | if ( (HdrFC== 0 ) ) | |
414 | tlu_ecc_hw_reg.range(62,62) = 1; | |
415 | else | |
416 | tlu_ecc_hw_reg.range(62,62) = 0; | |
417 | ||
418 | if ( (DataFC== 0 ) ) | |
419 | tlu_ecl_hw_reg.range(62,62) = 1; | |
420 | else | |
421 | tlu_ecl_hw_reg.range(62,62) = 0; | |
422 | ||
423 | tlu_ecl_hw_reg.range(59,52) = HdrFC; | |
424 | tlu_ecl_hw_reg.range(51,40) = DataFC; | |
425 | ||
426 | LOG_DEBUG << " initfc1CMPL ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
427 | LOG_DEBUG << " initfc1CMPL ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
428 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
429 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
430 | break; | |
431 | ||
432 | case 12: // init fc2 p | |
433 | if ( (HdrFC== 0 ) ) | |
434 | tlu_ecc_hw_reg.range(60,60) = 1; | |
435 | else | |
436 | tlu_ecc_hw_reg.range(60,60) = 0; | |
437 | ||
438 | if ( (DataFC== 0 ) ) | |
439 | tlu_ecl_hw_reg.range(60,60) = 1; | |
440 | else | |
441 | tlu_ecl_hw_reg.range(60,60) = 0; | |
442 | ||
443 | tlu_ecl_hw_reg.range(19,12) = HdrFC; | |
444 | tlu_ecl_hw_reg.range(11,0) = DataFC; | |
445 | ||
446 | LOG_DEBUG << " initfc2P ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
447 | LOG_DEBUG << " initfc2P ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
448 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
449 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
450 | break; | |
451 | ||
452 | case 13: // init fc2 np | |
453 | if ( (HdrFC== 0 ) ) | |
454 | tlu_ecc_hw_reg.range(61,61) = 1; | |
455 | else | |
456 | tlu_ecc_hw_reg.range(61,61) = 0; | |
457 | ||
458 | if ( (DataFC== 0 ) ) | |
459 | tlu_ecl_hw_reg.range(61,61) = 1; | |
460 | else | |
461 | tlu_ecl_hw_reg.range(61,61) = 0; | |
462 | ||
463 | tlu_ecl_hw_reg.range(39,32) = HdrFC; | |
464 | tlu_ecl_hw_reg.range(31,20) = DataFC; | |
465 | ||
466 | LOG_DEBUG << " initfc2NP ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
467 | LOG_DEBUG << " initfc2NP ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
468 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
469 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
470 | break; | |
471 | ||
472 | case 14: // init fc2 cpl | |
473 | if ( (HdrFC== 0 ) ) | |
474 | tlu_ecc_hw_reg.range(62,62) = 1; | |
475 | else | |
476 | tlu_ecc_hw_reg.range(62,62) = 0; | |
477 | ||
478 | if ( (DataFC== 0 ) ) | |
479 | tlu_ecl_hw_reg.range(62,62) = 1; | |
480 | else | |
481 | tlu_ecl_hw_reg.range(62,62) = 0; | |
482 | ||
483 | tlu_ecl_hw_reg.range(59,52) = HdrFC; | |
484 | tlu_ecl_hw_reg.range(51,40) = DataFC; | |
485 | ||
486 | LOG_DEBUG << " initfc2CMPL ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
487 | LOG_DEBUG << " initfc2CMPL ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg; | |
488 | ||
489 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
490 | if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg); | |
491 | break; | |
492 | ||
493 | case 8: // update p | |
494 | if( (HdrFC!=0 && tlu_ecc_hw_reg.range(60,60)==1) || | |
495 | (DataFC!=0 && tlu_ecl_hw_reg.range(60,60)==1)) { | |
496 | //Infinite credit update has arrived | |
497 | LOG_DEBUG << "Warning: P Infinite credit update error..."; | |
498 | LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " PHI= " << tlu_ecc_hw_reg.range(60,60) << " PDI= " << tlu_ecl_hw_reg.range(60,60); | |
499 | ||
500 | write_error_csr(UE,13,45,"fcp"); | |
501 | // } else if(((HdrFC-tlu_ecl_hw_reg(19,12))%256)>128 || ((DataFC-tlu_ecl_hw_reg(11,0))%4096)>2048){ | |
502 | // LOG_DEBUG << "Warning: UpdateFC_P has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ; | |
503 | // write_error_csr(UE,13,45,"fcp"); | |
504 | } else { | |
505 | tlu_ecl_hw_reg.range(19,12) = HdrFC; | |
506 | tlu_ecl_hw_reg.range(11,0) = DataFC; | |
507 | LOG_DEBUG << " P UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
508 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
509 | } | |
510 | break; | |
511 | case 9: // update np | |
512 | if( (HdrFC!=0 && tlu_ecc_hw_reg.range(61,61)==1) || | |
513 | (DataFC!=0 && tlu_ecl_hw_reg.range(61,61)==1)) { | |
514 | //Infinite credit update has arrived | |
515 | LOG_DEBUG << "Warning: NP Infinite credit update error..."; | |
516 | LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " NHI= " << tlu_ecc_hw_reg.range(61,61) << " NDI= " << tlu_ecl_hw_reg.range(61,61); | |
517 | write_error_csr(UE,13,45,"fcp"); | |
518 | // } else if(((HdrFC-tlu_ecl_hw_reg(39,32))%256)>128 || ((DataFC-tlu_ecl_hw_reg(31,20))%4096)>2048){ | |
519 | // LOG_DEBUG << "Warning: UpdateFC_NP has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ; | |
520 | // write_error_csr(UE,13,45,"fcp"); | |
521 | } else { | |
522 | tlu_ecl_hw_reg.range(39,32) = HdrFC; | |
523 | tlu_ecl_hw_reg.range(31,20) = DataFC; | |
524 | LOG_DEBUG << " NP UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
525 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
526 | } | |
527 | break; | |
528 | case 10: // update cpl | |
529 | if( (HdrFC!=0 && tlu_ecc_hw_reg.range(62,62)==1) || | |
530 | (DataFC!=0 && tlu_ecl_hw_reg.range(62,62)==1)) { | |
531 | //Infinite credit update has arrived | |
532 | LOG_DEBUG << "Warning: CMPL Infinite credit update error..."; | |
533 | LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " CHI= " << tlu_ecc_hw_reg.range(62,62) << " CDI= " << tlu_ecl_hw_reg.range(62,62); | |
534 | write_error_csr(UE,13,45,"fcp"); | |
535 | ||
536 | // } else if((((sc_uint<8>)HdrFC-tlu_ecl_hw_reg(59,52))%256)>128 || (((sc_uint<12>)DataFC-tlu_ecl_hw_reg(51,40))%4096)>2048){ | |
537 | // LOG_DEBUG << "Warning: UpdateFC_CMPL has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ; | |
538 | // write_error_csr(UE,13,45,"fcp"); | |
539 | } else { | |
540 | tlu_ecl_hw_reg.range(59,52) = HdrFC; | |
541 | tlu_ecl_hw_reg.range(51,40) = DataFC; | |
542 | LOG_DEBUG << " CMPL UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg; | |
543 | csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg); | |
544 | } | |
545 | break; | |
546 | default: //Added to capture the unsupport DLLPs | |
547 | LOG_DEBUG << " _DLLP_ : Unsupported DLLP recvd. Drop and ignore."; | |
548 | break; | |
549 | } | |
550 | } // if(CRC matches) | |
551 | } // if DLLP_INVALID | |
552 | }// if(SDP) | |
553 | ||
554 | // Check FCINIT1 packets for vc0 | |
555 | if ( rx_pkt->get_byte(1) == DLLP_INITFC1_P ) | |
556 | { | |
557 | LOG_DEBUG << "_DLL_ : ------------ Received initfc1_p from PL"; | |
558 | Flag_FC1_P = 1; | |
559 | fc_init1_complete_ev.notify(); | |
560 | } | |
561 | if ( rx_pkt->get_byte(1) == DLLP_INITFC1_NP ) | |
562 | { | |
563 | LOG_DEBUG << "_DLL_: ------------ Received initfc1_np from PL" ; | |
564 | Flag_FC1_NP = 1; | |
565 | } | |
566 | if ( rx_pkt->get_byte(1) == DLLP_INITFC1_CPL ) | |
567 | { | |
568 | LOG_DEBUG << "_DLL_ : ------------ Received initfc1_cpl from PL"; | |
569 | Flag_FC1_CPL = 1; | |
570 | } | |
571 | ||
572 | if ( (Flag_FC1_P & Flag_FC1_NP & Flag_FC1_CPL) && !Flag_FC1 ){ | |
573 | Flag_FC1 = 1; | |
574 | } | |
575 | ||
576 | if ( Flag_FC1 && // we are in fcinit2 | |
577 | ( ( rx_pkt->get_byte(1) == DLLP_INITFC2_P ) || // any dllp packet sets fI2 | |
578 | ( rx_pkt->get_byte(1) == DLLP_INITFC2_NP ) || | |
579 | ( rx_pkt->get_byte(1) == DLLP_INITFC2_CPL ) || | |
580 | ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_CPL ) || // any updatefc sets fI2 | |
581 | ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_NP ) || | |
582 | ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_P ) ) ) | |
583 | { | |
584 | Flag_FC2 = 1; | |
585 | fc_init2_complete_ev.notify(); | |
586 | } | |
587 | }//end while | |
588 | }//end try | |
589 | catch(sc_exception &e){ | |
590 | LOG_DEBUG<<"DLL: Out of pl_consumer"; | |
591 | } | |
592 | } | |
593 | ||
594 | ||
595 | void dll_top::write_error_csr(uint8 err_type, uint8 primary, uint8 secondary, char field_name[3]){ | |
596 | sc_uint<64> orig_csr_val; | |
597 | sc_uint<64> new_csr_val=0; | |
598 | ||
599 | LOG_DEBUG << "Setting err bit: " << field_name; | |
600 | ||
601 | switch(err_type){ | |
602 | case OE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_OE_ERR_RW1C_ALIAS_HW_ADDR); | |
603 | LOG_DEBUG << "Updating OE CSR (orig val: " << orig_csr_val << ")"; | |
604 | break; | |
605 | case UE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_UE_ERR_RW1C_ALIAS_HW_ADDR); | |
606 | LOG_DEBUG << "Updating UE CSR (orig val: " << orig_csr_val << ")"; | |
607 | break; | |
608 | case CE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_CE_ERR_RW1C_ALIAS_HW_ADDR); | |
609 | LOG_DEBUG << "Updating CE CSR (orig val: " << orig_csr_val << ")"; | |
610 | break; | |
611 | default: LOG_ERROR << "Warning: undefined error type!"; | |
612 | return; | |
613 | } | |
614 | ||
615 | if(orig_csr_val.range(primary,primary)!=1) | |
616 | new_csr_val.range(primary,primary)=1; | |
617 | else if(orig_csr_val.range(secondary,secondary)!=1) | |
618 | new_csr_val.range(secondary,secondary)=1; | |
619 | else | |
620 | LOG_DEBUG << "Warning: Both PRIMARY and SECONDARY of " << field_name << "are set."; | |
621 | ||
622 | switch(err_type){ | |
623 | case OE: csr_port.write_csr(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val); | |
624 | LOG_DEBUG << "Updating OE CSR (new val : " << new_csr_val << ")"; | |
625 | break; | |
626 | case UE: csr_port.write_csr(PEU_CSR_A_UE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val); | |
627 | LOG_DEBUG << "Updating UE CSR (new val : " << new_csr_val << ")"; | |
628 | break; | |
629 | case CE: csr_port.write_csr(PEU_CSR_A_CE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val); | |
630 | LOG_DEBUG << "Updating CE CSR (new val : " << new_csr_val << ")"; | |
631 | break; | |
632 | } | |
633 | return; | |
634 | }//end write_csr_error | |
635 | ||
636 | void dll_top::write_error_csr2(uint8 err_type, uint8 primary, uint8 secondary, char field_name[3]){ | |
637 | sc_uint<64> orig_csr_val; | |
638 | sc_uint<64> new_csr_val=0; | |
639 | ||
640 | LOG_DEBUG << "Setting err bit: " << field_name; | |
641 | ||
642 | switch(err_type){ | |
643 | case OE: orig_csr_val = csr_port.read_csr( PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR ); | |
644 | LOG_DEBUG << "Updating OE CSR (orig val: " << orig_csr_val << ")"; | |
645 | break; | |
646 | case UE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR); | |
647 | LOG_DEBUG << "Updating UE CSR (orig val: " << orig_csr_val << ")"; | |
648 | break; | |
649 | case CE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR); | |
650 | LOG_DEBUG << "Updating CE CSR (orig val: " << orig_csr_val << ")"; | |
651 | break; | |
652 | default: LOG_ERROR << "Warning: undefined error type!"; | |
653 | return; | |
654 | } | |
655 | ||
656 | if(orig_csr_val.range(primary,primary)!=1) | |
657 | new_csr_val.range(primary,primary)=1; | |
658 | else if(orig_csr_val.range(secondary,secondary)!=1) | |
659 | new_csr_val.range(secondary,secondary)=1; | |
660 | else | |
661 | LOG_DEBUG << "Warning: Both PRIMARY and SECONDARY of " << field_name << "are set."; | |
662 | ||
663 | switch(err_type){ | |
664 | case OE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val); | |
665 | LOG_DEBUG << "Updating OE CSR (new val : " << new_csr_val << ")"; | |
666 | break; | |
667 | case UE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val); | |
668 | LOG_DEBUG << "Updating UE CSR (new val : " << new_csr_val << ")"; | |
669 | break; | |
670 | case CE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val); | |
671 | LOG_DEBUG << "Updating CE CSR (new val : " << new_csr_val << ")"; | |
672 | break; | |
673 | } | |
674 | return; | |
675 | }//end write_csr_error | |
676 | } |