Custom Firmware Development Guide for PCIe Endpoint Modeling
Shout out to the legend that donated, I will be in contact soon. I’m gonna put your name here if you want just DM me.
Trying to organize this into a wiki but honestly I can barely organize my own life right now so the wiki’s coming along like everything else – slowly and in between crisis moments. Help is welcome.
📌 DMA Threat Landscape 2024-2026:
Simple VID/DID spoofing on stock PCILeech firmware is no longer sufficient. Detection has evolved significantly. Swapping two hex values in Verilog and hoping for the best is not a strategy.
Fact tier – confirmed: The pre-boot DMA CVEs are real: CVE-2025-11901 (ASUS), CVE-2025-14302 (Gigabyte), CVE-2025-14303 (MSI), CVE-2025-14304 (ASRock), tracked as VU#382314 by CERT/CC. Affected UEFI firmware misreported IOMMU as active while hardware was NOT initialized during early boot. Riot’s security team discovered this. Vanguard reportedly blocks game launch on unpatched boards (VAN:Restriction).
Fact tier – observed/inferred: IOMMU is required for FACEIT (confirmed 2025) and EAC competitive Fortnite (since Feb 2026). For Vanguard, Riot’s June 2026 docs state IOMMU is required only for the optional Pre-Check/on-demand mode, not for the mandatory traditional driver. Community reports indicate anti-cheat kernels inspect PCIe config space for known signatures; specific offsets and signature content are not publicly documented. Honeypot memory regions are technically possible as a detection strategy but the observation mechanism varies by platform.
Fact tier – speculative/unconfirmed: In May 2026 Riot claimed Vanguard can interfere with unauthorized DMA hardware. The mechanism is not publicly documented; host-side software cannot generically reconfigure arbitrary FPGA endpoints without an endpoint-specific control surface. Treat as unverified.
Build and test on DEDICATED ISOLATED HARDWARE. See §19.
A Note from the Author:
This is probably the last major version. I might do a stripped-down one for people who already understand hardware – if you know what an FTDI chip does, I don’t need to explain UART to you. This information needed to exist and nobody else was going to write it, so here it is. If it helped you and you’re in a position to help back, that would mean something. If not, I get it.
This guide exists because real firmware development knowledge was scattered across forum threads, Discord servers that disappeared, pastebins that 404’d overnight, and gatekeepers who treated basic Verilog like state secrets. I’ve tried to put all of this together in one place – the PCIe architecture, the Vivado workflow, the config space model, the TLP handling, the detection landscape, the shadow config technique, the whole thing from silicon to software. Knowledge doesn’t expire. Understanding how the silicon works doesn’t get patched out in an update.
In Memoriam

This guide is dedicated to Ross Freeman (1947-1989). Co-founder of Xilinx. Father of the FPGA. Dead at 44. This man invented a category of computing hardware that now runs AI accelerators, high-frequency trading systems, military radar, 5G infrastructure, and the Artix-7 chip in your FPGA card. All of it traces back to Ross Freeman in 1984 asking “what if the hardware could be reconfigured after manufacturing?” while the entire semiconductor industry told him he was crazy. At the time the whole race was toward smaller, faster, fixed-function ASICs, and this guy said: what if it could CHANGE? What if you could REWIRE it? They laughed at him. He was right. He got patent #4,870,302 and then died at 44 before he saw any of it. Posthumous National Inventors Hall of Fame induction in 2009. Ross Freeman gave the world programmable silicon.
“The ultimate goal of the FPGA was to make programmable logic devices that could replace standard digital chips.” – Ross Freeman
Also for Terrence Andrew Davis (1969-2018). TempleOS. Wrote his own kernel, his own compiler, his own editor, his own graphics stack, his own programming language called HolyC – one man, 100,000+ lines of code, while battling severe mental illness that made his hands shake so badly he could barely type.
Terry understood something the entire software industry forgot: COMPLEXITY IS A COPE. It’s what mediocre people do to make you think they’re smart – they build things so complicated and abstract and overengineered that you can’t understand them, so you assume genius. Academic journals do this. Xilinx does this. Vivado is FIFTY GIGABYTES of software for an IDE that programs an FPGA chip. FIFTY. Terry’s ENTIRE operating system – kernel, compiler, editor, games, graphics, networking stack – was measured in MEGABYTES. He compiled his whole OS faster than Vivado can synthesize a basic PCIe core on a 16-core workstation. His computer from 2005 built an operating system in less time than your Ryzen 9 takes to generate a bitstream for a 35T Artix-7. You tell me who the madman is.
Terry passed away in August 2018 at age 48. He was homeless, living in a van. Fans brought him food and supplies, but he refused housing because Terry didn’t want your house – he wanted you to understand TempleOS. And nobody did. Not while he was alive. That’s the pattern – Ross Freeman gets the plaque after he’s dead, Terry Davis gets the “actually he was a genius” articles after he’s dead, and the living people building things right now are struggling and nobody notices until you’re gone. I’m not Ross Freeman and I’m not Terry Davis, but I understand them. I understand building something while everything collapses. I understand doing the work anyway.
“An idiot admires complexity, a genius admires simplicity.” – Terry A. Davis
“What people are going to read is, ‘It’s about a pathetic schizophrenic who made a crappy operating system.’ My perspective is, ‘God said I made His temple.’” – Terry A. Davis
RIP King Terry. They never figured it out.
Before you begin. You’re about to spend 40-60 hours breathing SystemVerilog, fighting Vivado’s 50 GB install, and potentially bricking your FPGA at least once. If you think you’re going to copy-paste hex values from a repo and be done by Tuesday – this isn’t that guide. Ross Freeman invented the FPGA in 1984. He’s been dead nearly 40 years. You’re standing on a dead genius’s shoulders. The minimum respect is learning how the silicon actually works.
Table of Contents
Part 1: The Silicon Doesn’t Care About Your Feelings
- Introduction
- Key Definitions
- Device Compatibility
- Requirements
- Gathering Donor Device Information
- Initial Firmware Customization
- Vivado Project Setup and Customization
Part 2: Your Device’s Passport, and Why a Forged One Is Not a Personality
- Advanced Firmware Customization
- Emulating Device-Specific Capabilities
- Completions: Where Bad Tags Go to Die
Part 3: Prove It Works Before You Call It Firmware
- Building, Flashing, and Testing
- The ILA: Vivado’s Tiny Black Box Recorder
- Troubleshooting: When the Host Calls Your Device an Unknown Piece of Garbage
- Timing, CDC, and Other Ways to Lose Your Weekend
- Best Practices for Firmware Development
- Additional Resources
- Contact Information
- Support and Contributions
- DMA Advances & State of the Art (2024-2026)
Part 1: The Silicon Doesn’t Care About Your Feelings
1. Introduction
1.1 Purpose of the Guide
The overarching goal of this guide is to empower you with the knowledge and practical skills to develop custom Direct Memory Access (DMA) firmware for Field-Programmable Gate Array (FPGA)-based devices. This specialized firmware allows your FPGA to accurately emulate the identity and behavior of other PCIe (Peripheral Component Interconnect Express) hardware devices. Such emulation is a powerful technique with profound implications across several advanced domains:
Hardware Security Research:
- Vulnerability Discovery: By emulating a device, you can create a controlled environment to send malformed or unexpected data to host drivers, systematically fuzzing for vulnerabilities (e.g., buffer overflows, race conditions) that might be exploitable from a hardware peripheral.
- Driver Analysis: Observe how operating systems and specific drivers interact with hardware. You can emulate devices with non-standard configurations or undocumented features to understand driver behavior, identify security assumptions, or reverse-engineer proprietary protocols.
- Side-Channel Analysis: While more complex, an emulated device could potentially be programmed to assist in experiments related to information leakage through timing or power analysis, by precisely controlling peripheral operations.
Red Teaming & Penetration Testing:
- Bypassing Security Measures: Emulate a seemingly benign or whitelisted hardware device (e.g., a common NIC or storage controller) to gain DMA privileges. Once achieved, this allows direct interaction with system memory, potentially bypassing endpoint detection and response (EDR) systems or anti-malware solutions that operate at higher software layers.
- Stealthy Persistence: An emulated malicious device could offer a covert way to maintain access to a compromised system, as it might be harder to detect than software-based implants.
- Exploiting Trust Relationships: Systems often have implicit trust in connected hardware. Custom firmware can exploit this by mimicking devices that are granted specific permissions or access.
System Debugging & Diagnostics:
- Reproducible Testbeds: Create highly specific hardware scenarios to reliably reproduce elusive bugs that may only occur with particular device states or data patterns.
- Fault Injection: Intentionally emulate faulty device behavior (e.g., incorrect TLP formation, delayed responses) to test the robustness and error handling capabilities of the host system and its drivers.
Hardware Testing & Validation:
- Driver Development: Test new or modified drivers against an emulated hardware profile before physical prototypes are available, or to simulate a wider range of hardware variants than physically accessible.
- Compliance Testing: While not a substitute for official compliance tests, an emulated device can help pre-verify certain aspects of PCIe protocol adherence.
Legacy System Support & Interoperability:
- Emulate older, discontinued, or hard-to-source PCIe devices to keep legacy systems operational or to bridge compatibility gaps between different hardware generations.
By progressing through this guide, you will gain proficiency in:
- Meticulously extracting identifying attributes and configuration details from a physical “donor” PCIe device.
- Modifying and extending existing open-source FPGA firmware frameworks to model a subset of a PCIe endpoint’s configuration space and MMIO behavior.
- Configuring and utilizing the Xilinx Vivado FPGA development toolchain alongside Visual Studio Code.
- Developing a solid understanding of the PCIe architecture’s layered model, the mechanics of DMA data transfers, and the constraints of modeling hardware behavior in an FPGA.
What this guide does NOT deliver: This guide teaches PCIe configuration-space modeling and generic BAR-backed MMIO behavior. It does not produce a functional clone of a NIC, NVMe controller, USB host controller, Wi-Fi adapter, or any other complex device. Real devices have proprietary register semantics, DMA descriptor engines, firmware protocols, radio/PHY/media behavior, and driver contracts that static config-space replication cannot satisfy. A Wi-Fi identity without a radio is an identity card, not a radio. An NVMe class code without an NVMe controller behind it gets you through enumeration but not through nvme identify. Know what you’re building and what you’re not.
1.2 Target Audience
This guide is tailored for individuals who already possess a foundational to intermediate knowledge of computer systems, hardware principles, and software development. The content is technically demanding and assumes a capacity for detailed, low-level work. Specifically, it caters to:
- Firmware Developers: Engineers aiming to design or adapt firmware for FPGAs, especially for applications involving high-speed data transfer (DMA) and direct hardware interface manipulation over PCIe. A background in Verilog/VHDL and experience with FPGA development tools are highly recommended.
- Hardware Engineers: Professionals involved in the design, testing, or validation of PCIe-based hardware. This guide can help in creating sophisticated test harnesses or emulating components within a larger system design. Familiarity with PCIe protocol and digital design is expected.
- Cybersecurity Professionals & Researchers:
- Vulnerability Researchers & Exploit Developers: Those looking to explore hardware-level attack surfaces or develop proof-of-concept exploits leveraging DMA. Understanding of OS internals, memory management, and driver architecture is crucial.
- Red Team Members: Operators seeking advanced techniques for system access, persistence, and data exfiltration by leveraging direct hardware manipulation.
- Digital Forensics & Incident Responders: While this guide is offensively focused, understanding these techniques can aid in recognizing and analyzing sophisticated hardware-based attacks.
- FPGA Enthusiasts & Advanced Hobbyists: Individuals with prior FPGA project experience who are eager to tackle complex challenges like PCIe communication and hardware emulation. A willingness to dig into datasheets and technical specifications is key.
Prerequisite Knowledge (Recommended):
- Solid understanding of digital logic and computer architecture.
- Familiarity with at least one Hardware Description Language (HDL), such as Verilog or VHDL.
- Basic proficiency in a Linux environment (many tools and scripts are Linux-friendly) and familiarity with command-line interfaces.
- Experience with a C/C++ or a scripting language (like Python) for host-side interaction or test scripting.
- A conceptual understanding of operating system principles (memory management, drivers, interrupts).
- Patience and a methodical approach to debugging, as firmware development can be intricate.
The learning curve can be steep, especially if PCIe or advanced FPGA concepts are new. However, the guide aims to break down complex topics into manageable steps.
1.3 How to Use This Guide
This guide is segmented into three logically progressing parts designed to build your knowledge incrementally:
- Part 1: Foundational Concepts: This initial part is crucial. It introduces the core terminology, the underlying principles of PCIe and DMA, the necessary hardware and software stack (including setup instructions for tools like Xilinx Vivado and the PCILeech-FPGA framework), and the initial procedures for acquiring vital information from your target “donor” device and making basic firmware modifications. You should work through this part sequentially and thoroughly.
- Part 2: Intermediate Concepts and Implementation: (Forthcoming sections) Building on the foundation, this part will guide you through more advanced firmware customizations. Topics will include fine-tuning PCIe operational parameters, emulating device-specific registers and capabilities (such as power management states and Message Signaled Interrupts - MSI/MSI-X), and gaining an initial understanding of constructing and interpreting Transaction Layer Packets (TLPs).
- Part 3: Advanced Techniques and Optimization: (Forthcoming sections) The final part will explore sophisticated debugging methodologies (including the use of Integrated Logic Analyzers - ILAs and external PCIe protocol analyzers), techniques for optimizing firmware performance and emulation accuracy, comprehensive troubleshooting for common and complex issues, and a critical discussion on best practices, particularly focusing on the security implications of developing and deploying emulated PCIe devices.
Working Through the Guide:
- Sequential Progression: Especially for Parts 1 and 2, follow the sections in order, as later concepts build upon earlier ones.
- Hands-On Practice: This is a practical guide. Actively perform the setup steps, code modifications, and experiments on your own hardware.
- Adapt to Your Environment: File paths, specific device IDs, and software versions may vary. Understand the concepts behind the instructions to adapt them to your particular setup.
- Consult External Resources: The PCIe specification and FPGA documentation are your ultimate references. This guide simplifies and directs, but deep dives often require consulting primary sources.
- Iterative Development: Firmware development is rarely linear. Expect to iterate, debug, and refine your designs. Use the troubleshooting sections and debugging techniques extensively.
You will be working with HDLs (SystemVerilog in PCILeech-FPGA), FPGA synthesis and implementation tools (Vivado), and potentially host-side programming tools and PCIe analysis utilities.
2. Key Definitions
A solid grasp of the following terminology is essential for navigating the complexities of PCIe device emulation and custom firmware development. These terms will be used extensively throughout the guide.
-
DMA (Direct Memory Access):
- Definition: A fundamental feature of modern computer architectures that allows hardware peripherals (like network cards, GPUs, or your FPGA-based emulated device) to read from and write to the main system memory (RAM) directly, without involving the Central Processing Unit (CPU) for every byte transferred.
- Significance: DMA is crucial for high-performance I/O operations. By offloading data transfer tasks from the CPU, it frees up the CPU to perform other computations, significantly improving overall system throughput and efficiency. For this guide, your FPGA will leverage DMA to interact with the host system’s memory, which is a powerful capability.
-
PCIe (Peripheral Component Interconnect Express):
- Definition: A high-speed serial computer expansion bus standard designed to replace older bus standards like PCI, PCI-X, and AGP. It uses a point-to-point topology, with separate serial links connecting each device to the root complex (typically part of the chipset or CPU). Communication occurs via packets.
- Significance: PCIe is the dominant standard for connecting high-performance peripherals to motherboards. Understanding its protocol, layered architecture (Physical Layer, Data Link Layer, Transaction Layer), and configuration mechanisms is paramount for emulating any modern hardware device.
-
TLP (Transaction Layer Packet):
- Definition: The fundamental unit of data exchange at the Transaction Layer of the PCIe protocol. TLPs are responsible for conveying requests (e.g., memory read/write, I/O read/write, configuration read/write) and completions (responses to requests) between PCIe devices. Each TLP consists of a header, an optional data payload, and an optional End-to-End CRC (ECRC).
- Significance: To emulate a device accurately, your FPGA firmware must be capable of correctly forming, transmitting, receiving, and interpreting TLPs that match the behavior of the donor device. Understanding TLP types, formats, and flow control is critical for advanced emulation.
-
BAR (Base Address Register):
- Definition: Located within a PCIe device’s Configuration Space, BARs are special registers used by the device to request address space resources from the host system. A device can have up to six 32-bit BARs (or fewer, or pairs of 32-bit BARs can form 64-bit BARs). These registers define the starting addresses and sizes of memory-mapped I/O (MMIO) regions or I/O port regions that the device uses to expose its registers and internal memory to the host CPU.
- Significance: When the host system enumerates a PCIe device, it reads the BARs to determine the device’s memory and I/O requirements, then allocates and programs these BARs with the actual base addresses in the system’s physical address map. Your emulated device must accurately define its BARs to match the donor device so that the host OS and drivers can interact with it correctly.
-
FPGA (Field-Programmable Gate Array):
- Definition: An integrated circuit (IC) that can be configured by a designer or customer after manufacturing – hence “field-programmable.” FPGAs contain an array of programmable logic blocks and a hierarchy of reconfigurable interconnects that allow the blocks to be “wired together” to implement custom digital logic circuits.
- Significance: FPGAs are the core hardware used in this guide. Their reconfigurable nature makes them ideal for emulating other hardware devices, as you can define the precise logic and interfaces required to mimic the donor device’s PCIe presence and behavior.
-
MSI/MSI-X (Message Signaled Interrupts / Message Signaled Interrupts Extended):
- Definition: Mechanisms that allow a PCIe device to deliver interrupts to the CPU by writing a special message (a TLP, specifically a Memory Write TLP) to a system-defined memory address, rather than using dedicated physical interrupt lines (as in legacy PCI). MSI-X is an enhancement of MSI, offering more interrupt vectors and greater flexibility.
- Significance: Most modern PCIe devices use MSI or MSI-X for more efficient and flexible interrupt handling. Accurate emulation often requires implementing the chosen interrupt mechanism of the donor device, including configuring the MSI/MSI-X capability structures and generating interrupt messages correctly.
-
DSN (Device Serial Number):
- Definition: A 64-bit globally unique identifier that can be optionally implemented by a PCIe device. If present, it’s typically located in an extended capability structure within the device’s Configuration Space.
- Significance: While not all devices have a DSN, some drivers or management software might use it for unique identification, licensing, or tracking purposes. Emulating it correctly can be important for full transparency and avoiding detection of the emulated device.
-
PCIe Configuration Space:
- Definition: A standardized 256-byte (for Type 0, endpoint devices) or 4KB address region associated with each PCIe function (a device can have multiple functions). This space contains vital information about the device, including its Vendor ID, Device ID, Class Code, Revision ID, BARs, capability pointers, and various status and control registers. It is accessed by the host system using special Configuration Read and Configuration Write TLPs.
- Significance: The Configuration Space is the “identity card” of a PCIe device. The very first step in device emulation is to meticulously replicate the relevant parts of the donor device’s Configuration Space in your FPGA firmware. The host system uses this information to identify, configure, and allocate resources to the device.
-
Donor Device:
- Definition: The physical PCIe hardware device whose identity and behavior you aim to emulate on your FPGA. This device serves as the source for extracting configuration details (Vendor ID, Device ID, BAR settings, capabilities, etc.) and behavioral patterns.
- Significance: The fidelity of your emulation directly depends on how accurately and completely you can gather and replicate the characteristics of the donor device.
-
Root Complex (RC):
- Definition: The entity in a PCIe hierarchy that connects the CPU and memory subsystem to the PCIe fabric. It generates PCIe transactions on behalf of the CPU and processes transactions initiated by downstream PCIe devices. It also performs the initial bus enumeration and configuration.
- Significance: Your emulated device will primarily interact with the Root Complex (or switches connected to it) when communicating with the host system.
-
Endpoint (EP):
- Definition: A type of PCIe device that resides at the periphery of the PCIe fabric, consuming or producing data. Examples include network cards, graphics cards, storage controllers, and the FPGA device you will be programming. Endpoints request resources and initiate transactions to the Root Complex.
- Significance: In this guide, your FPGA will be programmed to act as an Endpoint device, emulating a specific donor Endpoint.
-
HDL (Hardware Description Language):
- Definition: A specialized computer language used to describe the structure, design, and operation of electronic circuits, particularly digital logic circuits. Common HDLs include Verilog and VHDL.
- Significance: You will be working with Verilog (specifically SystemVerilog, an extension of Verilog) within the PCILeech-FPGA project to define the custom logic for your emulated device.
-
Bitstream:
- Definition: The final configuration file that is loaded onto an FPGA to program its logic blocks and interconnects, thereby implementing your custom hardware design. It’s the compiled output from the FPGA development tools (like Xilinx Vivado).
- Significance: Generating and flashing the correct bitstream is the ultimate step in deploying your custom firmware onto the FPGA.
-
IOMMU (Input-Output Memory Management Unit) – Intel VT-d / AMD-Vi:
- Definition: A hardware unit that provides address translation and access control for DMA-capable devices, analogous to how a CPU’s MMU protects process memory. Each PCIe device can be assigned a set of page tables (a domain) limiting which physical addresses it can read or write.
- Significance: When IOMMU is enabled and properly configured, a DMA device cannot access arbitrary system memory – it can only reach addresses mapped in its domain. A device hitting an unmapped address generates a translation fault. This is the primary hardware defense against unauthorized DMA. FACEIT and EAC competitive modes require IOMMU to be enabled. Vanguard’s optional Pre-Check mode requires it.
-
ACS (Access Control Services):
- Definition: A PCIe capability that controls peer-to-peer routing between devices. ACS can block downstream devices from sending TLPs directly to each other, forcing all traffic through the root complex.
- Significance: DMA cards connected via Thunderbolt or behind a PCIe switch need ACS enforcement to prevent peer-to-peer DMA bypass of IOMMU. FACEIT’s IOMMU requirement typically also requires ACS to be enabled and enforced.
-
VFIO (Virtual Function I/O):
- Definition: A Linux kernel framework that exposes direct device access to userspace through IOMMU-protected memory mappings. Used by QEMU/KVM for device passthrough to virtual machines.
- Significance: VFIO is the Linux mechanism for attaching an IOMMU domain to a device. When you see “IOMMU groups” in
lspci -vvv, what you’re seeing is the VFIO grouping. Automated firmware generation tools use VFIO to dump donor device config space from userspace without a kernel driver.
-
TOCTOU (Time-of-Check, Time-of-Use):
- Definition: A class of race condition where a value is validated (“check”) and then used (“use”) with a gap between the two operations allowing the value to change. In DMA contexts, TOCTOU attacks exploit the window between when a hypervisor or IOMMU validates a DMA buffer and when the device actually reads/writes it.
- Significance: Modern DMA defense research (DMAArmor, Deferred DMA Attack) focuses on eliminating TOCTOU windows in DMA buffer lifetime management. A device that passes validation for a read to address X, then has its mapping revoked before the actual TLP arrives, creates a TOCTOU vulnerability.
-
VMD (Volume Management Device):
- Definition: An Intel chipset feature that presents NVMe SSDs behind a PCIe bridge called a VMD controller. The OS sees the VMD controller rather than the individual NVMe devices behind it.
- Significance: A DMA firmware trick circa 2024-2025 was to present as an NVMe device hidden behind Intel VMD, hoping anti-cheat would only enumerate the VMD controller and not drill down. Vanguard now enumerates through VMD (confirmed May 2025). Do not rely on VMD as a hiding mechanism.
3. Device Compatibility
Achieving successful and accurate PCIe device emulation hinges on ensuring your chosen FPGA-based hardware and host system configuration are fully compatible. This section details the supported FPGA platforms, critical PCIe hardware considerations, and the necessary system requirements to set up your development environment.
3.1 Supported FPGA-Based Hardware
While this guide provides a generic methodology adaptable to various FPGA-based DMA hardware, our primary examples and specific instructions will focus on Xilinx 7-series FPGAs, commonly found in open-source DMA boards due to their balance of performance and accessibility.
The core principles and techniques for customizing the PCIe IP core and developing HDL code are broadly applicable to the following FPGA families:
- Squirrel / Screamer (Artix-7 35T) – entry-level, USB-C, sufficient logic for standard memory acquisition and basic emulation. Most common starting point.
- Enigma-X1 (Artix-7 75T) – mid-tier, more logic cells and BRAM for complex emulation.
- ZDMA (Artix-7 100T) – higher-performance, Thunderbolt, 1000+ MB/s, most on-chip resources in the Artix-7 line.
- Kintex-7 (K325T, K410T, etc.) – advanced tier, higher PCIe lane counts and speeds (Gen3 x8/x16), significantly more logic and DSP slices.
Newer 7-series boards that ship PCILeech-compatible firmware (2024-2026):
- CaptainDMA (35T / 75T / 100T / 4.1th / M.2) – flashes via WCH CH347 / CH347_OpenOCD over an integrated update port, no separate JTAG dongle required. The M.2 100T variant pushes ~220 MB/s over USB-C.
- Screamer / Squirrel (35T) – the original workhorse boards. USB-C, ~190 MB/s.
- IMMORTAL DMA (XC7A35T, USB-C) – compact Artix-7 card, ~275 MB/s.
- M.2 form factor – sits on an M.2/NGFF slot or via an M.2-to-PCIe cable. Smaller footprint than a full-height card. Available from multiple PCB vendors.
- MITM passthrough – not endpoint emulators but man-in-the-middle PCIe interposers: a real donor device is passed through and its traffic is observed/modified, giving genuine device behavior by construction because the config space bytes come from actual silicon. Build your own or don’t bother – anyone selling pre-built interposers on Discord is a scammer.
Beyond 7-series:
- Xilinx UltraScale+ (Kintex/Virtex UltraScale+) with the Gen3/Gen4 integrated block (PCIe4C/PCIE4CE, PG213) – moves you from Gen2 (7-series ceiling) to Gen3 x4/x8 and Gen4 x4/x8.
- Xilinx Versal ACAP (Prime/Premium) with the Gen4/Gen5 DMA & Bridge Subsystem (PG344) – Gen5 capability for maximum throughput.
- Wupper (Nikhef/CERN FELIX) – a proven open-source PCIe Gen3/Gen4/Gen5 DMA engine ported to Virtex-7, Kintex UltraScale, Virtex UltraScale+, and Versal; a strong base if you outgrow the PCILeech 7-series pipeline.
Important Note on FPGA Families: While the principles are similar, specific IP core configurations and clocking structures may vary slightly between different Xilinx 7-series FPGAs (Artix-7, Kintex-7, Zynq-7000 PS/PL). Always refer to the specific board’s documentation and the Xilinx PCIe IP Core user guides for your chosen FPGA family. The PCILeech-FPGA project often provides board-specific Tcl scripts and source files to simplify this process.
Supported scope for this guide:
- Target hardware: Xilinx Artix-7 (35T, 75T, 100T), Kintex-7 (K325T, K410T) FPGAs using the 7-series Integrated Block for PCI Express (PG054)
- PCIe generation: Gen2 x1/x4. The 7-series hard block does not support Gen3 or higher
- Toolchain: Xilinx Vivado 2023.x or later, WebPACK edition (free)
- Config space: Conventional 256-byte configuration space (offsets 0x00-0xFF). Extended capabilities (offsets >= 0x100) are not covered by the baseline
.coe workflow
- Interface: AXI4-Stream user interface to the PCIe hard block, as generated by Vivado Tcl scripts
- Verified host platforms: 64-bit Windows 10/11, 64-bit Ubuntu 20.04/22.04 LTS
- What’s not covered: Gen3/Gen4/Gen5 (requires UltraScale+ or Versal), extended configuration space emulation, full device-class behavioral modeling (NIC DMA rings, NVMe command queues, USB transfer descriptors), radio/PHY/media-layer emulation, bitstream encryption, formal verification
⚠️ Cheap M.2-to-PCIe adapters: Those $8 adapter boards from AliExpress will destroy your hardware. They print CE, FCC, and RoHS logos on the silkscreen like it means something – it doesn’t. Nobody verified those marks. Nobody tested that board. That CE mark was applied by the same person who misspelled “PCI Express” in the listing title. The factory that assembled it doesn’t have a compliance department, doesn’t own a spectrum analyzer, and has never filed a RoHS declaration with any regulatory body. That CE-FCC-RoHS trinity printed on the solder mask is just a sticker. A prayer. A lie printed in white silkscreen on a PCB that will arc your 12V rail to ground because the trace clearance is whatever the autorouter decided looked fine on a Friday afternoon. There is no polyfuse. There is no ESD protection. There is nobody to sue when your motherboard catches fire. You saved $12 and lost a $200 board. Buy from a vendor that publishes actual schematics and lists real protection components with DigiKey part numbers. If the listing photo is an AI-upscaled render of a green rectangle with no visible component markings, close the tab. Electrical fires are not a debugging tool.
3.2 PCIe Hardware Considerations
To ensure smooth and unrestricted operation of your FPGA-based DMA device for emulation, several PCIe-specific and host system features require careful consideration and, in some cases, modification.
- IOMMU / VT-d / AMD-Vi Settings
- Recommendation: For initial setup and testing, it is highly recommended to disable IOMMU (Intel’s Virtualization Technology for Directed I/O - VT-d) or AMD’s equivalent (AMD-Vi) in your system’s BIOS/UEFI settings.
- Rationale: IOMMUs are hardware components that provide memory management units for DMA-capable devices. They perform address translation, similar to a CPU’s MMU, and can enforce memory access permissions. While crucial for security and virtualization (preventing a rogue device from accessing unauthorized memory regions), they will restrict your DMA device’s access to system memory, potentially interfering with memory acquisition and device emulation. Disabling the IOMMU allows your DMA device unrestricted access, which is often necessary for advanced emulation and security research purposes.
- Location: Typically found under “CPU Configuration,” “Virtualization,” “Advanced Settings,” or “I/O Virtualization” in your BIOS/UEFI.
- Kernel DMA Protection (Windows) / Thunderbolt Security Level (Linux)
- Recommendation (Windows): Disable Kernel DMA Protection features in modern Windows systems. This includes settings like Virtualization-Based Security (VBS) and Memory Integrity (HVCI). These features leverage the IOMMU to prevent unauthorized DMA attacks from external peripherals connected via Thunderbolt or PCIe.
- Steps (Windows):
- Access Windows Security settings: Start > Settings > Privacy & security > Windows Security > Device security.
- Under “Core isolation,” click “Core isolation details.”
- Turn off “Memory integrity.”
- You may also need to disable Secure Boot in BIOS/UEFI, as VBS often depends on it.
- Caution: Disabling these features significantly reduces your system’s security posture, making it vulnerable to various attacks, including those involving malicious DMA devices. This should only be done on a dedicated test system, not on your primary machine, and in a secure, isolated environment where you understand the risks.
- Recommendation (Linux/Thunderbolt): If using a system with Thunderbolt ports, understand and potentially adjust the Thunderbolt Security Level in your BIOS/UEFI. Lower security levels (e.g., “No Security,” “User Authorization”) are generally required for arbitrary Thunderbolt/PCIe devices to perform DMA without explicit host approval.
- PCIe Slot Requirements
- Recommendation: Use a compatible PCIe slot that physically matches the FPGA device’s requirements. Most Artix-7-based DMA cards operate at PCIe Gen2 x1 or x4.
- Rationale:
- Physical Fit: An x1 card can fit into x1, x4, x8, or x16 slots, but an x4 card requires at least an x4 slot.
- Performance: While an x4 card might work in an x1 slot (if the physical connector is open-ended or modified), it will operate at the x1 speed, severely limiting data transfer rates. For optimal performance and accurate emulation of a donor device’s capabilities, ensure the FPGA board is installed in a slot that provides at least the emulated link width and speed (e.g., if you’re emulating a Gen2 x4 device, use a Gen2 x4 slot on the host).
- Motherboard BIOS Settings: Some motherboards allow configuration of PCIe slot speeds (e.g., forcing Gen1 or Gen2). Ensure these settings do not conflict with your desired emulation speed.
3.3 System Requirements
Setting up a robust development environment is key for efficient firmware development, synthesis, and debugging.
- Host System
- Processor: A modern multi-core CPU is essential for running FPGA development tools like Vivado, which are computationally intensive during synthesis and implementation. (e.g., Intel Core i5/i7/i9 or AMD Ryzen 5/7/9 equivalent, 8th generation or newer recommended).
- Memory (RAM): Minimum 16 GB RAM is strongly recommended; 32 GB or more is ideal for complex FPGA designs, as Vivado can consume significant memory, especially during implementation.
- Storage: A Solid-State Drive (SSD) with at least 200 GB of free space is crucial. FPGA tool installations (Vivado alone can be 50+ GB), project files, and synthesis/implementation outputs can quickly consume disk space. The speed of an SSD dramatically reduces build times.
- Operating System:
- Windows 10/11 (64-bit Professional or Enterprise edition): Widely supported by Xilinx Vivado and many hardware debugging tools. Remember the Kernel DMA Protection considerations.
- Compatible Linux Distribution (64-bit): Ubuntu LTS (Long Term Support) releases (e.g., 20.04, 22.04) are commonly used and well-supported for Vivado. Linux often provides a more flexible environment for scripting and low-level PCIe interaction tools.
- Peripheral Devices
- JTAG Programmer: Absolutely necessary for flashing the compiled bitstream onto your FPGA-based DMA card. Examples include Xilinx Platform Cable USB II, Digilent JTAG-HS3, or integrated JTAG programmers found on some development boards. Ensure it’s compatible with your FPGA board and Vivado.
- PCIe Slot: As discussed in Section 3.2, ensure your host system has an available and compatible PCIe slot for your DMA card.
- USB Port: For connecting the JTAG programmer and potentially for a UART/serial console to your FPGA board for debug output.
4. Requirements
This section outlines the essential hardware and software components, along with the recommended environment setup, necessary to embark on custom firmware development for PCIe device emulation. Having these prerequisites in place before you begin will streamline your development process.
4.1 Hardware
- Donor PCIe Device
- Purpose: This is the physical hardware device whose configuration and behavior you intend to emulate on your FPGA. It serves as the authoritative source for critical identification details, register values, and operational characteristics.
- Examples: Common examples include a standard Network Interface Card (NIC), a SATA or NVMe storage controller, a USB controller, or any other generic PCIe expansion card that you can safely remove from a system for analysis. It is highly recommended to use a device that is not essential for the system’s operation, as you will be inspecting its low-level configuration.
- DMA FPGA Card
- Description: An FPGA-based development board specifically designed or adapted to perform Direct Memory Access (DMA) operations over a PCIe interface. This is the platform onto which your custom firmware will be loaded.
- Examples: As detailed in Section 3.1, compatible cards include the Squirrel (Artix-7 35T), Enigma-X1 (Artix-7 75T), ZDMA (Artix-7 100T), or various Kintex-7 based solutions. Ensure your chosen card has a PCIe edge connector.
- JTAG Programmer
- Purpose: This crucial tool facilitates the communication between your development PC and the FPGA on your DMA card. It’s used to program (flash) the compiled bitstream onto the FPGA and, importantly, for interactive debugging using tools like Vivado’s Hardware Manager and Integrated Logic Analyzer (ILA).
- Examples:
- Xilinx Platform Cable USB II: A traditional, widely compatible programmer for Xilinx FPGAs. Ensure you have the necessary drivers installed.
- Digilent JTAG-HS3 / JTAG-HS2: Popular and reliable programmers known for good Vivado integration and support. The HS3 offers faster programming speeds.
- Integrated JTAG: Some FPGA boards may have an onboard USB-to-JTAG bridge (e.g., a FTDI chip) which eliminates the need for a separate programmer. Consult your board’s documentation.
4.2 Software
- Xilinx Vivado Design Suite
- Description: The official, comprehensive FPGA development environment from Xilinx (now AMD). Vivado is essential for synthesizing your HDL code, implementing the design onto the target FPGA, generating the final bitstream, and performing hardware debugging. It includes the necessary IP cores, compilers, and utilities.
- Download: Visit the official Xilinx (AMD) downloads page: https://www.xilinx.com/support/download.html.
- Version Note: While older versions like Vivado 2020.1 might be referenced in some legacy guides, it is strongly recommended to download a recent stable version (e.g., Vivado 2023.x or later) compatible with your target FPGA family (Artix-7, Kintex-7). The PCILeech-FPGA project generally supports newer Vivado versions.
- Visual Studio Code
- Description: A highly customizable and feature-rich code editor from Microsoft. It’s an excellent choice for writing and editing your Verilog/SystemVerilog HDL code due to its extensive extension ecosystem, offering features like syntax highlighting, linting, auto-completion, and version control integration.
- Download: https://code.visualstudio.com/
- PCILeech-FPGA
- Description: An open-source framework and base code repository for FPGA-based DMA development. It provides ready-to-use PCIe IP core instantiations and a well-structured project that serves as an excellent starting point for custom firmware. This guide heavily leverages its architecture.
- Repository: https://github.com/ufrisk/pcileech-fpga
- Arbor (MindShare)
- Description: A powerful and user-friendly software tool specifically designed for in-depth scanning and analysis of PCIe devices. It provides detailed insights into the configuration space, capabilities, and registers of connected PCIe hardware, making it invaluable for gathering donor device information.
- Download: Available from the MindShare website: https://www.mindshare.com/ (You will likely need to navigate to their software section).
- Note: Typically requires account creation and may offer a time-limited trial.
- Alternative PCIe Device Analysis Tools
- Telescan PE (Teledyne LeCroy):
- OS-Native Tools (For basic checks):
- Windows Device Manager: Provides basic Vendor ID, Device ID, Subsystem ID, and Class Code information under the “Details” tab of a device’s properties.
- Linux
lspci utility: A powerful command-line tool for inspecting PCIe devices. Use lspci -nn for Vendor/Device IDs, lspci -vvv for verbose details including BARs and capabilities, and lspci -s <BUS:DEV.FUN> -xxxx for raw configuration space dumps.
4.3 Environment Setup
4.3.1 Install Vivado Without Losing Your Mind
Download the latest Vivado that supports 7-series from xilinx.com. During install, only select “7 Series” devices unless you enjoy downloading 50 GB of Kintex UltraScale+ support you will never use. Select “Design Tools” and “Programming & Debugging” components. That is it. The installer will take an hour. Go touch grass.
4.3.2 VS Code + Verilog Extension
Install VS Code, then add the “Verilog-HDL/SystemVerilog” extension (mshr-h). Syntax highlighting. Linting. Done.
4.3.3 Clone the Source
git clone https://github.com/ufrisk/pcileech-fpga.git
cd pcileech-fpga
Navigate into the board-specific subdirectory for your hardware (e.g., pcileech-squirrel-35t). The project structure from here is: src/ holds the SystemVerilog, ip/ holds .xci Xilinx IP cores, and the Vivado .tcl scripts in the board root do project generation and building.
4.3.4 Use Dedicated Hardware
Do not develop DMA firmware on your gaming PC. Do not use a VM with PCIe passthrough for your first build. Use a separate physical machine where you can disable IOMMU, Secure Boot, and any kernel DMA protection without worrying about bricking something you care about. This is not a suggestion.
Accurate device emulation hinges on meticulously extracting and replicating critical information from the donor device. This comprehensive data collection enables your FPGA to faithfully mimic the target hardware’s PCIe configuration and behavior, ensuring compatibility and functionality when interfacing with the host system.
5.1 Using Arbor for PCIe Device Scanning
Arbor (MindShare) is the tool for extracting donor device configuration space. It shows you every register, every capability, every BAR in decoded form. Alternatives: lspci -vvv on Linux, Telescan PE (Teledyne LeCroy, free with registration), or Windows Device Manager for basic VID/DID checks.
5.1.1 Install and Scan
Download Arbor from mindshare.com (requires account). Install it. Launch it. Click Local System > Scan. It enumerates every PCIe device on your bus. Find your donor by matching vendor name or VID/DID. Click it to view its full configuration space.
5.1.2 The Data You Actually Need
Extracting detailed information from the donor device is essential for accurate emulation.
Information to Extract:
- Device ID (0xXXXX): A 16-bit identifier unique to the device model.
- Vendor ID (0xYYYY): A 16-bit identifier assigned to the manufacturer.
- Subsystem ID (0xZZZZ): Identifies the specific subsystem or variant (e.g., a specific model within a product line).
- Subsystem Vendor ID (0xWWWW): Identifies the vendor of the subsystem (often the same as the main Vendor ID, but can differ for OEM versions).
- Revision ID (0xRR): Indicates the hardware revision level of the device.
- Class Code (0xCCCCCC): A 24-bit code that defines the primary function/type of device (e.g.,
0x020000 for Ethernet Controller, 0x010802 for NVMe controller). This helps the OS load generic drivers.
- Base Address Registers (BARs):
- Registers defining the memory or I/O address regions the device uses.
- Includes BAR0 through BAR5, each potentially 32 or 64 bits. For each BAR, note its Type (Memory or I/O), Bit Width (32-bit or 64-bit), Size (e.g., 256 MB, 4KB), and Prefetchable Status (Yes/No). This is crucial for memory mapping.
- Capabilities: Lists supported features and their configurations, often found in a linked list structure within the configuration space. Examples include:
- PCIe Capability Structure: PCIe Link Speed (e.g., Gen2, Gen3), Link Width (e.g., x1, x4), Max Payload Size, Max Read Request Size.
- MSI/MSI-X Capability Structure: Information on Message Signaled Interrupts, including the number of vectors supported.
- Power Management Capability Structure: Supported power states (D0, D1, D2, D3hot, D3cold).
- Device Serial Number (DSN): A 64-bit unique identifier, if the device supports it (found in the “Device Serial Number” Extended Capability). Not all devices implement this.
Steps:
- Navigate to the PCI Config Tab:
- Within the device’s detailed view, find and select the PCI Config or Configuration Space tab. This typically presents a decoded view of the raw configuration space registers.
- Record Relevant Details:
- Carefully document each of the required fields listed above.
- Use screenshots or copy the values into a text file, a dedicated spreadsheet, or a structured documentation format for accuracy.
- Ensure hexadecimal values are noted correctly, including the
0x prefix if used.
- Expand Capability Lists:
- Look for sections labeled Capabilities or Advanced Features. These are often clickable or expandable to reveal sub-sections.
- Document each capability present and its relevant parameters (e.g., MSI message control, power state flags, current/max PCIe link settings).
- Examine BARs in Detail:
- Within the Configuration Space, locate the entries for BAR0 through BAR5.
- For each active BAR, note its allocated size, whether it’s Memory-mapped or I/O, its bit width (32-bit or 64-bit), and if it’s prefetchable. This information is often presented clearly in Arbor’s GUI.
- Save the Data for Reference:
- Compile all the extracted information into a well-organized document (e.g., a Markdown file, a
.txt file, or an Excel spreadsheet).
- Label each section clearly for easy reference during firmware customization.
https://github.com/user-attachments/assets/0f192c29-d1ad-4e68-aa21-607976037218
5.2 Extracting and Recording Device Attributes
After capturing the data, it’s crucial to understand the significance of each attribute and ensure they’ve been accurately documented for successful emulation.
Ensure You Have Accurately Recorded the Following:
- Device ID:
- Purpose: Uniquely identifies the specific model of the PCIe device.
- Usage in Emulation: Essential for the host Operating System (OS) to correctly identify the emulated device and, crucially, to attempt to load the appropriate device driver.
- Vendor ID:
- Purpose: Identifies the manufacturer of the PCIe device.
- Usage in Emulation: Used in conjunction with the Device ID to form a unique identifier (
VendorID:DeviceID) that the OS uses to match the device to its corresponding driver.
- Subsystem ID and Subsystem Vendor ID:
- Purpose: These optional IDs allow for differentiation between variants of a device from the same vendor, or for OEM-specific versions where the main Vendor/Device ID might be generic.
- Usage in Emulation: Important for emulating devices with multiple configurations or those supplied by an OEM, as the driver might specifically look for these values.
- Revision ID:
- Purpose: Indicates the hardware revision level of the device.
- Usage in Emulation: Helps in identifying specific hardware versions that might require different drivers, firmware, or possess subtle behavioral differences.
- Class Code:
- Purpose: A 24-bit code that categorizes the device’s general function (e.g.,
0x020000 for an Ethernet controller, 0x010802 for an NVMe controller, 0x0C0300 for a USB host controller). It’s composed of a Base Class, Sub-Class, and Programming Interface.
- Usage in Emulation: Allows the OS to understand the device’s general function and load a generic class driver if a specific vendor driver isn’t found. This is crucial for initial device recognition.
- Base Address Registers (BARs):
- Purpose: Define the memory-mapped or I/O port address regions that the device uses for registers, internal buffers, or configuration space extensions. The host OS allocates physical addresses to these BARs during enumeration.
- Usage in Emulation: Critical for mapping the emulated device’s internal memory and registers into the host system’s address space. The size, type (Memory/I/O, 32/64-bit), and prefetchability status of each BAR must be precisely matched to the donor device.
- Capabilities:
- Purpose: Lists the advanced features the device supports, such as advanced error reporting, power management, MSI/MSI-X, PCIe Advanced Capabilities (e.g., AER, VC/PF), etc. Each capability is defined by a structure with its own registers.
- Usage in Emulation: Essential for accurately replicating how the donor device advertises its features and how the host system interacts with these features (e.g., interrupt delivery mechanisms, power state transitions, error reporting).
- Device Serial Number (DSN):
- Purpose: A unique 64-bit identifier for the device, typically an optional extended capability.
- Usage in Emulation: While optional, some drivers or management applications might specifically query and rely on the DSN for identification, licensing, or security checks. Emulating this accurately can prevent detection of your device as a generic or modified peripheral.
Best Practices for Data Collection:
- Organize the Data: Create a structured document or spreadsheet. Use clear headings and subheadings for each attribute. A template can be beneficial.
- Include Units and Formats: Always indicate units for sizes (e.g., MB, KB) and use consistent formatting for hexadecimal values (e.g.,
0x1234, 16'h1234).
- Cross-Reference with Specifications (If Possible): If available, consult the donor device’s datasheet or publicly available specifications to verify values. This can help identify any discrepancies or unusual configurations not immediately obvious from a raw scan.
- Secure the Data: Store the collected information securely. Be mindful that this data might contain proprietary or sensitive information.
- Understand “What’s Missing”: Specialized tools like Arbor are excellent, but they may not capture every single nuance of complex, highly proprietary devices (e.g., specific vendor-defined registers outside standard configuration space). For advanced emulation, you might need to combine this information with reverse engineering of the donor device’s drivers.
6. Initial Firmware Customization
With the donor device’s information meticulously documented, the next critical phase involves customizing your FPGA’s firmware to emulate the donor device accurately. This process begins by modifying key identification registers within the PCIe configuration space and ensuring that specific identifiers, like the Device Serial Number, are correctly integrated.
6.1 Modifying Configuration Space
The PCIe Configuration Space is a fundamental component that defines how the device is recognized and interacts with the host system during enumeration. Customizing this space to precisely match the donor device’s profile is absolutely essential for successful emulation, allowing the host OS to load the correct driver and interact as expected.
6.1.1 Navigate to the Configuration File
The PCIe configuration space parameters are typically defined within a specific SystemVerilog (.sv) file in the PCILeech-FPGA project. This file synthesizes into the logic that configures the PCIe IP core and exposes the device’s identity to the host.
Common Path for PCILeech-FPGA (Artix-7 based boards like Squirrel):
Locate the file responsible for configuring the PCIe parameters for your specific board. For many Artix-7 PCILeech variants, this will be:
pcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv
6.1.2 Open the File in Visual Studio Code
Editing the configuration file requires a suitable code editor that supports syntax highlighting for SystemVerilog (or Verilog), making the code easier to read and modify.
Steps:
- Launch Visual Studio Code:
- Click on the VS Code icon or find it via the Start Menu.
- Open the File:
- Use File > Open File or press
Ctrl + O (or Cmd + O on macOS).
- Navigate to the configuration file path identified in Section 6.1.1 (e.g.,
pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv).
- Select the file and click Open.
- Verify Syntax Highlighting:
- Ensure that the editor recognizes the
.sv file extension and applies proper SystemVerilog syntax highlighting. If it doesn’t, revisit Section 4.3.2 to ensure you’ve installed the recommended Verilog/SystemVerilog extensions for VS Code.
- Familiarize Yourself with the File Structure:
- Scroll through the file. You will typically find parameters defined using
localparam or reg assignments, often with comments explaining their purpose. Look for sections where standard PCIe configuration registers (Vendor ID, Device ID, etc.) are defined and assigned.
6.1.3 Modify Device ID and Vendor ID
Updating these fundamental identifiers is the most crucial step for the host system to correctly recognize the emulated device as your donor. The Operating System relies heavily on the Vendor ID and Device ID pair to identify connected hardware and load the appropriate device driver.
Steps:
- Search for
cfg_deviceid:
- Update Device ID:
- Search for
cfg_vendorid:
- Update Vendor ID:
- Ensure Correct Formatting:
- Verify that hexadecimal values are correctly prefixed with
16'h (indicating a 16-bit hexadecimal number).
- Maintain consistent indentation and commenting style for readability.
6.1.4 Modify Subsystem ID and Revision ID
These identifiers provide additional details about the device variant, specific product models, or hardware revisions. While often optional, matching them enhances the authenticity of the emulation and can be critical for drivers that perform granular checks.
Steps:
- Search for
cfg_subsysid:
- Locate the line defining
cfg_subsysid.
reg [15:0] cfg_subsysid = 16'hCCCC; // Placeholder Subsystem ID
- Update Subsystem ID:
- Search for
cfg_subsysvendorid:
- Locate the line defining
cfg_subsysvendorid.
reg [15:0] cfg_subsysvendorid = 16'hDDDD; // Placeholder Subsystem Vendor ID
- Update Subsystem Vendor ID (if applicable):
- Search for
cfg_revisionid:
- Locate the line defining
cfg_revisionid.
reg [7:0] cfg_revisionid = 8'hEE; // Placeholder Revision ID
- Update Revision ID:
6.1.5 Update Class Code
The Class Code informs the host Operating System about the device’s general type and function (e.g., network controller, storage device). This is vital for the OS to load generic class drivers, even if a specific vendor driver isn’t installed.
Steps:
- Search for
cfg_classcode:
- Locate the line defining
cfg_classcode.
reg [23:0] cfg_classcode = 24'hFFFFFF; // Default or placeholder Class Code
- Update Class Code:
- Replace
FFFFFF with the 24-bit hexadecimal Class Code you extracted from the donor device (e.g., 0x020000 for an Ethernet Controller). Remember the format: Base Class, Sub-Class, Programming Interface.
- Example:
</your_board_variant></bus:dev>
README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。
评论