From nobody Sun Feb 8 20:08:48 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; dkim=fail; spf=pass (zoho.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=1555538686; cv=none; d=zoho.com; s=zohoarc; b=QO5Pr2rJ3VBrRWmr3zGHcnG2PsR972F6w+pSDJKak9I9/cQ2rDqReYimaJg9je5ssEvM4XQK6k17Hv8AvB9xkJWZ47a03I041FEE7wOqnRbWv5wYryGwjwu/l3NgcwRPKOtQH4EwFfr/yr/2lZs3Lg0TfqMy8gr9FmFpGglWPKo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1555538686; h=Content-Transfer-Encoding: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:ARC-Authentication-Results; bh=Jv0E8JtBAEhamTwvz2jAbN/sxL4NNiW4E2UIqBfaHx8=; b=IAdq2+QY5IPHlHjA8ZikYW5zU7iKnS4Jzym5RIYkeInse9P/tVOxCrVpPeO7iUQnuVo2AAsTn46PB8EscBPwUN0nuiG5fupYMcoIjIH+rlN7NLw5bTD8yGepYZi7TwVdNpjTcr7iYJLd9Aq7Rh3pxkJqlAMqvve7QlkKE0Ukr4c= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.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 (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1555538686061281.17168830912556; Wed, 17 Apr 2019 15:04:46 -0700 (PDT) Received: from localhost ([127.0.0.1]:60291 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGsfW-0008HO-IC for importer@patchew.org; Wed, 17 Apr 2019 18:04:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:37930) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGsdP-00071P-VX for qemu-devel@nongnu.org; Wed, 17 Apr 2019 18:02:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hGsdN-0004Pf-My for qemu-devel@nongnu.org; Wed, 17 Apr 2019 18:02:27 -0400 Received: from mail-it1-x144.google.com ([2607:f8b0:4864:20::144]:34450) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hGsdN-0004Os-Et for qemu-devel@nongnu.org; Wed, 17 Apr 2019 18:02:25 -0400 Received: by mail-it1-x144.google.com with SMTP id z17so6437504itc.1 for ; Wed, 17 Apr 2019 15:02:25 -0700 (PDT) Received: from worksec.wireless.oberlin.edu (ip-70-93.wireless.oberlin.edu. [132.162.70.93]) by smtp.gmail.com with ESMTPSA id e81sm147874itc.3.2019.04.17.15.02.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Apr 2019 15:02:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oberlin-edu.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Jv0E8JtBAEhamTwvz2jAbN/sxL4NNiW4E2UIqBfaHx8=; b=ckKcpm/56tIjycgKqg3QfQwOVwCTctwAporEbm0/wJFsF6ZvnpkIypN5HbCV4WAQGk yLaxG3aAUp3Cgkd6dvQfVXB40/VBgcsZwMHhk2gMeV4iolzT6B8Xb5sYvWOLGSGUOHYY kDLFHSWmyR1z4XuClL9EpRW9XcmIJPn0krweqZlIF4MgJEGmIUhaq/P4ev+v+azN4ZKg A0zA3VcZiHT8NNdi9Jm4O6+z5YYek7gCvIS0DNLCmLKpDtNgxjnZwRzTD61xOSfQ5SY2 JHwiCmVCUGq/YxpwFMmXLWByt0s8H7xgPJgm415UUIOEqRcnAO0kFeMBW4VmUdQIRyma herw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Jv0E8JtBAEhamTwvz2jAbN/sxL4NNiW4E2UIqBfaHx8=; b=E/nofJYNC37Clcgu7D0WJKk4MgeswSw9KopzFdC5GLrbm+DEWPnMz++Tm3fEvoOEUT bVMw8b6z+1+W+6+HYAYYv78/ou3iHjifWzPPrnr9cpk+ksseCjtMb8Acq7LHDjHO/cPU f0C7UVq1DCpz1WxHxTbus3cDSfQMVUHghudpQDXFb7PkW+bswDWRZHYSDFPBkrGMOXNx PptaULzFvYS/Q5zHjH3d/j2AASnQ8PkXYLLT7ET8mMSTlDP5nSGoLUQ1VnjKxHe98O6G uLFO+8m+POL4Oa+e8FuARi5SHYpIDqXtcQl2f/m1iBg5Y8j4I/3C9CZFzsnHhQchaW7s DXWg== X-Gm-Message-State: APjAAAUb5tJX4v33C/PkwOa5spUNjniJSb5oLg9w54/WVnfCUCmOSuZn 3S4KNxbttcmcub1RvF+e7W1/EBtTrhZMPeEf X-Google-Smtp-Source: APXvYqxzESyWHadKs/1m5OobI2Wisb5ZjbelzPS5IsIh9/RcGelO6Obnz6HagaL9vPjF5y+OC4gwCA== X-Received: by 2002:a24:e346:: with SMTP id d67mr791174ith.42.1555538544640; Wed, 17 Apr 2019 15:02:24 -0700 (PDT) From: Stephen Checkoway To: QEMU Developers , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Kevin Wolf , Max Reitz , "open list:Block layer core" , Stephen Checkoway , Markus Armbruster , Laszlo Ersek , Laurent Vivier , Paolo Bonzini Date: Wed, 17 Apr 2019 18:01:39 -0400 Message-Id: <20190417220147.67648-3-stephen.checkoway@oberlin.edu> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190417220147.67648-1-stephen.checkoway@oberlin.edu> References: <20190417220147.67648-1-stephen.checkoway@oberlin.edu> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::144 Subject: [Qemu-devel] [PATCH v3 02/10] block/pflash_cfi02: Refactor, NFC intended 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Simplify and refactor for upcoming commits. In particular, pull out all of the code to modify the status into simple helper functions. Status handling becomes more complex once multiple chips are interleaved to produce a single device. No change in functionality is intended with this commit. Signed-off-by: Stephen Checkoway --- hw/block/pflash_cfi02.c | 221 +++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 126 deletions(-) diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index f2c6201f81..4b7af71806 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -46,18 +46,19 @@ #include "hw/sysbus.h" #include "trace.h" =20 -//#define PFLASH_DEBUG -#ifdef PFLASH_DEBUG +#define PFLASH_DEBUG false #define DPRINTF(fmt, ...) \ do { \ - fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__); \ + if (PFLASH_DEBUG) { \ + fprintf(stderr, "PFLASH: " fmt, ## __VA_ARGS__); \ + } \ } while (0) -#else -#define DPRINTF(fmt, ...) do { } while (0) -#endif =20 #define PFLASH_LAZY_ROMD_THRESHOLD 42 =20 +/* Special write cycle for CFI queries. */ +#define WCYCLE_CFI 7 + struct PFlashCFI02 { /*< private >*/ SysBusDevice parent_obj; @@ -97,6 +98,31 @@ struct PFlashCFI02 { void *storage; }; =20 +/* + * Toggle status bit DQ7. + */ +static inline void toggle_dq7(PFlashCFI02 *pfl) +{ + pfl->status ^=3D 0x80; +} + +/* + * Set status bit DQ7 to bit 7 of value. + */ +static inline void set_dq7(PFlashCFI02 *pfl, uint8_t value) +{ + pfl->status &=3D 0x7F; + pfl->status |=3D value & 0x80; +} + +/* + * Toggle status bit DQ6. + */ +static inline void toggle_dq6(PFlashCFI02 *pfl) +{ + pfl->status ^=3D 0x40; +} + /* * Set up replicated mappings of the same region. */ @@ -126,7 +152,7 @@ static void pflash_timer (void *opaque) =20 trace_pflash_timer_expired(pfl->cmd); /* Reset flash */ - pfl->status ^=3D 0x80; + toggle_dq7(pfl); if (pfl->bypass) { pfl->wcycle =3D 2; } else { @@ -136,12 +162,34 @@ static void pflash_timer (void *opaque) pfl->cmd =3D 0; } =20 -static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset, - int width, int be) +/* + * Read data from flash. + */ +static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr offset, + unsigned int width) { + uint8_t *p =3D (uint8_t *)pfl->storage + offset; + uint64_t ret =3D pfl->be ? ldn_be_p(p, width) : ldn_le_p(p, width); + /* XXX: Need a trace_pflash_data_read(offset, ret, width) */ + switch (width) { + case 1: + trace_pflash_data_read8(offset, ret); + break; + case 2: + trace_pflash_data_read16(offset, ret); + break; + case 4: + trace_pflash_data_read32(offset, ret); + break; + } + return ret; +} + +static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int widt= h) +{ + PFlashCFI02 *pfl =3D opaque; hwaddr boff; - uint32_t ret; - uint8_t *p; + uint64_t ret; =20 ret =3D -1; trace_pflash_read(offset, pfl->cmd, width, pfl->wcycle); @@ -166,39 +214,8 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr o= ffset, case 0x80: /* We accept reads during second unlock sequence... */ case 0x00: - flash_read: /* Flash area read */ - p =3D pfl->storage; - switch (width) { - case 1: - ret =3D p[offset]; - trace_pflash_data_read8(offset, ret); - break; - case 2: - if (be) { - ret =3D p[offset] << 8; - ret |=3D p[offset + 1]; - } else { - ret =3D p[offset]; - ret |=3D p[offset + 1] << 8; - } - trace_pflash_data_read16(offset, ret); - break; - case 4: - if (be) { - ret =3D p[offset] << 24; - ret |=3D p[offset + 1] << 16; - ret |=3D p[offset + 2] << 8; - ret |=3D p[offset + 3]; - } else { - ret =3D p[offset]; - ret |=3D p[offset + 1] << 8; - ret |=3D p[offset + 2] << 16; - ret |=3D p[offset + 3] << 24; - } - trace_pflash_data_read32(offset, ret); - break; - } + ret =3D pflash_data_read(pfl, offset, width); break; case 0x90: /* flash ID read */ @@ -213,23 +230,23 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr = offset, case 0x0E: case 0x0F: ret =3D boff & 0x01 ? pfl->ident3 : pfl->ident2; - if (ret =3D=3D (uint8_t)-1) { - goto flash_read; + if (ret !=3D (uint8_t)-1) { + break; } - break; + /* Fall through to data read. */ default: - goto flash_read; + ret =3D pflash_data_read(pfl, offset, width); } - 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; + toggle_dq6(pfl); break; case 0x98: /* CFI query mode */ @@ -245,8 +262,7 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr of= fset, } =20 /* update flash content on disk */ -static void pflash_update(PFlashCFI02 *pfl, int offset, - int size) +static void pflash_update(PFlashCFI02 *pfl, int offset, int size) { int offset_end; if (pfl->blk) { @@ -259,9 +275,10 @@ static void pflash_update(PFlashCFI02 *pfl, int offset, } } =20 -static void pflash_write(PFlashCFI02 *pfl, hwaddr offset, - uint32_t value, int width, int be) +static void pflash_write(void *opaque, hwaddr offset, uint64_t value, + unsigned int width) { + PFlashCFI02 *pfl =3D opaque; hwaddr boff; uint8_t *p; uint8_t cmd; @@ -277,7 +294,7 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offse= t, trace_pflash_write(offset, value, width, pfl->wcycle); offset &=3D pfl->chip_len - 1; =20 - DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d\n", __func__, + 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) @@ -295,7 +312,7 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offse= t, if (boff =3D=3D 0x55 && cmd =3D=3D 0x98) { enter_CFI_mode: /* Enter CFI query mode */ - pfl->wcycle =3D 7; + pfl->wcycle =3D WCYCLE_CFI; pfl->cmd =3D 0x98; return; } @@ -345,40 +362,22 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr off= set, goto check_unlock0; case 0xA0: trace_pflash_data_write(offset, value, width, 0); - p =3D pfl->storage; if (!pfl->ro) { - switch (width) { - case 1: - p[offset] &=3D value; - pflash_update(pfl, offset, 1); - break; - case 2: - if (be) { - p[offset] &=3D value >> 8; - p[offset + 1] &=3D value; - } else { - p[offset] &=3D value; - p[offset + 1] &=3D value >> 8; - } - pflash_update(pfl, offset, 2); - break; - case 4: - if (be) { - p[offset] &=3D value >> 24; - p[offset + 1] &=3D value >> 16; - p[offset + 2] &=3D value >> 8; - p[offset + 3] &=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; - } - pflash_update(pfl, offset, 4); - break; + p =3D (uint8_t *)pfl->storage + offset; + if (pfl->be) { + uint64_t current =3D ldn_be_p(p, width); + stn_be_p(p, width, current & value); + } else { + uint64_t current =3D ldn_le_p(p, width); + stn_le_p(p, width, current & value); } + pflash_update(pfl, offset, width); } - pfl->status =3D 0x00 | ~(value & 0x80); + /* + * While programming, status bit DQ7 should hold the opposite + * value from how it was programmed. + */ + set_dq7(pfl, ~value); /* Let's pretend write is immediate */ if (pfl->bypass) goto do_bypass; @@ -426,7 +425,7 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offse= t, memset(pfl->storage, 0xFF, pfl->chip_len); pflash_update(pfl, 0, pfl->chip_len); } - pfl->status =3D 0x00; + set_dq7(pfl, 0x00); /* Let's wait 5 seconds before chip erase is done */ timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (NANOSECONDS_PER_SECOND * 5)); @@ -441,7 +440,7 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offse= t, memset(p + offset, 0xFF, pfl->sector_len); pflash_update(pfl, offset, pfl->sector_len); } - pfl->status =3D 0x00; + set_dq7(pfl, 0x00); /* Let's wait 1/2 second before sector erase is done */ timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (NANOSECONDS_PER_SECOND / 2)); @@ -467,7 +466,7 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offse= t, goto reset_flash; } break; - case 7: /* Special value for CFI queries */ + case WCYCLE_CFI: /* Special value for CFI queries */ DPRINTF("%s: invalid write in CFI query mode\n", __func__); goto reset_flash; default: @@ -492,39 +491,9 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offs= et, pfl->cmd =3D 0; } =20 -static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size) -{ - return pflash_read(opaque, addr, size, 1); -} - -static void pflash_be_writefn(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - pflash_write(opaque, addr, value, size, 1); -} - -static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size) -{ - return pflash_read(opaque, addr, size, 0); -} - -static void pflash_le_writefn(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - pflash_write(opaque, addr, value, size, 0); -} - -static const MemoryRegionOps pflash_cfi02_ops_be =3D { - .read =3D pflash_be_readfn, - .write =3D pflash_be_writefn, - .valid.min_access_size =3D 1, - .valid.max_access_size =3D 4, - .endianness =3D DEVICE_NATIVE_ENDIAN, -}; - -static const MemoryRegionOps pflash_cfi02_ops_le =3D { - .read =3D pflash_le_readfn, - .write =3D pflash_le_writefn, +static const MemoryRegionOps pflash_cfi02_ops =3D { + .read =3D pflash_read, + .write =3D pflash_write, .valid.min_access_size =3D 1, .valid.max_access_size =3D 4, .endianness =3D DEVICE_NATIVE_ENDIAN, @@ -552,9 +521,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Erro= r **errp) =20 chip_len =3D pfl->sector_len * pfl->nb_blocs; =20 - memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ? - &pflash_cfi02_ops_be : &pflash_cfi02_ops= _le, - pfl, pfl->name, chip_len, &local_err); + memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), + &pflash_cfi02_ops, pfl, pfl->name, + chip_len, &local_err); if (local_err) { error_propagate(errp, local_err); return; --=20 2.20.1 (Apple Git-117)