1*bf21cd93STycho Nightingale /*- 2*bf21cd93STycho Nightingale * Copyright (c) 2011 NetApp, Inc. 3*bf21cd93STycho Nightingale * All rights reserved. 4*bf21cd93STycho Nightingale * 5*bf21cd93STycho Nightingale * Redistribution and use in source and binary forms, with or without 6*bf21cd93STycho Nightingale * modification, are permitted provided that the following conditions 7*bf21cd93STycho Nightingale * are met: 8*bf21cd93STycho Nightingale * 1. Redistributions of source code must retain the above copyright 9*bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer. 10*bf21cd93STycho Nightingale * 2. Redistributions in binary form must reproduce the above copyright 11*bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer in the 12*bf21cd93STycho Nightingale * documentation and/or other materials provided with the distribution. 13*bf21cd93STycho Nightingale * 14*bf21cd93STycho Nightingale * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15*bf21cd93STycho Nightingale * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*bf21cd93STycho Nightingale * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*bf21cd93STycho Nightingale * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18*bf21cd93STycho Nightingale * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*bf21cd93STycho Nightingale * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*bf21cd93STycho Nightingale * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*bf21cd93STycho Nightingale * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*bf21cd93STycho Nightingale * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*bf21cd93STycho Nightingale * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*bf21cd93STycho Nightingale * SUCH DAMAGE. 25*bf21cd93STycho Nightingale * 26*bf21cd93STycho Nightingale * $FreeBSD: head/usr.sbin/bhyve/pci_emul.h 269700 2014-08-08 03:49:01Z neel $ 27*bf21cd93STycho Nightingale */ 28*bf21cd93STycho Nightingale 29*bf21cd93STycho Nightingale #ifndef _PCI_EMUL_H_ 30*bf21cd93STycho Nightingale #define _PCI_EMUL_H_ 31*bf21cd93STycho Nightingale 32*bf21cd93STycho Nightingale #include <sys/types.h> 33*bf21cd93STycho Nightingale #include <sys/queue.h> 34*bf21cd93STycho Nightingale #include <sys/kernel.h> 35*bf21cd93STycho Nightingale #include <sys/_pthreadtypes.h> 36*bf21cd93STycho Nightingale 37*bf21cd93STycho Nightingale #include <dev/pci/pcireg.h> 38*bf21cd93STycho Nightingale 39*bf21cd93STycho Nightingale #include <assert.h> 40*bf21cd93STycho Nightingale 41*bf21cd93STycho Nightingale #define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */ 42*bf21cd93STycho Nightingale 43*bf21cd93STycho Nightingale struct vmctx; 44*bf21cd93STycho Nightingale struct pci_devinst; 45*bf21cd93STycho Nightingale struct memory_region; 46*bf21cd93STycho Nightingale 47*bf21cd93STycho Nightingale struct pci_devemu { 48*bf21cd93STycho Nightingale char *pe_emu; /* Name of device emulation */ 49*bf21cd93STycho Nightingale 50*bf21cd93STycho Nightingale /* instance creation */ 51*bf21cd93STycho Nightingale int (*pe_init)(struct vmctx *, struct pci_devinst *, 52*bf21cd93STycho Nightingale char *opts); 53*bf21cd93STycho Nightingale 54*bf21cd93STycho Nightingale /* ACPI DSDT enumeration */ 55*bf21cd93STycho Nightingale void (*pe_write_dsdt)(struct pci_devinst *); 56*bf21cd93STycho Nightingale 57*bf21cd93STycho Nightingale /* config space read/write callbacks */ 58*bf21cd93STycho Nightingale int (*pe_cfgwrite)(struct vmctx *ctx, int vcpu, 59*bf21cd93STycho Nightingale struct pci_devinst *pi, int offset, 60*bf21cd93STycho Nightingale int bytes, uint32_t val); 61*bf21cd93STycho Nightingale int (*pe_cfgread)(struct vmctx *ctx, int vcpu, 62*bf21cd93STycho Nightingale struct pci_devinst *pi, int offset, 63*bf21cd93STycho Nightingale int bytes, uint32_t *retval); 64*bf21cd93STycho Nightingale 65*bf21cd93STycho Nightingale /* BAR read/write callbacks */ 66*bf21cd93STycho Nightingale void (*pe_barwrite)(struct vmctx *ctx, int vcpu, 67*bf21cd93STycho Nightingale struct pci_devinst *pi, int baridx, 68*bf21cd93STycho Nightingale uint64_t offset, int size, uint64_t value); 69*bf21cd93STycho Nightingale uint64_t (*pe_barread)(struct vmctx *ctx, int vcpu, 70*bf21cd93STycho Nightingale struct pci_devinst *pi, int baridx, 71*bf21cd93STycho Nightingale uint64_t offset, int size); 72*bf21cd93STycho Nightingale }; 73*bf21cd93STycho Nightingale #define PCI_EMUL_SET(x) DATA_SET(pci_devemu_set, x); 74*bf21cd93STycho Nightingale 75*bf21cd93STycho Nightingale enum pcibar_type { 76*bf21cd93STycho Nightingale PCIBAR_NONE, 77*bf21cd93STycho Nightingale PCIBAR_IO, 78*bf21cd93STycho Nightingale PCIBAR_MEM32, 79*bf21cd93STycho Nightingale PCIBAR_MEM64, 80*bf21cd93STycho Nightingale PCIBAR_MEMHI64 81*bf21cd93STycho Nightingale }; 82*bf21cd93STycho Nightingale 83*bf21cd93STycho Nightingale struct pcibar { 84*bf21cd93STycho Nightingale enum pcibar_type type; /* io or memory */ 85*bf21cd93STycho Nightingale uint64_t size; 86*bf21cd93STycho Nightingale uint64_t addr; 87*bf21cd93STycho Nightingale }; 88*bf21cd93STycho Nightingale 89*bf21cd93STycho Nightingale #define PI_NAMESZ 40 90*bf21cd93STycho Nightingale 91*bf21cd93STycho Nightingale struct msix_table_entry { 92*bf21cd93STycho Nightingale uint64_t addr; 93*bf21cd93STycho Nightingale uint32_t msg_data; 94*bf21cd93STycho Nightingale uint32_t vector_control; 95*bf21cd93STycho Nightingale } __packed; 96*bf21cd93STycho Nightingale 97*bf21cd93STycho Nightingale /* 98*bf21cd93STycho Nightingale * In case the structure is modified to hold extra information, use a define 99*bf21cd93STycho Nightingale * for the size that should be emulated. 100*bf21cd93STycho Nightingale */ 101*bf21cd93STycho Nightingale #define MSIX_TABLE_ENTRY_SIZE 16 102*bf21cd93STycho Nightingale #define MAX_MSIX_TABLE_ENTRIES 2048 103*bf21cd93STycho Nightingale #define PBA_SIZE(msgnum) (roundup2((msgnum), 64) / 8) 104*bf21cd93STycho Nightingale 105*bf21cd93STycho Nightingale enum lintr_stat { 106*bf21cd93STycho Nightingale IDLE, 107*bf21cd93STycho Nightingale ASSERTED, 108*bf21cd93STycho Nightingale PENDING 109*bf21cd93STycho Nightingale }; 110*bf21cd93STycho Nightingale 111*bf21cd93STycho Nightingale struct pci_devinst { 112*bf21cd93STycho Nightingale struct pci_devemu *pi_d; 113*bf21cd93STycho Nightingale struct vmctx *pi_vmctx; 114*bf21cd93STycho Nightingale uint8_t pi_bus, pi_slot, pi_func; 115*bf21cd93STycho Nightingale char pi_name[PI_NAMESZ]; 116*bf21cd93STycho Nightingale int pi_bar_getsize; 117*bf21cd93STycho Nightingale int pi_prevcap; 118*bf21cd93STycho Nightingale int pi_capend; 119*bf21cd93STycho Nightingale 120*bf21cd93STycho Nightingale struct { 121*bf21cd93STycho Nightingale int8_t pin; 122*bf21cd93STycho Nightingale enum lintr_stat state; 123*bf21cd93STycho Nightingale int pirq_pin; 124*bf21cd93STycho Nightingale int ioapic_irq; 125*bf21cd93STycho Nightingale pthread_mutex_t lock; 126*bf21cd93STycho Nightingale } pi_lintr; 127*bf21cd93STycho Nightingale 128*bf21cd93STycho Nightingale struct { 129*bf21cd93STycho Nightingale int enabled; 130*bf21cd93STycho Nightingale uint64_t addr; 131*bf21cd93STycho Nightingale uint64_t msg_data; 132*bf21cd93STycho Nightingale int maxmsgnum; 133*bf21cd93STycho Nightingale } pi_msi; 134*bf21cd93STycho Nightingale 135*bf21cd93STycho Nightingale struct { 136*bf21cd93STycho Nightingale int enabled; 137*bf21cd93STycho Nightingale int table_bar; 138*bf21cd93STycho Nightingale int pba_bar; 139*bf21cd93STycho Nightingale uint32_t table_offset; 140*bf21cd93STycho Nightingale int table_count; 141*bf21cd93STycho Nightingale uint32_t pba_offset; 142*bf21cd93STycho Nightingale int pba_size; 143*bf21cd93STycho Nightingale int function_mask; 144*bf21cd93STycho Nightingale struct msix_table_entry *table; /* allocated at runtime */ 145*bf21cd93STycho Nightingale } pi_msix; 146*bf21cd93STycho Nightingale 147*bf21cd93STycho Nightingale void *pi_arg; /* devemu-private data */ 148*bf21cd93STycho Nightingale 149*bf21cd93STycho Nightingale u_char pi_cfgdata[PCI_REGMAX + 1]; 150*bf21cd93STycho Nightingale struct pcibar pi_bar[PCI_BARMAX + 1]; 151*bf21cd93STycho Nightingale }; 152*bf21cd93STycho Nightingale 153*bf21cd93STycho Nightingale struct msicap { 154*bf21cd93STycho Nightingale uint8_t capid; 155*bf21cd93STycho Nightingale uint8_t nextptr; 156*bf21cd93STycho Nightingale uint16_t msgctrl; 157*bf21cd93STycho Nightingale uint32_t addrlo; 158*bf21cd93STycho Nightingale uint32_t addrhi; 159*bf21cd93STycho Nightingale uint16_t msgdata; 160*bf21cd93STycho Nightingale } __packed; 161*bf21cd93STycho Nightingale 162*bf21cd93STycho Nightingale struct msixcap { 163*bf21cd93STycho Nightingale uint8_t capid; 164*bf21cd93STycho Nightingale uint8_t nextptr; 165*bf21cd93STycho Nightingale uint16_t msgctrl; 166*bf21cd93STycho Nightingale uint32_t table_info; /* bar index and offset within it */ 167*bf21cd93STycho Nightingale uint32_t pba_info; /* bar index and offset within it */ 168*bf21cd93STycho Nightingale } __packed; 169*bf21cd93STycho Nightingale 170*bf21cd93STycho Nightingale struct pciecap { 171*bf21cd93STycho Nightingale uint8_t capid; 172*bf21cd93STycho Nightingale uint8_t nextptr; 173*bf21cd93STycho Nightingale uint16_t pcie_capabilities; 174*bf21cd93STycho Nightingale 175*bf21cd93STycho Nightingale uint32_t dev_capabilities; /* all devices */ 176*bf21cd93STycho Nightingale uint16_t dev_control; 177*bf21cd93STycho Nightingale uint16_t dev_status; 178*bf21cd93STycho Nightingale 179*bf21cd93STycho Nightingale uint32_t link_capabilities; /* devices with links */ 180*bf21cd93STycho Nightingale uint16_t link_control; 181*bf21cd93STycho Nightingale uint16_t link_status; 182*bf21cd93STycho Nightingale 183*bf21cd93STycho Nightingale uint32_t slot_capabilities; /* ports with slots */ 184*bf21cd93STycho Nightingale uint16_t slot_control; 185*bf21cd93STycho Nightingale uint16_t slot_status; 186*bf21cd93STycho Nightingale 187*bf21cd93STycho Nightingale uint16_t root_control; /* root ports */ 188*bf21cd93STycho Nightingale uint16_t root_capabilities; 189*bf21cd93STycho Nightingale uint32_t root_status; 190*bf21cd93STycho Nightingale 191*bf21cd93STycho Nightingale uint32_t dev_capabilities2; /* all devices */ 192*bf21cd93STycho Nightingale uint16_t dev_control2; 193*bf21cd93STycho Nightingale uint16_t dev_status2; 194*bf21cd93STycho Nightingale 195*bf21cd93STycho Nightingale uint32_t link_capabilities2; /* devices with links */ 196*bf21cd93STycho Nightingale uint16_t link_control2; 197*bf21cd93STycho Nightingale uint16_t link_status2; 198*bf21cd93STycho Nightingale 199*bf21cd93STycho Nightingale uint32_t slot_capabilities2; /* ports with slots */ 200*bf21cd93STycho Nightingale uint16_t slot_control2; 201*bf21cd93STycho Nightingale uint16_t slot_status2; 202*bf21cd93STycho Nightingale } __packed; 203*bf21cd93STycho Nightingale 204*bf21cd93STycho Nightingale typedef void (*pci_lintr_cb)(int b, int s, int pin, int pirq_pin, 205*bf21cd93STycho Nightingale int ioapic_irq, void *arg); 206*bf21cd93STycho Nightingale 207*bf21cd93STycho Nightingale int init_pci(struct vmctx *ctx); 208*bf21cd93STycho Nightingale void msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, 209*bf21cd93STycho Nightingale int bytes, uint32_t val); 210*bf21cd93STycho Nightingale void msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, 211*bf21cd93STycho Nightingale int bytes, uint32_t val); 212*bf21cd93STycho Nightingale void pci_callback(void); 213*bf21cd93STycho Nightingale int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, 214*bf21cd93STycho Nightingale enum pcibar_type type, uint64_t size); 215*bf21cd93STycho Nightingale int pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx, 216*bf21cd93STycho Nightingale uint64_t hostbase, enum pcibar_type type, uint64_t size); 217*bf21cd93STycho Nightingale int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum); 218*bf21cd93STycho Nightingale int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type); 219*bf21cd93STycho Nightingale void pci_generate_msi(struct pci_devinst *pi, int msgnum); 220*bf21cd93STycho Nightingale void pci_generate_msix(struct pci_devinst *pi, int msgnum); 221*bf21cd93STycho Nightingale void pci_lintr_assert(struct pci_devinst *pi); 222*bf21cd93STycho Nightingale void pci_lintr_deassert(struct pci_devinst *pi); 223*bf21cd93STycho Nightingale void pci_lintr_request(struct pci_devinst *pi); 224*bf21cd93STycho Nightingale int pci_msi_enabled(struct pci_devinst *pi); 225*bf21cd93STycho Nightingale int pci_msix_enabled(struct pci_devinst *pi); 226*bf21cd93STycho Nightingale int pci_msix_table_bar(struct pci_devinst *pi); 227*bf21cd93STycho Nightingale int pci_msix_pba_bar(struct pci_devinst *pi); 228*bf21cd93STycho Nightingale int pci_msi_msgnum(struct pci_devinst *pi); 229*bf21cd93STycho Nightingale int pci_parse_slot(char *opt); 230*bf21cd93STycho Nightingale void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr); 231*bf21cd93STycho Nightingale int pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum); 232*bf21cd93STycho Nightingale int pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size, 233*bf21cd93STycho Nightingale uint64_t value); 234*bf21cd93STycho Nightingale uint64_t pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size); 235*bf21cd93STycho Nightingale int pci_count_lintr(int bus); 236*bf21cd93STycho Nightingale void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg); 237*bf21cd93STycho Nightingale void pci_write_dsdt(void); 238*bf21cd93STycho Nightingale uint64_t pci_ecfg_base(void); 239*bf21cd93STycho Nightingale int pci_bus_configured(int bus); 240*bf21cd93STycho Nightingale 241*bf21cd93STycho Nightingale static __inline void 242*bf21cd93STycho Nightingale pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val) 243*bf21cd93STycho Nightingale { 244*bf21cd93STycho Nightingale assert(offset <= PCI_REGMAX); 245*bf21cd93STycho Nightingale *(uint8_t *)(pi->pi_cfgdata + offset) = val; 246*bf21cd93STycho Nightingale } 247*bf21cd93STycho Nightingale 248*bf21cd93STycho Nightingale static __inline void 249*bf21cd93STycho Nightingale pci_set_cfgdata16(struct pci_devinst *pi, int offset, uint16_t val) 250*bf21cd93STycho Nightingale { 251*bf21cd93STycho Nightingale assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); 252*bf21cd93STycho Nightingale *(uint16_t *)(pi->pi_cfgdata + offset) = val; 253*bf21cd93STycho Nightingale } 254*bf21cd93STycho Nightingale 255*bf21cd93STycho Nightingale static __inline void 256*bf21cd93STycho Nightingale pci_set_cfgdata32(struct pci_devinst *pi, int offset, uint32_t val) 257*bf21cd93STycho Nightingale { 258*bf21cd93STycho Nightingale assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); 259*bf21cd93STycho Nightingale *(uint32_t *)(pi->pi_cfgdata + offset) = val; 260*bf21cd93STycho Nightingale } 261*bf21cd93STycho Nightingale 262*bf21cd93STycho Nightingale static __inline uint8_t 263*bf21cd93STycho Nightingale pci_get_cfgdata8(struct pci_devinst *pi, int offset) 264*bf21cd93STycho Nightingale { 265*bf21cd93STycho Nightingale assert(offset <= PCI_REGMAX); 266*bf21cd93STycho Nightingale return (*(uint8_t *)(pi->pi_cfgdata + offset)); 267*bf21cd93STycho Nightingale } 268*bf21cd93STycho Nightingale 269*bf21cd93STycho Nightingale static __inline uint16_t 270*bf21cd93STycho Nightingale pci_get_cfgdata16(struct pci_devinst *pi, int offset) 271*bf21cd93STycho Nightingale { 272*bf21cd93STycho Nightingale assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); 273*bf21cd93STycho Nightingale return (*(uint16_t *)(pi->pi_cfgdata + offset)); 274*bf21cd93STycho Nightingale } 275*bf21cd93STycho Nightingale 276*bf21cd93STycho Nightingale static __inline uint32_t 277*bf21cd93STycho Nightingale pci_get_cfgdata32(struct pci_devinst *pi, int offset) 278*bf21cd93STycho Nightingale { 279*bf21cd93STycho Nightingale assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); 280*bf21cd93STycho Nightingale return (*(uint32_t *)(pi->pi_cfgdata + offset)); 281*bf21cd93STycho Nightingale } 282*bf21cd93STycho Nightingale 283*bf21cd93STycho Nightingale #endif /* _PCI_EMUL_H_ */ 284