The 0xffff mask was applied to the result of (16 * UBRDIV) instead of the register value itself, due to C operator precedence (* binds tighter than &). When UBRDIV >= 0x1000, the multiplication by 16 pushes bits past the 16-bit mask, producing a wrong baud rate calculation.
Reported-by: Pavee Hui <[email protected]> Signed-off-by: Marc-André Lureau <[email protected]> --- hw/char/exynos4210_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 9d1825150d1c..7240ff7b5c24 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -327,7 +327,7 @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s) uclk_rate = 24000000; - speed = uclk_rate / ((16 * (s->reg[I_(UBRDIV)]) & 0xffff) + + speed = uclk_rate / ((16 * (s->reg[I_(UBRDIV)] & 0xffff)) + (s->reg[I_(UFRACVAL)] & 0x7) + 16); ssp.speed = speed; -- 2.56.0.rc0.29.g47ce80527c56
