From nobody Sun Apr 28 20:28:18 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1576786575; cv=none; d=zohomail.com; s=zohoarc; b=G8j7FtmPXliSE9bBlUA5LOH+IFh7xUOGsP9Qfx3YxtHVdQ2QER5SVW4vtW1T5Y7mrW/wECkKcppCwxqh4HLlcqU/JjFz95i4O8CfoYXJQ9em+l70Pk9evQNzNDJvqVd8C/HEOvcx9bo/Y3KTnbUTxq9Ml4+TQfxLtd6/hRPphkw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1576786575; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=pfI2psoZtsT+qEQzy646rXRerqY7fLjbwrEOSYmE730=; b=lTQNI6JtKJWFHSRjaCEjTQ+aE42YO4blGOxrfdpRIATUqeEU6wXCJS8O88eE4tXthpXp2P/TxyTe+Xu7uVUF9jCgtHzYEIw6sDQYk4Swwej5CzGpMUQK2T1oSXrd9ihVjI6unorIKmH50LCyDPl+tVs2oQY9/JykUZF9VfCWh88= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1576786575538596.5944944961485; Thu, 19 Dec 2019 12:16:15 -0800 (PST) Received: from localhost ([::1]:47450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii2DW-0002Sh-4e for importer@patchew.org; Thu, 19 Dec 2019 15:16:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39451) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii2C9-0001Gy-Nw for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ii2C6-0004MZ-TM for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:49 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:35885) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ii2C6-0004If-C0 for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:46 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue009 [212.227.15.167]) with ESMTPSA (Nemesis) id 1MmU9R-1hzf161mSX-00iVeZ; Thu, 19 Dec 2019 21:14:41 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Subject: [PATCH 1/2] q800: fix mac_via RTC PRAM commands Date: Thu, 19 Dec 2019 21:14:38 +0100 Message-Id: <20191219201439.84804-2-laurent@vivier.eu> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191219201439.84804-1-laurent@vivier.eu> References: <20191219201439.84804-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:CzwElIE6Vqc63meeZjmdjRHTcaNrrMXefHPYOL/W/owrJASuqAK Tti3Ea4nQELCfUtQlg/vlIRaAiPIzk4MCcWmGJamrIurdZXKZ7Z8cLJ3AFkxbQ1xzfwCZEI bbJOy4e5/pbmHxgs0njFiG/1/mCEBFV0utJTVfg+62GMGwLgvLWk4mqhTN9sQKJIUOhRYCu EHInmd5aYqz9JCGmJsQeQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:aEQZnneeaW0=:d/CP33KkZEieyTFQFIo9Xy Z97M43ChjG8nWRAGN1wrJbOhB/0UdspQrTACFtnNKaBr7zh0dlPe2xh7icGS/vpYN9spyq9nb IafSPr3AtVQvJ8Wzf5x2jnlWR2nMNNoHymVf0+poT7LwUgDTr3TlOgNAkRY7DisedUU/J8cHb Cib7yVMNKqd6O19hPgdrlYWSTuh+XkAla1RwoDHTy5SBoq6fERWoi1BrlGDq47j/cdHGiQgUq L7PgddTOzR0HcJJG0DnOjRicSmRheQZQTQyrhzJlcaTYkvrBqPar6ysPOun1ZfLndXtX3z7sH Bhq0atT5bRQZL9syHLnT5YVCYh1vVpTy5RVQK9I32jvMwC2KkrppO4/UJbwyQfPtCPmK5089h EQbdIhjAnyYz9hrLJq/+gMN2Y0fXMKuGZb8XD7lHIR0keJeZMUKQN2xk0b5+IFPwOC5X2W4Jt X1Zx2j4yBgDSdMoY1TmSPsSRUJcB/jzbW7MckfDJpHEeR4bldpm4QHoASi5ZrgmL/QY7ZMQci YPdiILvOTgLgO6RNG9Fo2G3uUL5Jt96cmXgOruc39WRSAe6KzVUizWf1Ao0w0bjC1ln6bffus 4SvSc1OaMWITKMqleW5dTYAU78A/YlclhY3l6b/j5BA87dr0im2xqYx6SqreDg4tYf1EDFp4/ PZ0VG7e69Bjeuhhp2xlXFATq4zxt8YagNuv3bTvwoIYUJtcDC1WH4X1gIHGofoZUGuG3xKAOx O+FaUzkXP9mvouIE2YRYcKJy3Olx7qaJiLSnn5086PpPS+us436kEB/glapR8O1Oq3QSt+TsJ SJelJsUyEZodkVPQYgpyObX7cuKI/uLmcGy47b64jhsIxBHWm9oc0AjNYhSFoYGfEOUdluTPF jn8OvsQ2wxVHu7nE8Ycg== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Mark Cave-Ayland , Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The command byte is not decoded correctly. This patch reworks the RTC/PRAM interface and fixes the problem. It adds a comment before the function to explain how are encoded commands and some trace-events to ease debugging. Bug: https://bugs.launchpad.net/qemu/+bug/1856549 Fixes: 6dca62a000 ("hw/m68k: add VIA support") Signed-off-by: Laurent Vivier Reviewed-by: Mark Cave-Ayland --- hw/misc/mac_via.c | 274 ++++++++++++++++++++++++++++++------------- hw/misc/trace-events | 19 +++ 2 files changed, 210 insertions(+), 83 deletions(-) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index f3f130ad96..e5658af922 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -27,7 +27,7 @@ #include "sysemu/runstate.h" #include "qapi/error.h" #include "qemu/cutils.h" - +#include "trace.h" =20 /* * VIAs: There are two in every machine, @@ -278,6 +278,21 @@ /* VIA returns time offset from Jan 1, 1904, not 1970 */ #define RTC_OFFSET 2082844800 =20 +enum { + REG_0, + REG_1, + REG_2, + REG_3, + REG_TEST, + REG_WPROTECT, + REG_PRAM_ADDR, + REG_PRAM_ADDR_LAST =3D REG_PRAM_ADDR + 19, + REG_PRAM_SECT, + REG_PRAM_SECT_LAST =3D REG_PRAM_SECT + 7, + REG_INVALID, + REG_EMPTY =3D 0xff, +}; + static void via1_VBL_update(MOS6522Q800VIA1State *v1s) { MOS6522State *s =3D MOS6522(v1s); @@ -360,10 +375,62 @@ static void via2_irq_request(void *opaque, int irq, i= nt level) mdc->update_irq(s); } =20 +/* + * RTC Commands + * + * Command byte Register addressed by the command + * + * z0000001 Seconds register 0 (lowest-order byte) + * z0000101 Seconds register 1 + * z0001001 Seconds register 2 + * z0001101 Seconds register 3 (highest-order byte) + * 00110001 Test register (write-only) + * 00110101 Write-Protect Register (write-only) + * z010aa01 RAM address 100aa ($10-$13) (first 20 bytes only) + * z1aaaa01 RAM address 0aaaa ($00-$0F) (first 20 bytes only) + * z0111aaa Extended memory designator and sector number + * + * For a read request, z=3D1, for a write z=3D0 + * The letter a indicates bits whose value depend on what parameter + * RAM byte you want to address + */ +static int via1_rtc_compact_cmd(uint8_t value) +{ + uint8_t read =3D value & 0x80; + + value &=3D 0x7f; + + /* the last 2 bits of a command byte must always be 0b01 ... */ + if ((value & 0x78) =3D=3D 0x38) { + /* except for the extended memory designator */ + return read | (REG_PRAM_SECT + (value & 0x07)); + } + if ((value & 0x03) =3D=3D 0x01) { + value >>=3D 2; + if ((value & 0x1c) =3D=3D 0) { + /* seconds registers */ + return read | (REG_0 + (value & 0x03)); + } else if ((value =3D=3D 0x0c) && !read) { + return REG_TEST; + } else if ((value =3D=3D 0x0d) && !read) { + return REG_WPROTECT; + } else if ((value & 0x1c) =3D=3D 0x08) { + /* RAM address 0x10 to 0x13 */ + return read | (REG_PRAM_ADDR + 0x10 + (value & 0x03)); + } else if ((value & 0x43) =3D=3D 0x41) { + /* RAM address 0x00 to 0x0f */ + return read | (REG_PRAM_ADDR + (value & 0x0f)); + } + } + return REG_INVALID; +} + static void via1_rtc_update(MacVIAState *m) { MOS6522Q800VIA1State *v1s =3D &m->mos6522_via1; MOS6522State *s =3D MOS6522(v1s); + int cmd, sector, addr; + uint32_t time; =20 if (s->b & VIA1B_vRTCEnb) { return; @@ -376,7 +443,9 @@ static void via1_rtc_update(MacVIAState *m) m->data_out |=3D s->b & VIA1B_vRTCData; m->data_out_cnt++; } + trace_via1_rtc_update_data_out(m->data_out_cnt, m->data_out); } else { + trace_via1_rtc_update_data_in(m->data_in_cnt, m->data_in); /* receive bits from the RTC */ if ((v1s->last_b & VIA1B_vRTCClk) && !(s->b & VIA1B_vRTCClk) && @@ -386,96 +455,132 @@ static void via1_rtc_update(MacVIAState *m) m->data_in <<=3D 1; m->data_in_cnt--; } + return; } =20 - if (m->data_out_cnt =3D=3D 8) { - m->data_out_cnt =3D 0; - - if (m->cmd =3D=3D 0) { - if (m->data_out & 0x80) { - /* this is a read command */ - uint32_t time =3D m->tick_offset + - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / - NANOSECONDS_PER_SECOND); - if (m->data_out =3D=3D 0x81) { /* seconds register = 0 */ - m->data_in =3D time & 0xff; - m->data_in_cnt =3D 8; - } else if (m->data_out =3D=3D 0x85) { /* seconds register = 1 */ - m->data_in =3D (time >> 8) & 0xff; - m->data_in_cnt =3D 8; - } else if (m->data_out =3D=3D 0x89) { /* seconds register = 2 */ - m->data_in =3D (time >> 16) & 0xff; - m->data_in_cnt =3D 8; - } else if (m->data_out =3D=3D 0x8d) { /* seconds register = 3 */ - m->data_in =3D (time >> 24) & 0xff; - m->data_in_cnt =3D 8; - } else if ((m->data_out & 0xf3) =3D=3D 0xa1) { - /* PRAM address 0x10 -> 0x13 */ - int addr =3D (m->data_out >> 2) & 0x03; - m->data_in =3D v1s->PRAM[addr]; - m->data_in_cnt =3D 8; - } else if ((m->data_out & 0xf3) =3D=3D 0xa1) { - /* PRAM address 0x00 -> 0x0f */ - int addr =3D (m->data_out >> 2) & 0x0f; - m->data_in =3D v1s->PRAM[addr]; - m->data_in_cnt =3D 8; - } else if ((m->data_out & 0xf8) =3D=3D 0xb8) { - /* extended memory designator and sector number */ - m->cmd =3D m->data_out; - } - } else { - /* this is a write command */ - m->cmd =3D m->data_out; + if (m->data_out_cnt !=3D 8) { + return; + } + + m->data_out_cnt =3D 0; + + trace_via1_rtc_internal_status(m->cmd, m->alt, m->data_out); + /* first byte: it's a command */ + if (m->cmd =3D=3D REG_EMPTY) { + + cmd =3D via1_rtc_compact_cmd(m->data_out); + trace_via1_rtc_internal_cmd(cmd); + + if (cmd =3D=3D REG_INVALID) { + trace_via1_rtc_cmd_invalid(m->data_out); + return; + } + + if (cmd & 0x80) { /* this is a read command */ + switch (cmd & 0x7f) { + case REG_0...REG_3: /* seconds registers */ + /* + * register 0 is lowest-order byte + * register 3 is highest-order byte + */ + + time =3D m->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VI= RTUAL) + / NANOSECONDS_PER_SECOND); + trace_via1_rtc_internal_time(time); + m->data_in =3D (time >> ((cmd & 0x03) << 3)) & 0xff; + m->data_in_cnt =3D 8; + trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0, + m->data_in); + break; + case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST: + /* PRAM address 0x00 -> 0x13 */ + m->data_in =3D v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR]; + m->data_in_cnt =3D 8; + trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR, + m->data_in); + break; + case REG_PRAM_SECT...REG_PRAM_SECT_LAST: + /* + * extended memory designator and sector number + * the only two-byte read command + */ + trace_via1_rtc_internal_set_cmd(cmd); + m->cmd =3D cmd; + break; + default: + g_assert_not_reached(); + break; } + return; + } + + /* this is a write command, needs a parameter */ + if (cmd =3D=3D REG_WPROTECT || !m->wprotect) { + trace_via1_rtc_internal_set_cmd(cmd); + m->cmd =3D cmd; } else { + trace_via1_rtc_internal_ignore_cmd(cmd); + } + return; + } + + /* second byte: it's a parameter */ + if (m->alt =3D=3D REG_EMPTY) { + switch (m->cmd & 0x7f) { + case REG_0...REG_3: /* seconds register */ + /* FIXME */ + trace_via1_rtc_cmd_seconds_write(m->cmd - REG_0, m->data_out); + m->cmd =3D REG_EMPTY; + break; + case REG_TEST: + /* device control: nothing to do */ + trace_via1_rtc_cmd_test_write(m->data_out); + m->cmd =3D REG_EMPTY; + break; + case REG_WPROTECT: + /* Write Protect register */ + trace_via1_rtc_cmd_wprotect_write(m->data_out); + m->wprotect =3D !!(m->data_out & 0x80); + m->cmd =3D REG_EMPTY; + break; + case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST: + /* PRAM address 0x00 -> 0x13 */ + trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_= out); + v1s->PRAM[m->cmd - REG_PRAM_ADDR] =3D m->data_out; + m->cmd =3D REG_EMPTY; + break; + case REG_PRAM_SECT...REG_PRAM_SECT_LAST: + addr =3D (m->data_out >> 2) & 0x1f; + sector =3D (m->cmd & 0x7f) - REG_PRAM_SECT; if (m->cmd & 0x80) { - if ((m->cmd & 0xf8) =3D=3D 0xb8) { - /* extended memory designator and sector number */ - int sector =3D m->cmd & 0x07; - int addr =3D (m->data_out >> 2) & 0x1f; - - m->data_in =3D v1s->PRAM[sector * 8 + addr]; - m->data_in_cnt =3D 8; - } - } else if (!m->wprotect) { - /* this is a write command */ - if (m->alt !=3D 0) { - /* extended memory designator and sector number */ - int sector =3D m->cmd & 0x07; - int addr =3D (m->alt >> 2) & 0x1f; - - v1s->PRAM[sector * 8 + addr] =3D m->data_out; - - m->alt =3D 0; - } else if (m->cmd =3D=3D 0x01) { /* seconds register 0 */ - /* FIXME */ - } else if (m->cmd =3D=3D 0x05) { /* seconds register 1 */ - /* FIXME */ - } else if (m->cmd =3D=3D 0x09) { /* seconds register 2 */ - /* FIXME */ - } else if (m->cmd =3D=3D 0x0d) { /* seconds register 3 */ - /* FIXME */ - } else if (m->cmd =3D=3D 0x31) { - /* Test Register */ - } else if (m->cmd =3D=3D 0x35) { - /* Write Protect register */ - m->wprotect =3D m->data_out & 1; - } else if ((m->cmd & 0xf3) =3D=3D 0xa1) { - /* PRAM address 0x10 -> 0x13 */ - int addr =3D (m->cmd >> 2) & 0x03; - v1s->PRAM[addr] =3D m->data_out; - } else if ((m->cmd & 0xf3) =3D=3D 0xa1) { - /* PRAM address 0x00 -> 0x0f */ - int addr =3D (m->cmd >> 2) & 0x0f; - v1s->PRAM[addr] =3D m->data_out; - } else if ((m->cmd & 0xf8) =3D=3D 0xb8) { - /* extended memory designator and sector number */ - m->alt =3D m->cmd; - } + /* it's a read */ + m->data_in =3D v1s->PRAM[sector * 32 + addr]; + m->data_in_cnt =3D 8; + trace_via1_rtc_cmd_pram_sect_read(sector, addr, + sector * 32 + addr, + m->data_in); + m->cmd =3D REG_EMPTY; + } else { + /* it's a write, we need one more parameter */ + trace_via1_rtc_internal_set_alt(addr, sector, addr); + m->alt =3D addr; } + break; + default: + g_assert_not_reached(); + break; } - m->data_out =3D 0; + return; } + + /* third byte: it's the data of a REG_PRAM_SECT write */ + g_assert(REG_PRAM_SECT <=3D m->cmd && m->cmd <=3D REG_PRAM_SECT_LAST); + sector =3D m->cmd - REG_PRAM_SECT; + v1s->PRAM[sector * 32 + m->alt] =3D m->data_out; + trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->al= t, + m->data_out); + m->alt =3D REG_EMPTY; + m->cmd =3D REG_EMPTY; } =20 static int adb_via_poll(MacVIAState *s, int state, uint8_t *data) @@ -742,6 +847,9 @@ static void mac_via_reset(DeviceState *dev) v1s->next_VBL =3D 0; timer_del(v1s->one_second_timer); v1s->next_second =3D 0; + + m->cmd =3D REG_EMPTY; + m->alt =3D REG_EMPTY; } =20 static void mac_via_realize(DeviceState *dev, Error **errp) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 1deb1d08c1..2e0c820834 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -149,3 +149,22 @@ bcm2835_mbox_write(unsigned int size, uint64_t addr, u= int64_t value) "mbox write bcm2835_mbox_read(unsigned int size, uint64_t addr, uint64_t value) "mbox = read sz:%u addr:0x%"PRIx64" data:0x%"PRIx64 bcm2835_mbox_irq(unsigned level) "mbox irq:ARM level:%u" bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbo= x property tag:0x%08x in_sz:%u out_sz:%zu" + +# mac_via.c +via1_rtc_update_data_out(int count, int value) "count=3D%d value=3D0x%02x" +via1_rtc_update_data_in(int count, int value) "count=3D%d value=3D0x%02x" +via1_rtc_internal_status(int cmd, int alt, int value) "cmd=3D0x%02x alt=3D= 0x%02x value=3D0x%02x" +via1_rtc_internal_cmd(int cmd) "cmd=3D0x%02x" +via1_rtc_cmd_invalid(int value) "value=3D0x%02x" +via1_rtc_internal_time(uint32_t time) "time=3D0x%08x" +via1_rtc_internal_set_cmd(int cmd) "cmd=3D0x%02x" +via1_rtc_internal_ignore_cmd(int cmd) "cmd=3D0x%02x" +via1_rtc_internal_set_alt(int alt, int sector, int offset) "alt=3D0x%02x s= ector=3D%u offset=3D%u" +via1_rtc_cmd_seconds_read(int reg, int value) "reg=3D%d value=3D0x%02x" +via1_rtc_cmd_seconds_write(int reg, int value) "reg=3D%d value=3D0x%02x" +via1_rtc_cmd_test_write(int value) "value=3D0x%02x" +via1_rtc_cmd_wprotect_write(int value) "value=3D0x%02x" +via1_rtc_cmd_pram_read(int addr, int value) "addr=3D%u value=3D0x%02x" +via1_rtc_cmd_pram_write(int addr, int value) "addr=3D%u value=3D0x%02x" +via1_rtc_cmd_pram_sect_read(int sector, int offset, int addr, int value) "= sector=3D%u offset=3D%u addr=3D%d value=3D0x%02x" +via1_rtc_cmd_pram_sect_write(int sector, int offset, int addr, int value) = "sector=3D%u offset=3D%u addr=3D%d value=3D0x%02x" --=20 2.24.1 From nobody Sun Apr 28 20:28:18 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1576786573; cv=none; d=zohomail.com; s=zohoarc; b=iQhTg7RZPpB83VqXFjvahNwLRPKvpgs7TiNGgEvbiAIrjlGbBlIfNzGJiZfIZSo0HjZvOIrQjcMR9NBdZoqSv7SdZ4lKQoEg+nJvoRCwia0tAe7Kt+w5UXYIE/dV7NXl7W2139T8PdsTHi7oYjO9sXIKXYVOAIF4We2iKVppBJM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1576786573; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Z7fJOCSgL+AU0h00jaDEGj2zHWCgXVszXgN5i+Ixgw0=; b=Po0TyZXOGL6Q5YtVrfhrVzUNK2w0Ae5ol3vvcJJhVxKQjEjyiAk/+F6Ua75v9nJm0Ie9F0UYE+fAF+Ixu2S+QIMLaz60q5jqg0G/lW81Dj/d98kQpCJeY/VfK9v4bwdlEIqI95QyIkyqjYe1YOt0Wi9cZUd5fn8WuSSuflZ7DyQ= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1576786573255250.00504541484793; Thu, 19 Dec 2019 12:16:13 -0800 (PST) Received: from localhost ([::1]:47448 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii2DT-0002Np-FR for importer@patchew.org; Thu, 19 Dec 2019 15:16:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39483) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii2CA-0001I2-BB for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ii2C8-0004Nh-Cs for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:49 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:36095) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ii2C6-0004JE-SV for qemu-devel@nongnu.org; Thu, 19 Dec 2019 15:14:47 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue009 [212.227.15.167]) with ESMTPSA (Nemesis) id 1Mo6zD-1hsU0n0LxT-00pdSf; Thu, 19 Dec 2019 21:14:42 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Subject: [PATCH 2/2] q800: add a block backend to the PRAM Date: Thu, 19 Dec 2019 21:14:39 +0100 Message-Id: <20191219201439.84804-3-laurent@vivier.eu> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191219201439.84804-1-laurent@vivier.eu> References: <20191219201439.84804-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:dGGNl1CfEnXbkwvBBKymQbm0Hoia5yJdMX6tyMvkG3bxVoDyRVl dYGE7yYx6MX+gXjunfyt/T88oaKtXIf5MI35a6Zj6RotmI3/khK6wAYKzgHAOUF7x/HR8bP JsLHGY+n4XavFfBKF78LRqkkkjvCw65TFLcqvwQ0HMMNGgSkGvwdez2Y6om9epEe7X55frb WWycDSWhWvYrRd3aiikBg== X-UI-Out-Filterresults: notjunk:1;V03:K0:6QPa6aGw7gw=:fC3HpLbCZD+CMaGsCGMGXR xSO0chSu0KTEH1XhEpBUmBQpqDjY4UpG+aZ0Y9xJ0cmVQKoIN4ZXlpwU5o82VTK3IgPRtKUBD 0e1lufTEmCGTGs8O7FPG+McaRyoJlCoDn8FwAmgXjTAbN8LKRrs4YA4YoRH+KZ6NI5igznLjf Xb3e9HOqk9Gsq2uwg6kgDlIFcNUqC/lhkhJ4eNEe4I+FIqZLLbKeRkTDCTkQAj/eYVzf/kHvT soVlfKoUemv20wfGEX3aK95YKBRVjVa4RHTNolejqmCjefbWXof66PPPofZqysWmaofkZKkCe N6pNsYNHEFvpfY1pBRhQ9A0l7UHgeLzMnejBG5wHjTO5Ne8Djyt3E/9PM7xpDeTPWPiDi+1ed fj/8w9wXlHOld45jeNHJ/FHGF9vQ5DiAuTaq2Wu0y8pGekGNLg89u/TA9h7DB8ZW7XzpFphjA p/xD9wd0JYv0zoQAhYKjFujsFAzTQtuh92uv8NZQOUgNbyNyKtZf0dgwukvBtflBsGgxk6sEr 8gGCohHwe8d8kxxqPm14ffnaqAeHKbhl3aaOKtj9jhv5uDRMKmNqP01MUth7lxbTpzCbiI02u 38XPe69qoTNx4afqB0kSE9r0eMUrXpWifJQx7N65jusvpi1QwfI6P2L4ZXdvcj274b16qwKsv qnVV2Srm2rIKlHcRT2XPgPb8j/W1dvKXHLsslLPgc0bSGeJPqPhgvALmsvdUzaLHYHB7O2uaH 3g0M3FSCa77IRWmnVVt4Aett8ZrbnnIltz3jkT6Sz8B5eeKpQp1JLPvBnsQliXYwbsHRzIGCx G8w5Sq8zVgRqRfr98tBqbX67b9mn9Xa0VTACpZmkRRbl5gYJkxXPUdO47j/N8AJnaPrQUlFzh 0q1gwR5Ni3JAwzYZLFtQ== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.131 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Mark Cave-Ayland , Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This allows to save and restore the content of the PRAM. It may be useful if we want to check the configuration or to change it. The backend is added using mtd interface, for instance: ... -drive file=3Dpram.img,format=3Draw,if=3Dmtd ... where pram.img is the file where the data will be stored, its size must be 256 bytes. Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 6 ++++ hw/misc/mac_via.c | 65 +++++++++++++++++++++++++++++++++++++++ include/hw/misc/mac_via.h | 3 ++ 3 files changed, 74 insertions(+) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 4ca8678007..0c445c74bf 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -158,6 +158,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; GLUEState *irq; qemu_irq *pic; + DriveInfo *dinfo; =20 linux_boot =3D (kernel_filename !=3D NULL); =20 @@ -200,6 +201,11 @@ static void q800_init(MachineState *machine) /* VIA */ =20 via_dev =3D qdev_create(NULL, TYPE_MAC_VIA); + dinfo =3D drive_get(IF_MTD, 0, 0); + if (dinfo) { + qdev_prop_set_drive(via_dev, "drive", blk_by_legacy_dinfo(dinfo), + &error_abort); + } qdev_init_nofail(via_dev); sysbus =3D SYS_BUS_DEVICE(via_dev); sysbus_mmio_map(sysbus, 0, VIA_BASE); diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index e5658af922..e9e6a95eab 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -27,6 +27,8 @@ #include "sysemu/runstate.h" #include "qapi/error.h" #include "qemu/cutils.h" +#include "hw/qdev-properties.h" +#include "sysemu/block-backend.h" #include "trace.h" =20 /* @@ -375,6 +377,15 @@ static void via2_irq_request(void *opaque, int irq, in= t level) mdc->update_irq(s); } =20 + +static void pram_update(MacVIAState *m) +{ + if (m->blk) { + blk_pwrite(m->blk, 0, m->mos6522_via1.PRAM, + sizeof(m->mos6522_via1.PRAM), 0); + } +} + /* * RTC Commands * @@ -547,6 +558,7 @@ static void via1_rtc_update(MacVIAState *m) /* PRAM address 0x00 -> 0x13 */ trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_= out); v1s->PRAM[m->cmd - REG_PRAM_ADDR] =3D m->data_out; + pram_update(m); m->cmd =3D REG_EMPTY; break; case REG_PRAM_SECT...REG_PRAM_SECT_LAST: @@ -577,6 +589,7 @@ static void via1_rtc_update(MacVIAState *m) g_assert(REG_PRAM_SECT <=3D m->cmd && m->cmd <=3D REG_PRAM_SECT_LAST); sector =3D m->cmd - REG_PRAM_SECT; v1s->PRAM[sector * 32 + m->alt] =3D m->data_out; + pram_update(m); trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->al= t, m->data_out); m->alt =3D REG_EMPTY; @@ -857,6 +870,7 @@ static void mac_via_realize(DeviceState *dev, Error **e= rrp) MacVIAState *m =3D MAC_VIA(dev); MOS6522State *ms; struct tm tm; + int ret; =20 /* Init VIAs 1 and 2 */ sysbus_init_child_obj(OBJECT(dev), "via1", &m->mos6522_via1, @@ -890,6 +904,28 @@ static void mac_via_realize(DeviceState *dev, Error **= errp) m->adb_poll_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m= ); m->adb_data_ready =3D qdev_get_gpio_in_named(dev, "via1-irq", VIA1_IRQ_ADB_READY_BIT); + + if (m->blk) { + int64_t len =3D blk_getlength(m->blk); + if (len < 0) { + error_setg_errno(errp, -len, + "could not get length of backing image"); + return; + } + ret =3D blk_set_perm(m->blk, + BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, + BLK_PERM_ALL, errp); + if (ret < 0) { + return; + } + + len =3D blk_pread(m->blk, 0, m->mos6522_via1.PRAM, + sizeof(m->mos6522_via1.PRAM)); + if (len !=3D sizeof(m->mos6522_via1.PRAM)) { + error_setg(errp, "can't read PRAM contents"); + return; + } + } } =20 static void mac_via_init(Object *obj) @@ -914,10 +950,33 @@ static void mac_via_init(Object *obj) TYPE_ADB_BUS, DEVICE(obj), "adb.0"); } =20 +static void postload_update_cb(void *opaque, int running, RunState state) +{ + MacVIAState *m =3D MAC_VIA(opaque); + + qemu_del_vm_change_state_handler(m->vmstate); + m->vmstate =3D NULL; + + pram_update(m); +} + +static int mac_via_post_load(void *opaque, int version_id) +{ + MacVIAState *m =3D MAC_VIA(opaque); + + if (m->blk) { + m->vmstate =3D qemu_add_vm_change_state_handler(postload_update_cb, + m); + } + + return 0; +} + static const VMStateDescription vmstate_mac_via =3D { .name =3D "mac-via", .version_id =3D 1, .minimum_version_id =3D 1, + .post_load =3D mac_via_post_load, .fields =3D (VMStateField[]) { /* VIAs */ VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mo= s6522, @@ -950,6 +1009,11 @@ static const VMStateDescription vmstate_mac_via =3D { } }; =20 +static Property mac_via_properties[] =3D { + DEFINE_PROP_DRIVE("drive", MacVIAState, blk), + DEFINE_PROP_END_OF_LIST(), +}; + static void mac_via_class_init(ObjectClass *oc, void *data) { DeviceClass *dc =3D DEVICE_CLASS(oc); @@ -957,6 +1021,7 @@ static void mac_via_class_init(ObjectClass *oc, void *= data) dc->realize =3D mac_via_realize; dc->reset =3D mac_via_reset; dc->vmsd =3D &vmstate_mac_via; + dc->props =3D mac_via_properties; } =20 static TypeInfo mac_via_info =3D { diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h index 3f86fcb7e1..e74f85be0f 100644 --- a/include/hw/misc/mac_via.h +++ b/include/hw/misc/mac_via.h @@ -81,6 +81,8 @@ typedef struct MOS6522Q800VIA2State { typedef struct MacVIAState { SysBusDevice busdev; =20 + VMChangeStateEntry *vmstate; + /* MMIO */ MemoryRegion mmio; MemoryRegion via1mem; @@ -100,6 +102,7 @@ typedef struct MacVIAState { uint8_t cmd; int wprotect; int alt; + BlockBackend *blk; =20 /* ADB */ ADBBusState adb_bus; --=20 2.24.1