From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1M3XgU-0006zx-OB for qemu-devel@nongnu.org; Mon, 11 May 2009 11:44:54 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1M3XgR-0006yJ-15 for qemu-devel@nongnu.org; Mon, 11 May 2009 11:44:54 -0400 Received: from [199.232.76.173] (port=38804 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1M3XgQ-0006y8-Fj for qemu-devel@nongnu.org; Mon, 11 May 2009 11:44:50 -0400 Received: from mx20.gnu.org ([199.232.41.8]:57101) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1M3XgP-0000oE-8s for qemu-devel@nongnu.org; Mon, 11 May 2009 11:44:49 -0400 Received: from mail.codesourcery.com ([65.74.133.4]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1M3XgN-0007yg-9Y for qemu-devel@nongnu.org; Mon, 11 May 2009 11:44:47 -0400 From: Vladimir Prus Subject: Re: [Qemu-devel] Re: SH: support 7785 serial Date: Mon, 11 May 2009 19:44:46 +0400 References: <200904022129.02385.vladimir@codesourcery.com> <49E9BDBF.1060503@juno.dti.ne.jp> <20090418163757.GB29955@volta.aurel32.net> In-Reply-To: <20090418163757.GB29955@volta.aurel32.net> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_vfECKLU+J6iBxO+" Message-Id: <200905111944.47469.vladimir@codesourcery.com> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Aurelien Jarno Cc: qemu-devel@nongnu.org --Boundary-00=_vfECKLU+J6iBxO+ Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Saturday 18 April 2009 20:37:57 Aurelien Jarno wrote: > On Sat, Apr 18, 2009 at 08:47:11PM +0900, Shin-ichiro KAWASAKI wrote: > > Vladimir Prus wrote: > >> Shin-ichiro KAWASAKI wrote: > >> > >>>> This patch was tested both with r2d, using kernel and userland found > >>>> at: > >>>> > >>>> thttp://www.assembla.com/wiki/show/qemu-sh4/BuildingEnvironment > >>>> > >>>> and with 7785, using a hand-made kernel. > >>> Patch 2 produces a trouble in my environment. > >>> For r2d, the output to SCIF from kernel is OK, but output from > >>> shell is broken by inserted white space, like follows. > >>> > >>> (before applying patch 2) > >>> # ls > >>> > >>> (after applying patch2) > >>> # l s > >>> > >>> Do you have time to investigate it? > >> > >> The attached revision of the patch fixes the problem for me. I failed to > >> account for the fact that one cannot write '1' bit into FSR register. > > > > I've checked that the new patch avoids the problem. > > Those 3 patches all seem OK for me. Thank you! > > > > I have looked at the three patches, they all looks ok, except for coding > style issues of block structures. Vladimir, could you please fix that > (see file CODING_STYLE, 4. Block structure) and send the patches with a > Signed-off-by: ? I'll apply them. Here are the revised patches -- there were a few places where preexisting code did not have {} around one-line statement, I've added braces there too. Thanks, Volodya --Boundary-00=_vfECKLU+J6iBxO+ Content-Type: text/x-patch; charset="UTF-8"; name="0001-Make-RX-fifo-size-configurable.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Make-RX-fifo-size-configurable.patch" =46rom c9335797806ab006bca95b3749dfcb4ff0c1772c Mon Sep 17 00:00:00 2001 =46rom: Vladimir Prus Date: Thu, 2 Apr 2009 13:49:08 +0400 Subject: [PATCH 1/6] Make RX fifo size configurable. Signed-off-by: Vladimir Prus =2D-- hw/sh_serial.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hw/sh_serial.c b/hw/sh_serial.c index 4957c41..7fefaa6 100644 =2D-- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -37,8 +37,6 @@ #define SH_SERIAL_FLAG_BRK (1 << 3) #define SH_SERIAL_FLAG_DR (1 << 4) =20 =2D#define SH_RX_FIFO_LENGTH (16) =2D typedef struct { uint8_t smr; uint8_t brr; @@ -48,10 +46,11 @@ typedef struct { uint16_t fcr; uint8_t sptr; =20 =2D uint8_t rx_fifo[SH_RX_FIFO_LENGTH]; /* frdr / rdr */ + uint8_t *rx_fifo; /* frdr / rdr */ uint8_t rx_cnt; uint8_t rx_tail; uint8_t rx_head; + int rx_capacity; =20 int freq; int feat; @@ -69,7 +68,7 @@ typedef struct { =20 static void sh_serial_clear_fifo(sh_serial_state * s) { =2D memset(s->rx_fifo, 0, SH_RX_FIFO_LENGTH); + memset(s->rx_fifo, 0, s->rx_capacity); s->rx_cnt =3D 0; s->rx_head =3D 0; s->rx_tail =3D 0; @@ -236,10 +235,12 @@ static uint32_t sh_serial_ioport_read(void *opaque, u= int32_t offs) if (s->rx_cnt > 0) { ret =3D s->rx_fifo[s->rx_tail++]; s->rx_cnt--; =2D if (s->rx_tail =3D=3D SH_RX_FIFO_LENGTH) + if (s->rx_tail =3D=3D s->rx_capacity) { s->rx_tail =3D 0; =2D if (s->rx_cnt < s->rtrg) + } + if (s->rx_cnt < s->rtrg) { s->flags &=3D ~SH_SERIAL_FLAG_RDF; + } } break; #if 0 @@ -297,10 +298,11 @@ static int sh_serial_can_receive(sh_serial_state *s) static void sh_serial_receive_byte(sh_serial_state *s, int ch) { if (s->feat & SH_SERIAL_FEAT_SCIF) { =2D if (s->rx_cnt < SH_RX_FIFO_LENGTH) { + if (s->rx_cnt < s->rx_capacity) { s->rx_fifo[s->rx_head++] =3D ch; =2D if (s->rx_head =3D=3D SH_RX_FIFO_LENGTH) + if (s->rx_head =3D=3D s->rx_capacity) { s->rx_head =3D 0; + } s->rx_cnt++; if (s->rx_cnt >=3D s->rtrg) { s->flags |=3D SH_SERIAL_FLAG_RDF; @@ -393,6 +395,8 @@ void sh_serial_init (target_phys_addr_t base, int feat, s->dr =3D 0xff; } =20 + s->rx_capacity =3D 16; + s->rx_fifo =3D (uint8_t *)malloc(s->rx_capacity); sh_serial_clear_fifo(s); =20 s_io_memory =3D cpu_register_io_memory(0, sh_serial_readfn, =2D-=20 1.6.2.1 --Boundary-00=_vfECKLU+J6iBxO+ Content-Type: text/x-patch; charset="UTF-8"; name="0003-Support-7785-s-serial.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0003-Support-7785-s-serial.patch" =46rom 4db2ac5c9f9b50dad488ba9d8c75d435ad30247f Mon Sep 17 00:00:00 2001 =46rom: Vladimir Prus Date: Thu, 2 Apr 2009 20:44:01 +0400 Subject: [PATCH 3/6] Support 7785's serial. Signed-off-by: Vladimir Prus =2D-- hw/sh.h | 1 + hw/sh_serial.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++----= =2D-- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/hw/sh.h b/hw/sh.h index 5e3c22b..da051f1 100644 =2D-- a/hw/sh.h +++ b/hw/sh.h @@ -37,6 +37,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint3= 2_t freq, =20 /* sh_serial.c */ #define SH_SERIAL_FEAT_SCIF (1 << 0) +#define SH_SERIAL_FEAT_7785 (1 << 1) void sh_serial_init (target_phys_addr_t base, int feat, uint32_t freq, CharDriverState *chr, qemu_irq eri_source, diff --git a/hw/sh_serial.c b/hw/sh_serial.c index fc7de72..2881b5c 100644 =2D-- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -158,10 +158,22 @@ static void sh_serial_ioport_write(void *opaque, uint= 32_t offs, uint32_t val) } =20 return; =2D case 0x20: /* SPTR */ =2D s->sptr =3D val & 0xf3; + case 0x20:=20 + if (s->feat & SH_SERIAL_FEAT_7785) { + /* Recieve fifo data count register, not writable. */ + } else { + /* SPTR */ + s->sptr =3D val & 0xf3; + } + return; + case 0x24:=20 + if (s->feat & SH_SERIAL_FEAT_7785) { + s->sptr =3D val & 0xf3; + } else { + /* LSR */ + } return; =2D case 0x24: /* LSR */ + case 0x28: return; } } @@ -240,12 +252,38 @@ static uint32_t sh_serial_ioport_read(void *opaque, u= int32_t offs) break; #endif case 0x1c: =2D ret =3D s->rx_cnt; + if (s->feat & SH_SERIAL_FEAT_7785) { + /* Trasmit fifo data count. Because we immediate send + everything, we also claim the fifo is always empty. */ + ret =3D 0; + } else { + /* On 7751, this is unified receive/trasmit fifo data + count register. The received data count is in low + 8 bits. In QEMU, transmit fifo is always empty, so + return just receive count. */ + ret =3D s->rx_cnt; + } break; case 0x20: =2D ret =3D s->sptr; + if (s->feat & SH_SERIAL_FEAT_7785) { + /* On 7785, there's separate trasmit fifo data register. = */ + ret =3D s->rx_cnt; + } else { + ret =3D s->sptr; + } break; case 0x24: + /* On 7785, this is serial port register. On 7751, this is li= ne + status register. */ + if (s->feat & SH_SERIAL_FEAT_7785) { + ret =3D s->sptr; + } else { + ret =3D 0; + } + break; + case 0x28: + /* On 7785, this is line status register. */ + assert(s->feat & SH_SERIAL_FEAT_7785); ret =3D 0; break; } @@ -367,6 +405,7 @@ void sh_serial_init (target_phys_addr_t base, int feat, { sh_serial_state *s; int s_io_memory; + int is_7785 =3D (feat & SH_SERIAL_FEAT_7785); =20 s =3D qemu_mallocz(sizeof(sh_serial_state)); =20 @@ -386,14 +425,17 @@ void sh_serial_init (target_phys_addr_t base, int fea= t, s->dr =3D 0xff; } =20 =2D s->rx_capacity =3D 16; + s->rx_capacity =3D is_7785 ? 64 : 16; s->rx_fifo =3D (uint8_t *)malloc(s->rx_capacity); sh_serial_clear_fifo(s); =20 s_io_memory =3D cpu_register_io_memory(0, sh_serial_readfn, sh_serial_writefn, s); =2D cpu_register_physical_memory(P4ADDR(base), 0x28, s_io_memory); =2D cpu_register_physical_memory(A7ADDR(base), 0x28, s_io_memory); + cpu_register_physical_memory(P4ADDR(base),=20 + is_7785 ? 0x2E : 0x28, s_io_memory); + cpu_register_physical_memory(A7ADDR(base),=20 + is_7785 ? 0x2E : 0x28, s_io_memory); + =20 s->chr =3D chr; =20 =2D-=20 1.6.2.1 --Boundary-00=_vfECKLU+J6iBxO+ Content-Type: text/x-patch; charset="UTF-8"; name="0002-Use-symbolic-constants.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-Use-symbolic-constants.patch" =46rom 9783a5ec82bcc6357f84633bacc1e9de3d055598 Mon Sep 17 00:00:00 2001 =46rom: Vladimir Prus Date: Thu, 2 Apr 2009 17:20:09 +0400 Subject: [PATCH 2/6] Use symbolic constants. Signed-off-by: Vladimir Prus =2D-- hw/sh_serial.c | 77 ++++++++++++++++++++++++----------------------------= =2D-- 1 files changed, 34 insertions(+), 43 deletions(-) diff --git a/hw/sh_serial.c b/hw/sh_serial.c index 7fefaa6..fc7de72 100644 =2D-- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -31,11 +31,15 @@ =20 //#define DEBUG_SERIAL =20 =2D#define SH_SERIAL_FLAG_TEND (1 << 0) =2D#define SH_SERIAL_FLAG_TDE (1 << 1) =2D#define SH_SERIAL_FLAG_RDF (1 << 2) =2D#define SH_SERIAL_FLAG_BRK (1 << 3) =2D#define SH_SERIAL_FLAG_DR (1 << 4) +#define SCR_RE (1 << 4) +#define SCR_TE (1 << 5) +#define SCR_RIE (1 << 6) +#define SCR_TIE (1 << 7) + +#define FSR_DR (1 << 0) +#define FSR_RDF (1 << 1) +#define FSR_TDFE (1 << 5) +#define FSR_TEND (1 << 6) =20 typedef struct { uint8_t smr; @@ -54,7 +58,6 @@ typedef struct { =20 int freq; int feat; =2D int flags; int rtrg; =20 CharDriverState *chr; @@ -93,12 +96,13 @@ static void sh_serial_ioport_write(void *opaque, uint32= _t offs, uint32_t val) case 0x08: /* SCR */ /* TODO : For SH7751, SCIF mask should be 0xfb. */ s->scr =3D val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff); =2D if (!(val & (1 << 5))) =2D s->flags |=3D SH_SERIAL_FLAG_TEND; + if (!(val & SCR_TE)) { + s->sr |=3D FSR_TEND; + } if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) { =2D qemu_set_irq(s->txi, val & (1 << 7)); + qemu_set_irq(s->txi, val & SCR_TIE); } =2D if (!(val & (1 << 6))) { + if (!(val & SCR_RIE)) { qemu_set_irq(s->rxi, 0); } return; @@ -108,7 +112,7 @@ static void sh_serial_ioport_write(void *opaque, uint32= _t offs, uint32_t val) qemu_chr_write(s->chr, &ch, 1); } s->dr =3D val; =2D s->flags &=3D ~SH_SERIAL_FLAG_TDE; + s->sr &=3D ~FSR_TDFE; return; #if 0 case 0x14: /* FRDR / RDR */ @@ -119,18 +123,14 @@ static void sh_serial_ioport_write(void *opaque, uint= 32_t offs, uint32_t val) if (s->feat & SH_SERIAL_FEAT_SCIF) { switch(offs) { case 0x10: /* FSR */ =2D if (!(val & (1 << 6))) =2D s->flags &=3D ~SH_SERIAL_FLAG_TEND; =2D if (!(val & (1 << 5))) =2D s->flags &=3D ~SH_SERIAL_FLAG_TDE; =2D if (!(val & (1 << 4))) =2D s->flags &=3D ~SH_SERIAL_FLAG_BRK; =2D if (!(val & (1 << 1))) =2D s->flags &=3D ~SH_SERIAL_FLAG_RDF; =2D if (!(val & (1 << 0))) =2D s->flags &=3D ~SH_SERIAL_FLAG_DR; =2D =2D if (!(val & (1 << 1)) || !(val & (1 << 0))) { + /* Bits 2 and 3 cannot be written at all. */ + val &=3D 0xf3;=20 + /* Other bits can only be cleared by writing 0 + to them. In other words, a bit should remain set + only if it was set, and value 1 is written. */ = =20 + s->sr =3D s->sr & val; + + if (!(val & FSR_RDF) || !(val & FSR_DR)) { if (s->rxi) { qemu_set_irq(s->rxi, 0); } @@ -214,21 +214,12 @@ static uint32_t sh_serial_ioport_read(void *opaque, u= int32_t offs) case 0x08: /* SCR */ ret =3D s->scr; break; =2D case 0x10: /* FSR */ =2D ret =3D 0; =2D if (s->flags & SH_SERIAL_FLAG_TEND) =2D ret |=3D (1 << 6); =2D if (s->flags & SH_SERIAL_FLAG_TDE) =2D ret |=3D (1 << 5); =2D if (s->flags & SH_SERIAL_FLAG_BRK) =2D ret |=3D (1 << 4); =2D if (s->flags & SH_SERIAL_FLAG_RDF) =2D ret |=3D (1 << 1); =2D if (s->flags & SH_SERIAL_FLAG_DR) =2D ret |=3D (1 << 0); =2D =2D if (s->scr & (1 << 5)) =2D s->flags |=3D SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND; + case 0x10: /* FSR */ =20 + ret =3D s->sr; + + if (s->scr & SCR_TE) { + s->sr |=3D FSR_TDFE | FSR_TEND; + } =20 break; case 0x14: @@ -239,7 +230,7 @@ static uint32_t sh_serial_ioport_read(void *opaque, uin= t32_t offs) s->rx_tail =3D 0; } if (s->rx_cnt < s->rtrg) { =2D s->flags &=3D ~SH_SERIAL_FLAG_RDF; + s->sr &=3D ~FSR_RDF; } } break; @@ -292,7 +283,7 @@ static uint32_t sh_serial_ioport_read(void *opaque, uin= t32_t offs) =20 static int sh_serial_can_receive(sh_serial_state *s) { =2D return s->scr & (1 << 4); + return s->scr & SCR_RE; } =20 static void sh_serial_receive_byte(sh_serial_state *s, int ch) @@ -305,8 +296,8 @@ static void sh_serial_receive_byte(sh_serial_state *s, = int ch) } s->rx_cnt++; if (s->rx_cnt >=3D s->rtrg) { =2D s->flags |=3D SH_SERIAL_FLAG_RDF; =2D if (s->scr & (1 << 6) && s->rxi) { + s->sr |=3D FSR_RDF; + if (s->scr & SCR_RIE && s->rxi) { qemu_set_irq(s->rxi, 1); } } @@ -380,7 +371,7 @@ void sh_serial_init (target_phys_addr_t base, int feat, s =3D qemu_mallocz(sizeof(sh_serial_state)); =20 s->feat =3D feat; =2D s->flags =3D SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE; + s->sr =3D FSR_TEND | FSR_TDFE; s->rtrg =3D 1; =20 s->smr =3D 0; =2D-=20 1.6.2.1 --Boundary-00=_vfECKLU+J6iBxO+--