Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / tl / rsb.cpp
CommitLineData
86530b38
AT
1#include "rsb.hpp"
2#include "pcie_common/logger.hpp"
3
4namespace pcie{
5
6 /**
7 * This method initializes module registers and flags.
8 * It also spawns threads that handle module operation.
9 */
10 void rsb::init(){
11 for(unsigned int i=0; i<NUM_RSB_ENTRIES ; i++){
12 rsb_db[i].vld=0;
13 }
14 POR_RESET=false;
15 STOP_TIMER=false;
16 eg_handler_ph = sc_spawn(sc_bind(&rsb::eg_handler,this));
17 update_timer_ph = sc_spawn(sc_bind(&rsb::update_timer,this));
18 LOG_INFO << "RSB: SW Reset : threads spawned";
19 }
20
21 /**
22 * This thread processes ingress TLP CMPL headers. Detected errors are flagged and reported.
23 */
24 void rsb::ing_handler(){
25 RefPciePacket in_pkt;
26 while(1){
27 try{
28 ing_port->get(in_pkt);
29 LOG_DEBUG << "ITL->RSB: Get Packet: " << in_pkt->getPacketId() << "\n";
30 sc_uint<RSB_TAG_SIZE> rsb_tag = GET_TLP_CMPL_TAG(in_pkt).range(RSB_TAG_SIZE-1,0);
31
32 rs2it_err = 0; //Reset error bits
33
34 if(in_pkt->isCmpl()){
35 sc_uint<64> peu_diag_reg = csr_port.read_csr(PEU_CSR_A_TLU_DIAG_HW_ADDR);
36 LOG_DEBUG << "PEU_DIAG_CSR: " << peu_diag_reg;
37
38 if( (!rsb_db[rsb_tag].vld) ||
39 (GET_TLP_CMPL_REQ_ID(in_pkt)!=rsb_db[rsb_tag].req_id) ||
40 (in_pkt->get_byte(TLP_HDR_START) == tlp_CplLk) ||
41 (in_pkt->get_byte(TLP_HDR_START) == tlp_CplDLk) ||
42 (rsb_db[rsb_tag].vld && (rsb_db[rsb_tag].tlp_tag != GET_TLP_CMPL_TAG(in_pkt)))
43 ){
44 //Check for Unsolicited CMPLs
45
46 LOG_WARNING << "Warning: Unsolicited CMPLs " ;
47 rs2it_err.range(3,3) = 1;
48
49 } else if(in_pkt->hasData() && GET_TLP_CMPL_STATUS(in_pkt)!=0 && GET_TLP_CMPL_STATUS(in_pkt)!=0x2){
50 //Check for Malformed Completion/////////////////////////////////
51 //1. CplD with unsuccessful status
52
53 LOG_WARNING << "Warning: CplD with unsuccessful status." ;
54 rs2it_err.range(2,2) = 1;
55
56 } else if((peu_diag_reg.range(40,40)!=1) && //Error check is not disabled
57 (GET_TLP_CMPL_STATUS(in_pkt)==0x2 &&
58 (rsb_db[rsb_tag].raw_payload[0] != tlp_CfgRd0 &&
59 rsb_db[rsb_tag].raw_payload[0] != tlp_CfgRd1 &&
60 rsb_db[rsb_tag].raw_payload[0] != tlp_CfgWr0 &&
61 rsb_db[rsb_tag].raw_payload[0] != tlp_CfgWr1 ))
62 ) {
63 //2. completion status is "configuration retry" for a non-configuration PIO request.
64
65 LOG_WARNING << "Warning: completion status is configuration retry for a non-configuration PIO request." ;
66 rs2it_err.range(2,2) = 1;
67
68 } else if((in_pkt->get_byte(TLP_HDR_START) == tlp_CplD) &&
69 ((rsb_db[rsb_tag].raw_payload[0] == tlp_MWr_32) ||
70 (rsb_db[rsb_tag].raw_payload[0] == tlp_MWr_64) ||
71 (rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr) ||
72 (rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0) ||
73 (rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1) )
74 ) {
75 //3. CplD associates with a PIO write request.
76
77 LOG_WARNING << "Warning: CplD associates with a PIO write request. " ;
78 rs2it_err.range(2,2) = 1;
79
80 } else if((in_pkt->get_byte(TLP_HDR_START) == tlp_Cpl) &&
81 ( GET_TLP_CMPL_STATUS(in_pkt) == 0) &&
82 ((rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32) ||
83 (rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64) ||
84 (rsb_db[rsb_tag].raw_payload[0] == tlp_IORd) ||
85 (rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0) ||
86 (rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1) )
87 ) {
88 //4. Successful Cpl associates with a PIO read request.
89
90 LOG_WARNING << "Warning: Successful Cpl associates with a PIO read request." ;
91 rs2it_err.range(2,2) = 1;
92
93 } else if((GET_TLP_ATTR(in_pkt)!=0 && peu_diag_reg.range(42,42)!=1) || (GET_TLP_TC(in_pkt)!=0 && peu_diag_reg.range(41,41)!=1)) {
94 //5. Hdr field mis-match: (i) TC!=0. (ii) Attr!=0
95 LOG_WARNING << "Warning: Incorrect (non-zero) Attr/TC fields. Attr: " << GET_TLP_ATTR(in_pkt) << " TC: " << GET_TLP_TC(in_pkt) ;
96 rs2it_err.range(2,2) = 1;
97
98 } else if( in_pkt->get_byte(TLP_HDR_START) == tlp_CplD &&
99 (GET_TLP_LEN(in_pkt) != (rsb_db[rsb_tag].raw_payload[2].range(1,0),rsb_db[rsb_tag].raw_payload[3]))
100 ){
101 // (iii) length for CplD
102
103 LOG_WARNING << "Warning: length for CplD" ;
104 rs2it_err.range(2,2) = 1;
105
106 } else if( (peu_diag_reg.range(43,43)!=1) && //Error check is not disabled
107 (((rsb_db[rsb_tag].raw_payload[0] == tlp_IORd || rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr ||
108 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 || //if IO/Cfg Rd/Wr, byteCount==4
109 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 || rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 ||
110 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 ) && (GET_TLP_BYTEC(in_pkt)!=0x4) ) ||
111
112 ((rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32 || rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64) &&
113 (GET_TLP_BYTEC(in_pkt) != rsb_db[rsb_tag].expect_bc) )
114 )
115 ) {
116 // (iv) Byte Count (it should be 12?h4 in Cpl/CplD resulted from PIO io/cfg rd/wr requests)
117
118 LOG_WARNING << "Warning: Byte Count (it should be 12?h4 in Cpl/CplD resulted from PIO io/cfg rd/wr requests). ByteCnt= " << GET_TLP_BYTEC(in_pkt) ;
119 rs2it_err.range(2,2) = 1;
120
121 } else if( (peu_diag_reg.range(44,44)!=1) && //Error check is not disabled
122 (((rsb_db[rsb_tag].raw_payload[0] == tlp_IORd || rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr ||
123 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 || //if IO/Cfg Rd/Wr, lowAddr==0
124 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 || rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 ||
125 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 ) && (GET_TLP_CMPL_LADDR(in_pkt)!=0) ) ||
126
127 ((rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32 || rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64) &&
128 (GET_TLP_CMPL_LADDR(in_pkt) != rsb_db[rsb_tag].expect_la) )
129 )
130 ) {
131 // (v) Lower Address (it should be 7?b0 in Cpl/CplD resulted from PIO io/cfg rd/wr requests)
132
133 LOG_WARNING << "Warning: Lower Address (it should be 7?b0 in Cpl/CplD resulted from PIO io/cfg rd/wr requests). LowAddr= " << GET_TLP_CMPL_LADDR(in_pkt) ;
134 rs2it_err.range(2,2) = 1;
135
136 //////////////////////////////////////////////////////////////////
137 } else if( GET_TLP_CMPL_STATUS(in_pkt)==0x2 &&
138 (rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 ||
139 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 ||
140 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 ||
141 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 )
142 ){
143 LOG_WARNING << "Configuration retry error - completion status in Cpl header is configuration retry for a configuration PIO request." ;
144 rs2it_err.range(1,1) = 1;
145 } else if( (peu_diag_reg.range(40,40)==1) &&
146 GET_TLP_CMPL_STATUS(in_pkt)!=0x0 &&
147 (rsb_db[rsb_tag].raw_payload[0] == tlp_IORd ||
148 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32 ||
149 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64 ||
150 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 ||
151 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 )
152 ){
153 LOG_WARNING << "Unsuccessful read error - completion resulted from PIO read request, whose status in Cpl header is not successful completion" ;
154 rs2it_err.range(4,4) = 1;
155 rsb_db[rsb_tag].vld=false;
156 } else if( (peu_diag_reg.range(40,40)==1) &&
157 GET_TLP_CMPL_STATUS(in_pkt)!=0x0 &&
158 (rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr ||
159 rsb_db[rsb_tag].raw_payload[0] == tlp_MWr_32 ||
160 rsb_db[rsb_tag].raw_payload[0] == tlp_MWr_64 ||
161 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 ||
162 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 )
163 ){
164 LOG_WARNING << "Unsuccessful write error - completion resulted from PIO write request, whose status in Cpl header is not successful completion" ;
165 rs2it_err.range(5,5) = 1;
166 rsb_db[rsb_tag].vld=false;
167 } else if( GET_TLP_CMPL_STATUS(in_pkt)==0x4 &&
168 (rsb_db[rsb_tag].raw_payload[0] == tlp_IORd ||
169 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32 ||
170 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64 ||
171 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 ||
172 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 )
173 ){
174 LOG_WARNING << "Rd CMPL with Completer Abort Status set" ;
175 rs2it_err.range(4,4) = 1;
176 } else if( GET_TLP_CMPL_STATUS(in_pkt)==0x4 &&
177 (rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr ||
178 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 ||
179 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 )
180 ){
181 LOG_WARNING << "Wr CMPL with Completer Abort Status set" ;
182 rs2it_err.range(5,5) = 1;
183
184 } else if(((GET_TLP_CMPL_STATUS(in_pkt)==0x1) || //CMPL Status is UR
185 (GET_TLP_CMPL_STATUS(in_pkt)!=0x0 && GET_TLP_CMPL_STATUS(in_pkt)!=0x1 && //or CMPL Status is a reserved value
186 GET_TLP_CMPL_STATUS(in_pkt)!=0x2 && GET_TLP_CMPL_STATUS(in_pkt)!=0x4)) &&
187 (rsb_db[rsb_tag].raw_payload[0] == tlp_IOWr ||
188 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr0 ||
189 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgWr1 )
190 ){
191 LOG_WARNING << "IO/CfgWr with UR status" ;
192 rs2it_err.range(5,5) = 1;
193 } else if( ((GET_TLP_CMPL_STATUS(in_pkt)==0x1) || //CMPL Status is UR
194 (GET_TLP_CMPL_STATUS(in_pkt)!=0x0 && GET_TLP_CMPL_STATUS(in_pkt)!=0x1 && //or CMPL Status is a reserved value
195 GET_TLP_CMPL_STATUS(in_pkt)!=0x2 && GET_TLP_CMPL_STATUS(in_pkt)!=0x4)) &&
196 (rsb_db[rsb_tag].raw_payload[0] == tlp_IORd ||
197 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_32 ||
198 rsb_db[rsb_tag].raw_payload[0] == tlp_MRd_64 ||
199 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd0 ||
200 rsb_db[rsb_tag].raw_payload[0] == tlp_CfgRd1 )
201 ){
202 LOG_WARNING << "Rd CMPL with UR Status set" ;
203 rs2it_err.range(4,4) = 1;
204
205 } else {
206 rsb_db[rsb_tag].vld=false;
207 }
208 /////////////////////////////////////////////////////////////////
209 if(rs2it_err==0)
210 ing_port->put(false);
211 else {
212 if(rs2it_err.range(4,4)==1 || rs2it_err.range(5,5)==1)
213 ing_port->put(false);
214 else
215 ing_port->put(true);
216
217 //CSR Error Bit and Header Log updates
218 //Error Bits
219 sc_uint<64> peu_oes_clr_reg; //PEU Other Event Error Clr Status Reg
220 sc_uint<64> peu_ues_clr_reg; //PEU Uncorrectable Error Clr Status Reg
221 if(rs2it_err.range(2,2)==1){
222 write_error_csr(OE,22,54,"mfc");
223 }
224 if(rs2it_err.range(1,1)==1){
225 write_error_csr(OE,15,47,"crs");
226 }
227 if(rs2it_err.range(4,4)==1){
228 write_error_csr(OE,16,48,"ruc");
229 }
230 if(rs2it_err.range(5,5)==1){
231 write_error_csr(OE,17,49,"wuc");
232 }
233
234 if(rs2it_err.range(3,3)==1 ){
235 write_error_csr(UE,16,48,"uc");
236
237 sc_uint<64> peu_rcv_ueh1_log_reg; //PEU Recv Other Event Header1 Log Register
238 sc_uint<64> peu_rcv_ueh2_log_reg; //PEU Recv Other Event Header2 Log Register
239 peu_rcv_ueh1_log_reg(63,56) = in_pkt->get_byte(TLP_HDR_START+ 0);
240 peu_rcv_ueh1_log_reg(55,48) = in_pkt->get_byte(TLP_HDR_START+ 1);
241 peu_rcv_ueh1_log_reg(47,40) = in_pkt->get_byte(TLP_HDR_START+ 2);
242 peu_rcv_ueh1_log_reg(39,32) = in_pkt->get_byte(TLP_HDR_START+ 3);
243 peu_rcv_ueh1_log_reg(31,24) = in_pkt->get_byte(TLP_HDR_START+ 4);
244 peu_rcv_ueh1_log_reg(23,16) = in_pkt->get_byte(TLP_HDR_START+ 5);
245 peu_rcv_ueh1_log_reg(15, 8) = in_pkt->get_byte(TLP_HDR_START+ 6);
246 peu_rcv_ueh1_log_reg( 7, 0) = in_pkt->get_byte(TLP_HDR_START+ 7);
247
248 peu_rcv_ueh2_log_reg(63,56) = in_pkt->get_byte(TLP_HDR_START+ 8);
249 peu_rcv_ueh2_log_reg(55,48) = in_pkt->get_byte(TLP_HDR_START+ 9);
250 peu_rcv_ueh2_log_reg(47,40) = in_pkt->get_byte(TLP_HDR_START+10);
251 peu_rcv_ueh2_log_reg(39,32) = in_pkt->get_byte(TLP_HDR_START+11);
252 if(GET_TLP_FMT(in_pkt) == 1 || GET_TLP_FMT(in_pkt) == 3)
253 {
254 peu_rcv_ueh2_log_reg(31,24) = in_pkt->get_byte(TLP_HDR_START+12);
255 peu_rcv_ueh2_log_reg(23,16) = in_pkt->get_byte(TLP_HDR_START+13);
256 peu_rcv_ueh2_log_reg(15, 8) = in_pkt->get_byte(TLP_HDR_START+14);
257 peu_rcv_ueh2_log_reg( 7, 0) = in_pkt->get_byte(TLP_HDR_START+15);
258 }
259 LOG_INFO << "RUEH1: " << peu_rcv_ueh1_log_reg ;
260 LOG_INFO << "RUEH2: " << peu_rcv_ueh2_log_reg ;
261 csr_port.write_csr(PEU_CSR_A_RUE_HDR1_HW_ADDR,peu_rcv_ueh1_log_reg);
262 csr_port.write_csr(PEU_CSR_A_RUE_HDR2_HW_ADDR,peu_rcv_ueh2_log_reg);
263 }
264
265 //Log Header
266 if(rs2it_err.range(2,2)==1 || rs2it_err.range(1,1)==1 || rs2it_err.range(4,4)==1 || rs2it_err.range(5,5)==1){
267 sc_uint<64> peu_rcv_oeh1_log_reg; //PEU Recv Other Event Header1 Log Register
268 sc_uint<64> peu_rcv_oeh2_log_reg; //PEU Recv Other Event Header2 Log Register
269 peu_rcv_oeh1_log_reg(63,56) = in_pkt->get_byte(TLP_HDR_START+ 0);
270 peu_rcv_oeh1_log_reg(55,48) = in_pkt->get_byte(TLP_HDR_START+ 1);
271 peu_rcv_oeh1_log_reg(47,40) = in_pkt->get_byte(TLP_HDR_START+ 2);
272 peu_rcv_oeh1_log_reg(39,32) = in_pkt->get_byte(TLP_HDR_START+ 3);
273 peu_rcv_oeh1_log_reg(31,24) = in_pkt->get_byte(TLP_HDR_START+ 4);
274 peu_rcv_oeh1_log_reg(23,16) = in_pkt->get_byte(TLP_HDR_START+ 5);
275 peu_rcv_oeh1_log_reg(15, 8) = in_pkt->get_byte(TLP_HDR_START+ 6);
276 peu_rcv_oeh1_log_reg( 7, 0) = in_pkt->get_byte(TLP_HDR_START+ 7);
277
278 peu_rcv_oeh2_log_reg(63,56) = in_pkt->get_byte(TLP_HDR_START+ 8);
279 peu_rcv_oeh2_log_reg(55,48) = in_pkt->get_byte(TLP_HDR_START+ 9);
280 peu_rcv_oeh2_log_reg(47,40) = in_pkt->get_byte(TLP_HDR_START+10);
281 peu_rcv_oeh2_log_reg(39,32) = in_pkt->get_byte(TLP_HDR_START+11);
282 if(GET_TLP_FMT(in_pkt) == 1 || GET_TLP_FMT(in_pkt) == 3)
283 {
284 peu_rcv_oeh2_log_reg(31,24) = in_pkt->get_byte(TLP_HDR_START+12);
285 peu_rcv_oeh2_log_reg(23,16) = in_pkt->get_byte(TLP_HDR_START+13);
286 peu_rcv_oeh2_log_reg(15, 8) = in_pkt->get_byte(TLP_HDR_START+14);
287 peu_rcv_oeh2_log_reg( 7, 0) = in_pkt->get_byte(TLP_HDR_START+15);
288 }
289 LOG_INFO << "ROEH1: " << peu_rcv_oeh1_log_reg ;
290 LOG_INFO << "ROEH2: " << peu_rcv_oeh2_log_reg ;
291 csr_port.write_csr(PEU_CSR_A_ROE_HDR1_HW_ADDR,peu_rcv_oeh1_log_reg);
292 csr_port.write_csr(PEU_CSR_A_ROE_HDR2_HW_ADDR,peu_rcv_oeh2_log_reg);
293
294
295 sc_uint<RSB_TAG_SIZE> tlp_tag = GET_TLP_CMPL_TAG(in_pkt).range(RSB_TAG_SIZE-1,0);
296 sc_uint<64> peu_xmt_oeh1_log_reg; //PEU Xmit Other Event Header1 Log Register
297 sc_uint<64> peu_xmt_oeh2_log_reg; //PEU Xmit Other Event Header2 Log Register
298 peu_xmt_oeh1_log_reg(63,56) = rsb_db[tlp_tag].raw_payload[0];
299 peu_xmt_oeh1_log_reg(55,48) = rsb_db[tlp_tag].raw_payload[1];
300 peu_xmt_oeh1_log_reg(47,40) = rsb_db[tlp_tag].raw_payload[2];
301 peu_xmt_oeh1_log_reg(39,32) = rsb_db[tlp_tag].raw_payload[3];
302 peu_xmt_oeh1_log_reg(31,24) = rsb_db[tlp_tag].raw_payload[4];
303 peu_xmt_oeh1_log_reg(23,16) = rsb_db[tlp_tag].raw_payload[5];
304 peu_xmt_oeh1_log_reg(15, 8) = rsb_db[tlp_tag].raw_payload[6];
305 peu_xmt_oeh1_log_reg( 7, 0) = rsb_db[tlp_tag].raw_payload[7];
306
307 peu_xmt_oeh2_log_reg(63,56) = rsb_db[tlp_tag].raw_payload[8];
308 peu_xmt_oeh2_log_reg(55,48) = rsb_db[tlp_tag].raw_payload[9];
309 peu_xmt_oeh2_log_reg(47,40) = rsb_db[tlp_tag].raw_payload[10];
310 peu_xmt_oeh2_log_reg(39,32) = rsb_db[tlp_tag].raw_payload[11];
311 peu_xmt_oeh2_log_reg(31,24) = rsb_db[tlp_tag].raw_payload[12];
312 peu_xmt_oeh2_log_reg(23,16) = rsb_db[tlp_tag].raw_payload[13];
313 peu_xmt_oeh2_log_reg(15, 8) = rsb_db[tlp_tag].raw_payload[14];
314 peu_xmt_oeh2_log_reg( 7, 0) = rsb_db[tlp_tag].raw_payload[15];
315 LOG_INFO << "TOEH1: " << peu_xmt_oeh1_log_reg ;
316 LOG_INFO << "TOEH2: " << peu_xmt_oeh2_log_reg ;
317 csr_port.write_csr(PEU_CSR_A_TOE_HDR1_HW_ADDR,peu_xmt_oeh1_log_reg);
318 csr_port.write_csr(PEU_CSR_A_TOE_HDR2_HW_ADDR,peu_xmt_oeh2_log_reg);
319 }
320 if(rs2it_err.range(2,2)==1 || rs2it_err.range(1,1)==1)
321 cto_req_port->put(GET_TLP_CMPL_TAG(in_pkt).range(CTO_TAG_SIZE-1,0));
322 }
323 }
324 else
325 LOG_WARNING << "Warning: RSB has received a non-CMPL for processing." ;
326 }
327 catch(sc_exception &e){
328 LOG_WARNING<<"RSB: ing_handler exception...remaining in the thread";
329 }
330 }//end while(1)
331 } //ing_handler()
332
333 /**
334 * This thread receives out-going TLP requests and populates the RSB for check on the ingress side.
335 */
336 void rsb::eg_handler(){
337 LOG_INFO << "RSB: eg_handler begins...";
338 RefPciePacket in_pkt;
339 try{
340 while(1){
341 eg_port.get_packet(in_pkt);
342 LOG_DEBUG << "ETL->RSB: In_pkt: " << in_pkt->to_string();
343
344 sc_uint<RSB_TAG_SIZE> rsb_tag = GET_TLP_REQ_TAG(in_pkt).range(RSB_TAG_SIZE-1,0);
345
346 if(rsb_db[rsb_tag].vld)
347 LOG_WARNING << "\tWarning: RSB already has a valid entry at location: " << rsb_tag ;
348
349 rsb_db[rsb_tag].vld = 1;
350 rsb_db[rsb_tag].raw_payload.resize((in_pkt->get_pkt_size())-TLP_HDR_START);
351 for(unsigned int i=0; i<(rsb_db[rsb_tag].raw_payload.size()) ; i++){
352 rsb_db[rsb_tag].raw_payload[i]=in_pkt->get_byte(TLP_HDR_START+i);
353 }
354 rsb_db[rsb_tag].tlp_tag = GET_TLP_REQ_TAG(in_pkt).range(CTO_TAG_SIZE-1,0);
355 rsb_db[rsb_tag].timeout = get_Cpl_TO();
356 if(rsb_db[rsb_tag].timeout == SC_ZERO_TIME) rsb_db[rsb_tag].infTO = true;
357 else rsb_db[rsb_tag].infTO = false;
358
359 rsb_db[rsb_tag].req_id = GET_TLP_REQ_ID(in_pkt);
360
361 sc_uint<4> becount = 0;
362 sc_uint<8> benable = 0;
363 benable=GET_TLP_BE(in_pkt);
364 if(benable!=0){
365 if(benable.range(7,4)==0){
366 if(benable.range(3,0) == 1 || benable.range(3,0) == 2 || benable.range(3,0) == 4 || benable.range(3,0) == 8){
367 rsb_db[rsb_tag].expect_bc = 1;
368 } else if(benable.range(3,0) == 3 || benable.range(3,0) == 6 || benable.range(3,0) == 12){
369 rsb_db[rsb_tag].expect_bc = 2;
370 } else if(benable.range(0,0) == 1 && benable.range(3,3)==1 ){
371 rsb_db[rsb_tag].expect_bc = 4;
372 } else {
373 rsb_db[rsb_tag].expect_bc = 3;
374 }
375 unsigned int index = 0;
376 while(benable.range(index,index)!=1 && index<4) {becount++; index++;}
377 rsb_db[rsb_tag].expect_la.range(1,0) = becount;
378 } else {
379 unsigned int index = 0;
380 while(benable.range(index,index)!=1 && index<4) {becount++; index++;}
381 rsb_db[rsb_tag].expect_la.range(1,0) = becount;
382 if(GET_TLP_LEN(in_pkt)!=1){
383 index=7;
384 while(benable.range(index,index)!=1 && index>3) {becount++; index--;}
385 }
386 rsb_db[rsb_tag].expect_bc = GET_TLP_LEN(in_pkt)*4 - becount;
387 }
388 } else {
389 rsb_db[rsb_tag].expect_bc = 1;
390 rsb_db[rsb_tag].expect_la.range(1,0) = 0;
391 }
392 if(GET_TLP_FMT(in_pkt)==1 || GET_TLP_FMT(in_pkt)==3){
393 rsb_db[rsb_tag].expect_la.range(6,2) = in_pkt->get_byte(TLP_HDR_START+15)(6,2);
394 } else
395 rsb_db[rsb_tag].expect_la.range(6,2) = in_pkt->get_byte(TLP_HDR_START+11)(6,2);
396 } //end while()
397 }
398 catch(sc_exception &e){
399 LOG_WARNING<<"RSB: Out of eg_handler";
400 }
401 } //eg_handler()
402
403 /**
404 * This thread updates the RSB timer and checks for CMPL timeout.
405 * A detected timeout is reported to the ILU interface.
406 */
407 void rsb::update_timer(){
408 LOG_INFO << "RSB: update_timer begins..." ;
409 sc_uint<RSB_TAG_SIZE> rsb_ctr = 0;
410 try{
411 while(1){
412 WAIT(rsb_clk.posedge_event());
413 WAIT(rsb_clk.posedge_event());
414 WAIT(rsb_clk.posedge_event());
415 WAIT(rsb_clk.posedge_event());
416 if(!STOP_TIMER && rsb_db[rsb_ctr].vld){
417 if(!rsb_db[rsb_ctr].infTO)
418
419 if((sc_time_stamp()) >= rsb_db[rsb_ctr].timeout){
420 sc_uint<64> peu_csr_ue_log_enable = csr_port.read_csr(PEU_CSR_A_UE_LOG_HW_ADDR);
421 sc_uint<64> peu_csr_oe_log_enable = csr_port.read_csr(PEU_CSR_A_OE_LOG_HW_ADDR);
422
423 LOG_WARNING << "RSB: Warning: CMPL Timeout for tag " << rsb_db[rsb_ctr].tlp_tag ;
424 LOG_WARNING << "RSB: CTO ENABLED..." ;
425 cto_req_port->put((rsb_db[rsb_ctr].tlp_tag));
426 rsb_db[rsb_ctr].vld = false;
427
428 if(peu_csr_ue_log_enable.range(14,14)==1 && peu_csr_oe_log_enable.range(21,21)==1){
429
430 write_error_csr(UE,14,46,"cto");
431
432 sc_uint<64> peu_ueh1_log_reg; //PEU Uncorrectable Error Header1 Log Register
433 sc_uint<64> peu_ueh2_log_reg; //PEU Uncorrectable Error Header2 Log Register
434 peu_ueh1_log_reg(63,56) = rsb_db[rsb_ctr].raw_payload[0];
435 peu_ueh1_log_reg(55,48) = rsb_db[rsb_ctr].raw_payload[1];
436 peu_ueh1_log_reg(47,40) = rsb_db[rsb_ctr].raw_payload[2];
437 peu_ueh1_log_reg(39,32) = rsb_db[rsb_ctr].raw_payload[3];
438 peu_ueh1_log_reg(31,24) = rsb_db[rsb_ctr].raw_payload[4];
439 peu_ueh1_log_reg(23,16) = rsb_db[rsb_ctr].raw_payload[5];
440 peu_ueh1_log_reg(15, 8) = rsb_db[rsb_ctr].raw_payload[6];
441 peu_ueh1_log_reg( 7, 0) = rsb_db[rsb_ctr].raw_payload[7];
442
443 peu_ueh2_log_reg(63,56) = rsb_db[rsb_ctr].raw_payload[8];
444 peu_ueh2_log_reg(55,48) = rsb_db[rsb_ctr].raw_payload[9];
445 peu_ueh2_log_reg(47,40) = rsb_db[rsb_ctr].raw_payload[10];
446 peu_ueh2_log_reg(39,32) = rsb_db[rsb_ctr].raw_payload[11];
447 peu_ueh2_log_reg(31,24) = rsb_db[rsb_ctr].raw_payload[12];
448 peu_ueh2_log_reg(23,16) = rsb_db[rsb_ctr].raw_payload[13];
449 peu_ueh2_log_reg(15, 8) = rsb_db[rsb_ctr].raw_payload[14];
450 peu_ueh2_log_reg( 7, 0) = rsb_db[rsb_ctr].raw_payload[15];
451 LOG_INFO << "TUEH1: " << peu_ueh1_log_reg ;
452 LOG_INFO << "TUEH2: " << peu_ueh2_log_reg ;
453 csr_port.write_csr(PEU_CSR_A_TUE_HDR1_HW_ADDR,peu_ueh1_log_reg);
454 csr_port.write_csr(PEU_CSR_A_TUE_HDR2_HW_ADDR,peu_ueh2_log_reg);
455
456 write_error_csr(OE,21,53,"cto");
457
458 sc_uint<64> peu_xmt_oeh1_log_reg; //PEU Xmit Other Event Header1 Log Register
459 sc_uint<64> peu_xmt_oeh2_log_reg; //PEU Xmit Other Event Header2 Log Register
460 peu_xmt_oeh1_log_reg(63,56) = rsb_db[rsb_ctr].raw_payload[0];
461 peu_xmt_oeh1_log_reg(55,48) = rsb_db[rsb_ctr].raw_payload[1];
462 peu_xmt_oeh1_log_reg(47,40) = rsb_db[rsb_ctr].raw_payload[2];
463 peu_xmt_oeh1_log_reg(39,32) = rsb_db[rsb_ctr].raw_payload[3];
464 peu_xmt_oeh1_log_reg(31,24) = rsb_db[rsb_ctr].raw_payload[4];
465 peu_xmt_oeh1_log_reg(23,16) = rsb_db[rsb_ctr].raw_payload[5];
466 peu_xmt_oeh1_log_reg(15, 8) = rsb_db[rsb_ctr].raw_payload[6];
467 peu_xmt_oeh1_log_reg( 7, 0) = rsb_db[rsb_ctr].raw_payload[7];
468
469 peu_xmt_oeh2_log_reg(63,56) = rsb_db[rsb_ctr].raw_payload[8];
470 peu_xmt_oeh2_log_reg(55,48) = rsb_db[rsb_ctr].raw_payload[9];
471 peu_xmt_oeh2_log_reg(47,40) = rsb_db[rsb_ctr].raw_payload[10];
472 peu_xmt_oeh2_log_reg(39,32) = rsb_db[rsb_ctr].raw_payload[11];
473 peu_xmt_oeh2_log_reg(31,24) = rsb_db[rsb_ctr].raw_payload[12];
474 peu_xmt_oeh2_log_reg(23,16) = rsb_db[rsb_ctr].raw_payload[13];
475 peu_xmt_oeh2_log_reg(15, 8) = rsb_db[rsb_ctr].raw_payload[14];
476 peu_xmt_oeh2_log_reg( 7, 0) = rsb_db[rsb_ctr].raw_payload[15];
477 LOG_INFO << "TOEH1: " << peu_xmt_oeh1_log_reg ;
478 LOG_INFO << "TOEH2: " << peu_xmt_oeh2_log_reg ;
479 csr_port.write_csr(PEU_CSR_A_TOE_HDR1_HW_ADDR,peu_xmt_oeh1_log_reg);
480 csr_port.write_csr(PEU_CSR_A_TOE_HDR2_HW_ADDR,peu_xmt_oeh2_log_reg);
481 }
482 else
483 LOG_INFO << "RSB: Error log disabled..." ;
484 }
485 }
486 rsb_ctr++;
487 }//end while(1)
488 }//end try
489 catch(sc_exception &e){
490 LOG_WARNING<<"RSB: Out of update_timer";
491 }
492 }//update_timer()
493
494 /**
495 * This method determines the CMPL timeout value specified in the control CSR.
496 */
497 sc_time rsb::get_Cpl_TO(){
498 sc_time to4US(4,SC_US);
499 sc_time to8_4MS(8.4,SC_MS);
500 sc_time to16_8MS(16.8,SC_MS);
501 sc_time to33_6MS(33.6,SC_MS);
502 sc_time to67_1MS(67.1,SC_MS);
503 sc_time to134MS(134,SC_MS);
504 sc_time to268MS(2684,SC_MS);
505
506 sc_uint<64> peu_ctrl_csr_reg = csr_port.read_csr(PEU_CSR_A_TLU_CTL_HW_ADDR);
507
508 switch(peu_ctrl_csr_reg.range(18,16)){
509 case 0: return SC_ZERO_TIME;//RSB_TIMER_MAX_TIME; //Infinite CPL Timeout
510 case 1: return (to268MS +sc_time_stamp());
511 case 2: return (to134MS +sc_time_stamp());
512 case 3: return (to67_1MS+sc_time_stamp());
513 case 4: return (to33_6MS+sc_time_stamp());
514 case 5: return (to16_8MS+sc_time_stamp());
515 case 6: return (to8_4MS +sc_time_stamp());
516 case 7: return (to4US +sc_time_stamp());
517 }//end switch
518 }//end get_Cpl_TO()
519
520 /**
521 * This function updates the requested UE, CE and OE error bits.
522 */
523 void rsb::write_error_csr(uint8 err_type, uint8 primary, uint8 secondary, char field_name[3]){
524 sc_uint<64> orig_csr_val;
525 sc_uint<64> new_csr_val=0;
526 sc_uint<64> log_enable;
527
528 LOG_WARNING << "Setting err bit: " << field_name;
529
530 switch(err_type){
531 case OE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_OE_ERR_RW1C_ALIAS_HW_ADDR);
532 LOG_INFO << "Updating OE CSR (orig val: " << orig_csr_val << ")";
533 log_enable = csr_port.read_csr(PEU_CSR_A_OE_LOG_HW_ADDR);
534 LOG_INFO << "OE Log enable : " << log_enable << ")";
535 break;
536 case UE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_UE_ERR_RW1C_ALIAS_HW_ADDR);
537 LOG_INFO << "Updating UE CSR (orig val: " << orig_csr_val << ")";
538 log_enable = csr_port.read_csr(PEU_CSR_A_UE_LOG_HW_ADDR);
539 LOG_INFO << "UE Log Enable : " << log_enable << ")";
540 break;
541 case CE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_CE_ERR_RW1C_ALIAS_HW_ADDR);
542 LOG_INFO << "Updating CE CSR (orig val: " << orig_csr_val << ")";
543 log_enable = csr_port.read_csr(PEU_CSR_A_CE_LOG_HW_ADDR);
544 LOG_INFO << "CE Log Enable : " << log_enable << ")";
545 break;
546 default: LOG_ERROR << "Warning: undefined error type!";
547 return;
548 }
549
550 if(log_enable.range(primary,primary)==1)
551 {
552 if(orig_csr_val.range(primary,primary)!=1)
553 new_csr_val.range(primary,primary)=1;
554 else if(orig_csr_val.range(secondary,secondary)!=1)
555 new_csr_val.range(secondary,secondary)=1;
556 else
557 LOG_DEBUG << "Warning: Both PRIMARY and SECONDARY of " << field_name << "are set.";
558 }
559
560 switch(err_type){
561 case OE: csr_port.write_csr(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
562 LOG_DEBUG << "Updating OE CSR (new val : " << new_csr_val << ")";
563 break;
564 case UE: csr_port.write_csr(PEU_CSR_A_UE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
565 LOG_DEBUG << "Updating UE CSR (new val : " << new_csr_val << ")";
566 break;
567 case CE: csr_port.write_csr(PEU_CSR_A_CE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
568 LOG_DEBUG << "Updating CE CSR (new val : " << new_csr_val << ")";
569 break;
570 }
571 return;
572 }//end write_csr_error
573
574 /**
575 * This thread handles reset behavior of the module. On the arrival of a reset global event,
576 * it issue termination requests to threads in this module. Following the reset exit global event
577 * it invokes init() to re-spawn terminated threads.
578 */
579 void rsb::reset_handler(){
580 while(1){
581 wait(*parent_global_ev);
582 switch(*global_event_type){
583 case POR_RESET_ENTER:
584 case WMR_RESET_ENTER:
585 LOG_WARNING << "\tRSB: WMR/POR_RESET enter signal..." ;
586 POR_RESET=true;
587 //Notify wait()'s in ITL thread
588 reset_ev.notify();
589 //Wait for all thread to terminate
590 while(1){
591 if(eg_handler_ph.terminated() && update_timer_ph.terminated()) break;
592 wait(eg_handler_ph.terminated_event()|update_timer_ph.terminated_event());
593 }
594 LOG_WARNING << "RSB: WMR/POR Reset threads terminated" ;
595 LOG_WARNING << "RSB: WMR/POR Reset dbs cleared" ;
596 break;
597
598 case POR_RESET_EXIT:
599 case WMR_RESET_EXIT:
600 LOG_INFO << "\tRSB: WMR/POR_RESET exit signal..." ;
601 init();
602 break;
603
604 case SW_RESET_ENTER:
605 LOG_WARNING<<"RSB: SW_RESET_ENTER";
606 STOP_TIMER=true;
607 break;
608
609 case SW_RESET_EXIT:
610 LOG_INFO<<"RSB: SW_RESET_EXIT";
611 STOP_TIMER=false;
612 break;
613 }
614 }//end while(1)
615 }//end reset_handler()
616}