You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
memflow-pcileech/c-shell

169 lines
4.2 KiB
Plaintext

// 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);
}