From patchwork Thu Jul 17 11:02:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 371134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E7E78140175 for ; Thu, 17 Jul 2014 23:39:33 +1000 (EST) Received: from localhost ([::1]:44313 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X7luF-0006fU-R0 for incoming@patchwork.ozlabs.org; Thu, 17 Jul 2014 09:39:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X7jSQ-00046N-0X for qemu-devel@nongnu.org; Thu, 17 Jul 2014 07:02:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X7jSJ-00041Y-7K for qemu-devel@nongnu.org; Thu, 17 Jul 2014 07:02:37 -0400 Received: from mail.ispras.ru ([83.149.199.45]:47336) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X7jSI-00041K-P2 for qemu-devel@nongnu.org; Thu, 17 Jul 2014 07:02:31 -0400 Received: from [10.10.150.172] (unknown [80.250.189.177]) by mail.ispras.ru (Postfix) with ESMTPSA id ECED1540151; Thu, 17 Jul 2014 15:02:29 +0400 (MSK) To: qemu-devel@nongnu.org From: Pavel Dovgalyuk Date: Thu, 17 Jul 2014 15:02:33 +0400 Message-ID: <20140717110233.8352.53806.stgit@PASHA-ISP> In-Reply-To: <20140717110153.8352.80175.stgit@PASHA-ISP> References: <20140717110153.8352.80175.stgit@PASHA-ISP> User-Agent: StGit/0.16 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 X-Mailman-Approved-At: Thu, 17 Jul 2014 09:36:32 -0400 Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com, mark.burton@greensocs.com, real@ispras.ru, batuzovk@ispras.ru, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, fred.konrad@greensocs.com Subject: [Qemu-devel] [RFC PATCH v2 06/49] serial: fixing vmstate for save/restore X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Some fields were added to VMState by this patch to preserve correct loading of the serial port controller state. Updating FCR value while loading was also modified to disable generating an interrupt by loadvm. Signed-off-by: Pavel Dovgalyuk --- hw/char/serial.c | 115 ++++++++++++++++++++++++++++++++---------------------- 1 files changed, 69 insertions(+), 46 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 54180a9..1969723 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -267,6 +267,61 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) } +/* Setter for FCR. + is_load flag means, that value is set while loading VM state + and interrupt should not be invoked */ +static void serial_write_fcr(void *opaque, uint32_t val, int is_load) +{ + SerialState *s = opaque; + val = val & 0xFF; + + if (s->fcr == val) + return; + + /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ + if ((val ^ s->fcr) & UART_FCR_FE) + val |= UART_FCR_XFR | UART_FCR_RFR; + + /* FIFO clear */ + + if (val & UART_FCR_RFR) { + timer_del(s->fifo_timeout_timer); + s->timeout_ipending=0; + fifo8_reset(&s->recv_fifo); + } + + if (val & UART_FCR_XFR) { + fifo8_reset(&s->xmit_fifo); + } + + if (val & UART_FCR_FE) { + s->iir |= UART_IIR_FE; + /* Set recv_fifo trigger Level */ + switch (val & 0xC0) { + case UART_FCR_ITL_1: + s->recv_fifo_itl = 1; + break; + case UART_FCR_ITL_2: + s->recv_fifo_itl = 4; + break; + case UART_FCR_ITL_3: + s->recv_fifo_itl = 8; + break; + case UART_FCR_ITL_4: + s->recv_fifo_itl = 14; + break; + } + } else + s->iir &= ~UART_IIR_FE; + + /* Set fcr - or at least the bits in it that are supposed to "stick" */ + s->fcr = val & 0xC9; + + if (!is_load) { + serial_update_irq(s); + } +} + static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -320,50 +375,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, } break; case 2: - val = val & 0xFF; - - if (s->fcr == val) - break; - - /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ - if ((val ^ s->fcr) & UART_FCR_FE) - val |= UART_FCR_XFR | UART_FCR_RFR; - - /* FIFO clear */ - - if (val & UART_FCR_RFR) { - timer_del(s->fifo_timeout_timer); - s->timeout_ipending=0; - fifo8_reset(&s->recv_fifo); - } - - if (val & UART_FCR_XFR) { - fifo8_reset(&s->xmit_fifo); - } - - if (val & UART_FCR_FE) { - s->iir |= UART_IIR_FE; - /* Set recv_fifo trigger Level */ - switch (val & 0xC0) { - case UART_FCR_ITL_1: - s->recv_fifo_itl = 1; - break; - case UART_FCR_ITL_2: - s->recv_fifo_itl = 4; - break; - case UART_FCR_ITL_3: - s->recv_fifo_itl = 8; - break; - case UART_FCR_ITL_4: - s->recv_fifo_itl = 14; - break; - } - } else - s->iir &= ~UART_IIR_FE; - - /* Set fcr - or at least the bits in it that are supposed to "stick" */ - s->fcr = val & 0xC9; - serial_update_irq(s); + serial_write_fcr(s, val, 0); break; case 3: { @@ -591,20 +603,22 @@ static int serial_post_load(void *opaque, int version_id) s->fcr_vmstate = 0; } /* Initialize fcr via setter to perform essential side-effects */ - serial_ioport_write(s, 0x02, s->fcr_vmstate, 1); + serial_write_fcr(s, s->fcr_vmstate, 1); serial_update_parameters(s); return 0; } const VMStateDescription vmstate_serial = { .name = "serial", - .version_id = 3, + .version_id = 4, .minimum_version_id = 2, .pre_save = serial_pre_save, .post_load = serial_post_load, .fields = (VMStateField[]) { VMSTATE_UINT16_V(divider, SerialState, 2), VMSTATE_UINT8(rbr, SerialState), + VMSTATE_UINT8_V(thr, SerialState, 4), + VMSTATE_UINT8_V(tsr, SerialState, 4), VMSTATE_UINT8(ier, SerialState), VMSTATE_UINT8(iir, SerialState), VMSTATE_UINT8(lcr, SerialState), @@ -613,6 +627,15 @@ const VMStateDescription vmstate_serial = { VMSTATE_UINT8(msr, SerialState), VMSTATE_UINT8(scr, SerialState), VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3), + VMSTATE_INT32_V(thr_ipending, SerialState, 4), + VMSTATE_INT32_V(last_break_enable, SerialState, 4), + VMSTATE_INT32_V(tsr_retry, SerialState, 4), + VMSTATE_STRUCT(recv_fifo, SerialState, 4, vmstate_fifo8, Fifo8), + VMSTATE_STRUCT(xmit_fifo, SerialState, 4, vmstate_fifo8, Fifo8), + VMSTATE_TIMER_V(fifo_timeout_timer, SerialState, 4), + VMSTATE_INT32_V(timeout_ipending, SerialState, 4), + VMSTATE_INT32_V(poll_msl, SerialState, 4), + VMSTATE_TIMER_V(modem_status_poll, SerialState, 4), VMSTATE_END_OF_LIST() } };