diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index fc2aaf181..ee3733df2 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -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); diff --git a/hypervisor/dm/vuart.c b/hypervisor/dm/vuart.c index 0dc864faa..5c07f0778 100644 --- a/hypervisor/dm/vuart.c +++ b/hypervisor/dm/vuart.c @@ -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); + } +} diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index 720030fe0..c5ddf0d68 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -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 */ diff --git a/hypervisor/include/dm/vuart.h b/hypervisor/include/dm/vuart.h index 91e946240..51db8f5cc 100644 --- a/hypervisor/include/dm/vuart.h +++ b/hypervisor/include/dm/vuart.h @@ -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);