From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57225) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtozH-0004Nf-OM for qemu-devel@nongnu.org; Tue, 03 Nov 2015 22:43:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZtozF-0002Q7-AN for qemu-devel@nongnu.org; Tue, 03 Nov 2015 22:43:51 -0500 Date: Wed, 4 Nov 2015 14:42:04 +1100 From: David Gibson Message-ID: <20151104034204.GM21954@voom.redhat.com> References: <1445608598-24485-1-git-send-email-mark.cave-ayland@ilande.co.uk> <1445608598-24485-14-git-send-email-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="yklP1rR72f9kjNtc" Content-Disposition: inline In-Reply-To: <1445608598-24485-14-git-send-email-mark.cave-ayland@ilande.co.uk> Subject: Re: [Qemu-devel] [PATCH 13/13] cuda.c: add delay to setting of SR_INT bit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Mark Cave-Ayland Cc: cormac@c-obrien.org, qemu-ppc@nongnu.org, qemu-devel@nongnu.org, agraf@suse.de --yklP1rR72f9kjNtc Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Oct 23, 2015 at 02:56:38PM +0100, Mark Cave-Ayland wrote: > MacOS 9 is racy when it comes to accessing the shift register. Fix this by > introducing a small delay between data accesses and raising the SR_INT > interrupt bit. >=20 > Signed-off-by: Mark Cave-Ayland Reviewed-by: David Gibson > --- > hw/misc/macio/cuda.c | 44 +++++++++++++++++++++++++++++++++----------- > hw/ppc/mac.h | 3 +++ > 2 files changed, 36 insertions(+), 11 deletions(-) >=20 > diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c > index d864b24..5156c72 100644 > --- a/hw/misc/macio/cuda.c > +++ b/hw/misc/macio/cuda.c > @@ -248,6 +248,31 @@ static void cuda_timer2(void *opaque) > cuda_update_irq(s); > } > =20 > +static void cuda_set_sr_int(void *opaque) > +{ > + CUDAState *s =3D opaque; > + > + CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__); > + s->ifr |=3D SR_INT; > + cuda_update_irq(s); > +} > + > +static void cuda_delay_set_sr_int(CUDAState *s) > +{ > + int64_t expire; > + > + if (s->dirb =3D=3D 0xff) { > + /* Not in Mac OS, fire the IRQ directly */ > + cuda_set_sr_int(s); > + return; > + } > + > + CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__); > + > + expire =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 300 * SCALE_US; > + timer_mod(s->sr_delay_timer, expire); > +} > + > static uint32_t cuda_readb(void *opaque, hwaddr addr) > { > CUDAState *s =3D opaque; > @@ -418,8 +443,7 @@ static void cuda_update(CUDAState *s) > if (s->data_out_index < sizeof(s->data_out)) { > CUDA_DPRINTF("send: %02x\n", s->sr); > s->data_out[s->data_out_index++] =3D s->sr; > - s->ifr |=3D SR_INT; > - cuda_update_irq(s); > + cuda_delay_set_sr_int(s); > } > } > } else { > @@ -432,8 +456,7 @@ static void cuda_update(CUDAState *s) > if (s->data_in_index >=3D s->data_in_size) { > s->b =3D (s->b | TREQ); > } > - s->ifr |=3D SR_INT; > - cuda_update_irq(s); > + cuda_delay_set_sr_int(s); > } > } > } > @@ -445,15 +468,13 @@ static void cuda_update(CUDAState *s) > s->b =3D (s->b | TREQ); > else > s->b =3D (s->b & ~TREQ); > - s->ifr |=3D SR_INT; > - cuda_update_irq(s); > + cuda_delay_set_sr_int(s); > } else { > if (!(s->last_b & TIP)) { > /* handle end of host to cuda transfer */ > packet_received =3D (s->data_out_index > 0); > /* always an IRQ at the end of transfer */ > - s->ifr |=3D SR_INT; > - cuda_update_irq(s); > + cuda_delay_set_sr_int(s); > } > /* signal if there is data to read */ > if (s->data_in_index < s->data_in_size) { > @@ -490,8 +511,7 @@ static void cuda_send_packet_to_host(CUDAState *s, > s->data_in_size =3D len; > s->data_in_index =3D 0; > cuda_update(s); > - s->ifr |=3D SR_INT; > - cuda_update_irq(s); > + cuda_delay_set_sr_int(s); > } > =20 > static void cuda_adb_poll(void *opaque) > @@ -714,7 +734,7 @@ static void cuda_reset(DeviceState *dev) > =20 > s->b =3D 0; > s->a =3D 0; > - s->dirb =3D 0; > + s->dirb =3D 0xff; > s->dira =3D 0; > s->sr =3D 0; > s->acr =3D 0; > @@ -732,6 +752,8 @@ static void cuda_reset(DeviceState *dev) > set_counter(s, &s->timers[0], 0xffff); > =20 > s->timers[1].latch =3D 0xffff; > + > + s->sr_delay_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_i= nt, s); > } > =20 > static void cuda_realizefn(DeviceState *dev, Error **errp) > diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h > index 8bdba30..e375ed2 100644 > --- a/hw/ppc/mac.h > +++ b/hw/ppc/mac.h > @@ -103,6 +103,9 @@ typedef struct CUDAState { > uint8_t last_b; > uint8_t last_acr; > =20 > + /* MacOS 9 is racy and requires a delay upon setting the SR_INT bit = */ > + QEMUTimer *sr_delay_timer; > + > int data_in_size; > int data_in_index; > int data_out_index; --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --yklP1rR72f9kjNtc Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJWOX6MAAoJEGw4ysog2bOSYp8P/1bsT8v9P2Pml4MGr9TXMEFw 3vP4uzfQUXMqM9gE1sgMML1MGVXJvpAhfDakHveiRbwfJel3+jYLFqPUIibA/u7k n4Q9bZH9c88/yvRiRD1c42RBYNHovP1V7X0JZGa7HZCqeubANKNMX3riyV6dKKcd y/xdPTVAU/8jlpyDICbB9FJ+Ls65X9+FA9bbtN5L2iaAj9W8/6TLdZ3cqzMZWBsP 4pT2u8qx6rQSfyR709OyzHBw/zpuWkeQPGP+5FcEcNQvZ/RLNv1SRxf/w35GluvL bzKRVQkLiacH6rMInBHEGzVyBd9BTqrDOOgRYAzPv4UHUClBjRMIVwX/T7TdhxXq dEJs1XDSdMERaqU5o930GxuZbAuLbUvs8PvkYFqqI74oQaHOvrsSk56PdAi9p2ct nVW3QXY37XRffg4pX7tTvBs214wyWLGSpetJsEKFZZZOdqKBSuYC+ON4LbTtzSh+ DnlquInsvs+S7GptNXUmy1JQybM9rEp5YJDsT/4KXE9R1OdAoYS80iImCSKgQUP+ 95oDuM5HcWeLNL0N5se6RuL9zFDLodH2voIbFWS667HUyFmFFuajQpUJ64cjxVNB 3+SsXxFNNePPe4Dt8viQ0OGetisTckGlCtC3oLIX8/y81Gc4R6eBXiETdPDyNSaJ mZrswSJjEx6DFMI9VxfG =D3BO -----END PGP SIGNATURE----- --yklP1rR72f9kjNtc--