mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-03 12:49:45 +00:00
HV: vuart: enable connect mode for VM
Enable connection mode for vuart, so that vuart in different VMs can set up connection. In pre-launched VM's configuration file, ttyS1 is set to be the connection port. To enable it in post-launched VM, just add vuart configuration. Tracked-On: #2987 Signed-off-by: Conghui Chen <conghui.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
235d886103
commit
bed57dd242
@ -168,14 +168,32 @@ static void vuart_toggle_intr(const struct acrn_vuart *vu)
|
|||||||
vioapic_set_irqline_lock(vu->vm, vu->irq, operation);
|
vioapic_set_irqline_lock(vu->vm, vu->irq, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vuart_write_to_target(struct acrn_vuart *vu, uint8_t value_u8)
|
||||||
|
{
|
||||||
|
vuart_lock(vu);
|
||||||
|
if (vu->active) {
|
||||||
|
fifo_putchar(&vu->rxfifo, (char)value_u8);
|
||||||
|
vu->thre_int_pending = true;
|
||||||
|
vuart_toggle_intr(vu);
|
||||||
|
}
|
||||||
|
vuart_unlock(vu);
|
||||||
|
}
|
||||||
|
|
||||||
static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
||||||
__unused size_t width, uint32_t value)
|
__unused size_t width, uint32_t value)
|
||||||
{
|
{
|
||||||
uint16_t offset = offset_arg;
|
uint16_t offset = offset_arg;
|
||||||
struct acrn_vuart *vu = find_vuart_by_port(vm, offset);
|
struct acrn_vuart *vu = find_vuart_by_port(vm, offset);
|
||||||
uint8_t value_u8 = (uint8_t)value;
|
uint8_t value_u8 = (uint8_t)value;
|
||||||
|
struct acrn_vuart *target_vu = NULL;
|
||||||
|
|
||||||
offset -= vu->port_base;
|
offset -= vu->port_base;
|
||||||
|
target_vu = vu->target_vu;
|
||||||
|
if ((offset == UART16550_THR) && target_vu) {
|
||||||
|
vuart_write_to_target(target_vu, value_u8);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
vuart_lock(vu);
|
vuart_lock(vu);
|
||||||
/*
|
/*
|
||||||
* Take care of the special case DLAB accesses first
|
* Take care of the special case DLAB accesses first
|
||||||
@ -431,6 +449,7 @@ static void vuart_setup(struct acrn_vm *vm,
|
|||||||
vu->vm = vm;
|
vu->vm = vm;
|
||||||
vuart_fifo_init(vu);
|
vuart_fifo_init(vu);
|
||||||
vuart_lock_init(vu);
|
vuart_lock_init(vu);
|
||||||
|
vu->target_vu = NULL;
|
||||||
if (vu_config->type == VUART_LEGACY_PIO) {
|
if (vu_config->type == VUART_LEGACY_PIO) {
|
||||||
vu->port_base = vu_config->addr.port_base;
|
vu->port_base = vu_config->addr.port_base;
|
||||||
vu->irq = vu_config->irq;
|
vu->irq = vu_config->irq;
|
||||||
@ -443,6 +462,49 @@ static void vuart_setup(struct acrn_vm *vm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct acrn_vuart *find_active_target_vuart(struct vuart_config *vu_config)
|
||||||
|
{
|
||||||
|
struct acrn_vm *target_vm = NULL;
|
||||||
|
struct acrn_vuart *target_vu = NULL, *ret_vu = NULL;
|
||||||
|
uint16_t target_vmid, target_vuid;
|
||||||
|
|
||||||
|
target_vmid = vu_config->t_vuart.vm_id;
|
||||||
|
target_vuid = vu_config->t_vuart.vuart_id;
|
||||||
|
if (target_vmid < CONFIG_MAX_VM_NUM)
|
||||||
|
target_vm = get_vm_from_vmid(target_vmid);
|
||||||
|
|
||||||
|
if (target_vuid < MAX_VUART_NUM_PER_VM)
|
||||||
|
target_vu = &target_vm->vuart[target_vuid];
|
||||||
|
|
||||||
|
if (target_vu && target_vu->active) {
|
||||||
|
ret_vu = target_vu;
|
||||||
|
}
|
||||||
|
return ret_vu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vuart_setup_connection(struct acrn_vm *vm,
|
||||||
|
struct vuart_config *vu_config, uint16_t vuart_idx)
|
||||||
|
{
|
||||||
|
struct acrn_vuart *vu, *t_vu;
|
||||||
|
|
||||||
|
vu = &vm->vuart[vuart_idx];
|
||||||
|
if (vu->active) {
|
||||||
|
t_vu = find_active_target_vuart(vu_config);
|
||||||
|
if (t_vu && (t_vu->target_vu == NULL)) {
|
||||||
|
vu->target_vu = t_vu;
|
||||||
|
t_vu->target_vu = vu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vuart_deinit_connect(struct acrn_vuart *vu)
|
||||||
|
{
|
||||||
|
struct acrn_vuart *t_vu = vu->target_vu;
|
||||||
|
|
||||||
|
t_vu->target_vu = NULL;
|
||||||
|
vu->target_vu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_vuart_intx(struct acrn_vm *vm, uint32_t intx_pin)
|
bool is_vuart_intx(struct acrn_vm *vm, uint32_t intx_pin)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -465,6 +527,13 @@ void vuart_init(struct acrn_vm *vm, struct vuart_config *vu_config)
|
|||||||
vu_config[i].addr.port_base == INVALID_COM_BASE)
|
vu_config[i].addr.port_base == INVALID_COM_BASE)
|
||||||
continue;
|
continue;
|
||||||
vuart_setup(vm, &vu_config[i], i);
|
vuart_setup(vm, &vu_config[i], i);
|
||||||
|
/*
|
||||||
|
* The first vuart is used for VM console.
|
||||||
|
* The rest of vuarts are used for connection.
|
||||||
|
*/
|
||||||
|
if (i != 0) {
|
||||||
|
vuart_setup_connection(vm, &vu_config[i], i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,6 +547,8 @@ void vuart_deinit(struct acrn_vm *vm)
|
|||||||
|
|
||||||
for (i = 0; i < MAX_VUART_NUM_PER_VM; i++) {
|
for (i = 0; i < MAX_VUART_NUM_PER_VM; i++) {
|
||||||
vm->vuart[i].active = false;
|
vm->vuart[i].active = false;
|
||||||
|
if (vm->vuart[i].target_vu)
|
||||||
|
vuart_deinit_connect(&vm->vuart[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ struct acrn_vuart {
|
|||||||
char vuart_tx_buf[TX_BUF_SIZE];
|
char vuart_tx_buf[TX_BUF_SIZE];
|
||||||
bool thre_int_pending; /* THRE interrupt pending */
|
bool thre_int_pending; /* THRE interrupt pending */
|
||||||
bool active;
|
bool active;
|
||||||
|
struct acrn_vuart *target_vu; /* Pointer to target vuart */
|
||||||
struct acrn_vm *vm;
|
struct acrn_vm *vm;
|
||||||
spinlock_t lock; /* protects all softc elements */
|
spinlock_t lock; /* protects all softc elements */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user