xref: /qemu/include/hw/xen/interface/physdev.h (revision 8ac98aed)
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