mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 23:13:26 +00:00
HV: vuart: split vuart_write
Split vuart_write as its cyclomatic complexity is greater than 20. 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
14e2c66a1e
commit
926fe655d5
@ -218,35 +218,51 @@ static uint8_t get_modem_status(uint8_t mcr)
|
|||||||
return msr;
|
return msr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
static uint8_t update_modem_status(uint8_t new_msr, uint8_t old_msr)
|
||||||
__unused size_t width, uint32_t value)
|
{
|
||||||
|
uint8_t update_msr = old_msr;
|
||||||
|
/*
|
||||||
|
* Detect if there has been any change between the
|
||||||
|
* previous and the new value of MSR. If there is
|
||||||
|
* then assert the appropriate MSR delta bit.
|
||||||
|
*/
|
||||||
|
if (((new_msr & MSR_CTS) ^ (old_msr & MSR_CTS)) != 0U) {
|
||||||
|
update_msr |= MSR_DCTS;
|
||||||
|
}
|
||||||
|
if (((new_msr & MSR_DSR) ^ (old_msr & MSR_DSR)) != 0U) {
|
||||||
|
update_msr |= MSR_DDSR;
|
||||||
|
}
|
||||||
|
if (((new_msr & MSR_DCD) ^ (old_msr & MSR_DCD)) != 0U) {
|
||||||
|
update_msr |= MSR_DDCD;
|
||||||
|
}
|
||||||
|
if (((new_msr & MSR_RI) == 0U) && ((old_msr & MSR_RI) != 0U)) {
|
||||||
|
update_msr |= MSR_TERI;
|
||||||
|
}
|
||||||
|
update_msr &= MSR_DELTA_MASK;
|
||||||
|
update_msr |= new_msr;
|
||||||
|
|
||||||
|
return update_msr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre: vu != NULL
|
||||||
|
*/
|
||||||
|
static void write_reg(struct acrn_vuart *vu, uint16_t reg, uint8_t value_u8)
|
||||||
{
|
{
|
||||||
uint16_t offset = offset_arg;
|
|
||||||
struct acrn_vuart *vu = find_vuart_by_port(vm, offset);
|
|
||||||
uint8_t value_u8 = (uint8_t)value;
|
|
||||||
struct acrn_vuart *target_vu = NULL;
|
|
||||||
uint8_t msr;
|
uint8_t msr;
|
||||||
|
|
||||||
if (vu != NULL) {
|
|
||||||
offset -= vu->port_base;
|
|
||||||
target_vu = vu->target_vu;
|
|
||||||
|
|
||||||
if (!(vu->mcr & MCR_LOOPBACK) &&
|
|
||||||
(offset == UART16550_THR) && (target_vu != NULL)) {
|
|
||||||
send_to_target(target_vu, value_u8);
|
|
||||||
} else {
|
|
||||||
vuart_lock(vu);
|
vuart_lock(vu);
|
||||||
/*
|
/*
|
||||||
* Take care of the special case DLAB accesses first
|
* Take care of the special case DLAB accesses first
|
||||||
*/
|
*/
|
||||||
if ((vu->lcr & LCR_DLAB) != 0U && offset == UART16550_DLL) {
|
if (((vu->lcr & LCR_DLAB) != 0U) && (reg == UART16550_DLL)) {
|
||||||
vu->dll = value_u8;
|
vu->dll = value_u8;
|
||||||
} else if ((vu->lcr & LCR_DLAB) != 0U && offset == UART16550_DLM) {
|
} else if (((vu->lcr & LCR_DLAB) != 0U) && (reg == UART16550_DLM)) {
|
||||||
vu->dlh = value_u8;
|
vu->dlh = value_u8;
|
||||||
} else {
|
} else {
|
||||||
switch (offset) {
|
switch (reg) {
|
||||||
case UART16550_THR:
|
case UART16550_THR:
|
||||||
if (vu->mcr & MCR_LOOPBACK) {
|
if ((vu->mcr & MCR_LOOPBACK) != 0U) {
|
||||||
fifo_putchar(&vu->rxfifo, (char)value_u8);
|
fifo_putchar(&vu->rxfifo, (char)value_u8);
|
||||||
vu->lsr |= LSR_OE;
|
vu->lsr |= LSR_OE;
|
||||||
} else {
|
} else {
|
||||||
@ -272,7 +288,6 @@ static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
|||||||
if ((value_u8 & FCR_RFR) != 0U) {
|
if ((value_u8 & FCR_RFR) != 0U) {
|
||||||
fifo_reset(&vu->rxfifo);
|
fifo_reset(&vu->rxfifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
vu->fcr = value_u8 & (FCR_FIFOE | FCR_DMA | FCR_RX_MASK);
|
vu->fcr = value_u8 & (FCR_FIFOE | FCR_DMA | FCR_RX_MASK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -281,27 +296,13 @@ static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
|||||||
break;
|
break;
|
||||||
case UART16550_MCR:
|
case UART16550_MCR:
|
||||||
/* Apply mask so that bits 5-7 are 0 */
|
/* Apply mask so that bits 5-7 are 0 */
|
||||||
vu->mcr = value & 0x1F;
|
vu->mcr = value_u8 & 0x1FU;
|
||||||
msr = get_modem_status(vu->mcr);
|
msr = get_modem_status(vu->mcr);
|
||||||
/*
|
|
||||||
* Detect if there has been any change between the
|
|
||||||
* previous and the new value of MSR. If there is
|
|
||||||
* then assert the appropriate MSR delta bit.
|
|
||||||
*/
|
|
||||||
if ((msr & MSR_CTS) ^ (vu->msr & MSR_CTS))
|
|
||||||
vu->msr |= MSR_DCTS;
|
|
||||||
if ((msr & MSR_DSR) ^ (vu->msr & MSR_DSR))
|
|
||||||
vu->msr |= MSR_DDSR;
|
|
||||||
if ((msr & MSR_DCD) ^ (vu->msr & MSR_DCD))
|
|
||||||
vu->msr |= MSR_DDCD;
|
|
||||||
if ((vu->msr & MSR_RI) != 0 && (msr & MSR_RI) == 0)
|
|
||||||
vu->msr |= MSR_TERI;
|
|
||||||
/*
|
/*
|
||||||
* Update the value of MSR while retaining the delta
|
* Update the value of MSR while retaining the delta
|
||||||
* bits.
|
* bits.
|
||||||
*/
|
*/
|
||||||
vu->msr &= MSR_DELTA_MASK;
|
vu->msr = update_modem_status(msr, vu->msr);
|
||||||
vu->msr |= msr;
|
|
||||||
break;
|
break;
|
||||||
case UART16550_LSR:
|
case UART16550_LSR:
|
||||||
/*
|
/*
|
||||||
@ -319,17 +320,35 @@ static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* For the offset that is not handled (either a read-only
|
* For the reg that is not handled (either a read-only
|
||||||
* register or an invalid register), ignore the write to it.
|
* register or an invalid register), ignore the write to it.
|
||||||
* Gracefully return if prior case clauses have not been met.
|
* Gracefully return if prior case clauses have not been met.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vuart_toggle_intr(vu);
|
vuart_toggle_intr(vu);
|
||||||
vuart_unlock(vu);
|
vuart_unlock(vu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vuart_write(struct acrn_vm *vm, uint16_t offset_arg,
|
||||||
|
__unused size_t width, uint32_t value)
|
||||||
|
{
|
||||||
|
uint16_t offset = offset_arg;
|
||||||
|
struct acrn_vuart *vu = find_vuart_by_port(vm, offset);
|
||||||
|
uint8_t value_u8 = (uint8_t)value;
|
||||||
|
struct acrn_vuart *target_vu = NULL;
|
||||||
|
|
||||||
|
if (vu != NULL) {
|
||||||
|
offset -= vu->port_base;
|
||||||
|
target_vu = vu->target_vu;
|
||||||
|
|
||||||
|
if (!(vu->mcr & MCR_LOOPBACK) &&
|
||||||
|
(offset == UART16550_THR) && (target_vu != NULL)) {
|
||||||
|
send_to_target(target_vu, value_u8);
|
||||||
|
} else {
|
||||||
|
write_reg(vu, offset, value_u8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user