提交 01478834 编写于 作者: C Calvin Lee 提交者: Paolo Bonzini

PC Chipset: Improve serial divisor calculation

This fixes several problems I found in the UART serial implementation.
Now all divisor values are allowed, while before divisor values of zero
and below the base baud rate were rejected. All changes are in reference
to http://www.sci.muni.cz/docs/pc/serport.txtSigned-off-by: NCalvin Lee <cyrus296@gmail.com>
Message-Id: <20180512000545.966-2-cyrus296@gmail.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 9ee8a692
......@@ -150,13 +150,10 @@ static void serial_update_irq(SerialState *s)
static void serial_update_parameters(SerialState *s)
{
int speed, parity, data_bits, stop_bits, frame_size;
float speed;
int parity, data_bits, stop_bits, frame_size;
QEMUSerialSetParams ssp;
if (s->divider == 0 || s->divider > s->baudbase) {
return;
}
/* Start bit. */
frame_size = 1;
if (s->lcr & 0x08) {
......@@ -169,14 +166,16 @@ static void serial_update_parameters(SerialState *s)
} else {
parity = 'N';
}
if (s->lcr & 0x04)
if (s->lcr & 0x04) {
stop_bits = 2;
else
} else {
stop_bits = 1;
}
data_bits = (s->lcr & 0x03) + 5;
frame_size += data_bits + stop_bits;
speed = s->baudbase / s->divider;
/* Zero divisor should give about 3500 baud */
speed = (s->divider == 0) ? 3500 : (float) s->baudbase / s->divider;
ssp.speed = speed;
ssp.parity = parity;
ssp.data_bits = data_bits;
......@@ -184,7 +183,7 @@ static void serial_update_parameters(SerialState *s)
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
DPRINTF("speed=%.2f parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits);
}
......@@ -341,7 +340,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
default:
case 0:
if (s->lcr & UART_LCR_DLAB) {
s->divider = (s->divider & 0xff00) | val;
if (size == 2) {
s->divider = (s->divider & 0xff00) | val;
} else if (size == 4) {
s->divider = val;
}
serial_update_parameters(s);
} else {
s->thr = (uint8_t) val;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册