Skip to content

Commit

Permalink
Version 2.3 - FPGA support.
Browse files Browse the repository at this point in the history
  • Loading branch information
ufrisk committed Oct 12, 2017
1 parent b65e2ad commit 52d2c9f
Show file tree
Hide file tree
Showing 33 changed files with 1,066 additions and 407 deletions.
2 changes: 1 addition & 1 deletion pcileech/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LOCAL_CFLAGS := -D ANDROID
LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g

LOCAL_C_INCLUDES := bionic
LOCAL_SRC_FILES:= pcileech.c oscompatibility.c device.c device3380.c device605.c executor.c extra.c help.c kmd.c memdump.c mempatch.c statistics.c tlp.c util.c vfs.c
LOCAL_SRC_FILES:= pcileech.c oscompatibility.c device.c device3380.c device605_uart.c device605_601.c executor.c extra.c help.c kmd.c memdump.c mempatch.c statistics.c tlp.c util.c vfs.c

LOCAL_MODULE := pcileech
LOCAL_SHARED_LIBRARIES += libusb1.0
Expand Down
2 changes: 1 addition & 1 deletion pcileech/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CC=gcc
CFLAGS=-I. -D LINUX -pthread `pkg-config libusb-1.0 --libs --cflags`
DEPS = pcileech.h
OBJ = pcileech oscompatibility.o pcileech.o device.o device3380.o device605.o executor.o extra.o help.o kmd.o memdump.o mempatch.o statistics.o tlp.o util.o vfs.o
OBJ = pcileech oscompatibility.o pcileech.o device.o device3380.o device605_uart.o device605_601.o executor.o extra.o help.o kmd.o memdump.o mempatch.o statistics.o tlp.o util.o vfs.o

%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
Expand Down
102 changes: 74 additions & 28 deletions pcileech/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,57 @@
//
#include "device.h"
#include "kmd.h"
#include "statistics.h"
#include "device3380.h"
#include "device605.h"
#include "device605_uart.h"
#include "device605_601.h"

BOOL DeviceReadDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _In_ QWORD flags)
{
if(flags & PCILEECH_MEM_FLAG_RETRYONFAIL) {
return DeviceReadDMA(ctx, qwAddr, pb, cb, 0) || DeviceReadDMA(ctx, qwAddr, pb, cb, 0);
}
if(PCILEECH_DEVICE_USB3380 == ctx->cfg->tpDevice) {
return Device3380_ReadDMA(ctx, qwAddr, pb, cb);
} else if(PCILEECH_DEVICE_SP605 == ctx->cfg->tpDevice) {
return Device605_ReadDMA(ctx, qwAddr, pb, cb);
return ctx->cfg->dev.pfnReadDMA ? ctx->cfg->dev.pfnReadDMA(ctx, qwAddr, pb, cb) : FALSE;
}

#define CHUNK_FAIL_DIVISOR 16
DWORD DeviceReadDMAEx_DoWork(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _Inout_opt_ PPAGE_STATISTICS pPageStat, _In_ DWORD cbMaxSizeIo)
{
DWORD cbRd, cbRdOff;
DWORD cbChunk, cChunkTotal, cChunkSuccess = 0;
DWORD i, cbSuccess = 0;
// calculate current chunk sizes
cbChunk = ~0xfff & min(cb, cbMaxSizeIo);
cbChunk = (cbChunk > 0x3000) ? cbChunk : 0x1000;
cChunkTotal = (cb / cbChunk) + ((cb % cbChunk) ? 1 : 0);
// try read memory
memset(pb, 0, cb);
for(i = 0; i < cChunkTotal; i++) {
cbRdOff = i * cbChunk;
cbRd = ((i == cChunkTotal - 1) && (cb % cbChunk)) ? (cb % cbChunk) : cbChunk; // (last chunk may be smaller)
if(DeviceReadDMA(ctx, qwAddr + cbRdOff, pb + cbRdOff, cbRd, 0)) {
cbSuccess += cbRd;
PageStatUpdate(pPageStat, qwAddr + cbRdOff + cbRd, cbRd / 0x1000, 0);
} else if(cbRd == 0x1000) {
PageStatUpdate(pPageStat, qwAddr + cbRdOff + cbRd, 0, 1);
} else {
cbSuccess += DeviceReadDMAEx_DoWork(ctx, qwAddr + cbRdOff, pb + cbRdOff, cbRd, pPageStat, cbRd / CHUNK_FAIL_DIVISOR);
}
}
return cbSuccess;
}

DWORD DeviceReadDMAEx(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _Inout_opt_ PPAGE_STATISTICS pPageStat)
{
BYTE pbWorkaround[4096];
DWORD cbWorkaround;
if(cb != 0x1000) {
return DeviceReadDMAEx_DoWork(ctx, qwAddr, pb, cb, pPageStat, (DWORD)ctx->cfg->qwMaxSizeDmaIo);
}
return FALSE;
// why is this working ??? if not here console is screwed up... (threading issue?)
cbWorkaround = DeviceReadDMAEx_DoWork(ctx, qwAddr, pbWorkaround, 0x1000, pPageStat, (DWORD)ctx->cfg->qwMaxSizeDmaIo);
memcpy(pb, pbWorkaround, 0x1000);
return cbWorkaround;
}

BOOL DeviceWriteDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE pb, _In_ DWORD cb, _In_ QWORD flags)
Expand All @@ -28,11 +65,7 @@ BOOL DeviceWriteDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE
if(flags & PCILEECH_MEM_FLAG_RETRYONFAIL) {
return DeviceWriteDMA(ctx, qwAddr, pb, cb, 0) || DeviceWriteDMA(ctx, qwAddr, pb, cb, 0);
}
if(PCILEECH_DEVICE_USB3380 == ctx->cfg->tpDevice) {
result = Device3380_WriteDMA(ctx, qwAddr, pb, cb);
} else if(PCILEECH_DEVICE_SP605 == ctx->cfg->tpDevice) {
result = Device605_WriteDMA(ctx, qwAddr, pb, cb);
}
result = ctx->cfg->dev.pfnWriteDMA ? ctx->cfg->dev.pfnWriteDMA(ctx, qwAddr, pb, cb) : FALSE;
if(!result) { return FALSE; }
if(flags & PCILEECH_MEM_FLAG_VERIFYWRITE) {
pbV = LocalAlloc(0, cb + 0x2000);
Expand All @@ -47,32 +80,43 @@ BOOL DeviceWriteDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE

BOOL DeviceProbeDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ DWORD cPages, _Out_ __bcount(cPages) PBYTE pbResultMap)
{
if(PCILEECH_DEVICE_SP605 == ctx->cfg->tpDevice) {
Device605_ProbeDMA(ctx, qwAddr, cPages, pbResultMap);
return TRUE;
}
return FALSE;
if(!ctx->cfg->dev.pfnProbeDMA) { return FALSE; }
ctx->cfg->dev.pfnProbeDMA(ctx, qwAddr, cPages, pbResultMap);
return TRUE;
}

BOOL DeviceWriteTlp(_Inout_ PPCILEECH_CONTEXT ctx, _In_ PBYTE pb, _In_ DWORD cb)
{
if(!ctx->cfg->dev.pfnWriteTlp) { return FALSE; }
return ctx->cfg->dev.pfnWriteTlp(ctx, pb, cb);
}

BOOL DeviceListenTlp(_Inout_ PPCILEECH_CONTEXT ctx, _In_ DWORD dwTime)
{
if(!ctx->cfg->dev.pfnListenTlp) { return FALSE; }
return ctx->cfg->dev.pfnListenTlp(ctx, dwTime);
}

VOID DeviceClose(_Inout_ PPCILEECH_CONTEXT ctx)
{
if(ctx->hDevice) {
if(PCILEECH_DEVICE_USB3380 == ctx->cfg->tpDevice) {
Device3380_Close(ctx);
} else if(PCILEECH_DEVICE_SP605 == ctx->cfg->tpDevice) {
Device605_Close(ctx);
}
if(ctx->hDevice && ctx->cfg->dev.pfnClose) {
ctx->cfg->dev.pfnClose(ctx);
}
}

BOOL DeviceOpen(_Inout_ PPCILEECH_CONTEXT ctx)
{
if(PCILEECH_DEVICE_USB3380 == ctx->cfg->tpDevice) {
return Device3380_Open(ctx);
} else if(PCILEECH_DEVICE_SP605 == ctx->cfg->tpDevice) {
return Device605_Open(ctx);
BOOL result = FALSE;
if(PCILEECH_DEVICE_USB3380 == ctx->cfg->dev.tp || PCILEECH_DEVICE_NA == ctx->cfg->dev.tp) {
result = Device3380_Open(ctx);
}
return FALSE;
if(PCILEECH_DEVICE_SP605_FT601 == ctx->cfg->dev.tp || PCILEECH_DEVICE_NA == ctx->cfg->dev.tp) {
result = Device605_601_Open(ctx);
}
if(PCILEECH_DEVICE_SP605_UART == ctx->cfg->dev.tp) {
result = Device605_UART_Open(ctx);
}
return result;
}

BOOL DeviceWriteMEM(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE pb, _In_ DWORD cb, _In_ QWORD flags)
Expand All @@ -88,7 +132,9 @@ BOOL DeviceReadMEM(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE
{
if(ctx->phKMD) {
return KMDReadMemory(ctx, qwAddr, pb, cb);
} else {
} else if(flags || cb == 0x1000) {
return DeviceReadDMA(ctx, qwAddr, pb, cb, flags);
} else {
return cb == DeviceReadDMAEx(ctx, qwAddr, pb, cb, NULL);
}
}
33 changes: 33 additions & 0 deletions pcileech/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef __DEVICE_H__
#define __DEVICE_H__
#include "pcileech.h"
#include "statistics.h"

#define PCILEECH_MEM_FLAG_RETRYONFAIL 0x01
#define PCILEECH_MEM_FLAG_VERIFYWRITE 0x02
Expand Down Expand Up @@ -34,6 +35,20 @@ VOID DeviceClose(_Inout_ PPCILEECH_CONTEXT ctx);
*/
BOOL DeviceReadDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _In_ QWORD flags);

/*
* Try read memory with DMA in a fairly optimal way considering device limits.
* The number of total successfully read bytes is returned. Failed reads will
* be zeroed out the he returned memory.
* -- ctx
* -- qwAddr
* -- pb
* -- cb
* -- pPageStat = optional page statistics
* -- return = the number of bytes successfully read.
*
*/
DWORD DeviceReadDMAEx(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _Inout_opt_ PPAGE_STATISTICS pPageStat);

/*
* Write data to the target system using DMA.
* -- ctx
Expand Down Expand Up @@ -82,4 +97,22 @@ BOOL DeviceWriteMEM(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE
*/
BOOL DeviceReadMEM(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb, _In_ QWORD flags);

/*
* Write PCIe Transaction Layer Packets (TLPs) to the device.
* -- ctx
* -- pb = PCIe TLP/TLPs to send.
* -- cb =
* -- return
*/
BOOL DeviceWriteTlp(_Inout_ PPCILEECH_CONTEXT ctx, _In_ PBYTE pb, _In_ DWORD cb);

/*
* Listen for incoming PCIe Transaction Layer Packets (TLPs) for a specific
* amount of time.
* -- ctx
* -- dwTime = time in ms
* -- return
*/
BOOL DeviceListenTlp(_Inout_ PPCILEECH_CONTEXT ctx, _In_ DWORD dwTime);

#endif /* __DEVICE_H__ */
44 changes: 26 additions & 18 deletions pcileech/device3380.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ BOOL Device3380_FlashEEPROM(_Inout_ PPCILEECH_CONTEXT ctx, _In_ PBYTE pbEEPROM,
VOID Action_Device3380_Flash(_Inout_ PPCILEECH_CONTEXT ctx)
{
BOOL result;
if(ctx->cfg->tpDevice != PCILEECH_DEVICE_USB3380) {
if(ctx->cfg->dev.tp != PCILEECH_DEVICE_USB3380) {
printf("Flash failed: unsupported device.\n");
return;
}
Expand All @@ -320,7 +320,7 @@ VOID Action_Device3380_Flash(_Inout_ PPCILEECH_CONTEXT ctx)
VOID Action_Device3380_8051Start(_Inout_ PPCILEECH_CONTEXT ctx)
{
BOOL result;
if(ctx->cfg->tpDevice != PCILEECH_DEVICE_USB3380) {
if(ctx->cfg->dev.tp != PCILEECH_DEVICE_USB3380) {
printf("8051 startup failed: unsupported device.\n");
return;
}
Expand All @@ -339,7 +339,7 @@ VOID Action_Device3380_8051Start(_Inout_ PPCILEECH_CONTEXT ctx)

VOID Action_Device3380_8051Stop(_Inout_ PPCILEECH_CONTEXT ctx)
{
if(ctx->cfg->tpDevice != PCILEECH_DEVICE_USB3380) {
if(ctx->cfg->dev.tp != PCILEECH_DEVICE_USB3380) {
printf("Stopping 8051 failed: unsupported device.\n");
return;
}
Expand Down Expand Up @@ -376,6 +376,18 @@ BOOL DevicePciInReadDma(_In_ PDEVICE_DATA pDeviceData, _In_ QWORD qwAddr, _Out_

BOOL Device3380_Open2(_Inout_ PPCILEECH_CONTEXT ctx);

VOID Device3380_Close(_Inout_ PPCILEECH_CONTEXT ctx)
{
PDEVICE_DATA pDeviceData = (PDEVICE_DATA)ctx->hDevice;
if(!pDeviceData) { return; }
if(!pDeviceData->HandlesOpen) { return; }
WinUsb_Free(pDeviceData->WinusbHandle);
if(pDeviceData->DeviceHandle) { CloseHandle(pDeviceData->DeviceHandle); }
pDeviceData->HandlesOpen = FALSE;
LocalFree(ctx->hDevice);
ctx->hDevice = 0;
}

BOOL Device3380_Open(_Inout_ PPCILEECH_CONTEXT ctx)
{
BOOL result;
Expand All @@ -384,7 +396,7 @@ BOOL Device3380_Open(_Inout_ PPCILEECH_CONTEXT ctx)
if(!result) { return FALSE; }
Device3380_ReadCsr((PDEVICE_DATA)ctx->hDevice, REG_USBSTAT, &dwReg, CSR_CONFIGSPACE_MEMM | CSR_BYTEALL);
if(ctx->cfg->fForceUsb2 && (dwReg & 0x0100 /* Super-Speed(USB3) */)) {
printf("Device Info: Device running at USB3 speed; downgrading to USB2 ...\n");
printf("Device Info: USB3380 running at USB3 speed; downgrading to USB2 ...\n");
dwReg = 0x04; // USB2=ENABLE, USB3=DISABLE
Device3380_WriteCsr((PDEVICE_DATA)ctx->hDevice, REG_USBCTL2, dwReg, CSR_CONFIGSPACE_MEMM | CSR_BYTE0);
Device3380_Close(ctx);
Expand All @@ -394,26 +406,22 @@ BOOL Device3380_Open(_Inout_ PPCILEECH_CONTEXT ctx)
Device3380_ReadCsr((PDEVICE_DATA)ctx->hDevice, REG_USBSTAT, &dwReg, CSR_CONFIGSPACE_MEMM | CSR_BYTEALL);
}
if(dwReg & 0xc0 /* Full-Speed(USB1)|High-Speed(USB2) */) {
printf("Device Info: Device running at USB2 speed.\n");
printf("Device Info: USB330 running at USB2 speed.\n");
} else if(ctx->cfg->fVerbose) {
printf("Device Info: Device running at USB3 speed.\n");
printf("Device Info: USB330 running at USB3 speed.\n");
}
if(ctx->cfg->fVerbose) { printf("Device Info: USB3380.\n"); }
// set callback functions and fix up config
ctx->cfg->dev.tp = PCILEECH_DEVICE_USB3380;
ctx->cfg->dev.qwMaxSizeDmaIo = 0x01000000;
ctx->cfg->dev.qwAddrMaxNative = 0x00000000ffffffff;
ctx->cfg->dev.fPartialPageReadSupported = TRUE;
ctx->cfg->dev.pfnClose = Device3380_Close;
ctx->cfg->dev.pfnReadDMA = Device3380_ReadDMA;
ctx->cfg->dev.pfnWriteDMA = Device3380_WriteDMA;
return TRUE;
}

VOID Device3380_Close(_Inout_ PPCILEECH_CONTEXT ctx)
{
PDEVICE_DATA pDeviceData = (PDEVICE_DATA)ctx->hDevice;
if(!pDeviceData) { return; }
if(!pDeviceData->HandlesOpen) { return; }
WinUsb_Free(pDeviceData->WinusbHandle);
if(pDeviceData->DeviceHandle) { CloseHandle(pDeviceData->DeviceHandle); }
pDeviceData->HandlesOpen = FALSE;
LocalFree(ctx->hDevice);
ctx->hDevice = 0;
}

#ifdef WIN32

#include <versionhelpers.h>
Expand Down
26 changes: 0 additions & 26 deletions pcileech/device3380.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,6 @@
*/
BOOL Device3380_Open(_Inout_ PPCILEECH_CONTEXT ctx);

/*
* Clean up various device related stuff and deallocate memory buffers.
* -- ctx
*/
VOID Device3380_Close(_Inout_ PPCILEECH_CONTEXT ctx);

/*
* Read data from the target system using DMA.
* -- ctx
* -- qwAddr - max supported address = 0x100000000 - cb - (32-bit address space)
* -- pb
* -- cb
* -- return
*/
BOOL Device3380_ReadDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _Out_ PBYTE pb, _In_ DWORD cb);

/*
* Write data to the target system using DMA.
* -- ctx
* -- qwAddr - max supported address = 0x100000000 - cb - (32-bit address space)
* -- pb
* -- cb
* -- return
*/
BOOL Device3380_WriteDMA(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _In_ PBYTE pb, _In_ DWORD cb);

/*
* Flash a new firmware into the onboard memory of the USB3380 card.
* This may be dangerious and the device may stop working after a reflash!
Expand Down
Loading

0 comments on commit 52d2c9f

Please sign in to comment.