Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
67438d9
sponsorship: FTWDMA
sercanarga Jun 23, 2026
b4ab213
updated special thanks
sercanarga Jun 23, 2026
be0d31f
lint generated hdl with verilator
sercanarga Jun 25, 2026
21ff04e
updated readme
sercanarga Jun 25, 2026
600770d
feat(trace): add mmio live trace capture command
NetVar1337 Jun 25, 2026
436060d
add per-bit write-1-to-clear masks to bar model, probe, and hdl emitter
sercanarga Jun 25, 2026
20dfb52
feat(firmware): add donor capability metadata
NetVar1337 Jun 25, 2026
e80f6a3
feat(firmware): expose donor capability offsets
NetVar1337 Jun 25, 2026
26c862a
fix(vivado): detect startup failures
NetVar1337 Jun 25, 2026
5f347a2
feat(firmware): emit BAR behavior profiles
NetVar1337 Jun 25, 2026
9f04696
test(vivado): clean startup failure regression
NetVar1337 Jun 25, 2026
ec2b748
Merge remote-tracking branch 'origin/main' into pr/mmio-trace-capture2
NetVar1337 Jun 25, 2026
ca481fb
fix board source path overrides
NetVar1337 Jun 25, 2026
733deb4
fix(firmware): keep capability writemask writable
NetVar1337 Jun 25, 2026
83ce87e
feat(trace): import offline mmiotrace logs
NetVar1337 Jun 25, 2026
263b032
fix(validate): fail cfgspace coe mismatch
NetVar1337 Jun 25, 2026
2d5ede3
Merge pull request #55 from VoidChecksum/pr/mmio-trace-capture2
sercanarga Jun 25, 2026
05677a4
fix(firmware): handle nvme admin prp2 crossings
NetVar1337 Jun 25, 2026
f3e58ee
Merge pull request #57 from VoidChecksum/codex/offline-mmio-trace-import
sercanarga Jun 25, 2026
977fe95
docs(board): note source path override exclusivity
NetVar1337 Jun 25, 2026
2ae447a
Merge pull request #58 from VoidChecksum/codex/nvme-admin-prp2-main
sercanarga Jun 25, 2026
80fdd9e
Merge pull request #56 from VoidChecksum/codex/enhance-pcileechgen-wi…
sercanarga Jun 25, 2026
6b443c4
fix(firmware): restore nvme admin prp2 handling
NetVar1337 Jun 25, 2026
9931059
Merge pull request #59 from VoidChecksum/nvme-admin-prp2-restore
sercanarga Jun 25, 2026
39489dd
feat(firmware): handle nvme format io queues
NetVar1337 Jun 25, 2026
87f63b2
Merge pull request #60 from VoidChecksum/nvme-format-io-queues
sercanarga Jun 25, 2026
02c6d83
fix vivado version on readme
sercanarga Jun 27, 2026
1acf391
@kissaikoyou import .v board sources in project tcl zdma
sercanarga Jun 27, 2026
0eb3bf9
recover license env when building under sudo #63
sercanarga Jun 28, 2026
acef7de
new sponsor: sgorm0
sercanarga Jun 29, 2026
4992329
added known issues
sercanarga Jun 29, 2026
43d6159
fixed ci tests
sercanarga Jun 29, 2026
b67d3cf
Add logging, Code-10 diagnostics, emulation-gap fixes, sim harness, a…
NetVar1337 Jun 30, 2026
3031f56
Skip destructive BAR write-probing for network donors (fixes "hung on…
NetVar1337 Jun 30, 2026
3730fa1
docs: document new build flags, artifacts, sim target, and Aquantia fix
NetVar1337 Jun 30, 2026
b05c256
sim: AHCI port command engine (fixes SATA Code 10 "I/O adapter hardwa…
NetVar1337 Jun 30, 2026
995905e
ahci: generate donor ATA IDENTIFY block for SATA clones
NetVar1337 Jun 30, 2026
4227df0
Close 13 emulation gaps: NVMe backing store, xHCI ring engine, multi-…
NetVar1337 Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,31 @@ jobs:
with:
go-version-file: go.mod

- name: Run tests with coverage
run: go test -race -coverprofile=coverage.out ./...
- name: Run tests
run: go test -race ./...

- name: Get coverage percentage
id: coverage
hdl-lint:
name: HDL Lint (Verilator)
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
submodules: recursive

- name: Install Verilator
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "percentage=$COVERAGE" >> $GITHUB_OUTPUT
echo "Coverage: $COVERAGE%"
sudo apt-get update
sudo apt-get install -y verilator

- name: Update coverage badge
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: schneegans/dynamic-badges-action@v1.8.0
- name: Setup Go
uses: actions/setup-go@v6
with:
auth: ${{ secrets.GIST_SECRET }}
gistID: ${{ vars.COVERAGE_GIST_ID }}
filename: coverage.json
label: coverage
message: ${{ steps.coverage.outputs.percentage }}%
valColorRange: ${{ steps.coverage.outputs.percentage }}
maxColorRange: 100
minColorRange: 0
go-version-file: go.mod

- name: Build pcileechgen
run: make build

- name: Run HDL lint
run: make hdl-lint
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pcileech_datastore/
*.bit
*.json
!internal/board/boards.json
!testdata/donors/*.json

# Go
*.exe
Expand Down Expand Up @@ -37,4 +38,6 @@ Thumbs.db
*.log
*.str
*.xpr
.Xil/
.Xil/
# iverilog sim build artifacts
sim/build/
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ linters:
- bodyclose
- durationcheck
- errorlint
- exportloopref
- nilerr
- prealloc
- unconvert
Expand Down
69 changes: 69 additions & 0 deletions KNOWN_ISSUES
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
problem: "device data collection failed" / BAR reads all 0xFF
cause: donor is in D3 sleep, IOMMU is off, or the donor is not bound to vfio-pci.
fix: enable IOMMU in GRUB (intel_iommu=on / amd_iommu=on iommu=pt), update-grub
+ reboot, wake the device to D0, bind it to vfio-pci, turn Secure Boot off.

problem: "VFIO_GROUP_SET_CONTAINER: invalid argument"
cause: the donor shares its IOMMU group with devices still on native drivers.
fix: move the whole group to vfio-pci, or isolate the donor (ACS).

problem: PC crashes / hard reboot during build
cause: a memory conflict - usually the OS/boot drive got bound to VFIO, or a
shared group. Look for MCE / "probe failed -22" in journalctl.
fix: never bind the drive you boot from; use a separate donor; isolate the group.

problem: "card in sleep mode"
cause: runtime PM or the host driver keeps the donor in D3.
fix: disable runtime PM, keep the donor in D0, bind it to vfio-pci.

problem: Live / USB-boot Ubuntu
cause: live-USB + VFIO is unreliable.
fix: do a real install to disk.

problem: Vivado "exit status 1" / "Invalid XML token"
cause: a corrupted Vivado install (device parts / XML), not the tool.
fix: reinstall Vivado cleanly; --skip-vivado proves the artifacts are fine.

problem: Vivado license lost under sudo
cause: sudo strips PATH / XILINXD_LICENSE_FILE.
fix: pass them back: sudo env PATH="$PATH" XILINXD_LICENSE_FILE="$..." \
./bin/pcileechgen build ... (latest build also recovers them itself)

problem: donor BAR > board BRAM -> [FAIL]
cause: the donor BAR is bigger than the board can emulate.
fix: pick a smaller-BAR donor or a bigger board

problem: Windows Code 10 "cannot start" (most common report)
cause: the clone loads but doesn't behave like the real device BAR0 reads FF,
MSI-X/interrupt setup fails, or device-type emulation is incomplete.
Often hidden: stale Windows device history.
fix: try a network / audio / wifi donor first (NVMe and xHCI hit Code 10 until
done); run tools/cleanup_device_history.ps1 (Admin) then reboot; Core
Isolation off; correct BIOS.

problem: stale device metadata / wrong driver after reflash
cause: Windows caches PCI device info in the registry.
fix: run the bundled cleanup_device_history utility, reboot, reconnect.

problem: yellow triangle / device not recognized after flash
cause: a partial flash image, or the device needs repo enhancements.
fix: rewrite the firmware with a working flasher; get a steady green light first.

problem: lone-dma-test shows BAD DTB / can't find ntoskrnl
cause: usually BIOS / Windows DMA settings, not the firmware.
fix: recheck BIOS + Windows settings; compare to a known-good firmware.

Note (not a bug): NVMe full disk emulation is still in progress.
The admin queue, init, and IO submission/completion queues work, but there is no
backing store yet (IO reads return zeros, writes are discarded), so NVMe donors
commonly hit Code 10 / stornvme Event 11 until a sector cache is added.

problem: NIC "hangs on BAR" during data collection (e.g. Aquantia 10GbE)
cause: BAR profiling write-probes live device registers to map RW/W1C bits;
firmware-mailbox NICs deadlock and the next MMIO read hangs the CPU.
fix: fixed - network-class donors are no longer write-probed. For any other
card that hangs on BAR, collect read-only with: build --probe-bars=false

Note (not a bug): xHCI (USB) emulation is partial.
Clones enumerate, but host read/write + doorbell gaps remain, so USBXHCI often
hits Code 10 (e.g. VIA VL805). Targeted this cycle.
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build test lint clean install
.PHONY: build test lint clean install fixtures hdl-lint sim

BINARY_NAME=pcileechgen
BUILD_DIR=bin
Expand Down Expand Up @@ -31,6 +31,19 @@ clean:
rm -rf $(BUILD_DIR)
rm -f coverage.out coverage.html

# generate synthetic donor fixture jsons
fixtures: build
$(BUILD_DIR)/$(BINARY_NAME) fixtures --out testdata/donors

sim:
@command -v iverilog >/dev/null 2>&1 || { echo "iverilog not installed (apt-get install iverilog)"; exit 1; }
./sim/run.sh

# lint generated sv with verilator
hdl-lint: build
@command -v verilator >/dev/null 2>&1 || { echo "verilator not installed; see Makefile"; exit 1; }
./scripts/hdl-lint.sh

# Install binary to GOPATH/bin
install:
$(GO) install $(GOFLAGS) -ldflags "$(LDFLAGS)" ./cmd/pcileechgen/
Expand Down
47 changes: 35 additions & 12 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Custom firmware generator for PCILeech FPGA boards. Reads a real PCI/PCIe
donor device through VFIO, clones its identity (config space, BARs,
capabilities), and builds a ready-to-flash .bin bitstream via Vivado.

Help / Discord: https://discord.gg/kcWVCAhNSg
Discord Community: https://discord.gg/kcWVCAhNSg

******************************************************************************
* WARNING: FOR EDUCATIONAL AND RESEARCH USE ONLY *
Expand All @@ -16,11 +16,25 @@ Help / Discord: https://discord.gg/kcWVCAhNSg
******************************************************************************


SPECIAL THANKS
--------------
FTWDMA Sponsorship
https://ftwdma.com
sgorm0 Sponsorship
https://github.com/sgorm0
TrueTuring Sponsorship, NVMe and xHCI fixes
https://github.com/TrueTuring
CaptainDMA Sponsorship
https://captaindma.com
pcileech-fpga The FPGA framework this project builds upon
https://github.com/ufrisk/pcileech-fpga


PREREQUISITES
-------------
- Go 1.26+
- Linux with IOMMU/VFIO enabled
- Vivado 2023.2+ (for synthesis)
- Vivado 2023.2 (for synthesis)

VFIO needs IOMMU enabled in BIOS and in the kernel parameters
(intel_iommu=on or amd_iommu=on).
Expand Down Expand Up @@ -60,6 +74,7 @@ COMMANDS
build generate firmware artifacts (+ Vivado)
validate verify artifacts match the donor context
verify-manifest check SHA256 integrity of build output
mmio-trace capture live or import saved BAR MMIO access traces
boards list supported FPGA boards
version print version

Expand All @@ -70,6 +85,20 @@ COMMANDS
--force allow donor BAR > board BRAM (may truncate)
--from-json <f> offline build from saved device_context.json
--output <dir> output directory (default: pcileech_datastore)
--mmio-trace <f> shape TLP latency emulation from a saved donor MMIO trace
--ila insert a Vivado ILA debug core (probes BAR/TLP/interrupt)
--ila-depth <n> ILA capture depth in samples (default 1024)
--probe-bars write-probe BAR registers (default on; auto-skipped for
network cards; set --probe-bars=false if a donor hangs)

Global flags (all commands):
--log-level <lvl> debug|info|warn|error (default info)
--log-file <f> tee the full pre/mid/post-generation run to a file
--json-logs structured JSON logs

Offline MMIO trace import:
pcileechgen mmio-trace --trace-file mmiotrace.txt --bar-base 0xf7800000 \
--bar-index 2 --bar-size 4096 --class-code 0x010802 --json


FEATURES
Expand Down Expand Up @@ -137,6 +166,7 @@ OUTPUT
device_context.json donor snapshot
pcileech_cfgspace.coe 4KB scrubbed config space
pcileech_cfgspace_writemask.coe per-register write masks
pcileech_cfgspace_w1cmask.coe per-bit write-1-to-clear mask
pcileech_bar_zero4k.coe BAR0 content (sized to donor/BRAM)
pcileech_bar_impl_device.sv register-level BAR implementation
pcileech_tlps128_bar_controller.sv TLP BAR controller
Expand All @@ -150,6 +180,8 @@ OUTPUT
identify_init.hex NVMe Identify ROM (if NVMe)
vivado_generate_project.tcl project creation
vivado_build.tcl synthesis script
code10_report.txt Code-10 risk summary for this build
ila_debug.txt ILA JTAG capture workflow (if --ila)
build_manifest.json checksums + metadata
src/ patched board SV sources
*.bin bitstream (after Vivado)
Expand All @@ -161,6 +193,7 @@ DEVELOPMENT
make test-coverage tests with coverage report
make lint run linter
make check vet + lint + test
make sim unit-simulate the behavioral RTL modules (needs iverilog)


UTILITIES
Expand Down Expand Up @@ -190,16 +223,6 @@ Windows device-history cleanup
the device.


SPECIAL THANKS
--------------
TrueTuring sponsorship, NVMe and xHCI fixes
https://github.com/TrueTuring
pcileech-fpga the FPGA framework this project builds upon
https://github.com/ufrisk/pcileech-fpga
CaptainDMA for best FPGA DMA hardware
https://captaindma.com


LICENSE
-------
Creative Commons Zero v1.0 Universal (CC0-1.0)
Expand Down
Loading