#ifndef _NV_VGPU_BAR_EMULATION_H_ #define _NV_VGPU_BAR_EMULATION_H_ #include "nvidia-vgpu-vfio.h" /* MSI-X Table entry size (16 bytes: addr_lo, addr_hi, data, vector_control) */ #define NV_VGPU_MSIX_ENTRY_SIZE 16 #define NV_VGPU_MSIX_TABLE_ENTRIES 32 #define NV_VGPU_MSIX_TABLE_SIZE (NV_VGPU_MSIX_ENTRY_SIZE * NV_VGPU_MSIX_TABLE_ENTRIES) #define NV_VGPU_MSIX_PBA_SIZE 8 /* 64 bits for 32 vectors */ struct nv_vgpu_msix_entry { u64 addr; u32 data; u32 vector_control; }; struct nv_vgpu_bar_emul_ctx { struct nv_vgpu_device *vgpu; void *bar0_shadow; size_t bar0_shadow_size; spinlock_t shadow_lock; /* MSI-X emulation */ struct nv_vgpu_msix_entry msix_table[NV_VGPU_MSIX_TABLE_ENTRIES]; u64 msix_pba; /* Pending Bit Array */ spinlock_t msix_lock; bool msix_enabled; struct { u32 offset; u32 value; bool is_write; bool trapped; } trap_regs[256]; int trap_count; }; int nv_vgpu_bar_emul_init(struct nv_vgpu_device *vgpu); void nv_vgpu_bar_emul_cleanup(struct nv_vgpu_device *vgpu); int nv_vgpu_bar_trap_register(struct nv_vgpu_device *vgpu, int bar_idx, u32 offset, u32 size); int nv_vgpu_bar_untrap_register(struct nv_vgpu_device *vgpu, int bar_idx, u32 offset); int nv_vgpu_bar_emul_read(struct nv_vgpu_device *vgpu, int bar_idx, u64 offset, void *val, size_t size); int nv_vgpu_bar_emul_write(struct nv_vgpu_device *vgpu, int bar_idx, u64 offset, void *val, size_t size); int nv_vgpu_bar_emul_handle_fault(struct nv_vgpu_device *vgpu, unsigned long addr, bool write); /* MSI-X emulation */ void nv_vgpu_msix_set_pending(struct nv_vgpu_device *vgpu, int vector); void nv_vgpu_msix_clear_pending(struct nv_vgpu_device *vgpu, int vector); static inline u32 nv_vgpu_read_reg(void __iomem *base, u32 offset) { return readl(base + offset); } static inline void nv_vgpu_write_reg(void __iomem *base, u32 offset, u32 val) { writel(val, base + offset); } static inline u64 nv_vgpu_read_reg64(void __iomem *base, u32 offset) { return readq(base + offset); } static inline void nv_vgpu_write_reg64(void __iomem *base, u32 offset, u64 val) { writeq(val, base + offset); } #endif