18ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */ 250c88402SJoao Martins /* 350c88402SJoao Martins * Copyright (c) 2006, Keir Fraser 450c88402SJoao Martins */ 550c88402SJoao Martins 650c88402SJoao Martins #ifndef __XEN_PUBLIC_PHYSDEV_H__ 750c88402SJoao Martins #define __XEN_PUBLIC_PHYSDEV_H__ 850c88402SJoao Martins 950c88402SJoao Martins #include "xen.h" 1050c88402SJoao Martins 1150c88402SJoao Martins /* 1250c88402SJoao Martins * Prototype for this hypercall is: 1350c88402SJoao Martins * int physdev_op(int cmd, void *args) 1450c88402SJoao Martins * @cmd == PHYSDEVOP_??? (physdev operation). 1550c88402SJoao Martins * @args == Operation-specific extra arguments (NULL if none). 1650c88402SJoao Martins */ 1750c88402SJoao Martins 1850c88402SJoao Martins /* 1950c88402SJoao Martins * Notify end-of-interrupt (EOI) for the specified IRQ. 2050c88402SJoao Martins * @arg == pointer to physdev_eoi structure. 2150c88402SJoao Martins */ 2250c88402SJoao Martins #define PHYSDEVOP_eoi 12 2350c88402SJoao Martins struct physdev_eoi { 2450c88402SJoao Martins /* IN */ 2550c88402SJoao Martins uint32_t irq; 2650c88402SJoao Martins }; 2750c88402SJoao Martins typedef struct physdev_eoi physdev_eoi_t; 2850c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); 2950c88402SJoao Martins 3050c88402SJoao Martins /* 3150c88402SJoao Martins * Register a shared page for the hypervisor to indicate whether the guest 3250c88402SJoao Martins * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly 3350c88402SJoao Martins * once the guest used this function in that the associated event channel 3450c88402SJoao Martins * will automatically get unmasked. The page registered is used as a bit 3550c88402SJoao Martins * array indexed by Xen's PIRQ value. 3650c88402SJoao Martins */ 3750c88402SJoao Martins #define PHYSDEVOP_pirq_eoi_gmfn_v1 17 3850c88402SJoao Martins /* 3950c88402SJoao Martins * Register a shared page for the hypervisor to indicate whether the 4050c88402SJoao Martins * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to 4150c88402SJoao Martins * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of 4250c88402SJoao Martins * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by 4350c88402SJoao Martins * Xen's PIRQ value. 4450c88402SJoao Martins */ 4550c88402SJoao Martins #define PHYSDEVOP_pirq_eoi_gmfn_v2 28 4650c88402SJoao Martins struct physdev_pirq_eoi_gmfn { 4750c88402SJoao Martins /* IN */ 4850c88402SJoao Martins xen_pfn_t gmfn; 4950c88402SJoao Martins }; 5050c88402SJoao Martins typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t; 5150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t); 5250c88402SJoao Martins 5350c88402SJoao Martins /* 5450c88402SJoao Martins * Query the status of an IRQ line. 5550c88402SJoao Martins * @arg == pointer to physdev_irq_status_query structure. 5650c88402SJoao Martins */ 5750c88402SJoao Martins #define PHYSDEVOP_irq_status_query 5 5850c88402SJoao Martins struct physdev_irq_status_query { 5950c88402SJoao Martins /* IN */ 6050c88402SJoao Martins uint32_t irq; 6150c88402SJoao Martins /* OUT */ 6250c88402SJoao Martins uint32_t flags; /* XENIRQSTAT_* */ 6350c88402SJoao Martins }; 6450c88402SJoao Martins typedef struct physdev_irq_status_query physdev_irq_status_query_t; 6550c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t); 6650c88402SJoao Martins 6750c88402SJoao Martins /* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */ 6850c88402SJoao Martins #define _XENIRQSTAT_needs_eoi (0) 6950c88402SJoao Martins #define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi) 7050c88402SJoao Martins 7150c88402SJoao Martins /* IRQ shared by multiple guests? */ 7250c88402SJoao Martins #define _XENIRQSTAT_shared (1) 7350c88402SJoao Martins #define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared) 7450c88402SJoao Martins 7550c88402SJoao Martins /* 7650c88402SJoao Martins * Set the current VCPU's I/O privilege level. 7750c88402SJoao Martins * @arg == pointer to physdev_set_iopl structure. 7850c88402SJoao Martins */ 7950c88402SJoao Martins #define PHYSDEVOP_set_iopl 6 8050c88402SJoao Martins struct physdev_set_iopl { 8150c88402SJoao Martins /* IN */ 8250c88402SJoao Martins uint32_t iopl; 8350c88402SJoao Martins }; 8450c88402SJoao Martins typedef struct physdev_set_iopl physdev_set_iopl_t; 8550c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t); 8650c88402SJoao Martins 8750c88402SJoao Martins /* 8850c88402SJoao Martins * Set the current VCPU's I/O-port permissions bitmap. 8950c88402SJoao Martins * @arg == pointer to physdev_set_iobitmap structure. 9050c88402SJoao Martins */ 9150c88402SJoao Martins #define PHYSDEVOP_set_iobitmap 7 9250c88402SJoao Martins struct physdev_set_iobitmap { 9350c88402SJoao Martins /* IN */ 9450c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x00030205 9550c88402SJoao Martins XEN_GUEST_HANDLE(uint8) bitmap; 9650c88402SJoao Martins #else 9750c88402SJoao Martins uint8_t *bitmap; 9850c88402SJoao Martins #endif 9950c88402SJoao Martins uint32_t nr_ports; 10050c88402SJoao Martins }; 10150c88402SJoao Martins typedef struct physdev_set_iobitmap physdev_set_iobitmap_t; 10250c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t); 10350c88402SJoao Martins 10450c88402SJoao Martins /* 10550c88402SJoao Martins * Read or write an IO-APIC register. 10650c88402SJoao Martins * @arg == pointer to physdev_apic structure. 10750c88402SJoao Martins */ 10850c88402SJoao Martins #define PHYSDEVOP_apic_read 8 10950c88402SJoao Martins #define PHYSDEVOP_apic_write 9 11050c88402SJoao Martins struct physdev_apic { 11150c88402SJoao Martins /* IN */ 11250c88402SJoao Martins unsigned long apic_physbase; 11350c88402SJoao Martins uint32_t reg; 11450c88402SJoao Martins /* IN or OUT */ 11550c88402SJoao Martins uint32_t value; 11650c88402SJoao Martins }; 11750c88402SJoao Martins typedef struct physdev_apic physdev_apic_t; 11850c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_apic_t); 11950c88402SJoao Martins 12050c88402SJoao Martins /* 12150c88402SJoao Martins * Allocate or free a physical upcall vector for the specified IRQ line. 12250c88402SJoao Martins * @arg == pointer to physdev_irq structure. 12350c88402SJoao Martins */ 12450c88402SJoao Martins #define PHYSDEVOP_alloc_irq_vector 10 12550c88402SJoao Martins #define PHYSDEVOP_free_irq_vector 11 12650c88402SJoao Martins struct physdev_irq { 12750c88402SJoao Martins /* IN */ 12850c88402SJoao Martins uint32_t irq; 12950c88402SJoao Martins /* IN or OUT */ 13050c88402SJoao Martins uint32_t vector; 13150c88402SJoao Martins }; 13250c88402SJoao Martins typedef struct physdev_irq physdev_irq_t; 13350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); 13450c88402SJoao Martins 13550c88402SJoao Martins #define MAP_PIRQ_TYPE_MSI 0x0 13650c88402SJoao Martins #define MAP_PIRQ_TYPE_GSI 0x1 13750c88402SJoao Martins #define MAP_PIRQ_TYPE_UNKNOWN 0x2 13850c88402SJoao Martins #define MAP_PIRQ_TYPE_MSI_SEG 0x3 13950c88402SJoao Martins #define MAP_PIRQ_TYPE_MULTI_MSI 0x4 14050c88402SJoao Martins 14150c88402SJoao Martins #define PHYSDEVOP_map_pirq 13 14250c88402SJoao Martins struct physdev_map_pirq { 14350c88402SJoao Martins domid_t domid; 14450c88402SJoao Martins /* IN */ 14550c88402SJoao Martins int type; 14650c88402SJoao Martins /* IN (ignored for ..._MULTI_MSI) */ 14750c88402SJoao Martins int index; 14850c88402SJoao Martins /* IN or OUT */ 14950c88402SJoao Martins int pirq; 15050c88402SJoao Martins /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */ 15150c88402SJoao Martins int bus; 15250c88402SJoao Martins /* IN */ 15350c88402SJoao Martins int devfn; 15450c88402SJoao Martins /* IN (also OUT for ..._MULTI_MSI) */ 15550c88402SJoao Martins int entry_nr; 15650c88402SJoao Martins /* IN */ 15750c88402SJoao Martins uint64_t table_base; 15850c88402SJoao Martins }; 15950c88402SJoao Martins typedef struct physdev_map_pirq physdev_map_pirq_t; 16050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); 16150c88402SJoao Martins 16250c88402SJoao Martins #define PHYSDEVOP_unmap_pirq 14 16350c88402SJoao Martins struct physdev_unmap_pirq { 16450c88402SJoao Martins domid_t domid; 16550c88402SJoao Martins /* IN */ 16650c88402SJoao Martins int pirq; 16750c88402SJoao Martins }; 16850c88402SJoao Martins 16950c88402SJoao Martins typedef struct physdev_unmap_pirq physdev_unmap_pirq_t; 17050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t); 17150c88402SJoao Martins 17250c88402SJoao Martins #define PHYSDEVOP_manage_pci_add 15 17350c88402SJoao Martins #define PHYSDEVOP_manage_pci_remove 16 17450c88402SJoao Martins struct physdev_manage_pci { 17550c88402SJoao Martins /* IN */ 17650c88402SJoao Martins uint8_t bus; 17750c88402SJoao Martins uint8_t devfn; 17850c88402SJoao Martins }; 17950c88402SJoao Martins 18050c88402SJoao Martins typedef struct physdev_manage_pci physdev_manage_pci_t; 18150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); 18250c88402SJoao Martins 18350c88402SJoao Martins #define PHYSDEVOP_restore_msi 19 18450c88402SJoao Martins struct physdev_restore_msi { 18550c88402SJoao Martins /* IN */ 18650c88402SJoao Martins uint8_t bus; 18750c88402SJoao Martins uint8_t devfn; 18850c88402SJoao Martins }; 18950c88402SJoao Martins typedef struct physdev_restore_msi physdev_restore_msi_t; 19050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); 19150c88402SJoao Martins 19250c88402SJoao Martins #define PHYSDEVOP_manage_pci_add_ext 20 19350c88402SJoao Martins struct physdev_manage_pci_ext { 19450c88402SJoao Martins /* IN */ 19550c88402SJoao Martins uint8_t bus; 19650c88402SJoao Martins uint8_t devfn; 1978ac98aedSDavid Woodhouse uint32_t is_extfn; 1988ac98aedSDavid Woodhouse uint32_t is_virtfn; 19950c88402SJoao Martins struct { 20050c88402SJoao Martins uint8_t bus; 20150c88402SJoao Martins uint8_t devfn; 20250c88402SJoao Martins } physfn; 20350c88402SJoao Martins }; 20450c88402SJoao Martins 20550c88402SJoao Martins typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t; 20650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t); 20750c88402SJoao Martins 20850c88402SJoao Martins /* 20950c88402SJoao Martins * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() 21050c88402SJoao Martins * hypercall since 0x00030202. 21150c88402SJoao Martins */ 21250c88402SJoao Martins struct physdev_op { 21350c88402SJoao Martins uint32_t cmd; 21450c88402SJoao Martins union { 21550c88402SJoao Martins physdev_irq_status_query_t irq_status_query; 21650c88402SJoao Martins physdev_set_iopl_t set_iopl; 21750c88402SJoao Martins physdev_set_iobitmap_t set_iobitmap; 21850c88402SJoao Martins physdev_apic_t apic_op; 21950c88402SJoao Martins physdev_irq_t irq_op; 22050c88402SJoao Martins } u; 22150c88402SJoao Martins }; 22250c88402SJoao Martins typedef struct physdev_op physdev_op_t; 22350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_op_t); 22450c88402SJoao Martins 22550c88402SJoao Martins #define PHYSDEVOP_setup_gsi 21 22650c88402SJoao Martins struct physdev_setup_gsi { 22750c88402SJoao Martins int gsi; 22850c88402SJoao Martins /* IN */ 22950c88402SJoao Martins uint8_t triggering; 23050c88402SJoao Martins /* IN */ 23150c88402SJoao Martins uint8_t polarity; 23250c88402SJoao Martins /* IN */ 23350c88402SJoao Martins }; 23450c88402SJoao Martins 23550c88402SJoao Martins typedef struct physdev_setup_gsi physdev_setup_gsi_t; 23650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t); 23750c88402SJoao Martins 23850c88402SJoao Martins /* leave PHYSDEVOP 22 free */ 23950c88402SJoao Martins 24050c88402SJoao Martins /* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI 24150c88402SJoao Martins * the hypercall returns a free pirq */ 24250c88402SJoao Martins #define PHYSDEVOP_get_free_pirq 23 24350c88402SJoao Martins struct physdev_get_free_pirq { 24450c88402SJoao Martins /* IN */ 24550c88402SJoao Martins int type; 24650c88402SJoao Martins /* OUT */ 24750c88402SJoao Martins uint32_t pirq; 24850c88402SJoao Martins }; 24950c88402SJoao Martins 25050c88402SJoao Martins typedef struct physdev_get_free_pirq physdev_get_free_pirq_t; 25150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t); 25250c88402SJoao Martins 25350c88402SJoao Martins #define XEN_PCI_MMCFG_RESERVED 0x1 25450c88402SJoao Martins 25550c88402SJoao Martins #define PHYSDEVOP_pci_mmcfg_reserved 24 25650c88402SJoao Martins struct physdev_pci_mmcfg_reserved { 25750c88402SJoao Martins uint64_t address; 25850c88402SJoao Martins uint16_t segment; 25950c88402SJoao Martins uint8_t start_bus; 26050c88402SJoao Martins uint8_t end_bus; 26150c88402SJoao Martins uint32_t flags; 26250c88402SJoao Martins }; 26350c88402SJoao Martins typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t; 26450c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t); 26550c88402SJoao Martins 26650c88402SJoao Martins #define XEN_PCI_DEV_EXTFN 0x1 26750c88402SJoao Martins #define XEN_PCI_DEV_VIRTFN 0x2 26850c88402SJoao Martins #define XEN_PCI_DEV_PXM 0x4 26950c88402SJoao Martins 27050c88402SJoao Martins #define PHYSDEVOP_pci_device_add 25 27150c88402SJoao Martins struct physdev_pci_device_add { 27250c88402SJoao Martins /* IN */ 27350c88402SJoao Martins uint16_t seg; 27450c88402SJoao Martins uint8_t bus; 27550c88402SJoao Martins uint8_t devfn; 27650c88402SJoao Martins uint32_t flags; 27750c88402SJoao Martins struct { 27850c88402SJoao Martins uint8_t bus; 27950c88402SJoao Martins uint8_t devfn; 28050c88402SJoao Martins } physfn; 28150c88402SJoao Martins /* 28250c88402SJoao Martins * Optional parameters array. 28350c88402SJoao Martins * First element ([0]) is PXM domain associated with the device (if 28450c88402SJoao Martins * XEN_PCI_DEV_PXM is set) 28550c88402SJoao Martins */ 28650c88402SJoao Martins uint32_t optarr[XEN_FLEX_ARRAY_DIM]; 28750c88402SJoao Martins }; 28850c88402SJoao Martins typedef struct physdev_pci_device_add physdev_pci_device_add_t; 28950c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t); 29050c88402SJoao Martins 29150c88402SJoao Martins #define PHYSDEVOP_pci_device_remove 26 29250c88402SJoao Martins #define PHYSDEVOP_restore_msi_ext 27 29350c88402SJoao Martins /* 29450c88402SJoao Martins * Dom0 should use these two to announce MMIO resources assigned to 29550c88402SJoao Martins * MSI-X capable devices won't (prepare) or may (release) change. 29650c88402SJoao Martins */ 29750c88402SJoao Martins #define PHYSDEVOP_prepare_msix 30 29850c88402SJoao Martins #define PHYSDEVOP_release_msix 31 29950c88402SJoao Martins struct physdev_pci_device { 30050c88402SJoao Martins /* IN */ 30150c88402SJoao Martins uint16_t seg; 30250c88402SJoao Martins uint8_t bus; 30350c88402SJoao Martins uint8_t devfn; 30450c88402SJoao Martins }; 30550c88402SJoao Martins typedef struct physdev_pci_device physdev_pci_device_t; 30650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t); 30750c88402SJoao Martins 30850c88402SJoao Martins #define PHYSDEVOP_DBGP_RESET_PREPARE 1 30950c88402SJoao Martins #define PHYSDEVOP_DBGP_RESET_DONE 2 31050c88402SJoao Martins 31150c88402SJoao Martins #define PHYSDEVOP_DBGP_BUS_UNKNOWN 0 31250c88402SJoao Martins #define PHYSDEVOP_DBGP_BUS_PCI 1 31350c88402SJoao Martins 31450c88402SJoao Martins #define PHYSDEVOP_dbgp_op 29 31550c88402SJoao Martins struct physdev_dbgp_op { 31650c88402SJoao Martins /* IN */ 31750c88402SJoao Martins uint8_t op; 31850c88402SJoao Martins uint8_t bus; 31950c88402SJoao Martins union { 32050c88402SJoao Martins physdev_pci_device_t pci; 32150c88402SJoao Martins } u; 32250c88402SJoao Martins }; 32350c88402SJoao Martins typedef struct physdev_dbgp_op physdev_dbgp_op_t; 32450c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t); 32550c88402SJoao Martins 32650c88402SJoao Martins /* 32750c88402SJoao Martins * Notify that some PIRQ-bound event channels have been unmasked. 32850c88402SJoao Martins * ** This command is obsolete since interface version 0x00030202 and is ** 32950c88402SJoao Martins * ** unsupported by newer versions of Xen. ** 33050c88402SJoao Martins */ 33150c88402SJoao Martins #define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4 33250c88402SJoao Martins 33350c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00040600 33450c88402SJoao Martins /* 33550c88402SJoao Martins * These all-capitals physdev operation names are superceded by the new names 33650c88402SJoao Martins * (defined above) since interface version 0x00030202. The guard above was 33750c88402SJoao Martins * added post-4.5 only though and hence shouldn't check for 0x00030202. 33850c88402SJoao Martins */ 33950c88402SJoao Martins #define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query 34050c88402SJoao Martins #define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl 34150c88402SJoao Martins #define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap 34250c88402SJoao Martins #define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read 34350c88402SJoao Martins #define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write 34450c88402SJoao Martins #define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector 34550c88402SJoao Martins #define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector 34650c88402SJoao Martins #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi 34750c88402SJoao Martins #define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared 34850c88402SJoao Martins #endif 34950c88402SJoao Martins 35050c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00040200 35150c88402SJoao Martins #define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1 35250c88402SJoao Martins #else 35350c88402SJoao Martins #define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2 35450c88402SJoao Martins #endif 35550c88402SJoao Martins 35650c88402SJoao Martins #endif /* __XEN_PUBLIC_PHYSDEV_H__ */ 35750c88402SJoao Martins 35850c88402SJoao Martins /* 35950c88402SJoao Martins * Local variables: 36050c88402SJoao Martins * mode: C 36150c88402SJoao Martins * c-file-style: "BSD" 36250c88402SJoao Martins * c-basic-offset: 4 36350c88402SJoao Martins * tab-width: 4 36450c88402SJoao Martins * indent-tabs-mode: nil 36550c88402SJoao Martins * End: 36650c88402SJoao Martins */ 367