Device driver

coyote_driver.h

Top-level file of the Coyote driver; entry and exit point.

Functions

static int __init coyote_init (void)

Top-level function of the Coyote driver, called when the driver is inserted. This function simply calls the pci_init() function, which is responsible for setting up the FPGA, vFPGAs, memory mappings etc. (see the documentation)

NOTE: In the past, we used to support Enzian (ECI) but it has been deprecated as of 2024. If you would like to add support for Enzian, reach out to us on GitHub or check how the code use to look before, with the diff commit being: 4555431cf251100e2f16255f7f49e9f02ddfb96d

static void __exit coyote_exit (void)

Reverse of the init function, called when the driver is removed Handles device clean-up, memory freeing etc. See the documentation in pci_dev

coyote_setup.h

Functions for initializing, setting up and freeing Coyote devices (vfpga_dev, reconfig_dev) and utility functions (set up sysfs, reading config etc.)

Functions

int read_shell_config(struct bus_driver_data *data)

Reads the synthesized shell configuration and populates fields of bus_driver_data The configuration was specifified during the hardware synthesis in CMakeLists.txt The method also prints the configuration to the kernel log; can be queryed with dmesg

int allocate_card_resources(struct bus_driver_data *data)

Allocates and initializes metadata structs used for managing card memory, if enabled.

void free_card_resources(struct bus_driver_data *data)

Releases metadata structs used for managing card memory, if enabled; opposite of allocate_card_resources.

void init_spin_locks(struct bus_driver_data *data)

Initialize general (not used by individual vFPGAs) spin locks used in Coyote; used to protect shared resources and ensure safe access.

int create_sysfs_entry(struct bus_driver_data *data)

Initialize sysfs entry for Coyote; for more details see coyote_sysfs.h.

void remove_sysfs_entry(struct bus_driver_data *data)

Removes sysfs entry for Coyote; used oly when the driver is unloaded.

int alloc_vfpga_devices(struct bus_driver_data *data, dev_t device)

Allocates and registers all the char vFPGA devices (one for every region)

int setup_vfpga_devices(struct bus_driver_data *data)

Sets up the previously allocated vFPGA char devices (above); memory mapping registers, initializing work queues, mutexes etc.

void teardown_vfpga_devices(struct bus_driver_data *data)

Releases resources used by vFPGA char devices; destroys work queues etc., opposite of setup_vfpga_devices.

void free_vfpga_devices(struct bus_driver_data *data)

Frees the allocated vFPGA char devices and unregisters it from the OS; opposite of alloc_vfpga_devices.

int alloc_reconfig_device(struct bus_driver_data *data, dev_t device)

Allocates a char reconfig_device which is used to interact with the static layer for shell reconfiguration.

int setup_reconfig_device(struct bus_driver_data *data)

Sets up the previously allocated reconfig char device (above); initializing work queues, mutexes, hash tables etc.

void teardown_reconfig_device(struct bus_driver_data *data)

Releases resources used by the reconfig device; destroys work queues etc., opposite of setup_reconfig_device.

void free_reconfig_device(struct bus_driver_data *data)

Frees the allocated reconfig char device and unregisters it from the OS; opposite of alloc_reconfig_device.

coyote_sysfs.h

Coyote sysfs module.

sysfs is a virtual filesystem in Linux that exposes kernel objects and their attributes to the user-space It can be used for reading and writing various attributes of devices in the kernel-space The following methods retrieve or set attributes from memory-mapped FPGA registers The attributes can also be read and set from a standard Linux terminal, e.g., cat /sys/kernel/coyote_sysfs_0/<attribute>

In general, the methods in this file follow similar steps:

  1. Parse a generic kernel object (kobj) into a Coyote-specific variable of type bus_driver_data

  2. Ensure the parsed object is non-null, using BUG_ON(…)

  3. Retrieve or set the target attribute

Functions

ssize_t cyt_attr_ip_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get FPGA IP address.

ssize_t cyt_attr_ip_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)

Set FPGA IP address.

ssize_t cyt_attr_mac_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get FPGA MAC address.

ssize_t cyt_attr_mac_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)

Set FPGA MAC address.

ssize_t cyt_attr_eost_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get PR end of start-up (EOS) time.

ssize_t cyt_attr_eost_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)

Set PR end of start-up (EOS) time.

ssize_t cyt_attr_nstats_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get network stats on port QSFP0.

ssize_t cyt_attr_hstats_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get host DMA (XDMA/QDMA) stats: number of commands, completion and data beats.

ssize_t cyt_attr_prstats_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get partial reconfiguration stats.

ssize_t cyt_attr_cnfg_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)

Get Coyote FPGA configuration (N_REGIONS, EN_MEM, EN_STRM, EN_PR, EN_RDMA, TLB config etc.)

vfpga_gup.h

Header file for memory management of vFPGAs.

This file defines the functions for handling page faults, managing user pages, exporting necessary DMA Buffers for FPGA-GPU communication. NOTE: GUP stands for “Get User Pages”, which is a Linux kernel mechanism to pin user-space pages in memory and Coyote swaps the pages between host and card. NOTE: Previously (currently in LEGACY), there was an alternative memory management mechanism, using Linux’s Hetereogeneous Memory Management (HMM) framework.

The mapped user pages are stored in a hash_table, called user_buff_map Functions in this file implement high-level logic for managing Coyote memory And call functions in vfpga_hw.h that handle the low-level logic by writing to the memory-mapped registers in the FPGA Additionally, this file provides functions for peer-to-peer DMA Buffer management, enabling direct FPGA-GPU communication.

Important functions in this file include:

  • mmu_handler_gup; the top-level function, handles page faults issued by the FPGA

  • tlb_map_gup and tlb_unmap_gup; which maps/unmaps user pages to the TLB

  • offload_user_pages and sync_user_pages; handling the offloading and syncing of user pages between host and card

  • P2P DMA Buffer functions for managing DMA Buffers to FPGA-GPU communication

Functions

int mmu_handler_gup(struct vfpga_dev *device, uint64_t vaddr, uint64_t len, int32_t ctid, int32_t stream, pid_t hpid, int32_t mem_block)

Top-level function; handles page faults issued by the FPGA.

Parameters:
  • device – vFPGA char device

  • vaddr – Buffer virtual address corresponding to the page fault

  • len – Length, in bytes, of the page-faulting buffer

  • ctid – Coyote thread ID

  • stream – Access type: HOST (1) or CARD (0)

  • hpid – Host process ID

  • mem_block – Target memory block for card memory; only applicable to Versal devices

Returns:

0 on success, negative error code on failure

struct user_pages *map_present(struct vfpga_dev *device, struct pf_aligned_desc *pf_desc)

Checks if a mapping is already present in the user buffer map.

Parameters:
  • device – vFPGA char device

  • pf_desc – Aligned page fault descriptor; holds info about virtual address, length etc.

Returns:

Pointer to the user_pages structure if mapping exists, NULL otherwise

void tlb_map_gup(struct vfpga_dev *device, struct pf_aligned_desc *pf_desc, struct user_pages *user_pg, pid_t hpid)

Creates a TLB mapping for the given user pages.

Parameters:
  • device – vFPGA char device

  • pf_desc – Aligned page fault descriptor; holds info about virtual address, length etc.

  • user_pg – User pages structure

  • hpid – Host process ID

void tlb_unmap_gup(struct vfpga_dev *device, struct user_pages *user_pg, pid_t hpid)

Removes a TLB mapping for the given user pages.

Parameters:
  • device – vFPGA char device

  • pf_desc – Aligned page fault descriptor; holds info about virtual address, length etc.

  • hpid – Host process ID

struct user_pages *tlb_get_user_pages(struct vfpga_dev *device, struct pf_aligned_desc *pf_desc, pid_t hpid, struct task_struct *curr_task, struct mm_struct *curr_mm, int32_t mem_block)

Pins user pages and prepares them for TLB mapping.

A function that is first called when no mapping for a user page exists In this case, the function performs the following:

  • Allocates a new user_pages struct which holds informaton about page physical address, length etc.,

  • Pins the pages, to avoid them being swapped out

  • Flushes the cache to ensure data consistency between the FPGA and the CPU

  • Allocates the corresponding card buffer, if memory is enabled This function is immediately followed by a call to tlb_map_gup, which maps the user pages to the vFPGA’s TLB

Parameters:
  • device – vFPGA char device

  • pf_desc – Aligned page fault descriptor

  • hpid – Host process ID

  • curr_task – Current task structure

  • curr_mm – Current memory management structure

  • mem_block – Target memory block for card memory; only applicable to Versal devices

Returns:

Pointer to the user_pages structure on success, NULL on failure

int tlb_put_user_pages(struct vfpga_dev *device, uint64_t vaddr, int32_t ctid, pid_t hpid, int dirtied)

Releases user pages and removes their TLB mappings.

Parameters:
  • device – vFPGA char device

  • vaddr – Starting virtual address

  • ctid – Coyote thread ID for which the pages were mapped

  • hpid – Host process ID for which the pages were mapped

  • dirtied – Indicates if the pages were modified

Returns:

0 on success, negative error code on failure

int tlb_put_user_pages_ctid(struct vfpga_dev *device, int32_t ctid, pid_t hpid, int dirtied)

Releases all user pages for a given Coyote thread.

Parameters:
  • device – vFPGA char device

  • ctid – Coyote thread ID for which the pages should be released

  • hpid – Host process ID associated with the Coyote thread

  • dirtied – Indicates if the pages were modified

Returns:

0 on success, negative error code on failure

void migrate_to_card(struct vfpga_dev *device, struct user_pages *user_pg)

Helper function, migrates user pages to card memory.

Parameters:
  • device – vFPGA char device

  • user_pg – User pages to be migrated

void migrate_to_host(struct vfpga_dev *device, struct user_pages *user_pg)

Helper function, migrates user pages back to the host memory.

Parameters:
  • device – vFPGA char device

  • user_pg – User pages to be migrated

int offload_user_pages(struct vfpga_dev *device, uint64_t vaddr, uint32_t len, int32_t ctid)

Trigger off-load operation; moving pages from host to card & updating mappings.

Parameters:
  • device – vFPGA char device

  • vaddr – Starting virtual address of the buffer to be offloaded

  • len – Length, in bytes, of the buffer to be offloaded

  • ctid – Coyote thread ID

Returns:

0 on success, negative error code on failure

int sync_user_pages(struct vfpga_dev *device, uint64_t vaddr, uint32_t len, int32_t ctid)

Trigger sync operation; moving pages from card to host & updating mappings.

Parameters:
  • device – vFPGA char device

  • vaddr – Starting virtual address of the buffer to be synced

  • len – Length, in bytes, of the buffer to be synced

  • ctid – Coyote thread ID

Returns:

0 on success, negative error code on failure

void p2p_move_notify(struct dma_buf_attachment *attach)

Callback for handling page movement notifications in peer-to-peer DMA.

To manage page movements in GPU memory, this routines deletes TLB entries and retrieves new entries It is passed as a parameter to the dma_buf_attach_ops struct, which is used when attaching the DMA Buffer

Parameters:

attach – DMA buffer attachment structure

int p2p_attach_dma_buf(struct vfpga_dev *device, int buf_fd, uint64_t vaddr, int32_t ctid, int32_t mem_block)

Attaches a DMA buffer to the vFPGA.

In general, this functions implements similary logic as tlb_get_user_pages, but for DMA Buffers Functionality includes:

  • Allocating a new user_pages struct which holds informaton about page physical address, length etc.,

  • Attaches the DMA Buffer to the vFPGA char device, allowing the vFPGA to access the buffer

  • Maps the DMA Buffer to the FPGA’s address spae, by providing a scatter-gather list represnting the physical memory of the buffer

  • Allocate corresponding card buffer, if memory is enabled

  • Maps the physical to virtual translations to the vFPGA’s TLB using tlb_map_gup

Parameters:
  • device – vFPGA char device

  • buf_fd – File descriptor of the DMA buffer

  • vaddr – Virtual address to map the buffer

  • ctid – Coyote thread ID

  • mem_block – Target memory block for card memory; only applicable to Versal devices

Returns:

0 on success, negative error code on failure

int p2p_detach_dma_buf(struct vfpga_dev *device, uint64_t vaddr, int32_t ctid, int dirtied)

Detaches a DMA buffer from the vFPGA device.

In general, this functions implements similary logic as tlb_put_user_pages, but for DMA Buffers It is called at the end of the Coyote thread’s execution, when the buffer is no longer needed Functionality includes (which is largely opposite to p2p_attach_dma_buf):

  • Removing the TLB entries using tlb_unmap_gup

  • Freeing card memory, if memory is enabled

  • Unmapping the DMA Buffer from the vFPGA’s address space

  • Detaching the vFPGA device from the DMA Buffer

Parameters:
  • device – vFPGA char device

  • vaddr – Virtual address of the buffer

  • ctid – Coyote thread ID

  • dirtied – Indicates if the buffer was modified

Returns:

0 on success, negative error code on failure

vfpga_hw.h

vFPGA hardware functions

Functions in this file are primarily used for low-level hardware operations in the vFPGA Typically, this includes writing to or reading from hardware registers, which are memory-mapped during driver loading The registers typically start an operation in hardware or contain some control flow data (virtual address, length etc.)

Functions

uint32_t read_irq_type(struct vfpga_dev *device)

Parse interrupt type.

Parameters:

device – vFPGA char device

Returns:

type of interrupt (IRQ_DMA_OFFL, IRQ_DMA_SYNC, IRQ_INVLDT, IRQ_PFAULT, IRQ_NOTIFY)

void read_irq_notify(struct vfpga_dev *device, struct vfpga_irq_notify *irq_not)

Parse user notification IRQ.

Parameters:
  • device – vFPGA char device

  • irq_not – notification struct, to be set (updated) by this function

void read_irq_pfault(struct vfpga_dev *device, struct vfpga_irq_pfault *irq_pf)

Parse page fault IRQ.

Parameters:
  • device – vFPGA char device

  • irq_pf – page fault struct, to be set (updated) by this function

void drop_irq_pfault(struct vfpga_dev *device, bool write, int32_t ctid)

Drops the page fault, because it went wrong somewhere.

Parameters:
  • device – vFPGA char device

  • write – write operation (true) or read operation (false)

  • ctid – Coyote thread ID

void clear_irq(struct vfpga_dev *device)

Resets the IRQ registers in hardware.

Parameters:

device – vFPGA char device

void restart_mmu(struct vfpga_dev *device, bool write, int32_t ctid)

Restarts the MMU, by signaling a page fault has correctly been handled.

Parameters:
  • device – vFPGA char device

  • write – write operation (true) or read operation (false)

  • ctid – Coyote thread ID

void invalidate_tlb_entry(struct vfpga_dev *device, uint64_t vaddr, uint32_t n_pages, int32_t hpid, bool last)

Invalidate a TLB entry.

Parameters:
  • device – vFPGA char device

  • vaddr – starting virtual address of the buffer to be invalidated

  • n_pages – number of consecutive pages to be invalidated

  • hpid – host process ID

  • last – is this the last page of the buffer to be invalidated (equivalent to a tlast in an AXI stream)

void change_tlb_lock(struct vfpga_dev *device)

Locks or unlocks the TLB, potentially prevent new entries (if locked)

Parameters:

device – vFPGA char device

void create_tlb_mapping(struct vfpga_dev *device, struct tlb_metadata *tlb_meta, uint64_t vaddr, uint64_t physical_address, int32_t host, int32_t ctid, pid_t hpid)

Create a TLB mapping.

Parameters:
  • device – vFPGA char device

  • tlb_meta – helper struct, containing TLB information (page size & shift, key size & shift etc.)

  • vaddr – buffer virtual address

  • physical_address – buffer physical address

  • host – does the buffer reside in host memory (1) or in card memory (0)

  • ctid – Coyote thread ID

  • hpid – Host process ID

void create_tlb_unmapping(struct vfpga_dev *device, struct tlb_metadata *tlb_meta, uint64_t vaddr, pid_t hpid)

Unmap TLB entry.

Parameters:
  • device – vFPGA char device

  • tlb_meta – helper struct, containing TLB information (page size & shift, key size & shift etc.)

  • vaddr – buffer virtual address

  • hpid – Host process ID

void trigger_dma_offload(struct vfpga_dev *device, uint64_t *host_address, uint64_t *card_address, uint32_t n_pages, bool huge)

Triggers DMA off-load from host memory to card memory (asynchronous)

Parameters:
  • device – vFPGA char device

  • host_address – - virtual address of the buffer on the host to be off-loaded

  • card_address – - target virtual address on the card

  • n_pages – - number of pages in the buffer to be off-loaded

  • huge – - whether the buffer is using hugepages or regular pages

void trigger_dma_sync(struct vfpga_dev *device, uint64_t *host_address, uint64_t *card_address, uint32_t n_pages, bool huge)

Triggers DMA sync from card memory to host memory (asynchronous)

Parameters:
  • device – vFPGA char device

  • host_address – - target virtual address of the buffer on the host

  • card_address – - virtual address of the buffer on the card

  • n_pages – - number of pages in the buffer to be synced

  • huge – - whether the buffer is using hugepages or regular pages

int alloc_card_memory(struct vfpga_dev *device, uint64_t *card_physical_address, uint32_t n_pages, bool huge, int32_t mem_block)

Allocates memory on the card’s HBM or DDR memory and updates the card_physical_address parameter with the allocated addresses.

Parameters:
  • device – vFPGA char device

  • card_physical_address – initially null/empty, set by the function to reflect the physical address of the allocated pages

  • n_pages – number of pages to be allocated

  • huge – whether the memory is using hugepages or regular pages

  • mem_block – Target memory block; only applicable to Versal devices with fine-grained memory allocation If -1, driver automatically selects the next free block

Returns:

whether the allocation was successful; can fail if there is insufficient space on the card

void free_card_memory(struct vfpga_dev *device, uint64_t *card_physical_address, uint32_t n_pages, bool huge)

Release memory on the card; opposite of the above alloc_card_memory function.

Parameters:
  • device – vFPGA char device

  • card_physical_address – list of pages allocated on the card’s memory and their corresponding physical addresses

  • n_pages – number of pages to be freed

  • huge – whether the memory to be freed is using hugepages or regular pages

vfpga_isr.h

vFPGA interrupts (page faults, invalidations, user interrupts etc.)

Functions

irqreturn_t vfpga_isr(int irq, void *d)

Top-level vFPGA interrupt routine; registered during set-up in msix_irq_setup(…)

Catches interrupts issued by the vFPGA (sent via QDMA/XDMA and PCIe) and calls the appropriate callback method Interrupts, in the order of importance are:

  1. Completed DMA offloads/syncs

  2. Completed TLB invalidation

  3. Page fault

  4. User interrupts (notification)

For more details, refer to: Chapter 3.1.3.5 Interrupts in Abstractions for Modern Heterogeneous Systems (2024), Dario Korlija

Parameters:
  • irq – Interrupt type

  • d – Generic pointer to a Linux device; internally parsed into a vfpga_dev pointer

void vfpga_notify_handler(struct work_struct *work)

Handles user interupts (notifications)

void vfpga_pfault_handler(struct work_struct *work)

Handles vFPGA page faults, by invalidating and updating TLB; migrating data where required.

vfpga_ops.h

Standard device operations for the vfpga_dev char device: open, release, ioctl and memory map (mmap)

Functions

int vfpga_dev_open(struct inode *inode, struct file *file)

vfpga_dev open char device

int vfpga_dev_release(struct inode *inode, struct file *file)

vfpga_dev release (close) char device

long vfpga_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

vfpga_dev IOCTL calls

int vfpga_dev_mmap(struct file *file, struct vm_area_struct *vma)

vfpga_dev memory map; maps user control region, vFPGA config and writeback regions

vfpga_uisr.h

vFPGA user interrupts (notifications)

Methods to register user interrupt (notification) callbacks, as requested by the user In Coyote, user interrupts (notifications) are linked to a Coyote thread, through its ID (ctid) Therefore, there can be multiple interrupt callbacks for one vFPGA, since it’s possible to have more than one Coyote thread per vFPGA For more details, see Example 3: Multi-threading and Example 4: User interrupts

To handle interrupts, Coyote uses eventfd, a Linux kernel mechanism for event signalling eventfd can be used to communicate events between the kernel- and the user-space, or between processes In Coyote, an eventfd is created from the user-space and registered by the driver using the method vfpga_register_eventfd Then, when an interrupt from the FPGA is picked up by the driver (see vfpga_isr.c), the driver writes to the appropariate eventfd The user-space software polls on the same eventfd, and, when a change is detected, executes the appropriate callback (see sw/bThread.cpp)

Functions

int vfpga_register_eventfd(struct vfpga_dev *device, int ctid, int eventfd)

Registers an eventfd for a given Coyote thread and vFPGA device.

Parameters:
  • device – vfpga_dev for which the eventfd should be registered

  • ctid – Coyote thread ID (obtained from user-space)

  • eventfd – eventfd file descriptor, as created in the user-space (see sw/bThread.cpp)

Returns:

whether eventfd was successfully registered

void vfpga_unregister_eventfd(struct vfpga_dev *device, int ctid)

Unregisters an eventfd for a given Coyote thread and vFPGA device.

Parameters:
  • device – vfpga_dev for which the eventfd should be released

  • ctid – Coyote thread ID of the eventfd which should be released

reconfig_hw.h

Low-level hardware functionality to trigger run-time reconfiguration of the FPGA.

Functions

int reconfigure_start(struct reconfig_dev *device, uint64_t vaddr, uint64_t len, pid_t pid, uint32_t crid)

Triggers the reconfiguration process.

Parameters:
  • device – reconfig_device to be reconfigured (corresponding to the actual physical FPGA we want to reconfigure)

  • vaddr – bitstream buffer virtual address; obtained from alloc_buffer and mmap

  • pid – host process ID

  • crid – configuration ID

Returns:

reconfiguration started successfuly or not

reconfig_isr.h

Reconfiguration interrupt management; picking up interrupts when reconfiguration is complete.

Functions

irqreturn_t reconfig_isr(int irq, void *dev)

Handles incoming interrupts related to reconfiguration.

A reconfiguration interrupt issued by the FPGA corresponds to reconfiguration being completed successfuly Once picked up by this function, it sets the wait_rcnfg variable to SET, which is polled on during IOCTL_RECONFIGURE_(SHELL|APP) Finally, it clears the memory-mapped interrupt register in the FPGA

Parameters:
  • irq – interrupt value

  • dev – pointer to the reconfiguration device being reconfigured

Returns:

IRQ_HANDLED, indicating interrupt has been acknowledged

reconfig_mem.h

Memory management for reconfiguration: allocating and releasing memory to hold partial bitstreams.

Functions

int alloc_reconfig_buffer(struct reconfig_dev *device, unsigned long n_pages, pid_t pid, uint32_t crid)

Allocates host-side, kernel-space reconfiguration buffers.

In order for partial bitstreams to be loaded onto the FPGA, they need to be written to the ICAP from the driver via PCIe and the XDMA core This function allocates a buffer of sufficient size to hold a partial bitstream for reconfiguration Following this function, the buffer is mapped to the user-space using an mmap call (reconfig_ops.h) Finally, the partial bitstream can then be loaded into this buffer and used to trigger reconfiguration

Parameters:
  • device – reconfig_device for which the bitstream buffer should be allocated

  • n_pages – number of hugepages required to hold the bitsream; calculated in user-space

  • pid – host process ID

  • crid – configuration ID (uniquely identifies the shell bitstream to be loaded)

Returns:

whether target memory allocation completed successfully

int free_reconfig_buffer(struct reconfig_dev *device, uint64_t vaddr, pid_t pid, uint32_t crid)

De-allocates host-side, kernel-space reconfiguration buffer.

Performs the opposite of the function above; to be used when reconfiguration is complete

Parameters:
  • device – reconfig_device for which the bitstream buffer should be allocated

  • vaddr – buffer virtual address

  • pid – host process ID

  • crid – configuration ID

Returns:

always 0; check reconfig_mem.c for explanation

reconfig_ops.h

Standard device operations for the reconfig_dev char device: open, release, ioctl and memory map (mmap)

Functions

int reconfig_dev_open(struct inode *inode, struct file *file)

reconfig_dev open char device

int reconfig_dev_release(struct inode *inode, struct file *file)

reconfig_dev release (close) char device

long reconfig_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

reconfig_dev IOCTL calls

int reconfig_dev_mmap(struct file *file, struct vm_area_struct *vma)

reconfig_dev memory map; maps pages allocated using IOCTL_ALLOC_PR_BUFF from kernel space to user space

pci_util.h

Coyote PCI utility functions.

Functions

inline uint32_t build_u32(uint32_t hi, uint32_t lo)

Utility functions, concatenates two 16-bit values into a single 32-bit value.

void pci_enable_capability(struct pci_dev *pdev, int cmd)

Enables a specific PCIe capability for the device.

Parameters:
  • pdev – Pointer to the PCI device structure

  • capability – Capability to enable

bool msix_capable(struct pci_dev *pdev)

Checks if the PCI device supports MSI-X.

Parameters:

pdev – Pointer to the PCI device structure.

Returns:

true if MSI-X is supported, false otherwise.

uint32_t build_vector_reg(uint32_t a, uint32_t b, uint32_t c, uint32_t d)

Utility function, constructs a 32-bit MSI-X vector register value.

This function packs four 5-bit fields (a, b, c, d) into a single 32-bit value. Each field represents an MSI-X table entry index

Parameters:
  • a – The first 5-bit field (bits 0–4)

  • b – The second 5-bit field (bits 8–12)

  • c – The third 5-bit field (bits 16–20)

  • d – The fourth 5-bit field (bits 24–28)

Returns:

A 32-bit value representing the packed MSI-X vector register

pci_xdma.h

Contains functions for loading and setting up the Coyote driver on PCI platforms with the XDMA core.