1use std::convert::TryFrom;
2use std::fmt::Display;
3
4#[macro_use]
5extern crate bitfield;
6
7#[repr(u8)]
8#[derive(PartialEq, Copy, Clone)]
9pub enum TlpFmt {
10 NoDataHeader3DW = 0b000,
11 NoDataHeader4DW = 0b001,
12 WithDataHeader3DW = 0b010,
13 WithDataHeader4DW = 0b011,
14 TlpPrefix = 0b100,
15}
16
17impl Display for TlpFmt {
18 fn fmt (&self, fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
19 let name = match &self {
20 TlpFmt::NoDataHeader3DW => "3DW no Data Header",
21 TlpFmt::NoDataHeader4DW => "4DW no Data Header",
22 TlpFmt::WithDataHeader3DW => "3DW with Data Header",
23 TlpFmt::WithDataHeader4DW => "4DW with Data Header",
24 TlpFmt::TlpPrefix => "Tlp Prefix",
25 };
26 write!(fmt, "{}", name)
27 }
28}
29
30impl TryFrom<u32> for TlpFmt {
31 type Error = ();
32
33 fn try_from(v: u32) -> Result<Self, Self::Error> {
34 match v {
35 x if x == TlpFmt::NoDataHeader3DW as u32 => Ok(TlpFmt::NoDataHeader3DW),
36 x if x == TlpFmt::NoDataHeader4DW as u32 => Ok(TlpFmt::NoDataHeader4DW),
37 x if x == TlpFmt::WithDataHeader3DW as u32 => Ok(TlpFmt::WithDataHeader3DW),
38 x if x == TlpFmt::WithDataHeader4DW as u32 => Ok(TlpFmt::WithDataHeader4DW),
39 x if x == TlpFmt::TlpPrefix as u32 => Ok(TlpFmt::TlpPrefix),
40 _ => Err(()),
41 }
42 }
43}
44
45#[derive(PartialEq)]
46pub enum TlpFormatEncodingType {
47 MemoryRequest = 0b00000,
48 MemoryLockRequest = 0b00001,
49 IORequest = 0b00010,
50 ConfigType0Request = 0b00100,
51 ConfigType1Request = 0b00101,
52 Completion = 0b01010,
53 CompletionLocked = 0b01011,
54 FetchAtomicOpRequest = 0b01100,
55 UnconSwapAtomicOpRequest= 0b01101,
56 CompSwapAtomicOpRequest = 0b01110,
57}
58
59impl TryFrom<u32> for TlpFormatEncodingType {
60 type Error = ();
61
62 fn try_from(v: u32) -> Result<Self, Self::Error> {
63 match v {
64 x if x == TlpFormatEncodingType::MemoryRequest as u32 => Ok(TlpFormatEncodingType::MemoryRequest),
65 x if x == TlpFormatEncodingType::MemoryLockRequest as u32 => Ok(TlpFormatEncodingType::MemoryLockRequest),
66 x if x == TlpFormatEncodingType::IORequest as u32 => Ok(TlpFormatEncodingType::IORequest),
67 x if x == TlpFormatEncodingType::ConfigType0Request as u32 => Ok(TlpFormatEncodingType::ConfigType0Request),
68 x if x == TlpFormatEncodingType::ConfigType1Request as u32 => Ok(TlpFormatEncodingType::ConfigType1Request),
69 x if x == TlpFormatEncodingType::Completion as u32 => Ok(TlpFormatEncodingType::Completion),
70 x if x == TlpFormatEncodingType::CompletionLocked as u32 => Ok(TlpFormatEncodingType::CompletionLocked),
71 x if x == TlpFormatEncodingType::FetchAtomicOpRequest as u32 => Ok(TlpFormatEncodingType::FetchAtomicOpRequest),
72 x if x == TlpFormatEncodingType::UnconSwapAtomicOpRequest as u32 => Ok(TlpFormatEncodingType::UnconSwapAtomicOpRequest),
73 x if x == TlpFormatEncodingType::CompSwapAtomicOpRequest as u32 => Ok(TlpFormatEncodingType::CompSwapAtomicOpRequest),
74 _ => Err(()),
75 }
76 }
77}
78
79#[derive(PartialEq)]
80#[derive(Debug)]
81pub enum TlpType {
82 MemReadReq,
83 MemReadLockReq,
84 MemWriteReq,
85 IOReadReq,
86 IOWriteReq,
87 ConfType0ReadReq,
88 ConfType0WriteReq,
89 ConfType1ReadReq,
90 ConfType1WriteReq,
91 MsgReq,
92 MsgReqData,
93 Cpl,
94 CplData,
95 CplLocked,
96 CplDataLocked,
97 FetchAddAtomicOpReq,
98 SwapAtomicOpReq,
99 CompareSwapAtomicOpReq,
100 LocalTlpPrefix,
101 EndToEndTlpPrefix,
102}
103
104impl Display for TlpType {
105 fn fmt (&self, fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
106 let name = match &self {
107 TlpType::MemReadReq => "Memory Read Request",
108 TlpType::MemReadLockReq => "Locked Memory Read Request",
109 TlpType::MemWriteReq => "Memory Write Request",
110 TlpType::IOReadReq => "IO Read Request",
111 TlpType::IOWriteReq => "IO Write Request",
112 TlpType::ConfType0ReadReq => "Type 0 Config Read Request",
113 TlpType::ConfType0WriteReq => "Type 0 Config Write Request",
114 TlpType::ConfType1ReadReq => "Type 1 Config Read Request",
115 TlpType::ConfType1WriteReq => "Type 1 Config Write Request",
116 TlpType::MsgReq => "Message Request",
117 TlpType::MsgReqData => "Message with Data Request",
118 TlpType::Cpl => "Completion",
119 TlpType::CplData => "Completion with Data",
120 TlpType::CplLocked => "Locked Completion",
121 TlpType::CplDataLocked => "Locked Completion with Data",
122 TlpType::FetchAddAtomicOpReq => "Fetch Add Atomic Op Request",
123 TlpType::SwapAtomicOpReq => "Swap Atomic Op Request",
124 TlpType::CompareSwapAtomicOpReq => "Compare Swap Atomic Op Request",
125 TlpType::LocalTlpPrefix => "Local Tlp Prefix",
126 TlpType::EndToEndTlpPrefix => "End To End Tlp Prefix",
127 };
128 write!(fmt, "{}", name)
129 }
130}
131
132bitfield! {
133 struct TlpHeader(MSB0 [u8]);
134 u32;
135 get_format, _: 2, 0;
136 get_type, _: 7, 3;
137 get_t9, _: 8, 8;
138 get_tc, _: 11, 9;
139 get_t8, _: 12, 12;
140 get_attr_b2, _: 13, 13;
141 get_ln, _: 14, 14;
142 get_th, _: 15, 15;
143 get_td, _: 16, 16;
144 get_ep, _: 17, 17;
145 get_attr, _: 19, 18;
146 get_at, _: 21, 20;
147 get_length, _: 31, 22;
148}
149
150impl<T: AsRef<[u8]>> TlpHeader<T> {
151
152 fn get_tlp_type(&self) -> Result<TlpType, ()> {
153 let tlp_type = self.get_type();
154 let tlp_fmt = self.get_format();
155
156 match TlpFormatEncodingType::try_from(tlp_type) {
157 Ok(TlpFormatEncodingType::MemoryRequest) => {
158 match TlpFmt::try_from(tlp_fmt) {
159 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::MemReadReq),
160 Ok(TlpFmt::NoDataHeader4DW) => Ok(TlpType::MemReadReq),
161 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::MemWriteReq),
162 Ok(TlpFmt::WithDataHeader4DW) => Ok(TlpType::MemWriteReq),
163 _ => Err(()),
164 }
165 }
166 Ok(TlpFormatEncodingType::MemoryLockRequest) => {
167 match TlpFmt::try_from(tlp_fmt) {
168 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::MemReadLockReq),
169 Ok(TlpFmt::NoDataHeader4DW) => Ok(TlpType::MemReadLockReq),
170 _ => Err(()),
171 }
172 }
173 Ok(TlpFormatEncodingType::IORequest) => {
174 match TlpFmt::try_from(tlp_fmt) {
175 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::IOReadReq),
176 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::IOWriteReq),
177 _ => Err(()),
178 }
179 }
180 Ok(TlpFormatEncodingType::ConfigType0Request) => {
181 match TlpFmt::try_from(tlp_fmt) {
182 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::ConfType0ReadReq),
183 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::ConfType0WriteReq),
184 _ => Err(()),
185 }
186 }
187 Ok(TlpFormatEncodingType::ConfigType1Request) => {
188 match TlpFmt::try_from(tlp_fmt) {
189 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::ConfType1ReadReq),
190 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::ConfType1WriteReq),
191 _ => Err(()),
192 }
193 }
194 Ok(TlpFormatEncodingType::Completion) => {
195 println!("Completion fmt: {}", tlp_fmt);
196 match TlpFmt::try_from(tlp_fmt) {
197 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::Cpl),
198 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::CplData),
199 _ => Err(()),
200 }
201 }
202 Ok(TlpFormatEncodingType::CompletionLocked) => {
203 match TlpFmt::try_from(tlp_fmt) {
204 Ok(TlpFmt::NoDataHeader3DW) => Ok(TlpType::CplLocked),
205 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::CplDataLocked),
206 _ => Err(()),
207 }
208 }
209 Ok(TlpFormatEncodingType::FetchAtomicOpRequest) => {
210 match TlpFmt::try_from(tlp_fmt) {
211 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::FetchAddAtomicOpReq),
212 Ok(TlpFmt::WithDataHeader4DW) => Ok(TlpType::FetchAddAtomicOpReq),
213 _ => Err(()),
214 }
215 }
216 Ok(TlpFormatEncodingType::UnconSwapAtomicOpRequest) => {
217 match TlpFmt::try_from(tlp_fmt) {
218 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::SwapAtomicOpReq),
219 Ok(TlpFmt::WithDataHeader4DW) => Ok(TlpType::SwapAtomicOpReq),
220 _ => Err(()),
221 }
222 }
223 Ok(TlpFormatEncodingType::CompSwapAtomicOpRequest) => {
224 match TlpFmt::try_from(tlp_fmt) {
225 Ok(TlpFmt::WithDataHeader3DW) => Ok(TlpType::CompareSwapAtomicOpReq),
226 Ok(TlpFmt::WithDataHeader4DW) => Ok(TlpType::CompareSwapAtomicOpReq),
227 _ => Err(()),
228 }
229 }
230 Err(_) => Err(())
231 }
232 }
233}
234
235pub trait MemRequest {
242 fn address(&self) -> u64;
243 fn req_id(&self) -> u16;
244 fn tag(&self) -> u8;
245 fn ldwbe(&self) -> u8;
246 fn fdwbe(&self) -> u8;
247}
248
249bitfield! {
251 pub struct MemRequest3DW(MSB0 [u8]);
252 u32;
253 pub get_requester_id, _: 15, 0;
254 pub get_tag, _: 23, 16;
255 pub get_last_dw_be, _: 27, 24;
256 pub get_first_dw_be, _: 31, 28;
257 pub get_address32, _: 63, 32;
258}
259
260bitfield! {
261 pub struct MemRequest4DW(MSB0 [u8]);
262 u64;
263 pub get_requester_id, _: 15, 0;
264 pub get_tag, _: 23, 16;
265 pub get_last_dw_be, _: 27, 24;
266 pub get_first_dw_be, _: 31, 28;
267 pub get_address64, _: 95, 32;
268}
269
270impl <T: AsRef<[u8]>> MemRequest for MemRequest3DW<T> {
271 fn address(&self) -> u64 {
272 self.get_address32().into()
273 }
274 fn req_id(&self) -> u16 {
275 self.get_requester_id() as u16
276 }
277 fn tag(&self) -> u8 {
278 self.get_tag() as u8
279 }
280 fn ldwbe(&self) -> u8 {
281 self.get_last_dw_be() as u8
282 }
283 fn fdwbe(&self) -> u8 {
284 self.get_first_dw_be() as u8
285 }
286}
287
288impl <T: AsRef<[u8]>> MemRequest for MemRequest4DW<T> {
289 fn address(&self) -> u64 {
290 self.get_address64()
291 }
292 fn req_id(&self) -> u16 {
293 self.get_requester_id() as u16
294 }
295 fn tag(&self) -> u8 {
296 self.get_tag() as u8
297 }
298 fn ldwbe(&self) -> u8 {
299 self.get_last_dw_be() as u8
300 }
301 fn fdwbe(&self) -> u8 {
302 self.get_first_dw_be() as u8
303 }
304}
305
306pub fn new_mem_req(bytes: Vec<u8>, format: &TlpFmt) -> Box<dyn MemRequest> {
336 match format {
337 TlpFmt::NoDataHeader3DW => Box::new(MemRequest3DW(bytes)),
338 TlpFmt::NoDataHeader4DW => Box::new(MemRequest4DW(bytes)),
339 TlpFmt::WithDataHeader3DW => Box::new(MemRequest3DW(bytes)),
340 TlpFmt::WithDataHeader4DW => Box::new(MemRequest4DW(bytes)),
341 TlpFmt::TlpPrefix => Box::new(MemRequest3DW(bytes)),
342 }
343}
344
345pub trait ConfigurationRequest {
349 fn req_id(&self) -> u16;
350 fn tag(&self) -> u8;
351 fn bus_nr(&self) -> u8;
352 fn dev_nr(&self) -> u8;
353 fn func_nr(&self) -> u8;
354 fn ext_reg_nr(&self) -> u8;
355 fn reg_nr(&self) -> u8;
356}
357
358pub fn new_conf_req(bytes: Vec<u8>, _format: &TlpFmt) -> Box<dyn ConfigurationRequest> {
380 Box::new(ConfigRequest(bytes))
381}
382
383bitfield! {
384 pub struct ConfigRequest(MSB0 [u8]);
385 u32;
386 pub get_requester_id, _: 15, 0;
387 pub get_tag, _: 23, 16;
388 pub get_last_dw_be, _: 27, 24;
389 pub get_first_dw_be, _: 31, 28;
390 pub get_bus_nr, _: 39, 32;
391 pub get_dev_nr, _: 44, 40;
392 pub get_func_nr, _: 47, 45;
393 pub rsvd, _: 51, 48;
394 pub get_ext_reg_nr, _: 55, 52;
395 pub get_register_nr, _: 61, 56;
396 r, _: 63, 62;
397}
398
399impl <T: AsRef<[u8]>> ConfigurationRequest for ConfigRequest<T> {
400 fn req_id(&self) -> u16 {
401 self.get_requester_id() as u16
402 }
403 fn tag(&self) -> u8 {
404 self.get_tag() as u8
405 }
406 fn bus_nr(&self) -> u8 {
407 self.get_bus_nr() as u8
408 }
409 fn dev_nr(&self) -> u8 {
410 self.get_dev_nr() as u8
411 }
412 fn func_nr(&self) -> u8 {
413 self.get_func_nr() as u8
414 }
415 fn ext_reg_nr(&self) -> u8 {
416 self.get_ext_reg_nr() as u8
417 }
418 fn reg_nr(&self) -> u8 {
419 self.get_register_nr() as u8
420 }
421}
422
423pub trait CompletionRequest {
429 fn cmpl_id(&self) -> u16;
430 fn cmpl_stat(&self) -> u8;
431 fn bcm(&self) -> u8;
432 fn byte_cnt(&self) -> u16;
433 fn req_id(&self) -> u16;
434 fn tag(&self) -> u8;
435 fn laddr(&self) -> u8;
436}
437
438bitfield! {
439 pub struct CompletionReqDW23(MSB0 [u8]);
440 u16;
441 pub get_completer_id, _: 15, 0;
442 pub get_cmpl_stat, _: 18, 16;
443 pub get_bcm, _: 19, 19;
444 pub get_byte_cnt, _: 31, 20;
445 pub get_req_id, _: 47, 32;
446 pub get_tag, _: 55, 48;
447 r, _: 57, 56;
448 pub get_laddr, _: 63, 58;
449}
450
451impl <T: AsRef<[u8]>> CompletionRequest for CompletionReqDW23<T> {
452 fn cmpl_id(&self) -> u16 {
453 self.get_completer_id() as u16
454 }
455 fn cmpl_stat(&self) -> u8 {
456 self.get_cmpl_stat() as u8
457 }
458 fn bcm(&self) -> u8 {
459 self.get_bcm() as u8
460 }
461 fn byte_cnt(&self) -> u16 {
462 self.get_byte_cnt() as u16
463 }
464 fn req_id(&self) -> u16 {
465 self.get_req_id() as u16
466 }
467 fn tag(&self) -> u8 {
468 self.get_tag() as u8
469 }
470 fn laddr(&self) -> u8 {
471 self.get_laddr() as u8
472 }
473}
474
475pub fn new_cmpl_req(bytes: Vec<u8>, _format: &TlpFmt) -> Box<dyn CompletionRequest> {
493 Box::new(CompletionReqDW23(bytes))
494}
495
496pub trait MessageRequest {
499 fn req_id(&self) -> u16;
500 fn tag(&self) -> u8;
501 fn msg_code(&self) -> u8;
502 fn dw3(&self) -> u32;
504 fn dw4(&self) -> u32;
505}
506
507bitfield! {
508 pub struct MessageReqDW24(MSB0 [u8]);
509 u16;
510 pub get_requester_id, _: 15, 0;
511 pub get_tag, _: 23, 16;
512 pub get_msg_code, _: 31, 24;
513 pub get_dw3, _: 63, 32;
514 pub get_dw4, _: 96, 64;
515}
516
517impl <T: AsRef<[u8]>> MessageRequest for MessageReqDW24<T> {
518 fn req_id(&self) -> u16 {
519 self.get_requester_id() as u16
520 }
521 fn tag(&self) -> u8 {
522 self.get_tag() as u8
523 }
524 fn msg_code(&self) -> u8 {
525 self.get_msg_code() as u8
526 }
527 fn dw3(&self) -> u32 {
528 self.get_dw3() as u32
529 }
530 fn dw4(&self) -> u32 {
531 self.get_dw4() as u32
532 }
533 }
535
536pub fn new_msg_req(bytes: Vec<u8>, _format: &TlpFmt) -> Box<dyn MessageRequest> {
553 Box::new(MessageReqDW24(bytes))
554}
555
556pub struct TlpPacketHeader {
559 bytes: Vec<u8>,
560 header: TlpHeader<Vec<u8>>,
561}
562
563impl TlpPacketHeader {
564 pub fn new(bytes: Vec<u8>) -> TlpPacketHeader {
565 let mut dw0 = vec![0; 4];
566 dw0[..4].clone_from_slice(&bytes[0..4]);
567
568 TlpPacketHeader { bytes: bytes, header: TlpHeader(dw0) }
569 }
570
571 pub fn get_tlp_type(&self) -> Result<TlpType, ()> {
572 let mut dw0 = vec![0; 4];
573 dw0[..4].clone_from_slice(&self.bytes[0..4]);
574 let tlp_head = TlpHeader(dw0);
575
576 tlp_head.get_tlp_type()
577 }
578
579 pub fn get_format(&self) -> u32 {self.header.get_format()}
580 pub fn get_type(&self) -> u32 {self.header.get_type()}
581 pub fn get_t9(&self) -> u32 {self.header.get_t9()}
582 pub fn get_tc(&self) -> u32 {self.header.get_tc()}
583 pub fn get_t8(&self) -> u32 {self.header.get_t8()}
584 pub fn get_attr_b2(&self) -> u32 {self.header.get_attr_b2()}
585 pub fn get_ln(&self) -> u32 {self.header.get_ln()}
586 pub fn get_th(&self) -> u32 {self.header.get_th()}
587 pub fn get_td(&self) -> u32 {self.header.get_td()}
588 pub fn get_ep(&self) -> u32 {self.header.get_ep()}
589 pub fn get_attr(&self) -> u32 {self.header.get_attr()}
590 pub fn get_at(&self) -> u32 {self.header.get_at()}
591 pub fn get_length(&self) -> u32 {self.header.get_length()}
592
593}
594
595pub struct TlpPacket {
643 header: TlpPacketHeader,
644 data: Vec<u8>,
645}
646
647impl TlpPacket {
648 pub fn new(bytes: Vec<u8>) -> TlpPacket {
649 let mut ownbytes = bytes.to_vec();
650 let mut header = vec![0; 4];
651 header.clone_from_slice(&ownbytes[0..4]);
652 let data = ownbytes.drain(4..).collect();
653 TlpPacket {
654 header: TlpPacketHeader::new(header),
655 data: data,
656 }
657 }
658
659 pub fn get_header(&self) -> &TlpPacketHeader {
660 &self.header
661 }
662
663 pub fn get_data(&self) -> Vec<u8> {
664 self.data.to_vec()
665 }
666
667 pub fn get_tlp_type(&self) -> TlpType {
668 self.header.get_tlp_type().expect("Cannot Parse TLP!")
669 }
670
671 pub fn get_tlp_format(&self) -> TlpFmt {
672 let fmt : TlpFmt = TlpFmt::try_from(self.header.get_format()).unwrap();
673
674 fmt
675 }
676}
677
678
679#[cfg(test)]
680mod tests {
681 use super::*;
682
683 #[test]
684 fn test_tlp_packet() {
685 let d = vec![0x04, 0x00, 0x00, 0x01, 0x20, 0x01, 0xFF, 0x00, 0xC2, 0x81, 0xFF, 0x10];
686 let tlp = TlpPacket::new(d);
687
688 assert_eq!(tlp.get_tlp_type(), TlpType::ConfType0ReadReq);
689 assert_eq!(tlp.get_data(), vec![0x20, 0x01, 0xFF, 0x00, 0xC2, 0x81, 0xFF, 0x10]);
690 }
691
692 #[test]
693 fn test_complreq_trait() {
694 let cmpl_req = CompletionReqDW23([0x20, 0x01, 0xFF, 0x00, 0xC2, 0x81, 0xFF, 0x10]);
695
696 assert_eq!(0x2001, cmpl_req.cmpl_id());
697 assert_eq!(0x7, cmpl_req.cmpl_stat());
698 assert_eq!(0x1, cmpl_req.bcm());
699 assert_eq!(0xF00, cmpl_req.byte_cnt());
700 assert_eq!(0xC281, cmpl_req.req_id());
701 assert_eq!(0xFF, cmpl_req.tag());
702 assert_eq!(0x10, cmpl_req.laddr());
703 }
704
705 #[test]
706 fn test_configreq_trait() {
707 let conf_req = ConfigRequest([0x20, 0x01, 0xFF, 0x00, 0xC2, 0x81, 0xFF, 0x10]);
708
709 assert_eq!(0x2001, conf_req.req_id());
710 assert_eq!(0xFF, conf_req.tag());
711 assert_eq!(0xC2, conf_req.bus_nr());
712 assert_eq!(0x10, conf_req.dev_nr());
713 assert_eq!(0x01, conf_req.func_nr());
714 assert_eq!(0x0F, conf_req.ext_reg_nr());
715 assert_eq!(0x04, conf_req.reg_nr());
716 }
717
718 #[test]
719 fn is_memreq_tag_works() {
720 let mr3dw1 = MemRequest3DW([0x00, 0x00, 0x20, 0x0F, 0xF6, 0x20, 0x00, 0x0C]);
721 let mr3dw2 = MemRequest3DW([0x00, 0x00, 0x01, 0x0F, 0xF6, 0x20, 0x00, 0x0C]);
722 let mr3dw3 = MemRequest3DW([0x00, 0x00, 0x10, 0x0F, 0xF6, 0x20, 0x00, 0x0C]);
723 let mr3dw4 = MemRequest3DW([0x00, 0x00, 0x81, 0x0F, 0xF6, 0x20, 0x00, 0x0C]);
724
725 assert_eq!(0x20, mr3dw1.tag());
726 assert_eq!(0x01, mr3dw2.tag());
727 assert_eq!(0x10, mr3dw3.tag());
728 assert_eq!(0x81, mr3dw4.tag());
729
730 let mr4dw1 = MemRequest4DW([0x00, 0x00, 0x01, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00]);
731 let mr4dw2 = MemRequest4DW([0x00, 0x00, 0x10, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00]);
732 let mr4dw3 = MemRequest4DW([0x00, 0x00, 0x81, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00]);
733 let mr4dw4 = MemRequest4DW([0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00]);
734 let mr4dw5 = MemRequest4DW([0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00]);
735
736 assert_eq!(0x01, mr4dw1.tag());
737 assert_eq!(0x10, mr4dw2.tag());
738 assert_eq!(0x81, mr4dw3.tag());
739 assert_eq!(0xFF, mr4dw4.tag());
740 assert_eq!(0x00, mr4dw5.tag());
741 }
742
743 #[test]
744 fn is_memreq_3dw_address_works() {
745 let memreq_3dw = [0x00, 0x00, 0x20, 0x0F, 0xF6, 0x20, 0x00, 0x0C];
746 let mr = MemRequest3DW(memreq_3dw);
747
748 assert_eq!(0xF620000C, mr.address());
749 }
750
751 #[test]
752 fn is_memreq_4dw_address_works() {
753 let memreq_4dw = [0x00, 0x00, 0x20, 0x0F, 0x00, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x00, 0x00];
754 let mr = MemRequest4DW(memreq_4dw);
755
756 assert_eq!(0x17fc0000000, mr.address());
757 }
758
759 #[test]
760 fn is_tlppacket_creates() {
761 let memrd32_header = [0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x20, 0x0F, 0xF6, 0x20, 0x00, 0x0C];
762
763 let mr = TlpPacketHeader::new(memrd32_header.to_vec());
764 assert_eq!(mr.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemReadReq);
765 }
766
767 #[test]
768 fn tlp_header_type() {
769 let memread = TlpHeader([0x0, 0x0, 0x0, 0x0]);
771 assert_eq!(memread.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemReadReq);
772
773 let memread32 = TlpHeader([0x00, 0x00, 0x20, 0x01]);
775 assert_eq!(memread32.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemReadReq);
776
777 let memwrite32 = TlpHeader([0x40, 0x00, 0x00, 0x01]);
779 assert_eq!(memwrite32.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemWriteReq);
780
781 let cpl_no_data = TlpHeader([0x0a, 0x00, 0x10, 0x00]);
783 assert_eq!(cpl_no_data.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::Cpl);
784
785 let cpl_with_data = TlpHeader([0x4a, 0x00, 0x20, 0x40]);
787 assert_eq!(cpl_with_data.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::CplData);
788
789 let memread_4dw = TlpHeader([0x20, 0x00, 0x20, 0x40]);
791 assert_eq!(memread_4dw.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemReadReq);
792
793 let conf_t0_read = TlpHeader([0x04, 0x00, 0x00, 0x01]);
795 assert_eq!(conf_t0_read.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::ConfType0ReadReq);
796
797 let conf_t0_write = TlpHeader([0x44, 0x00, 0x00, 0x01]);
799 assert_eq!(conf_t0_write.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::ConfType0WriteReq);
800
801 let conf_t1_read = TlpHeader([0x05, 0x88, 0x80, 0x01]);
803 assert_eq!(conf_t1_read.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::ConfType1ReadReq);
804
805 let conf_t1_write = TlpHeader([0x45, 0x88, 0x80, 0x01]);
807 assert_eq!(conf_t1_write.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::ConfType1WriteReq);
808
809 let memwrite64 = TlpHeader([0x60, 0x00, 0x90, 0x01]);
812 assert_eq!(memwrite64.get_tlp_type().expect("Cannot Parse TLP!"), TlpType::MemWriteReq);
813 }
814
815 #[test]
816 fn tlp_header_works_all_zeros() {
817 let bits_locations = TlpHeader([0x0, 0x0, 0x0, 0x0]);
818
819 assert_eq!(bits_locations.get_format(), 0);
820 assert_eq!(bits_locations.get_type(), 0);
821 assert_eq!(bits_locations.get_t9(), 0);
822 assert_eq!(bits_locations.get_tc(), 0);
823 assert_eq!(bits_locations.get_t8(), 0);
824 assert_eq!(bits_locations.get_attr_b2(), 0);
825 assert_eq!(bits_locations.get_ln(), 0);
826 assert_eq!(bits_locations.get_th(), 0);
827 assert_eq!(bits_locations.get_td(), 0);
828 assert_eq!(bits_locations.get_ep(), 0);
829 assert_eq!(bits_locations.get_attr(), 0);
830 assert_eq!(bits_locations.get_at(), 0);
831 assert_eq!(bits_locations.get_length(), 0);
832 }
833
834 #[test]
835 fn tlp_header_works_all_ones() {
836 let bits_locations = TlpHeader([0xff, 0xff, 0xff, 0xff]);
837
838 assert_eq!(bits_locations.get_format(), 0x7);
839 assert_eq!(bits_locations.get_type(), 0x1f);
840 assert_eq!(bits_locations.get_t9(), 0x1);
841 assert_eq!(bits_locations.get_tc(), 0x7);
842 assert_eq!(bits_locations.get_t8(), 0x1);
843 assert_eq!(bits_locations.get_attr_b2(), 0x1);
844 assert_eq!(bits_locations.get_ln(), 0x1);
845 assert_eq!(bits_locations.get_th(), 0x1);
846 assert_eq!(bits_locations.get_td(), 0x1);
847 assert_eq!(bits_locations.get_ep(), 0x1);
848 assert_eq!(bits_locations.get_attr(), 0x3);
849 assert_eq!(bits_locations.get_at(), 0x3);
850 assert_eq!(bits_locations.get_length(), 0x3ff);
851 }
852}