mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-05 03:26:29 +00:00
hv: vuart: fix 'Shifting value too far'
MISRA-C requires that shift operation cannot exceed the word length. What this patch does: - Fix the bug in 'vuart_init' The register 'dll' and 'dlh' should be uint8_t rather than char. 'dll' is the lower 8-bit of divisor. 'dlh' is the higher 8-bit of divisor. So, the shift value should be 8U rather than 16U. - Fix other data type issues regarding to the registers in 'struct vuart' The registers should be unsigned variables. v1 -> v2: * Use a local variable 'uint8_t value_u8 = (uint8_t)value' to avoid mutiple times type conversion * Use '(uint8_t)divisor' rather than '(uint8_t)(divisor & 0xFFU)' to get the lower 8 bit of 'divisor' Direct type conversion is safe and simple per Xiangyang's suggestion. Tracked-On: #861 Signed-off-by: Shiqing Gao <shiqing.gao@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
de487fff2b
commit
3df3c9f6a1
@ -133,12 +133,13 @@ static void vuart_toggle_intr(struct vuart *vu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vuart_write(__unused struct vm_io_handler *hdlr,
|
static void vuart_write(__unused struct vm_io_handler *hdlr, struct vm *vm,
|
||||||
struct vm *vm, uint16_t offset_arg,
|
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 vuart *vu = vm_vuart(vm);
|
struct vuart *vu = vm_vuart(vm);
|
||||||
|
uint8_t value_u8 = (uint8_t)value;
|
||||||
|
|
||||||
offset -= vu->base;
|
offset -= vu->base;
|
||||||
vuart_lock(vu);
|
vuart_lock(vu);
|
||||||
/*
|
/*
|
||||||
@ -146,19 +147,19 @@ static void vuart_write(__unused struct vm_io_handler *hdlr,
|
|||||||
*/
|
*/
|
||||||
if ((vu->lcr & LCR_DLAB) != 0) {
|
if ((vu->lcr & LCR_DLAB) != 0) {
|
||||||
if (offset == UART16550_DLL) {
|
if (offset == UART16550_DLL) {
|
||||||
vu->dll = value;
|
vu->dll = value_u8;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == UART16550_DLM) {
|
if (offset == UART16550_DLM) {
|
||||||
vu->dlh = value;
|
vu->dlh = value_u8;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case UART16550_THR:
|
case UART16550_THR:
|
||||||
fifo_putchar(&vu->txfifo, value);
|
fifo_putchar(&vu->txfifo, value_u8);
|
||||||
vu->thre_int_pending = true;
|
vu->thre_int_pending = true;
|
||||||
break;
|
break;
|
||||||
case UART16550_IER:
|
case UART16550_IER:
|
||||||
@ -166,26 +167,26 @@ static void vuart_write(__unused struct vm_io_handler *hdlr,
|
|||||||
* Apply mask so that bits 4-7 are 0
|
* Apply mask so that bits 4-7 are 0
|
||||||
* Also enables bits 0-3 only if they're 1
|
* Also enables bits 0-3 only if they're 1
|
||||||
*/
|
*/
|
||||||
vu->ier = value & 0x0FU;
|
vu->ier = value_u8 & 0x0FU;
|
||||||
break;
|
break;
|
||||||
case UART16550_FCR:
|
case UART16550_FCR:
|
||||||
/*
|
/*
|
||||||
* The FCR_ENABLE bit must be '1' for the programming
|
* The FCR_ENABLE bit must be '1' for the programming
|
||||||
* of other FCR bits to be effective.
|
* of other FCR bits to be effective.
|
||||||
*/
|
*/
|
||||||
if ((value & FCR_FIFOE) == 0U) {
|
if ((value_u8 & FCR_FIFOE) == 0U) {
|
||||||
vu->fcr = 0;
|
vu->fcr = 0U;
|
||||||
} else {
|
} else {
|
||||||
if ((value & FCR_RFR) != 0U) {
|
if ((value_u8 & FCR_RFR) != 0U) {
|
||||||
fifo_reset(&vu->rxfifo);
|
fifo_reset(&vu->rxfifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
vu->fcr = value &
|
vu->fcr = value_u8 &
|
||||||
(FCR_FIFOE | FCR_DMA | FCR_RX_MASK);
|
(FCR_FIFOE | FCR_DMA | FCR_RX_MASK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UART16550_LCR:
|
case UART16550_LCR:
|
||||||
vu->lcr = value;
|
vu->lcr = value_u8;
|
||||||
break;
|
break;
|
||||||
case UART16550_MCR:
|
case UART16550_MCR:
|
||||||
/* ignore modem */
|
/* ignore modem */
|
||||||
@ -202,7 +203,7 @@ static void vuart_write(__unused struct vm_io_handler *hdlr,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case UART16550_SCR:
|
case UART16550_SCR:
|
||||||
vu->scr = value;
|
vu->scr = value_u8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
@ -218,14 +219,13 @@ done:
|
|||||||
vuart_unlock(vu);
|
vuart_unlock(vu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vuart_read(__unused struct vm_io_handler *hdlr,
|
static uint32_t vuart_read(__unused struct vm_io_handler *hdlr, struct vm *vm,
|
||||||
struct vm *vm, uint16_t offset_arg,
|
uint16_t offset_arg, __unused size_t width)
|
||||||
__unused size_t width)
|
|
||||||
{
|
{
|
||||||
uint16_t offset = offset_arg;
|
uint16_t offset = offset_arg;
|
||||||
char iir, reg;
|
uint8_t iir, reg, intr_reason;
|
||||||
uint8_t intr_reason;
|
|
||||||
struct vuart *vu = vm_vuart(vm);
|
struct vuart *vu = vm_vuart(vm);
|
||||||
|
|
||||||
offset -= vu->base;
|
offset -= vu->base;
|
||||||
vuart_lock(vu);
|
vuart_lock(vu);
|
||||||
/*
|
/*
|
||||||
@ -295,7 +295,7 @@ static uint32_t vuart_read(__unused struct vm_io_handler *hdlr,
|
|||||||
done:
|
done:
|
||||||
vuart_toggle_intr(vu);
|
vuart_toggle_intr(vu);
|
||||||
vuart_unlock(vu);
|
vuart_unlock(vu);
|
||||||
return reg;
|
return (uint32_t)reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vuart_register_io_handler(struct vm *vm)
|
static void vuart_register_io_handler(struct vm *vm)
|
||||||
@ -370,8 +370,8 @@ void *vuart_init(struct vm *vm)
|
|||||||
|
|
||||||
/* Set baud rate*/
|
/* Set baud rate*/
|
||||||
divisor = UART_CLOCK_RATE / BAUD_9600 / 16U;
|
divisor = UART_CLOCK_RATE / BAUD_9600 / 16U;
|
||||||
vu->dll = divisor;
|
vu->dll = (uint8_t)divisor;
|
||||||
vu->dlh = divisor >> 16U;
|
vu->dlh = (uint8_t)(divisor >> 8U);
|
||||||
|
|
||||||
vu->active = false;
|
vu->active = false;
|
||||||
vu->base = COM1_BASE;
|
vu->base = COM1_BASE;
|
||||||
|
@ -39,16 +39,16 @@ struct fifo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vuart {
|
struct vuart {
|
||||||
char data; /* Data register (R/W) */
|
uint8_t data; /* Data register (R/W) */
|
||||||
char ier; /* Interrupt enable register (R/W) */
|
uint8_t ier; /* Interrupt enable register (R/W) */
|
||||||
char lcr; /* Line control register (R/W) */
|
uint8_t lcr; /* Line control register (R/W) */
|
||||||
char mcr; /* Modem control register (R/W) */
|
uint8_t mcr; /* Modem control register (R/W) */
|
||||||
char lsr; /* Line status register (R/W) */
|
uint8_t lsr; /* Line status register (R/W) */
|
||||||
char msr; /* Modem status register (R/W) */
|
uint8_t msr; /* Modem status register (R/W) */
|
||||||
char fcr; /* FIFO control register (W) */
|
uint8_t fcr; /* FIFO control register (W) */
|
||||||
char scr; /* Scratch register (R/W) */
|
uint8_t scr; /* Scratch register (R/W) */
|
||||||
char dll; /* Baudrate divisor latch LSB */
|
uint8_t dll; /* Baudrate divisor latch LSB */
|
||||||
char dlh; /* Baudrate divisor latch MSB */
|
uint8_t dlh; /* Baudrate divisor latch MSB */
|
||||||
|
|
||||||
struct fifo rxfifo;
|
struct fifo rxfifo;
|
||||||
struct fifo txfifo;
|
struct fifo txfifo;
|
||||||
|
Loading…
Reference in New Issue
Block a user