Packets
Packet Definitions
The CXL packet definitions are under opencis/cxl/transport/transaction.py. Every packet is
a derived class of UnalignedBitStructure.
Hierarchy
The packet classes generally follow the following hierarchy.
Learn by example for CXL.io. Indentation indicates derived class.
class UnalignedBitStructureclass BasePacket(UnalignedBitStructure)class CxlIoBasePacket(BasePacket)class CxlIoMemReqPacket(CxlIoBasePacket)class CxlIoMemRdPacket(CxlIoMemReqPacket)class CxlIoMemWrPacket(CxlIoMemReqPacket)
class CxlIoCfgReqPacket(CxlIoBasePacket)class CxlIoCfgRdPacket(CxlIoCfgReqPacket)class CxlIoCfgWrPacket(CxlIoCfgReqPacket)
A similar hierarchy could be used for creating another class of packets (i.e. CXL.cache).
BitField, ByteField, StructureField
There are 3 types of field that can be used for packet definition. As the name implies, BitField
for bits and ByteField for bytes. Due to UnalignedBitStructure limitations, BitField and
ByteField cannot be directly combined in a single packet definition. This is where
StructureField comes in. One can define a combination of BitField as a StructField, then
combine them with a ByteField.
class CxlIoCompletionHeader(UnalignedBitStructure):
...
_fields = [
BitField("cpl_id", 0, 15),
BitField("byte_count_upper", 16, 19),
BitField("bcm", 20, 20),
BitField("status", 21, 23),
BitField("byte_count_lower", 24, 31),
BitField("req_id", 32, 47),
BitField("tag", 48, 55),
BitField("lower_addr", 56, 62),
BitField("rsvd", 63, 63),
]
class CxlIoCompletionWithDataPacket(CxlIoBasePacket):
...
_fields = CxlIoBasePacket._fields + [
StructureField(
"cpl_header",
CXL_IO_CPL_HEADER_START,
CXL_IO_CPL_HEADER_END,
CxlIoCompletionHeader,
),
ByteField("data", CXL_IO_CPL_FIELD_START, CXL_IO_CPL_FIELD_START + 0x07),
]
In the above example, CxlIoCompletionWithDataPacket._fields is a combination of three
entities.
CxlIoBasePacket._fieldsStructureField(..., CxlIoCompletionHeader), a combination ofBitFieldelements, 64-bits in length.ByteField, 8-bytes in length.
When a BitField in StructureField is greater than 8-bit in length, one must carefully consider
its byteorder (i.e. endianness). The default during runtime is the current machine's endianness,
which could be retrieved from sys.byteorder. CXL.io/PCIe fields are big endian, while the CXL.mem
fields are little endian.
List of Useful APIs
create(): Create the packet.get_size(): Get the length of the packet in bytes.get_pretty_string(): Get a human readable format of the packet contents.reset(payload): Overwrite the contents of the packet with the contents of payload.