Replaced old bitfield crate with a new one and unit tested tlp structs
parent
8ba97711aa
commit
f5cc8dd318
@ -0,0 +1,168 @@
|
|||||||
|
// Example program
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define WORD uint16_t
|
||||||
|
#define DWORD uint32_t
|
||||||
|
#define BYTE uint8_t
|
||||||
|
#define PBYTE uint8_t*
|
||||||
|
#define TRUE 1
|
||||||
|
#define BOOL int
|
||||||
|
#define QWORD uint64_t
|
||||||
|
#define FALSE 0
|
||||||
|
#define PDWORD DWORD*
|
||||||
|
|
||||||
|
#define ENDIAN_SWAP_DWORD(x) (x = (x << 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x >> 24))
|
||||||
|
|
||||||
|
#define TLP_MRd32 0x00
|
||||||
|
#define TLP_MRd64 0x20
|
||||||
|
#define TLP_MRdLk32 0x01
|
||||||
|
#define TLP_MRdLk64 0x21
|
||||||
|
#define TLP_MWr32 0x40
|
||||||
|
#define TLP_MWr64 0x60
|
||||||
|
#define TLP_IORd 0x02
|
||||||
|
#define TLP_IOWr 0x42
|
||||||
|
#define TLP_CfgRd0 0x04
|
||||||
|
#define TLP_CfgRd1 0x05
|
||||||
|
#define TLP_CfgWr0 0x44
|
||||||
|
#define TLP_CfgWr1 0x45
|
||||||
|
#define TLP_Cpl 0x0A
|
||||||
|
#define TLP_CplD 0x4A
|
||||||
|
#define TLP_CplLk 0x0B
|
||||||
|
#define TLP_CplDLk 0x4B
|
||||||
|
|
||||||
|
#define MAX_SIZE_TX 0x3f0
|
||||||
|
|
||||||
|
typedef struct tdTLP_HDR {
|
||||||
|
WORD Length : 10;
|
||||||
|
WORD _AT : 2;
|
||||||
|
WORD _Attr : 2;
|
||||||
|
WORD _EP : 1;
|
||||||
|
WORD _TD : 1;
|
||||||
|
BYTE _R1 : 4;
|
||||||
|
BYTE _TC : 3;
|
||||||
|
BYTE _R2 : 1;
|
||||||
|
BYTE TypeFmt;
|
||||||
|
} TLP_HDR, *PTLP_HDR;
|
||||||
|
|
||||||
|
typedef struct tdTLP_HDR_MRdWr32 {
|
||||||
|
TLP_HDR h;
|
||||||
|
BYTE FirstBE : 4;
|
||||||
|
BYTE LastBE : 4;
|
||||||
|
BYTE Tag;
|
||||||
|
WORD RequesterID;
|
||||||
|
DWORD Address;
|
||||||
|
} TLP_HDR_MRdWr32, *PTLP_HDR_MRdWr32;
|
||||||
|
|
||||||
|
typedef struct tdTLP_HDR_MRdWr64 {
|
||||||
|
TLP_HDR h;
|
||||||
|
BYTE FirstBE : 4;
|
||||||
|
BYTE LastBE : 4;
|
||||||
|
BYTE Tag;
|
||||||
|
WORD RequesterID;
|
||||||
|
DWORD AddressHigh;
|
||||||
|
DWORD AddressLow;
|
||||||
|
} TLP_HDR_MRdWr64, *PTLP_HDR_MRdWr64;
|
||||||
|
|
||||||
|
int pfnFT_WritePipe(PBYTE pb, DWORD cb) {
|
||||||
|
printf("writepipe: %d bytes\n", cb);
|
||||||
|
|
||||||
|
for (int i = 0; i < cb; i++) {
|
||||||
|
printf("%d, ", (int)pb[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DeviceFPGA_TxTlp(PBYTE pbTlp, DWORD cbTlp, BOOL fRdKeepalive, BOOL fFlush)
|
||||||
|
{
|
||||||
|
PBYTE txbuf_pb = (PBYTE)malloc(0x1000 * 32);
|
||||||
|
DWORD txbuf_cb = 0;
|
||||||
|
|
||||||
|
DWORD status;
|
||||||
|
PBYTE pbTx;
|
||||||
|
QWORD i;
|
||||||
|
DWORD cbTx, cbTxed = 0;
|
||||||
|
if(cbTlp & 0x3) { return FALSE; }
|
||||||
|
if(cbTlp > 4 * 4 + 128) { return FALSE; }
|
||||||
|
if(cbTlp && (txbuf_cb + (cbTlp << 1) + (fFlush ? 8 : 0) >= MAX_SIZE_TX)) {
|
||||||
|
if(!DeviceFPGA_TxTlp(NULL, 0, FALSE, TRUE)) { return FALSE; }
|
||||||
|
}
|
||||||
|
//if(ctxLC->fPrintf[LC_PRINTF_VVV]) {
|
||||||
|
// TLP_Print(ctxLC, pbTlp, cbTlp, TRUE);
|
||||||
|
//}
|
||||||
|
// prepare transmit buffer
|
||||||
|
pbTx = txbuf_pb + txbuf_cb;
|
||||||
|
cbTx = 2 * cbTlp;
|
||||||
|
for(i = 0; i < cbTlp; i += 4) {
|
||||||
|
*(PDWORD)(pbTx + (i << 1)) = *(PDWORD)(pbTlp + i);
|
||||||
|
*(PDWORD)(pbTx + ((i << 1) + 4)) = 0x77000000; // TX TLP
|
||||||
|
}
|
||||||
|
if(cbTlp) {
|
||||||
|
*(PDWORD)(pbTx + ((i << 1) - 4)) = 0x77040000; // TX TLP VALID LAST
|
||||||
|
}
|
||||||
|
if(fRdKeepalive) {
|
||||||
|
cbTx += 8;
|
||||||
|
*(PDWORD)(pbTx + (i << 1)) = 0xffeeddcc;
|
||||||
|
*(PDWORD)(pbTx + ((i << 1) + 4)) = 0x77020000; // LOOPBACK TX
|
||||||
|
}
|
||||||
|
txbuf_cb += cbTx;
|
||||||
|
// transmit
|
||||||
|
if((txbuf_cb >= MAX_SIZE_TX) || (fFlush && txbuf_cb)) {
|
||||||
|
status = pfnFT_WritePipe(txbuf_pb, txbuf_cb);
|
||||||
|
if(status == 0x20) {
|
||||||
|
//DeviceFPGA_ReInitializeFTDI(ctx); // try recovery if possible.
|
||||||
|
status = pfnFT_WritePipe(txbuf_pb, txbuf_cb);
|
||||||
|
}
|
||||||
|
txbuf_cb = 0;
|
||||||
|
//usleep(ctx->perf.DELAY_WRITE);
|
||||||
|
return (0 == status);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
DWORD tx[4] = { 0 };
|
||||||
|
PBYTE txb = (PBYTE)tx;
|
||||||
|
PTLP_HDR_MRdWr64 hdrRd64 = (PTLP_HDR_MRdWr64)tx;
|
||||||
|
PTLP_HDR_MRdWr32 hdrRd32 = (PTLP_HDR_MRdWr32)tx;
|
||||||
|
|
||||||
|
printf("stuff: 0x%x\n", (WORD)(0x123 >> 2));
|
||||||
|
/*
|
||||||
|
hdrRd32->h.TypeFmt = TLP_MRd64;
|
||||||
|
hdrRd32->h.Length = (WORD)(0x123 >> 2);
|
||||||
|
*/
|
||||||
|
hdrRd32->h.TypeFmt = TLP_MRd32;
|
||||||
|
hdrRd32->h.Length = (WORD)(0x123 >> 2);
|
||||||
|
hdrRd32->RequesterID = 17;
|
||||||
|
hdrRd32->Tag = 0x80;
|
||||||
|
hdrRd32->FirstBE = 0xf;
|
||||||
|
hdrRd32->LastBE = 0xf;
|
||||||
|
|
||||||
|
hdrRd32->Address = (DWORD)(0x6000);
|
||||||
|
//uint64_t addr = 0x100000000 + 0x6000;
|
||||||
|
//hdrRd64->AddressHigh = (DWORD)(addr >> 32);
|
||||||
|
//hdrRd64->AddressLow = (DWORD)(addr);
|
||||||
|
|
||||||
|
//printf("sizeof 32: 0x%x\n", sizeof(TLP_HDR_MRdWr32));
|
||||||
|
//printf("sizeof 64: 0x%x\n", sizeof(TLP_HDR_MRdWr64));
|
||||||
|
|
||||||
|
printf("tlp:\n");
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
printf("%d ", (int)txb[i]);
|
||||||
|
//printf("%X ", tx[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for(int j = 0; j < 4; j++) {
|
||||||
|
ENDIAN_SWAP_DWORD(tx[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceFPGA_TxTlp((PBYTE)tx, /*is32 ? 12 : 16*/ 12, FALSE, TRUE);
|
||||||
|
}
|
Loading…
Reference in New Issue