Skip to content

Commit

Permalink
Finished initial PCIe link training decode support (only tested on ge…
Browse files Browse the repository at this point in the history
…n1 x1 so far). Fixes #683.
  • Loading branch information
azonenberg committed Dec 31, 2022
1 parent 7c2bd58 commit 5a3ddca
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 9 deletions.
88 changes: 79 additions & 9 deletions scopeprotocols/PCIeLinkTrainingDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ using namespace std;
PCIeLinkTrainingDecoder::PCIeLinkTrainingDecoder(const string& color)
: PacketDecoder(color, CAT_BUS)
{
ClearStreams();
AddProtocolStream("packets");
AddProtocolStream("states");
CreateInput("lane");
Expand Down Expand Up @@ -83,10 +84,14 @@ vector<string> PCIeLinkTrainingDecoder::GetHeaders()
ret.push_back("Lane");
ret.push_back("Num FTS");
ret.push_back("Rates");
//TODO: Train CTL
ret.push_back("Flags");
return ret;
}

bool PCIeLinkTrainingDecoder::GetShowDataColumn()
{
return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actual decoder logic
Expand Down Expand Up @@ -223,8 +228,7 @@ void PCIeLinkTrainingDecoder::Refresh()
cap->m_offsets.push_back(din->m_offsets[i+1]);
cap->m_durations.push_back(din->m_durations[i+1]);
auto linkid = din->m_samples[i+1].m_data;
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_LINK_NUMBER,
linkid));
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_LINK_NUMBER, linkid));
if(linkid == 0xf7)
pack->m_headers["Link"] = "Unassigned";
else
Expand All @@ -234,8 +238,7 @@ void PCIeLinkTrainingDecoder::Refresh()
cap->m_offsets.push_back(din->m_offsets[i+2]);
cap->m_durations.push_back(din->m_durations[i+2]);
auto laneid = din->m_samples[i+2].m_data;
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_LANE_NUMBER,
laneid));
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_LANE_NUMBER, laneid));
if(laneid == 0xf7)
pack->m_headers["Lane"] = "Unassigned";
else
Expand All @@ -245,16 +248,14 @@ void PCIeLinkTrainingDecoder::Refresh()
auto numFTS = din->m_samples[i+3].m_data;
cap->m_offsets.push_back(din->m_offsets[i+3]);
cap->m_durations.push_back(din->m_durations[i+3]);
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_NUM_FTS,
numFTS));
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_NUM_FTS, numFTS));
pack->m_headers["Num FTS"] = to_string(numFTS);

//Rate ID
cap->m_offsets.push_back(din->m_offsets[i+4]);
cap->m_durations.push_back(din->m_durations[i+4]);
auto rates = din->m_samples[i+4].m_data;
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_RATE_ID,
rates));
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_RATE_ID, rates));
string srates;
if(rates & 2)
srates += "2.5G ";
Expand All @@ -267,6 +268,24 @@ void PCIeLinkTrainingDecoder::Refresh()
pack->m_headers["Rates"] = srates;

//Training control
cap->m_offsets.push_back(din->m_offsets[i+5]);
cap->m_durations.push_back(din->m_durations[i+5]);
auto flags = din->m_samples[i+5].m_data;
cap->m_samples.push_back(PCIeLinkTrainingSymbol(PCIeLinkTrainingSymbol::TYPE_TRAIN_CTL, flags));
string sflags;
if(flags & 1)
sflags += "Hot reset ";
if(flags & 2)
sflags += "Disable link ";
if(flags & 4)
sflags += "Loopback ";
if(flags & 8)
sflags += "Disable scrambling ";
if(flags & 0x10)
sflags += "Compliance Receive ";
if(sflags == "")
sflags = "None";
pack->m_headers["Flags"] = sflags;

//TS ID
cap->m_offsets.push_back(din->m_offsets[i+6]);
Expand Down Expand Up @@ -360,6 +379,35 @@ void PCIeLinkTrainingDecoder::Refresh()
scap->MarkModifiedFromCpu();
}

bool PCIeLinkTrainingDecoder::CanMerge(Packet* first, Packet* /*cur*/, Packet* next)
{
//If all headers are the same, it's mergeable
if(first->m_headers == next->m_headers)
return true;

return false;
}

Packet* PCIeLinkTrainingDecoder::CreateMergedHeader(Packet* pack, size_t i)
{
//Copy everything
Packet* ret = new Packet;
ret->m_offset = pack->m_offset;
ret->m_len = pack->m_len;
ret->m_headers = pack->m_headers;
ret->m_displayBackgroundColor = pack->m_displayBackgroundColor;

//Extend length
for(; i<m_packets.size(); i++)
{
if(CanMerge(pack, nullptr, m_packets[i]))
ret->m_len = (m_packets[i]->m_offset + m_packets[i]->m_len) - pack->m_offset;
else
break;
}

return ret;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PCIeLinkTrainingWaveform
Expand All @@ -373,6 +421,7 @@ string PCIeLinkTrainingWaveform::GetColor(size_t i)
case PCIeLinkTrainingSymbol::TYPE_HEADER:
case PCIeLinkTrainingSymbol::TYPE_NUM_FTS:
case PCIeLinkTrainingSymbol::TYPE_RATE_ID:
case PCIeLinkTrainingSymbol::TYPE_TRAIN_CTL:
return StandardColors::colors[StandardColors::COLOR_CONTROL];

case PCIeLinkTrainingSymbol::TYPE_TS_ID:
Expand Down Expand Up @@ -430,6 +479,27 @@ string PCIeLinkTrainingWaveform::GetText(size_t i)
snprintf(tmp, sizeof(tmp), "Need %d FTS", s.m_data);
return tmp;

case PCIeLinkTrainingSymbol::TYPE_TRAIN_CTL:
{
string ret;
if(s.m_data & 1)
ret += "Hot reset ";
if(s.m_data & 2)
ret += "Disable link ";
if(s.m_data & 4)
ret += "Loopback ";
if(s.m_data & 8)
ret += "Disable scrambling ";
if(s.m_data & 0x10)
ret += "Compliance Receive ";

if(ret == "")
ret = "No flags";

return ret;
}
break;

case PCIeLinkTrainingSymbol::TYPE_RATE_ID:
{
string ret;
Expand Down
4 changes: 4 additions & 0 deletions scopeprotocols/PCIeLinkTrainingDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ class PCIeLinkTrainingDecoder : public PacketDecoder
virtual void Refresh();

virtual std::vector<std::string> GetHeaders();
virtual bool GetShowDataColumn();

static std::string GetProtocolName();

virtual bool CanMerge(Packet* first, Packet* cur, Packet* next);
virtual Packet* CreateMergedHeader(Packet* pack, size_t i);

virtual bool ValidateChannel(size_t i, StreamDescriptor stream);

PROTOCOL_DECODER_INITPROC(PCIeLinkTrainingDecoder)
Expand Down

0 comments on commit 5a3ddca

Please sign in to comment.