mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 04:02:05 +00:00
HV: pci-vuart: pci based vuart emulation
Add emulation for pci based vuart device mcs9900 at hv land. add struct pci_vdev_ops vuart_pci_ops, the vdev callbalks for vuart. How to use In misc/vm_configs/scenarios/<SCENARIO>/<BOARD>/pci_dev.c, add pci vuart config to vm_pci_devs[] array. For example: struct acrn_vm_pci_dev_config vm0_pci_devs[] = { /* console vuart setting*/ { .emu_type = PCI_DEV_TYPE_HVEMUL, .vbdf.bits = {.b = 0x00U, .d = 0x04U, .f = 0x00U}, .vdev_ops = &vmcs_ops, .vbar_base[0] = 0x80001000, /* mmio bar */ .vbar_base[1] = 0x80002000, /* msix bar */ .vuart_idx = 0, }, /* communication vuart setting */ { .emu_type = PCI_DEV_TYPE_HVEMUL, .vbdf.bits = {.b = 0x00U, .d = 0x05U, .f = 0x00U}, .vdev_ops = &vmcs_ops, .vbar_base[0] = 0x80003000, .vbar_base[1] = 0x80004000, .vuart_idx = 1, .t_vuart.vm_id = 1U, .t_vuart.vuart_id = 1U, }, } Tracked-On: #5394 Signed-off-by: Tao Yuhong <yuhong.tao@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
4120bd391a
commit
55b7fae67a
@ -309,6 +309,7 @@ VP_DM_C_SRCS += dm/vpci/vmsi.c
|
||||
VP_DM_C_SRCS += dm/vpci/vmsix.c
|
||||
VP_DM_C_SRCS += dm/vpci/vmsix_on_msi.c
|
||||
VP_DM_C_SRCS += dm/vpci/vsriov.c
|
||||
VP_DM_C_SRCS += dm/vpci/vmcs9900.c
|
||||
VP_DM_C_SRCS += dm/mmio_dev.c
|
||||
VP_DM_C_SRCS += dm/vgpio.c
|
||||
VP_DM_C_SRCS += arch/x86/guest/vlapic.c
|
||||
|
152
hypervisor/dm/vpci/vmcs9900.c
Normal file
152
hypervisor/dm/vpci/vmcs9900.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <vm.h>
|
||||
#include <ept.h>
|
||||
#include <vpci.h>
|
||||
#include <logmsg.h>
|
||||
#include <vmcs9900.h>
|
||||
#include "vpci_priv.h"
|
||||
|
||||
#define MCS9900_MMIO_BAR 0U
|
||||
#define MCS9900_MSIX_BAR 1U
|
||||
|
||||
static int32_t read_vmcs9900_cfg(const struct pci_vdev *vdev,
|
||||
uint32_t offset, uint32_t bytes,
|
||||
uint32_t * val)
|
||||
{
|
||||
if (vbar_access(vdev, offset)) {
|
||||
*val = pci_vdev_read_vbar(vdev, pci_bar_index(offset));
|
||||
} else {
|
||||
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t vmcs9900_mmio_handler(struct io_request *io_req, void *data)
|
||||
{
|
||||
struct mmio_request *mmio = &io_req->reqs.mmio;
|
||||
struct pci_vdev *vdev = (struct pci_vdev *)data;
|
||||
struct acrn_vuart *vu = vdev->priv_data;
|
||||
struct pci_vbar *vbar = &vdev->vbars[MCS9900_MMIO_BAR];
|
||||
uint16_t offset;
|
||||
|
||||
offset = mmio->address - vbar->base_gpa;
|
||||
|
||||
if (mmio->direction == REQUEST_READ) {
|
||||
mmio->value = vuart_read_reg(vu, offset);
|
||||
} else {
|
||||
vuart_write_reg(vu, offset, (uint8_t) mmio->value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void map_vmcs9900_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
struct acrn_vuart *vu = vdev->priv_data;
|
||||
struct acrn_vm *vm = vpci2vm(vdev->vpci);
|
||||
struct pci_vbar *vbar = &vdev->vbars[idx];
|
||||
|
||||
if ((idx == MCS9900_MMIO_BAR) && (vbar->base_gpa != 0UL)) {
|
||||
register_mmio_emulation_handler(vm, vmcs9900_mmio_handler,
|
||||
vbar->base_gpa, vbar->base_gpa + vbar->size, vdev, false);
|
||||
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, vbar->base_gpa, vbar->size);
|
||||
vu->active = true;
|
||||
} else if ((idx == MCS9900_MSIX_BAR) && (vbar->base_gpa != 0UL)) {
|
||||
register_mmio_emulation_handler(vm, vmsix_handle_table_mmio_access, vbar->base_gpa,
|
||||
(vbar->base_gpa + vbar->size), vdev, false);
|
||||
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, vbar->base_gpa, vbar->size);
|
||||
vdev->msix.mmio_gpa = vbar->base_gpa;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void unmap_vmcs9900_vbar(struct pci_vdev *vdev, uint32_t idx)
|
||||
{
|
||||
struct acrn_vuart *vu = vdev->priv_data;
|
||||
struct acrn_vm *vm = vpci2vm(vdev->vpci);
|
||||
struct pci_vbar *vbar = &vdev->vbars[idx];
|
||||
|
||||
if ((idx == MCS9900_MMIO_BAR) && (vbar->base_gpa != 0UL)) {
|
||||
vu->active = false;
|
||||
}
|
||||
unregister_mmio_emulation_handler(vm, vbar->base_gpa, vbar->base_gpa + vbar->size);
|
||||
}
|
||||
|
||||
static int32_t write_vmcs9900_cfg(struct pci_vdev *vdev, uint32_t offset,
|
||||
uint32_t bytes, uint32_t val)
|
||||
{
|
||||
if (vbar_access(vdev, offset)) {
|
||||
vpci_update_one_vbar(vdev, pci_bar_index(offset), val,
|
||||
map_vmcs9900_vbar, unmap_vmcs9900_vbar);
|
||||
} else if (msixcap_access(vdev, offset)) {
|
||||
write_vmsix_cap_reg(vdev, offset, bytes, val);
|
||||
} else {
|
||||
pci_vdev_write_vcfg(vdev, offset, bytes, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_vmcs9900(struct pci_vdev *vdev)
|
||||
{
|
||||
struct acrn_vm_pci_dev_config *pci_cfg = vdev->pci_dev_config;
|
||||
struct acrn_vm *vm = vpci2vm(vdev->vpci);
|
||||
struct pci_vbar *mmio_vbar = &vdev->vbars[MCS9900_MMIO_BAR];
|
||||
struct pci_vbar *msix_vbar = &vdev->vbars[MCS9900_MSIX_BAR];
|
||||
struct acrn_vuart *vu = &vm->vuart[pci_cfg->vuart_idx];
|
||||
|
||||
/* 8250-pci compartiable device */
|
||||
pci_vdev_write_vcfg(vdev, PCIR_VENDOR, 2U, MCS9900_VENDOR);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_DEVICE, 2U, MCS9900_DEV);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_CLASS, 1U, PCIC_SIMPLECOMM);
|
||||
pci_vdev_write_vcfg(vdev, PCIV_SUB_SYSTEM_ID, 2U, 0x1000U);
|
||||
pci_vdev_write_vcfg(vdev, PCIV_SUB_VENDOR_ID, 2U, 0xa000U);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_SUBCLASS, 1U, 0x0U);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_CLASS_CODE, 1U, 0x2U);
|
||||
|
||||
add_vmsix_capability(vdev, 1, MCS9900_MSIX_BAR);
|
||||
|
||||
/* initialize vuart-pci mem bar */
|
||||
mmio_vbar->type = PCIBAR_MEM32;
|
||||
mmio_vbar->size = 0x1000U;
|
||||
mmio_vbar->base_gpa = pci_cfg->vbar_base[MCS9900_MMIO_BAR];
|
||||
mmio_vbar->mask = (uint32_t) (~(mmio_vbar->size - 1UL));
|
||||
mmio_vbar->fixed = (uint32_t) (mmio_vbar->base_gpa & PCI_BASE_ADDRESS_MEM_MASK);
|
||||
|
||||
/* initialize vuart-pci msix bar */
|
||||
msix_vbar->type = PCIBAR_MEM32;
|
||||
msix_vbar->size = 0x1000U;
|
||||
msix_vbar->base_gpa = pci_cfg->vbar_base[MCS9900_MSIX_BAR];
|
||||
msix_vbar->mask = (uint32_t) (~(msix_vbar->size - 1UL));
|
||||
msix_vbar->fixed = (uint32_t) (msix_vbar->base_gpa & PCI_BASE_ADDRESS_MEM_MASK);
|
||||
|
||||
vdev->nr_bars = 2;
|
||||
|
||||
pci_vdev_write_vbar(vdev, MCS9900_MMIO_BAR, mmio_vbar->base_gpa);
|
||||
pci_vdev_write_vbar(vdev, MCS9900_MSIX_BAR, msix_vbar->base_gpa);
|
||||
|
||||
/* init acrn_vuart */
|
||||
pr_info("init acrn_vuart[%d]", pci_cfg->vuart_idx);
|
||||
vdev->priv_data = vu;
|
||||
init_pci_vuart(vdev);
|
||||
|
||||
vdev->user = vdev;
|
||||
}
|
||||
|
||||
static void deinit_vmcs9900(struct pci_vdev *vdev)
|
||||
{
|
||||
deinit_pci_vuart(vdev);
|
||||
vdev->user = NULL;
|
||||
}
|
||||
|
||||
const struct pci_vdev_ops vmcs9900_ops = {
|
||||
.init_vdev = init_vmcs9900,
|
||||
.deinit_vdev = deinit_vmcs9900,
|
||||
.write_vdev_cfg = write_vmcs9900_cfg,
|
||||
.read_vdev_cfg = read_vmcs9900_cfg,
|
||||
};
|
15
hypervisor/include/dm/vmcs9900.h
Normal file
15
hypervisor/include/dm/vmcs9900.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef VMCS9900_H
|
||||
#define VMCS9900_H
|
||||
|
||||
#define MCS9900_VENDOR 0x9710U
|
||||
#define MCS9900_DEV 0x9900U
|
||||
|
||||
extern const struct pci_vdev_ops vmcs9900_ops;
|
||||
|
||||
#endif
|
@ -74,6 +74,7 @@
|
||||
#define PCIR_STATUS 0x06U
|
||||
#define PCIM_STATUS_CAPPRESENT 0x0010U
|
||||
#define PCIR_REVID 0x08U
|
||||
#define PCIR_CLASS_CODE 0x09U
|
||||
#define PCIR_SUBCLASS 0x0AU
|
||||
#define PCIR_CLASS 0x0BU
|
||||
#define PCIR_HDRTYPE 0x0EU
|
||||
@ -91,6 +92,7 @@
|
||||
#define PCIM_BAR_MEM_64 0x04U
|
||||
#define PCIM_BAR_MEM_BASE 0xFFFFFFF0U
|
||||
#define PCIV_SUB_VENDOR_ID 0x2CU
|
||||
#define PCIV_SUB_SYSTEM_ID 0x2EU
|
||||
#define PCIR_CAP_PTR 0x34U
|
||||
#define PCIR_CAP_PTR_CARDBUS 0x14U
|
||||
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
||||
@ -98,6 +100,7 @@
|
||||
#define PCIR_INTERRUPT_LINE 0x3cU
|
||||
#define PCIR_INTERRUPT_PIN 0x3dU
|
||||
|
||||
#define PCIC_SIMPLECOMM 0x07U
|
||||
/* config registers for header type 1 (PCI-to-PCI bridge) devices */
|
||||
#define PCIR_PRIBUS_1 0x18U
|
||||
#define PCIR_SECBUS_1 0x19U
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <rdt.h>
|
||||
#include <vuart.h>
|
||||
#include <ivshmem.h>
|
||||
#include <vmcs9900.h>
|
||||
#include <vpci.h>
|
||||
#include <hv_prebuild.h>
|
||||
|
||||
@ -23,6 +24,7 @@ static uint8_t safety_vm_uuid1[16] = SAFETY_VM_UUID1;
|
||||
struct acrn_vm_pci_dev_config sos_pci_devs[CONFIG_MAX_PCI_DEV_NUM];
|
||||
const struct pci_vdev_ops vhostbridge_ops;
|
||||
const struct pci_vdev_ops vpci_ivshmem_ops;
|
||||
const struct pci_vdev_ops vmcs9900_ops;
|
||||
|
||||
#define PLATFORM_CPUS_MASK ((1UL << MAX_PCPU_NUM) - 1UL)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user