Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / pcie_common / pciePacket.hpp
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pciePacket.hpp
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#ifndef INC_pciePacket_hpp__
36#define INC_pciePacket_hpp__
37
38#include "pcie_common/config.hpp"
39#include "pcie_common/packetRefCount.hpp"
40#include "pcie_common/packet.hpp"
41#include "pcie_common/basePacket.hpp"
42#include "pcie_common/logger.hpp"
43#include "pcie_common/symbol_encoding.hpp"
44
45#include <string>
46#include <vector>
47
48namespace pcie {
49
50#define PKT_END -1
51#define PKT_BEGIN 0
52
53#define ROWSIZE 8
54
55#define PKT_FRM_SIZE 1
56#define DLLP_PKT_SIZE 6
57#define DL_SEQ_NUM_SIZE 2
58#define LCRC_SIZE 4
59#define TLP_HDR_SIZE 12
60#define TLP_HDR_START (PKT_FRM_SIZE + DL_SEQ_NUM_SIZE)
61#define DLP_START PKT_FRM_SIZE
62
63
64#define PCIE_PLD_LEN_WDTH 10
65
66#define DLLP_ACK 0x00
67#define DLLP_NAK 0x10
68#define DLLP_NAK_FRAMING 0x11
69#define DLLP_PM_ENTER_L1 0x20
70#define DLLP_PM_ENTER_L23 0x21
71#define DLLP_PM_AS_REQ_L1 0x23
72#define DLLP_PM_ACK 0x24
73#define DLLP_VENDOR 0x30
74#define DLLP_INITFC1_P(VC) (0x47 & (VC))
75#define DLLP_INITFC1_NP(VC) (0x57 & (VC))
76#define DLLP_INITFC1_Cpl(VC) (0x67 & (VC))
77#define DLLP_INITFC2_P(VC) (0xC7 & (VC))
78#define DLLP_INITFC2_NP(VC) (0xD7 & (VC))
79#define DLLP_INITFC2_Cpl(VC) (0xE7 & (VC))
80#define DLLP_UPDATEFC_P(VC) (0x87 & (VC))
81#define DLLP_UPDATEFC_NP(VC) (0x97 & (VC))
82#define DLLP_UPDATEFC_Cpl(VC) (0xA7 & (VC))
83
84#define NEW_DLLP (new pciePacket(DLLP_PKT_SIZE+PKT_FRM_SIZE))
85#define NEW_TLP(HDR_SIZE) (new pciePacket(HDR_SIZE+PKT_FRM_SIZE+DL_SEQ_NUM_SIZE+LCRC_SIZE))
86
87#define GET_TLP_FMT(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START)(6,5))
88#define GET_TLP_TYPE(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START)(4,0))
89#define GET_TLP_TC(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+1)(6,4))
90#define GET_TLP_TD(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+2)[7])
91#define GET_TLP_EP(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+2)[6])
92#define GET_TLP_ATTR(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+2)(5,4))
93#define GET_TLP_LEN(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+2)(1,0)),\
94 (pkt_ref->get_byte(TLP_HDR_START+3)))
95#define GET_TLP_FBE(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+7)(3,0))
96#define GET_TLP_LBE(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+7)(7,4))
97#define GET_TLP_BE(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+7)(7,0))
98#define GET_TLP_REQ_TAG(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+6))
99#define GET_TLP_CMPL_TAG(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+10))
100#define GET_TLP_REQ_ID(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+5)),\
101 (pkt_ref->get_byte(TLP_HDR_START+4)))
102#define GET_TLP_ADDR(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+11)(7,2)),\
103 (pkt_ref->get_byte(TLP_HDR_START+10)),\
104 (pkt_ref->get_byte(TLP_HDR_START+9)),\
105 (pkt_ref->get_byte(TLP_HDR_START+8)) )
106#define GET_TLP_EX_ADDR(pkt_ref)((pkt_ref->get_byte(TLP_HDR_START+8)(7,2)),\
107 (pkt_ref->get_byte(TLP_HDR_START+7)),\
108 (pkt_ref->get_byte(TLP_HDR_START+6)),\
109 (pkt_ref->get_byte(TLP_HDR_START+5)) )
110#define GET_TLP_CMP_ID(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+9)),\
111 (pkt_ref->get_byte(TLP_HDR_START+8)))
112#define GET_TLP_BCM(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+6)[4])
113#define GET_TLP_REG_NUM(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+11)(7,2))
114#define GET_TLP_EX_REG_NUM(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+10)(3,2))
115#define GET_TLP_CMPL_STATUS(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+6)(7,5))
116#define GET_TLP_CMPL_LADDR(pkt_ref) (pkt_ref->get_byte(TLP_HDR_START+11)(6,0))
117#define GET_TLP_BYTEC(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+6)(3,0)), \
118 (pkt_ref->get_byte(TLP_HDR_START+7)(7,0)) )
119#define GET_TLP_CMPL_REQ_ID(pkt_ref) ((pkt_ref->get_byte(TLP_HDR_START+9)(7,0)),\
120 (pkt_ref->get_byte(TLP_HDR_START+8)(7,0)) )
121
122
123
124 /// TLP Packet Types: fmt [1:0] type[4:0]
125#define tlp_MRd_32 0x00
126#define tlp_MRd_64 0x20
127#define tlp_MRdLk_32 0x01
128#define tlp_MRdLk_64 0x21
129#define tlp_MWr_32 0x40
130#define tlp_MWr_64 0x60
131#define tlp_IORd 0x02
132#define tlp_IOWr 0x42
133#define tlp_CfgRd0 0x04
134#define tlp_CfgWr0 0x44
135#define tlp_CfgRd1 0x05
136#define tlp_CfgWr1 0x45
137#define tlp_Msg(R) (0x37 & R)
138#define tlp_MsgD(R) (0x77 & R)
139#define tlp_Cpl 0x0A
140#define tlp_CplD 0x4A
141#define tlp_CplLk 0x0B
142#define tlp_CplDLk 0x4B
143
144#define TLP_CMPL 0xA
145#define TLP_CMPLK 0xB
146
147#define DROP_TLP_ILUINTF_RECOVER_CREDITS 0xb
148
149 USING_NAMESPACE(std)
150 USING_NAMESPACE(Logger)
151
152#define LOG_SERVICE
153 uint32 genUniqPacketId();
154
155 class pciePacket : public basePacket {
156 public:
157 pciePacket() : basePacket("PCIE_PACKET")
158 {
159 size = 1;
160 raw_payload.resize(size);
161 for (int i = 0; i < size; i++) raw_payload[i] = 0;
162 }
163
164 pciePacket(int pkt_size) : basePacket("PCIE_PACKET")
165 {
166 size = pkt_size;
167 raw_payload.resize(size);
168 for (int i = 0; i < size; i++) raw_payload[i] = 0;
169 }
170
171 pciePacket(const pciePacket& other)
172 {
173 size = other.size;
174 raw_payload = other.raw_payload;
175 }
176
177 /// return the raw payload size
178 uint32 get_size() {
179 return size;
180 }
181
182 /// return the raw payload size
183 uint32 get_pkt_size() {
184 return size;
185 }
186
187 /// return the expected length for the packet, based on HDR fields
188 uint32 get_expect_len(){
189 uint32 lsize;
190 lsize = 3 + 4 + 1; //1st 3 bytes, LCRC, END
191 if(raw_payload[TLP_HDR_START].range(6,5)==1 ||
192 raw_payload[TLP_HDR_START].range(6,5)==3 )
193 lsize += 16;
194 else
195 lsize += 12;
196 if(raw_payload[TLP_HDR_START+2].range(7,7)==1)
197 lsize += 4; //Digest present
198 //If pkt contains data, add to lsize, else ignore length
199 if( raw_payload[TLP_HDR_START]==tlp_MWr_32 || raw_payload[TLP_HDR_START]==tlp_MWr_64 ||
200 raw_payload[TLP_HDR_START]==tlp_IOWr || raw_payload[TLP_HDR_START]==tlp_CfgWr0 ||
201 raw_payload[TLP_HDR_START]==tlp_CplD || raw_payload[TLP_HDR_START]==tlp_CfgWr1 ||
202 raw_payload[TLP_HDR_START]==tlp_CplDLk)
203 {
204 sc_uint<12> pl_len = (raw_payload[TLP_HDR_START+2].range(1,0),raw_payload[TLP_HDR_START+3])*4;
205 lsize += pl_len;
206 }
207 return lsize;
208 }
209
210 /// Gets the value of a byte at location loc [0..size)
211 sc_uint<8> get_byte (int loc) {
212 if (loc < size) {
213 return raw_payload[loc];
214 } else {
215 LOG_ERROR_S << "Reading Packet Byte @ " << loc
216 << "Max size is " << size << "\n";
217 return 0;
218 }
219 }
220
221 /// Modifys the byte at location loc [0..size)
222 sc_uint<8> modify_byte (int loc, sc_uint<8> byte_val = 0) {
223 if (loc >= size || loc < 0) {
224 LOG_ERROR_S << "Modifying Packet Byte @ " << loc
225 << "Max size is " << size << "\n";
226 } else {
227 return raw_payload[loc] = byte_val;
228 }
229 return 0;
230 }
231
232
233 void display_packet() {
234 int i;
235 cout << sc_time_stamp() << endl;
236
237 cout << " _DLL_ : ----------- PCIE PACKET BEGIN ---------------" << endl;
238 for(i=0; i < size; i++)
239 {
240 cout << "_DLL_ : Byte " << i << " PAYLOAD " << hex << raw_payload[i] << endl;
241
242 }
243 cout << " _DLL_ : ----------- PCIE PACKET END -----------------" << endl;
244
245 }
246
247
248 void pl2dll_display_stp_packet() {
249 int i;
250 sc_uint<8> tmp_byte;
251 sc_uint<12> seq_num;
252 sc_uint<10> pkt_len;
253
254 cout << sc_time_stamp() << endl;
255
256 cout << " _STP_ : ----------- STP PACKET BEGIN ---------------" << endl;
257
258 tmp_byte = raw_payload[1];
259 seq_num.range(11,8)=tmp_byte.range(3,0);
260 tmp_byte = raw_payload[2];
261 seq_num.range(7,0)=tmp_byte.range(7,0);
262
263 cout << " _STP_ : Seq_Num " << seq_num << endl;
264
265 tmp_byte = raw_payload[3];
266 cout << " _STP_ : R = " << tmp_byte.range(7,7) << endl;
267 cout << " _STP_ : Fmt = " << tmp_byte.range(6,5) << endl;
268 cout << " _STP_ : Type = " << tmp_byte.range(4,0) << endl;
269
270 tmp_byte = raw_payload[4];
271 cout << " _STP_ : R = " << tmp_byte.range(7,7) << endl;
272 cout << " _STP_ : TC = " << tmp_byte.range(6,4) << endl;
273 cout << " _STP_ : R = " << tmp_byte.range(3,0) << endl;
274
275 tmp_byte = raw_payload[5];
276 cout << " _STP_ : TD = " << tmp_byte.range(7,7) << endl;
277 cout << " _STP_ : EP = " << tmp_byte.range(6,6) << endl;
278 cout << " _STP_ : Attr = " << tmp_byte.range(5,4) << endl;
279 cout << " _STP_ : R = " << tmp_byte.range(3,2) << endl;
280 pkt_len.range(9,8)=tmp_byte.range(1,0);
281
282 tmp_byte = raw_payload[6];
283 pkt_len.range(7,0)=tmp_byte.range(7,0);
284
285 cout << " _STP_ : Length = " << pkt_len << endl;
286
287 if ( raw_payload[size-1] == END )
288 cout << " _STP_ : ----------- SDP PACKET END -----------------" << endl;
289 else if ( raw_payload[size-1] == EDB )
290 cout << " _STP_ : ----------- PACKET EDB -----------------" << endl;
291
292 }
293
294
295 void dll2pl_display_sdp_packet(int type) {
296 int i;
297 sc_uint<8> tmp_byte,HdrFC;
298 sc_uint<12> seq_num;
299 sc_uint<10> pkt_len;
300 sc_uint<12> DataFC;
301
302 seq_num.range(11,8)=raw_payload[2].range(3,0);
303 seq_num.range(7,0) =raw_payload[3].range(7,0);
304
305 HdrFC.range(7,2)=raw_payload[1].range(5,0);
306 HdrFC.range(1,0)=raw_payload[2].range(7,6);
307
308 DataFC.range(11,8)= raw_payload[2].range(3,0);
309 DataFC.range(7,0)= raw_payload[3];
310
311 cout << sc_time_stamp() << endl;
312
313 if ( type )
314 cout << "_SDP_ : ----------- TX SDP PACKET " << _id << " BEGIN ---------------" << endl;
315 else
316 cout << "_SDP_ : ----------- RX SDP PACKET " << _id << " BEGIN ---------------" << endl;
317
318 if ( raw_payload[0].range(7,4) == 1 )
319 cout << "_SDP_ PKT: NAK SEQ_NUM= " << seq_num ;
320 else if ( raw_payload[0].range(7,4) == 0 )
321 cout << "_SDP_ PKT: ACK SEQ_NUM= " << seq_num ;
322
323
324 switch ( raw_payload[0].range(7,4) )
325 {
326 case 0: cout << "_SDP_ PKT: ACK SEQ_NUM= " << seq_num ;
327 break;
328 case 1: cout << "_SDP_ PKT: NAK SEQ_NUM= " << seq_num ;
329 break;
330 case 4: cout << "_SDP_ PKT: InitFC1_P HdrFC = " << HdrFC << " DataFC = " << DataFC ;
331 break;
332 case 5: cout << "_SDP_ PKT: InitFC1_NP HdrFC = " << HdrFC << " DataFC = " << DataFC ;
333 break;
334 case 6: cout << "_SDP_ PKT: InitFC1_Cpl HdrFC = " << HdrFC << " DataFC = " << DataFC;
335 break;
336
337 case 12: cout << "_SDP_ PKT: InitFC2_P HdrFC = " <<HdrFC<< " DataFC = " <<DataFC;
338 break;
339 case 13: cout << "_SDP_ PKT: InitFC2_NP HdrFC = " << HdrFC << " DataFC = " <<DataFC ;
340
341 break;
342 case 14: cout << "_SDP_ PKT: InitFC2_Cpl HdrFC = " << HdrFC<< " DataFC = " <<DataFC ;
343 break;
344
345 case 8: cout << "_SDP_ PKT: UpdateFC_P HdrFC = " <<HdrFC << " DataFC = " << DataFC ;
346 break;
347 case 9: cout << "_SDP_ PKT: UpdateFC_NP HdrFC = " <<HdrFC<< " DataFC = " << DataFC;
348 break;
349 case 10: cout << "_SDP PKT: UpdateFC_Cpl HdrFC = " <<HdrFC<< " DataFC = " <<DataFC ;
350 break;
351 case 2: cout << "_SDP_ PKT: PM " ;
352 break;
353 }
354 cout << endl;
355
356 if ( type )
357 cout << "_SDP_ : ----------- TX SDP PACKET END ---------------" << endl;
358 else {
359 if ( raw_payload[size-1] == END )
360 cout << "_SDP_ : ----------- RX SDP PACKET END -----------------" << endl;
361 else if ( raw_payload[size-1] == EDB )
362 cout << "_SDP_ : ----------- RX SDP PACKET EDB -----------------" << endl;
363 }
364 }
365
366
367
368
369 void pl2dll_display_sdp_packet(int type) {
370 int i;
371 sc_uint<8> tmp_byte,HdrFC;
372
373 sc_uint<12> seq_num;
374 sc_uint<10> pkt_len;
375 sc_uint<12> DataFC;
376
377 seq_num.range(11,8)=raw_payload[2].range(3,0);
378 seq_num.range(7,0) =raw_payload[3].range(7,0);
379
380 HdrFC.range(7,2)=raw_payload[2].range(5,0);
381 HdrFC.range(1,0)=raw_payload[3].range(7,6);
382
383 DataFC.range(11,8)= raw_payload[3].range(3,0);
384 DataFC.range(7,0)= raw_payload[4];
385
386 cout << sc_time_stamp() << endl;
387
388 if ( type )
389 cout << "_SDP_ : ----------- TX SDP PACKET " << _id << " BEGIN ---------------" << endl;
390 else
391 cout << "_SDP_ : ----------- RX SDP PACKET " << _id << " BEGIN ---------------" << endl;
392
393 switch ( raw_payload[1].range(7,4) )
394 {
395 case 0: cout << "_SDP_ PKT: ACK SEQ_NUM= " << seq_num ;
396 break;
397 case 1: cout << "_SDP_ PKT: NAK SEQ_NUM= " << seq_num ;
398 break;
399 case 4: cout << "_SDP_ PKT: InitFC1_P HdrFC = " << HdrFC << " DataFC = " << DataFC ;
400 break;
401 case 5: cout << "_SDP_ PKT: InitFC1_NP HdrFC = " << HdrFC << " DataFC = " << DataFC ;
402 break;
403 case 6: cout << "_SDP_ PKT: InitFC1_Cpl HdrFC = " << HdrFC << " DataFC = " << DataFC;
404 break;
405
406 case 12: cout << "_SDP_ PKT: InitFC2_P HdrFC = " <<HdrFC<< " DataFC = " <<DataFC;
407 break;
408 case 13: cout << "_SDP_ PKT: InitFC2_NP HdrFC = " << HdrFC << " DataFC = " <<DataFC ;
409
410 break;
411 case 14: cout << "_SDP_ PKT: InitFC2_Cpl HdrFC = " << HdrFC<< " DataFC = " <<DataFC ;
412 break;
413
414 case 8: cout << "_SDP_ PKT: UpdateFC_P HdrFC = " <<HdrFC << " DataFC = " << DataFC ;
415 break;
416 case 9: cout << "_SDP_ PKT: UpdateFC_NP HdrFC = " <<HdrFC<< " DataFC = " << DataFC;
417 break;
418 case 10: cout << "_SDP PKT: UpdateFC_Cpl HdrFC = " <<HdrFC<< " DataFC = " <<DataFC ;
419 break;
420 case 2: cout << "_SDP_ PKT: PM " ;
421 break;
422 }
423 cout << endl;
424
425 if ( type )
426 cout << "_SDP_ : ----------- TX SDP PACKET END ---------------" << endl;
427 else {
428 if ( raw_payload[size-1] == END )
429 cout << "_SDP_ : ----------- RX SDP PACKET END -----------------" << endl;
430 else if ( raw_payload[size-1] == EDB )
431 cout << "_SDP_ : ----------- RX SDP PACKET EDB -----------------" << endl;
432 }
433 }
434
435
436 void set_control (sc_lv<5> control) { is_control = control; }
437 sc_lv<5> get_control () { return is_control; }
438
439 void alloc_bytes(int num) {
440 raw_payload.resize(size+num);
441 for (int i=size; i < size+num; i++) raw_payload[i] = 0;
442 size += num;
443 }
444
445 /// adds byte at loc, default PKT_END ..
446 /// if loc > PKT_END adds default value bytes
447 sc_uint<8> add_byte (sc_uint<8> byte_val, int loc = PKT_END) {
448 if (loc == PKT_BEGIN) {
449 raw_payload.insert( raw_payload.begin(),byte_val);
450 size++;
451 return byte_val;
452 }
453 if (loc == PKT_END) {
454 raw_payload.push_back(byte_val);
455 size++;
456 return byte_val;
457 }
458 if (loc >= size) {
459 size = loc;
460 raw_payload.resize(size);
461 raw_payload.push_back(byte_val);
462 return byte_val;
463 }
464 LOG_WARNING_S << "Insert byte -- Not Implemented \n";
465 return 0;
466 }
467
468 virtual ~pciePacket()
469 { }
470
471 virtual const USE_NAMESPACE(std)string to_string () const {
472 USE_NAMESPACE(std)string ts;
473
474 ts += ("PCIE Packet Id: " + (sc_uint<32>(_id)).to_string()
475 + " Size = " + (sc_uint<32>(size)).to_string(SC_HEX)
476 + " Control : " + is_control.to_string() + "\n");
477
478 if (raw_payload[0] == STP) {
479 ts += "TLP Packet : ";
480 switch (raw_payload[TLP_HDR_START]) {
481 case tlp_MRd_32:
482 ts += ("Mem Read32 (Tag: "
483 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
484 + " Len: "
485 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
486 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
487 + ")");
488 break;
489 case tlp_MRd_64:
490 ts += ("Mem Read64 (Tag: "
491 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
492 + " Len: "
493 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
494 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
495 + ")");
496 break;
497 case tlp_MRdLk_32:
498 ts += ("Mem ReadLock32 (Tag: "
499 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
500 + " Len: "
501 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
502 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
503 + ")");
504 break;
505 case tlp_MRdLk_64:
506 ts += ("Mem ReadLock64 (Tag: "
507 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
508 + " Len: "
509 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
510 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
511 + ")");
512 break;
513 case tlp_MWr_32:
514 ts += ("Mem Write32 (Tag: "
515 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
516 + " Len: "
517 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
518 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
519 + ")");
520 break;
521 case tlp_MWr_64:
522 ts += ("Mem Write64 (Tag: "
523 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
524 + " Len: "
525 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
526 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
527 + ")");
528 break;
529 case tlp_IORd:
530 ts += ("IO Read (Tag: "
531 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
532 + " Len: "
533 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
534 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
535 + ")");
536 break;
537 case tlp_IOWr:
538 ts += ("IO Write (Tag: "
539 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
540 + " Len: "
541 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
542 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
543 + ")");
544 break;
545 case tlp_CfgRd0:
546 ts += ("CFG Read0 (Tag: "
547 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
548 + " Len: "
549 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
550 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
551 + ")");
552 break;
553 case tlp_CfgWr0:
554 ts += ("CFG Write0 (Tag: "
555 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
556 + " Len: "
557 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
558 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
559 + ")");
560 break;
561 case tlp_CfgRd1:
562 ts += ("CFG Read1 (Tag: "
563 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
564 + " Len: "
565 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
566 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
567 + ")");
568 break;
569 case tlp_CfgWr1:
570 ts += ("CFG Write1 (Tag: "
571 + (sc_uint<8>(raw_payload[TLP_HDR_START+6])).to_string(SC_HEX)
572 + " Len: "
573 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
574 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
575 + ")");
576 break;
577 case tlp_Cpl:
578 ts += ("CMPL (Tag: "
579 + (sc_uint<8>(raw_payload[TLP_HDR_START+10])).to_string(SC_HEX)
580 + " Len: "
581 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
582 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
583 + ")");
584 break;
585 case tlp_CplD:
586 ts += ("CMPL with Data (Tag: "
587 + (sc_uint<8>(raw_payload[TLP_HDR_START+10])).to_string(SC_HEX)
588 + " Len: "
589 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
590 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
591 + ")");
592 break;
593 case tlp_CplLk:
594 ts += ("CMPL Lock (Tag: "
595 + (sc_uint<8>(raw_payload[TLP_HDR_START+10])).to_string(SC_HEX)
596 + " Len: "
597 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
598 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
599 + ")");
600 break;
601 case tlp_CplDLk:
602 ts += ("CMPL Lock with Data (Tag: "
603 + (sc_uint<8>(raw_payload[TLP_HDR_START+10])).to_string(SC_HEX)
604 + " Len: "
605 + (sc_uint<10>((raw_payload[TLP_HDR_START+2](1,0),
606 raw_payload[TLP_HDR_START+3]))).to_string(SC_HEX)
607 + ")");
608 break;
609 }
610 ts += (" TC: " + (sc_uint<3>(raw_payload[TLP_HDR_START+1](6,4))).to_string(SC_HEX)
611 + " TD: " + (sc_uint<1>(raw_payload[TLP_HDR_START+2][7])).to_string(SC_HEX)
612 + " EP: " + (sc_uint<1>(raw_payload[TLP_HDR_START+2][6])).to_string(SC_HEX)
613 + "\n");
614 if( (raw_payload[TLP_HDR_START] == tlp_Cpl) ||
615 (raw_payload[TLP_HDR_START] == tlp_CplD) ||
616 (raw_payload[TLP_HDR_START] == tlp_CplLk) ||
617 (raw_payload[TLP_HDR_START] == tlp_CplDLk)
618 ){
619 ts += ("ReqId: " + (sc_uint<16>((raw_payload[TLP_HDR_START+9],
620 raw_payload[TLP_HDR_START+8]))).to_string(SC_HEX)
621 + "\n");
622 } else
623 ts += ("ReqId: " + (sc_uint<16>((raw_payload[TLP_HDR_START+5],
624 raw_payload[TLP_HDR_START+4]))).to_string(SC_HEX)
625 + "\n");
626 }
627
628 int total_rows = size/ROWSIZE + ((size%ROWSIZE) ? 1 : 0);
629 for (int row = 0; row < total_rows; row++) {
630 int total_cols = ((size - row*ROWSIZE) > ROWSIZE) ? ROWSIZE : (size - row*ROWSIZE);
631 for (int col = 0; col < total_cols; col++) {
632 ts += ((sc_uint<8>(raw_payload[row*ROWSIZE+col])).to_string(SC_HEX) + " ");
633 }
634 ts += "\n";
635 }
636 return ts;
637 }
638
639 RefPacket clone( void ) const {
640 pciePacket *p = new pciePacket(*this);
641 p->raw_payload = raw_payload;
642 return RefPacket(p);
643 }
644
645
646 bool isPosted() const {
647 if (raw_payload[0] != STP) return false;
648 if ( (raw_payload[TLP_HDR_START] == tlp_MWr_32) ||
649 (raw_payload[TLP_HDR_START] == tlp_MWr_64) ||
650 (raw_payload[TLP_HDR_START][4] == 0x1) )
651 return true;
652
653 return false;
654 }
655
656 bool isCmpl() const {
657 if (raw_payload[0] != STP) return false;
658 if (raw_payload[TLP_HDR_START][3] == 0x1)
659 return true;
660 return false;
661 }
662
663 bool hasData() const {
664 if (raw_payload[0] != STP) return false;
665 if (raw_payload[TLP_HDR_START][6] == 0x1)
666 return true;
667 return false;
668 }
669
670 bool isValidDWBE() const {
671
672 if(this->isCmpl()) return false;
673
674 //CMPLs do not have DWBEs
675 sc_uint<10> len = (raw_payload[TLP_HDR_START+2].range(1,0),raw_payload[TLP_HDR_START+3]);
676 sc_uint<4> fBE = raw_payload[TLP_HDR_START+7].range(3,0);
677 sc_uint<4> lBE = raw_payload[TLP_HDR_START+7].range(7,4);
678
679 if( (raw_payload[TLP_HDR_START]==tlp_CfgRd0 || raw_payload[TLP_HDR_START]==tlp_CfgRd1 ||
680 raw_payload[TLP_HDR_START]==tlp_CfgWr0 || raw_payload[TLP_HDR_START]==tlp_CfgWr1 ||
681 raw_payload[TLP_HDR_START]==tlp_IORd || raw_payload[TLP_HDR_START]==tlp_IOWr) &&
682 (lBE!=0)){
683 return false;
684 }
685
686 bool isContiguous = false;
687 if((fBE==8 || fBE==12 || fBE==14 || fBE==15) && (lBE==1 || lBE==3 || lBE==7 || lBE==15))
688 isContiguous = true;
689
690 bool qwbndry = false;
691 sc_uint<2> addr_lsb = 0;
692 if(raw_payload[TLP_HDR_START].range(6,5)==1 || raw_payload[TLP_HDR_START].range(6,5)==3)
693 addr_lsb = raw_payload[TLP_HDR_START+15].range(3,2);
694 else
695 addr_lsb = raw_payload[TLP_HDR_START+11].range(3,2);
696 if(addr_lsb==0){
697 qwbndry = true;
698 }
699
700 if( (len==0x1 && lBE!=0) || (len>0x1 && lBE==0) || (len>0x1 && fBE==0) ||
701 (len>0x2 && !isContiguous) || (len==0x2 && !isContiguous && !qwbndry))
702 return false;
703 return true;
704 }
705
706 bool isCross4KB() const {
707 if(raw_payload[TLP_HDR_START]==tlp_MRd_32 || raw_payload[TLP_HDR_START]==tlp_MRd_64 ||
708 raw_payload[TLP_HDR_START]==tlp_MWr_32 || raw_payload[TLP_HDR_START]==tlp_MWr_64)
709 {
710 sc_uint<64> addr=0;
711 sc_uint<10> len= (raw_payload[TLP_HDR_START+2].range(1,0),raw_payload[TLP_HDR_START+3]);
712 if(raw_payload[TLP_HDR_START].range(6,5)==1 || raw_payload[TLP_HDR_START].range(6,5)==3 )
713 {
714 addr.range(63,2) = (raw_payload[TLP_HDR_START+8],raw_payload[TLP_HDR_START+9],raw_payload[TLP_HDR_START+10],raw_payload[TLP_HDR_START+11],raw_payload[TLP_HDR_START+12],raw_payload[TLP_HDR_START+13],raw_payload[TLP_HDR_START+14],raw_payload[TLP_HDR_START+15].range(7,2));
715 }
716 else
717 addr.range(31,2) = (raw_payload[TLP_HDR_START+8],raw_payload[TLP_HDR_START+9],raw_payload[TLP_HDR_START+10],raw_payload[TLP_HDR_START+11].range(7,2));
718 if( (addr%0x1000 + len*4) > 0x1000 )
719 return true;
720 }
721 return false;
722 }
723
724 bool isMalformed(sc_uint<64> peu_diag_reg){
725 if( (this->get_size() != this->get_expect_len()) ||
726 (peu_diag_reg.range(36,36)!=1 && !this->isValidDWBE() &&
727 !(raw_payload[TLP_HDR_START].range(6,5)==1 && raw_payload[TLP_HDR_START].range(4,0)>=0x10) //TLP is not a MsgD
728 || (peu_diag_reg.range(37,37)!=1 && this->isCross4KB() )))
729 return true;
730 return false;
731 }
732
733 private:
734 uint32 size;
735 sc_lv<5> is_control;
736 // is_control[4:0] = {EDB, END, SDP, STP, Control}
737 vector < sc_uint < 8 > > raw_payload;
738
739 };
740
741 typedef packetRefCount<pciePacket> RefPciePacket;
742
743#undef LOG_SERVICE
744}
745#endif //INC_pciePacket_hpp__
746