acrn-hypervisor/hypervisor/include/dm/vpci.h
Geoffroy Van Cutsem 8b16be9185 Remove "All rights reserved" string headers
Many of the license and Intel copyright headers include the "All rights
reserved" string. It is not relevant in the context of the BSD-3-Clause
license that the code is released under. This patch removes those strings
throughout the code (hypervisor, devicemodel and misc).

Tracked-On: #7254
Signed-off-by: Geoffroy Van Cutsem <geoffroy.vancutsem@intel.com>
2022-04-06 13:21:02 +08:00

221 lines
7.3 KiB
C

/*-
* Copyright (c) 2011 NetApp, Inc.
* Copyright (c) 2018 Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef VPCI_H_
#define VPCI_H_
#include <asm/lib/spinlock.h>
#include <pci.h>
#include <list.h>
#define VDEV_LIST_HASHBITS 4U
#define VDEV_LIST_HASHSIZE (1U << VDEV_LIST_HASHBITS)
struct pci_vbar {
bool is_mem64hi; /* this is to indicate the high part of 64 bits MMIO bar */
uint64_t size; /* BAR size */
uint64_t base_gpa; /* BAR guest physical address */
uint64_t base_hpa; /* BAR host physical address */
union pci_bar_type bar_type; /* the low 2(PIO)/4(MMIO) bits of BAR */
uint32_t mask; /* BAR size mask */
};
struct msix_table_entry {
uint64_t addr;
uint32_t data;
uint32_t vector_control;
};
/* MSI capability structure */
struct pci_msi {
bool is_64bit;
uint32_t capoff;
uint32_t caplen;
};
/* MSI-X capability structure */
struct msixcap {
uint8_t capid;
uint8_t nextptr;
uint16_t msgctrl;
uint32_t table_info; /* bar index and offset */
uint32_t pba_info; /* bar index and offset */
} __packed;
struct pci_msix {
struct msix_table_entry table_entries[CONFIG_MAX_MSIX_TABLE_NUM];
uint64_t mmio_gpa;
uint64_t mmio_hpa;
uint64_t mmio_size;
uint32_t capoff;
uint32_t caplen;
uint32_t table_bar;
uint32_t table_offset;
uint32_t table_count;
bool is_vmsix_on_msi;
bool is_vmsix_on_msi_programmed;
};
/* SRIOV capability structure */
struct pci_cap_sriov {
uint32_t capoff;
uint32_t caplen;
/*
* If the vdev is a SRIOV PF vdev, the vbars is used to store
* the bar information that is using to initialize SRIOV VF vdev bar.
*/
struct pci_vbar vbars[PCI_BAR_COUNT];
};
union pci_cfgdata {
uint8_t data_8[PCIE_CONFIG_SPACE_SIZE];
uint16_t data_16[PCIE_CONFIG_SPACE_SIZE >> 1U];
uint32_t data_32[PCIE_CONFIG_SPACE_SIZE >> 2U];
};
struct pci_vdev;
struct pci_vdev_ops {
void (*init_vdev)(struct pci_vdev *vdev);
void (*deinit_vdev)(struct pci_vdev *vdev);
int32_t (*write_vdev_cfg)(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);
int32_t (*read_vdev_cfg)(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val);
};
struct pci_vdev {
struct acrn_vpci *vpci;
/* The bus/device/function triple of the virtual PCI device. */
union pci_bdf bdf;
struct pci_pdev *pdev;
union pci_cfgdata cfgdata;
uint32_t flags;
/* The bar info of the virtual PCI device. */
uint32_t nr_bars; /* 6 for normal device, 2 for bridge, 1 for cardbus */
struct pci_vbar vbars[PCI_BAR_COUNT];
uint8_t prev_capoff; /* Offset of previous vPCI capability */
uint8_t free_capoff; /* Next free offset to add vPCI capability */
struct pci_msi msi;
struct pci_msix msix;
struct pci_cap_sriov sriov;
/* Pointer to the SRIOV VF associated PF's vdev */
struct pci_vdev *phyfun;
/* Pointer to corresponding PCI device's vm_config */
struct acrn_vm_pci_dev_config *pci_dev_config;
/* Pointer to corressponding operations */
const struct pci_vdev_ops *vdev_ops;
/*
* vdev in | HV | pre-VM | Service VM | post-VM
* | | |vdev used by Service VM|vdev used by post-VM|
* ----------------------------------------------------------------------------------------------------------
* parent_user| NULL(HV) | NULL(HV) | NULL(HV) | NULL(HV) | vdev in Service VM
* ----------------------------------------------------------------------------------------------------------
* user | vdev in HV | vdev in pre-VM | vdev in Service VM | vdev in post-VM | vdev in post-VM
*/
struct pci_vdev *parent_user;
struct pci_vdev *user; /* NULL means this device is not used or is a zombie VF */
struct hlist_node link;
void *priv_data;
};
union pci_cfg_addr_reg {
uint32_t value;
struct {
uint32_t reg_num : 8; /* BITs 0-7, Register Number (BITs 0-1, always reserve to 0) */
uint32_t bdf : 16; /* BITs 8-23, BDF Number */
uint32_t resv : 7; /* BITs 24-30, Reserved */
uint32_t enable : 1; /* BITs 31, Enable bit */
} bits;
};
/* start address & end address of MMIO BAR */
struct pci_mmio_res {
uint64_t start;
uint64_t end;
};
struct acrn_vpci {
spinlock_t lock;
union pci_cfg_addr_reg addr;
struct pci_mmcfg_region pci_mmcfg;
uint32_t pci_vdev_cnt;
struct pci_mmio_res res32; /* 32-bit mmio start/end address */
struct pci_mmio_res res64; /* 64-bit mmio start/end address */
struct pci_vdev pci_vdevs[CONFIG_MAX_PCI_DEV_NUM];
struct hlist_head vdevs_hlist_heads [VDEV_LIST_HASHSIZE];
};
struct acrn_vm;
extern const struct pci_vdev_ops vhostbridge_ops;
extern const struct pci_vdev_ops vpci_bridge_ops;
int32_t init_vpci(struct acrn_vm *vm);
void deinit_vpci(struct acrn_vm *vm);
struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
struct acrn_pcidev;
int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev);
int32_t vpci_deassign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev);
struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_config *dev_config, struct pci_vdev *parent_pf_vdev);
static inline bool is_pci_io_bar(struct pci_vbar *vbar)
{
return ((vbar->bar_type.io_space.indicator == 1U) && (!vbar->is_mem64hi));
}
static inline bool is_pci_mem_bar(struct pci_vbar *vbar)
{
return ((vbar->is_mem64hi) || ((vbar->bar_type.mem_space.indicator == 0U)));
}
/* Reserved PCI BAR type: 1.Memory bar with reserved memory type; 2.IO bar reserved bit is set */
static inline bool is_pci_reserved_bar(struct pci_vbar *vbar)
{
return (((vbar->bar_type.mem_space.indicator == 0U) && ((vbar->bar_type.mem_space.mem_type & 0x1U) == 0x1U) && (!vbar->is_mem64hi)) ||
((vbar->bar_type.io_space.indicator == 1U) && (vbar->bar_type.io_space.reserved == 1U)));
}
static inline bool is_pci_mem32_bar(struct pci_vbar *vbar)
{
return ((vbar->bar_type.mem_space.indicator == 0U) && (vbar->bar_type.mem_space.mem_type == 0U) && (!vbar->is_mem64hi));
}
static inline bool is_pci_mem64lo_bar(struct pci_vbar *vbar)
{
return ((vbar->bar_type.mem_space.indicator == 0U) && (vbar->bar_type.mem_space.mem_type == 2U) && (!vbar->is_mem64hi));
}
#endif /* VPCI_H_ */