HV: decouple legacy vuart interface from acrn_vuart layer

support pci-vuart type, and refine:
1.Rename init_vuart() to init_legacy_vuarts(), only init PIO type.
2.Rename deinit_vuart() to deinit_legacy_vuarts(), only deinit PIO type.
3.Move io handler code out of setup_vuart(), into init_legacy_vuarts()
4.add init_pci_vuart(), deinit_pci_vuart, for one pci vuart vdev.

and some change from requirement:
1.Increase MAX_VUART_NUM_PER_VM to 8.

Tracked-On: #5394
Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Tao Yuhong 2020-10-21 09:16:24 -04:00 committed by wenlingz
parent 6ed7b8767c
commit 4120bd391a
4 changed files with 66 additions and 34 deletions

View File

@ -478,7 +478,7 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v
enable_iommu();
/* Create virtual uart;*/
init_vuart(vm, vm_config->vuart);
init_legacy_vuarts(vm, vm_config->vuart);
register_reset_port_handler(vm);
@ -622,7 +622,7 @@ int32_t shutdown_vm(struct acrn_vm *vm)
ptirq_remove_configured_intx_remappings(vm);
deinit_vuart(vm);
deinit_legacy_vuarts(vm);
deinit_vpci(vm);

View File

@ -561,8 +561,7 @@ static bool vuart_register_io_handler(struct acrn_vm *vm, uint16_t port_base, ui
return ret;
}
static void setup_vuart(struct acrn_vm *vm,
const struct vuart_config *vu_config, uint16_t vuart_idx)
static void setup_vuart(struct acrn_vm *vm, uint16_t vuart_idx)
{
uint32_t divisor;
struct acrn_vuart *vu = &vm->vuart[vuart_idx];
@ -578,16 +577,6 @@ static void setup_vuart(struct acrn_vm *vm,
vu->ier = 0U;
vuart_toggle_intr(vu);
vu->target_vu = NULL;
if (vu_config->type == VUART_LEGACY_PIO) {
vu->port_base = vu_config->addr.port_base;
vu->irq = vu_config->irq;
if (vuart_register_io_handler(vm, vu->port_base, vuart_idx) != 0U) {
vu->active = true;
}
} else {
/*TODO: add pci vuart support here*/
printf("PCI vuart is not support\n");
}
}
static struct acrn_vuart *find_active_target_vuart(const struct vuart_config *vu_config)
@ -647,36 +636,73 @@ bool is_vuart_intx(const struct acrn_vm *vm, uint32_t intx_gsi)
return ret;
}
void init_vuart(struct acrn_vm *vm, const struct vuart_config *vu_config)
void init_legacy_vuarts(struct acrn_vm *vm, const struct vuart_config *vu_config)
{
uint8_t i;
struct acrn_vuart *vu;
for (i = 0U; i < MAX_VUART_NUM_PER_VM; i++) {
vm->vuart[i].active = false;
/* This vuart is not exist */
if ((vu_config[i].type == VUART_LEGACY_PIO) &&
(vu_config[i].addr.port_base == INVALID_COM_BASE)) {
continue;
}
setup_vuart(vm, &vu_config[i], i);
/*
* The first vuart is used for VM console.
* The rest of vuarts are used for connection.
*/
if (i != 0U) {
vuart_setup_connection(vm, &vu_config[i], i);
(vu_config[i].addr.port_base != INVALID_COM_BASE)) {
vu = &vm->vuart[i];
setup_vuart(vm, i);
vu->port_base = vu_config[i].addr.port_base;
vu->irq = vu_config[i].irq;
if (vuart_register_io_handler(vm, vu->port_base, i) != 0U) {
vu->active = true;
}
/*
* The first vuart is used for VM console.
* The rest of vuarts are used for connection.
*/
if (i != 0U) {
vuart_setup_connection(vm, &vu_config[i], i);
}
}
}
}
void deinit_vuart(struct acrn_vm *vm)
void deinit_legacy_vuarts(struct acrn_vm *vm)
{
uint8_t i;
for (i = 0U; i < MAX_VUART_NUM_PER_VM; i++) {
vm->vuart[i].active = false;
if (vm->vuart[i].target_vu != NULL) {
vuart_deinit_connection(&vm->vuart[i]);
if (vm->vuart[i].port_base != INVALID_COM_BASE) {
vm->vuart[i].active = false;
if (vm->vuart[i].target_vu != NULL) {
vuart_deinit_connection(&vm->vuart[i]);
}
}
}
}
void init_pci_vuart(struct pci_vdev *vdev)
{
struct acrn_vuart *vu = vdev->priv_data;
struct acrn_vm_pci_dev_config *pci_cfg = vdev->pci_dev_config;
uint16_t idx = pci_cfg->vuart_idx;
struct acrn_vm *vm = container_of(vdev->vpci, struct acrn_vm, vpci);
struct acrn_vm_config *vm_cfg = get_vm_config(vm->vm_id);
setup_vuart(vm, idx);
vu->vdev = vdev;
vm_cfg->vuart[idx].type = VUART_PCI;
vm_cfg->vuart[idx].t_vuart.vm_id = pci_cfg->t_vuart.vm_id;
vm_cfg->vuart[idx].t_vuart.vuart_id = pci_cfg->t_vuart.vuart_id;
vu->active = true;
if (pci_cfg->vuart_idx != 0U) {
vuart_setup_connection(vm, &vm_cfg->vuart[idx], idx);
}
}
void deinit_pci_vuart(struct pci_vdev *vdev)
{
struct acrn_vuart *vu = vdev->priv_data;
vu->active = false;
if (vu->target_vu != NULL) {
vuart_deinit_connection(vu);
}
}

View File

@ -21,7 +21,7 @@
#define AFFINITY_CPU(n) (1UL << (n))
#define MAX_VCPUS_PER_VM MAX_PCPU_NUM
#define MAX_VUART_NUM_PER_VM 2U
#define MAX_VUART_NUM_PER_VM 8U
#define MAX_VM_OS_NAME_LEN 32U
#define MAX_MOD_TAG_LEN 32U
@ -150,6 +150,9 @@ struct acrn_vm_pci_dev_config {
union pci_bdf vbdf; /* virtual BDF of PCI device */
union pci_bdf pbdf; /* physical BDF of PCI device */
char shm_region_name[32]; /* TODO: combine pbdf and shm_region_name into a union member */
/* TODO: All device specific attributions need move to other place */
struct target_vuart t_vuart;
uint16_t vuart_idx;
uint64_t vbar_base[PCI_BAR_COUNT]; /* vbar base address of PCI device, which is power-on default value */
struct pci_pdev *pdev; /* the physical PCI device if it's a PT device */
const struct pci_vdev_ops *vdev_ops; /* operations for PCI CFG read/write */

View File

@ -78,11 +78,14 @@ struct acrn_vuart {
bool active;
struct acrn_vuart *target_vu; /* Pointer to target vuart */
struct acrn_vm *vm;
struct pci_vdev *vdev; /* pci vuart */
spinlock_t lock; /* protects all softc elements */
};
void init_vuart(struct acrn_vm *vm, const struct vuart_config *vu_config);
void deinit_vuart(struct acrn_vm *vm);
void init_legacy_vuarts(struct acrn_vm *vm, const struct vuart_config *vu_config);
void deinit_legacy_vuarts(struct acrn_vm *vm);
void init_pci_vuart(struct pci_vdev *vdev);
void deinit_pci_vuart(struct pci_vdev *vdev);
void vuart_putchar(struct acrn_vuart *vu, char ch);
char vuart_getchar(struct acrn_vuart *vu);