From nobody Sat May 4 20:26:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 150946493228443.62397245940167; Tue, 31 Oct 2017 08:48:52 -0700 (PDT) Received: from localhost ([::1]:46282 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9YmK-0003QU-FS for importer@patchew.org; Tue, 31 Oct 2017 11:48:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9YjV-0001Tt-C8 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9YjT-0007Yn-EJ for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:41 -0400 Received: from relay2.gtri.gatech.edu ([130.207.199.168]:52382) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e9YjT-0007WZ-A3 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:39 -0400 Received: from kiawah.core.gtri.org (kiawah.core.gtri.org [10.41.31.71]) by relay2.gtri.gatech.edu with ESMTP id UQeylM5lNNk0gP6e (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=NO); Tue, 31 Oct 2017 11:45:37 -0400 (EDT) Received: from tybee.core.gtri.org (10.41.1.49) by kiawah.core.gtri.org (10.41.31.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1034.26; Tue, 31 Oct 2017 11:45:37 -0400 Received: from tia-mxn-d01.ctisl.gtri.org (130.207.205.130) by tybee.core.gtri.org (10.41.1.49) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1034.26; Tue, 31 Oct 2017 11:45:37 -0400 X-ASG-Debug-ID: 1509464737-0768e41b30561b70001-jgbH7p X-Barracuda-Envelope-From: Michael.Nawrocki@gtri.gatech.edu From: Mike Nawrocki To: , , , Date: Tue, 31 Oct 2017 11:44:06 -0400 X-ASG-Orig-Subj: [PATCH 1/2] Add 8-byte access to AMD CFI devices Message-ID: <20171031154407.4184-2-michael.nawrocki@gtri.gatech.edu> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171031154407.4184-1-michael.nawrocki@gtri.gatech.edu> References: <20171031154407.4184-1-michael.nawrocki@gtri.gatech.edu> MIME-Version: 1.0 X-Originating-IP: [130.207.205.130] X-ClientProxiedBy: apatlisdmfe4.core.gtri.org (10.41.47.104) To tybee.core.gtri.org (10.41.1.49) X-Barracuda-Connect: kiawah.core.gtri.org[10.41.31.71] X-Barracuda-Start-Time: 1509464737 X-Barracuda-Encrypted: ECDHE-RSA-AES128-SHA256 X-Barracuda-URL: https://130.207.199.168:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at gtri.gatech.edu X-Barracuda-Scan-Msg-Size: 10491 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=1000.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.44359 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 130.207.199.168 Subject: [Qemu-devel] [PATCH 1/2] Add 8-byte access to AMD CFI devices X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Mike Nawrocki , magnus.damm@gmail.com, alistair.francis@xilinx.com, michael@walle.cc, jan.kiszka@web.de, edgar.iglesias@gmail.com, mreitz@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This adds 8-byte wide access support to AMD CFI flash devices. Additionally, it migrates the MMIO operations from old_mmio to the new API. Signed-off-by: Mike Nawrocki --- hw/block/pflash_cfi02.c | 172 +++++++++++++++++++++++---------------------= ---- 1 file changed, 81 insertions(+), 91 deletions(-) diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index c81ddd3a99..0aed0ab218 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -18,7 +18,7 @@ */ =20 /* - * For now, this code can emulate flashes of 1, 2 or 4 bytes width. + * For now, this code can emulate flashes of 1, 2, 4, or 8 bytes width. * Supported commands/modes are: * - flash read * - flash write @@ -138,11 +138,11 @@ static void pflash_timer (void *opaque) pfl->cmd =3D 0; } =20 -static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, - int width, int be) +static uint64_t pflash_read(pflash_t *pfl, hwaddr offset, + int width, int be) { hwaddr boff; - uint32_t ret; + uint64_t ret; uint8_t *p; =20 DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset); @@ -158,6 +158,8 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offs= et, boff =3D boff >> 1; else if (pfl->width =3D=3D 4) boff =3D boff >> 2; + else if (pfl->width =3D=3D 8) + boff =3D boff >> 3; switch (pfl->cmd) { default: /* This should never happen : reset state & treat it as a read*/ @@ -200,6 +202,27 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr off= set, } // DPRINTF("%s: data offset %08x %08x\n", __func__, offset, ret= ); break; + case 8: + if (be) { + ret =3D (uint64_t)p[offset] << 56; + ret |=3D (uint64_t)p[offset + 1] << 48; + ret |=3D (uint64_t)p[offset + 2] << 40; + ret |=3D (uint64_t)p[offset + 3] << 32; + ret |=3D (uint64_t)p[offset + 4] << 24; + ret |=3D (uint64_t)p[offset + 5] << 16; + ret |=3D (uint64_t)p[offset + 6] << 8; + ret |=3D (uint64_t)p[offset + 7]; + } else { + ret =3D (uint64_t)p[offset]; + ret |=3D (uint64_t)p[offset + 1] << 8; + ret |=3D (uint64_t)p[offset + 2] << 16; + ret |=3D (uint64_t)p[offset + 3] << 24; + ret |=3D (uint64_t)p[offset + 4] << 32; + ret |=3D (uint64_t)p[offset + 5] << 40; + ret |=3D (uint64_t)p[offset + 6] << 48; + ret |=3D (uint64_t)p[offset + 7] << 56; + } + break; } break; case 0x90: @@ -222,14 +245,15 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr of= fset, default: goto flash_read; } - DPRINTF("%s: ID " TARGET_FMT_plx " %x\n", __func__, boff, ret); + DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx64 "\n", __func__, + boff, ret); break; case 0xA0: case 0x10: case 0x30: /* Status register read */ ret =3D pfl->status; - DPRINTF("%s: status %x\n", __func__, ret); + DPRINTF("%s: status %" PRIx64 "\n", __func__, ret); /* Toggle bit 6 */ pfl->status ^=3D 0x40; break; @@ -246,8 +270,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offs= et, } =20 /* update flash content on disk */ -static void pflash_update(pflash_t *pfl, int offset, - int size) +static void pflash_update(pflash_t *pfl, int offset, int size) { int offset_end; if (pfl->blk) { @@ -260,8 +283,8 @@ static void pflash_update(pflash_t *pfl, int offset, } } =20 -static void pflash_write (pflash_t *pfl, hwaddr offset, - uint32_t value, int width, int be) +static void pflash_write(pflash_t *pfl, hwaddr offset, + uint64_t value, int width, int be) { hwaddr boff; uint8_t *p; @@ -275,17 +298,19 @@ static void pflash_write (pflash_t *pfl, hwaddr offse= t, #endif goto reset_flash; } - DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d %d\n", __func__, - offset, value, width, pfl->wcycle); + DPRINTF("%s: offset " TARGET_FMT_plx " %08" PRIx64 " %d %d\n", + __func__, offset, value, width, pfl->wcycle); offset &=3D pfl->chip_len - 1; =20 - DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d\n", __func__, - offset, value, width); + DPRINTF("%s: offset " TARGET_FMT_plx " %08" PRIx64 " %d\n", + __func__, offset, value, width); boff =3D offset & (pfl->sector_len - 1); if (pfl->width =3D=3D 2) boff =3D boff >> 1; else if (pfl->width =3D=3D 4) boff =3D boff >> 2; + else if (pfl->width =3D=3D 8) + boff =3D boff >> 3; switch (pfl->wcycle) { case 0: /* Set the device in I/O access mode if required */ @@ -346,8 +371,8 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, /* We need another unlock sequence */ goto check_unlock0; case 0xA0: - DPRINTF("%s: write data offset " TARGET_FMT_plx " %08x %d\n", - __func__, offset, value, width); + DPRINTF("%s: write data offset " TARGET_FMT_plx + " %08" PRIx64 " %d\n", __func__, offset, value, width); p =3D pfl->storage; if (!pfl->ro) { switch (width) { @@ -379,6 +404,28 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, } pflash_update(pfl, offset, 4); break; + case 8: + if (be) { + p[offset] &=3D value >> 56; + p[offset + 1] &=3D value >> 48; + p[offset + 2] &=3D value >> 40; + p[offset + 3] &=3D value >> 32; + p[offset + 4] &=3D value >> 24; + p[offset + 5] &=3D value >> 16; + p[offset + 6] &=3D value >> 8; + p[offset + 7] &=3D value; + } else { + p[offset] &=3D value; + p[offset + 1] &=3D value >> 8; + p[offset + 2] &=3D value >> 16; + p[offset + 3] &=3D value >> 24; + p[offset + 4] &=3D value >> 32; + p[offset + 5] &=3D value >> 40; + p[offset + 6] &=3D value >> 48; + p[offset + 7] &=3D value >> 56; + } + pflash_update(pfl, offset, 8); + break; } } pfl->status =3D 0x00 | ~(value & 0x80); @@ -494,103 +541,46 @@ static void pflash_write (pflash_t *pfl, hwaddr offs= et, pfl->cmd =3D 0; } =20 - -static uint32_t pflash_readb_be(void *opaque, hwaddr addr) -{ - return pflash_read(opaque, addr, 1, 1); -} - -static uint32_t pflash_readb_le(void *opaque, hwaddr addr) -{ - return pflash_read(opaque, addr, 1, 0); -} - -static uint32_t pflash_readw_be(void *opaque, hwaddr addr) +static uint64_t pflash_read_le(void *opaque, hwaddr addr, unsigned size) { pflash_t *pfl =3D opaque; - - return pflash_read(pfl, addr, 2, 1); + return pflash_read(pfl, addr, size, 0); } =20 -static uint32_t pflash_readw_le(void *opaque, hwaddr addr) +static uint64_t pflash_read_be(void *opaque, hwaddr addr, unsigned size) { pflash_t *pfl =3D opaque; - - return pflash_read(pfl, addr, 2, 0); + return pflash_read(pfl, addr, size, 1); } =20 -static uint32_t pflash_readl_be(void *opaque, hwaddr addr) +static void pflash_write_le(void *opaque, hwaddr addr, uint64_t data, + unsigned size) { pflash_t *pfl =3D opaque; - - return pflash_read(pfl, addr, 4, 1); + pflash_write(pfl, addr, data, size, 0); } =20 -static uint32_t pflash_readl_le(void *opaque, hwaddr addr) +static void pflash_write_be(void *opaque, hwaddr addr, uint64_t data, + unsigned size) { pflash_t *pfl =3D opaque; - - return pflash_read(pfl, addr, 4, 0); -} - -static void pflash_writeb_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_write(opaque, addr, value, 1, 1); -} - -static void pflash_writeb_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_write(opaque, addr, value, 1, 0); -} - -static void pflash_writew_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl =3D opaque; - - pflash_write(pfl, addr, value, 2, 1); -} - -static void pflash_writew_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl =3D opaque; - - pflash_write(pfl, addr, value, 2, 0); -} - -static void pflash_writel_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl =3D opaque; - - pflash_write(pfl, addr, value, 4, 1); -} - -static void pflash_writel_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl =3D opaque; - - pflash_write(pfl, addr, value, 4, 0); + pflash_write(pfl, addr, data, size, 1); } =20 static const MemoryRegionOps pflash_cfi02_ops_be =3D { - .old_mmio =3D { - .read =3D { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, - .write =3D { pflash_writeb_be, pflash_writew_be, pflash_writel_be,= }, - }, + .read =3D pflash_read_be, + .write =3D pflash_write_be, .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid.max_access_size =3D 8, + .impl.max_access_size =3D 8, }; =20 static const MemoryRegionOps pflash_cfi02_ops_le =3D { - .old_mmio =3D { - .read =3D { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, - .write =3D { pflash_writeb_le, pflash_writew_le, pflash_writel_le,= }, - }, + .read =3D pflash_read_le, + .write =3D pflash_write_le, .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid.max_access_size =3D 8, + .impl.max_access_size =3D 8, }; =20 static void pflash_cfi02_realize(DeviceState *dev, Error **errp) --=20 2.14.2 From nobody Sat May 4 20:26:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 15094648430201009.9624141898638; Tue, 31 Oct 2017 08:47:23 -0700 (PDT) Received: from localhost ([::1]:46277 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Yky-0002RW-4o for importer@patchew.org; Tue, 31 Oct 2017 11:47:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9YjY-0001WX-HC for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9YjW-0007d7-8q for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:44 -0400 Received: from relay2.gtri.gatech.edu ([130.207.199.168]:52470) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e9YjW-0007bk-1Y for qemu-devel@nongnu.org; Tue, 31 Oct 2017 11:45:42 -0400 Received: from jekyll.core.gtri.org (jekyll.core.gtri.org [10.41.1.48]) by relay2.gtri.gatech.edu with ESMTP id h5UF1vmXlHdyktBt (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=NO); Tue, 31 Oct 2017 11:45:39 -0400 (EDT) Received: from tybee.core.gtri.org (10.41.1.49) by jekyll.core.gtri.org (10.41.1.48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1034.26; Tue, 31 Oct 2017 11:45:40 -0400 Received: from tia-mxn-d01.ctisl.gtri.org (130.207.205.130) by tybee.core.gtri.org (10.41.1.49) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1034.26; Tue, 31 Oct 2017 11:45:39 -0400 X-ASG-Debug-ID: 1509464739-0768e41b2f561b60001-jgbH7p X-Barracuda-Envelope-From: Michael.Nawrocki@gtri.gatech.edu From: Mike Nawrocki To: , , , Date: Tue, 31 Oct 2017 11:44:07 -0400 X-ASG-Orig-Subj: [PATCH 2/2] Add support for flash interleaving of AMD chips Message-ID: <20171031154407.4184-3-michael.nawrocki@gtri.gatech.edu> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171031154407.4184-1-michael.nawrocki@gtri.gatech.edu> References: <20171031154407.4184-1-michael.nawrocki@gtri.gatech.edu> MIME-Version: 1.0 X-Originating-IP: [130.207.205.130] X-ClientProxiedBy: apatlisdmfe4.core.gtri.org (10.41.47.104) To tybee.core.gtri.org (10.41.1.49) X-Barracuda-Connect: jekyll.core.gtri.org[10.41.1.48] X-Barracuda-Start-Time: 1509464739 X-Barracuda-Encrypted: ECDHE-RSA-AES128-SHA256 X-Barracuda-URL: https://130.207.199.168:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at gtri.gatech.edu X-Barracuda-Scan-Msg-Size: 12662 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=1000.0 tests=BSF_RULE7568M X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.44359 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE7568M Custom Rule 7568M X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 130.207.199.168 Subject: [Qemu-devel] [PATCH 2/2] Add support for flash interleaving of AMD chips X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Mike Nawrocki , magnus.damm@gmail.com, alistair.francis@xilinx.com, michael@walle.cc, jan.kiszka@web.de, edgar.iglesias@gmail.com, mreitz@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Flash interleaving is partially supported using the new interleave_num parameter, which indicates how many "devices" comprise the flash array. The supported flash access pattern is one where commands are sent to all devices simultaneously and the read result is duplicated according to the interleave number. For example, given a flash array of width 8, interleave 4, the command sequence 0x00AA00AA00AA00AA 0x0055005500550055 0x0090009000900090 sends the auto-select command sequence. If a read to address 0 is issued, the user would expect the following: 0x0001000100010001 to identify the AMD device array. Issuing commands to individual members of the flash array is not supported. Signed-off-by: Mike Nawrocki --- hw/arm/digic_boards.c | 2 +- hw/arm/musicpal.c | 4 ++-- hw/arm/xilinx_zynq.c | 2 +- hw/block/pflash_cfi02.c | 38 +++++++++++++++++++++++++++++++++++++- hw/lm32/lm32_boards.c | 4 ++-- hw/ppc/ppc405_boards.c | 15 ++++++--------- hw/sh4/r2d.c | 2 +- include/hw/block/flash.h | 1 + 8 files changed, 51 insertions(+), 17 deletions(-) diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c index 9f11dcd11f..7f039a989a 100644 --- a/hw/arm/digic_boards.c +++ b/hw/arm/digic_boards.c @@ -133,7 +133,7 @@ static void digic4_add_k8p3215uqb_rom(DigicBoardState *= s, hwaddr addr, NULL, FLASH_K8P3215UQB_SECTOR_SIZE, FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_= SIZE, DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE, - 4, + 4, 1, 0x00EC, 0x007E, 0x0003, 0x0001, 0x0555, 0x2aa, 0); =20 diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index b648770882..5d98cd1eac 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1640,14 +1640,14 @@ static void musicpal_init(MachineState *machine) "musicpal.flash", flash_size, blk, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, - 2, 0x00BF, 0x236D, 0x0000, 0x0000, + 2, 1, 0x00BF, 0x236D, 0x0000, 0x0000, 0x5555, 0x2AAA, 1); #else pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL, "musicpal.flash", flash_size, blk, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, - 2, 0x00BF, 0x236D, 0x0000, 0x0000, + 2, 1, 0x00BF, 0x236D, 0x0000, 0x0000, 0x5555, 0x2AAA, 0); #endif =20 diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 1836a4ed45..ea85333104 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -210,7 +210,7 @@ static void zynq_init(MachineState *machine) dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, FLASH_SECTOR_SIZE, FLASH_SIZE/FLASH_SECTOR_SIZE, 1, - 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, + 1, 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x= 2aa, 0); =20 dev =3D qdev_create(NULL, "xilinx,zynq_slcr"); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 0aed0ab218..b0f86584c5 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -28,11 +28,28 @@ * - unlock bypass command * - CFI queries * - * It does not support flash interleaving. * It does not implement boot blocs with reduced size * It does not implement software data protection as found in many real ch= ips * It does not implement erase suspend/resume commands * It does not implement multiple sectors erase + * + * Flash interleaving is partially supported using the interleave_num + * parameter, which indicates how many "devices" comprise the flash array. + * The supported flash access pattern is one where commands are sent to all + * devices simultaneously and the read result is duplicated according to t= he + * interleave number. For example, given a flash array of width 8, + * interleave 4, the command sequence + * + * 0x00AA00AA00AA00AA + * 0x0055005500550055 + * 0x0090009000900090 + * + * sends the auto-select command sequence. If a read to address 0 is + * issued, the user would expect the following: + * 0x0001000100010001 + * to identify the AMD device array. + * + * Issuing commands to individual members of the flash array is not suppor= ted. */ =20 #include "qemu/osdep.h" @@ -97,6 +114,7 @@ struct pflash_t { int read_counter; /* used for lazy switch-back to rom mode */ char *name; void *storage; + uint8_t interleave_num; /* number of devices that comprise the array */ }; =20 /* @@ -144,6 +162,8 @@ static uint64_t pflash_read(pflash_t *pfl, hwaddr offse= t, hwaddr boff; uint64_t ret; uint8_t *p; + int i; + uint8_t intlv_shift =3D (pfl->width / pfl->interleave_num) << 3; =20 DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset); ret =3D -1; @@ -231,6 +251,10 @@ static uint64_t pflash_read(pflash_t *pfl, hwaddr offs= et, case 0x00: case 0x01: ret =3D boff & 0x01 ? pfl->ident1 : pfl->ident0; + for (i =3D 1; i < pfl->interleave_num; ++i) { + ret =3D (ret << intlv_shift) | ret; + } + break; case 0x02: ret =3D 0x00; /* Pretend all sectors are unprotected */ @@ -241,6 +265,9 @@ static uint64_t pflash_read(pflash_t *pfl, hwaddr offse= t, if (ret =3D=3D (uint8_t)-1) { goto flash_read; } + for (i =3D 1; i < pfl->interleave_num; ++i) { + ret <<=3D intlv_shift; + } break; default: goto flash_read; @@ -253,6 +280,9 @@ static uint64_t pflash_read(pflash_t *pfl, hwaddr offse= t, case 0x30: /* Status register read */ ret =3D pfl->status; + for (i =3D 1; i < pfl->interleave_num; ++i) { + ret <<=3D intlv_shift; + } DPRINTF("%s: status %" PRIx64 "\n", __func__, ret); /* Toggle bit 6 */ pfl->status ^=3D 0x40; @@ -263,6 +293,9 @@ static uint64_t pflash_read(pflash_t *pfl, hwaddr offse= t, ret =3D 0; else ret =3D pfl->cfi_table[boff]; + for (i =3D 1; i < pfl->interleave_num; ++i) { + ret <<=3D intlv_shift; + } break; } =20 @@ -745,6 +778,7 @@ static Property pflash_cfi02_properties[] =3D { DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0), DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0), DEFINE_PROP_STRING("name", struct pflash_t, name), + DEFINE_PROP_UINT8("interleave_num", struct pflash_t, interleave_num, 1= ), DEFINE_PROP_END_OF_LIST(), }; =20 @@ -776,6 +810,7 @@ pflash_t *pflash_cfi02_register(hwaddr base, hwaddr size, BlockBackend *blk, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, + int interleave_num, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t unlock_addr0, uint16_t unlock_add= r1, @@ -798,6 +833,7 @@ pflash_t *pflash_cfi02_register(hwaddr base, qdev_prop_set_uint16(dev, "unlock-addr0", unlock_addr0); qdev_prop_set_uint16(dev, "unlock-addr1", unlock_addr1); qdev_prop_set_string(dev, "name", name); + qdev_prop_set_uint32(dev, "interleave_num", MAX(interleave_num, 1)); qdev_init_nofail(dev); =20 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index 002d638edd..523121142f 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -116,7 +116,7 @@ static void lm32_evr_init(MachineState *machine) pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, flash_sector_size, flash_size / flash_sector_siz= e, - 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); + 1, 2, 1, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1= ); =20 /* create irq lines */ env->pic_state =3D lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cp= u, 0)); @@ -209,7 +209,7 @@ static void lm32_uclinux_init(MachineState *machine) pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_si= ze, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, flash_sector_size, flash_size / flash_sector_siz= e, - 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); + 1, 2, 1, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1= ); =20 /* create irq lines */ env->pic_state =3D lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, en= v, 0)); diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index e92db2c66a..04d318ca65 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -241,9 +241,8 @@ static void ref405ep_init(MachineState *machine) #endif pflash_cfi02_register((uint32_t)(-bios_size), NULL, "ef405ep.bios", bios_size, - blk, 65536, fl_sectors, 1, - 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x= 2AA, - 1); + blk, 65536, fl_sectors, 1, 2, 1, + 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA= , 1); fl_idx++; } else #endif @@ -539,9 +538,8 @@ static void taihu_405ep_init(MachineState *machine) #endif pflash_cfi02_register((uint32_t)(-bios_size), NULL, "taihu_405ep.bios", bios_size, - blk, 65536, fl_sectors, 1, - 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x= 2AA, - 1); + blk, 65536, fl_sectors, 1, 4, 1, + 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA= , 1); fl_idx++; } else #endif @@ -586,9 +584,8 @@ static void taihu_405ep_init(MachineState *machine) blk_name(blk)); #endif pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_= size, - blk, 65536, fl_sectors, 1, - 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x= 2AA, - 1); + blk, 65536, fl_sectors, 1, 4, 1, + 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA= , 1); fl_idx++; } /* Register CLPD & LCD display */ diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 458ed83297..696175dad6 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -293,7 +293,7 @@ static void r2d_init(MachineState *machine) pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, (16 * 1024), FLASH_SIZE >> 16, - 1, 4, 0x0000, 0x0000, 0x0000, 0x0000, + 1, 4, 1, 0x0000, 0x0000, 0x0000, 0x0000, 0x555, 0x2aa, 0); =20 /* NIC: rtl8139 on-board, and 2 slots. */ diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h index 67c3aa329e..b23e3e3030 100644 --- a/include/hw/block/flash.h +++ b/include/hw/block/flash.h @@ -25,6 +25,7 @@ pflash_t *pflash_cfi02_register(hwaddr base, hwaddr size, BlockBackend *blk, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, + int interleave_num, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t unlock_addr0, uint16_t unlock_add= r1, --=20 2.14.2