From patchwork Thu Dec 5 21:35:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roy Franz X-Patchwork-Id: 22099 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f200.google.com (mail-ie0-f200.google.com [209.85.223.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E8ACD24002 for ; Thu, 5 Dec 2013 21:36:17 +0000 (UTC) Received: by mail-ie0-f200.google.com with SMTP id at1sf57440466iec.3 for ; Thu, 05 Dec 2013 13:36:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=PdMzOxrYFo8HoEgLjexjomzpnqV294SLTJuthBqnIx8=; b=Gic+8CsJMFgQVThDBmd+m8ARfDI+3ZUd0TXz6wbmHuvjWF4TK5C2nQ3TZHCaa6w8uG HNi+qGSuRxdy7ltUGMouPuSTSXyl+PhcaIkaTL2E3+lmwS0z4wB4Xq+kNJvHzT8ipTMv JhoKRUQNsiGN2K8w+p8SVnl2QAkPt4BGFYbp+Yz5rA9oUivMN4napPbfajdxrCNLfzDH yekZy5dUG0bfG3V0bjfEqLHlLaXzREIhZcg1mmtPgOdc+FlyPND2r7ehrusPGkNgJae9 ZpsdVFb8KPJymH1Z2/ASmuCKEzCF/B8cL+13W6dUaacGB10jhXhisAlnAdnAdx9VYDCP EmYw== X-Gm-Message-State: ALoCoQlmrMd7T4ICJy66DOOcieNBxZM4Q6yqbm0zgIM7PA1fXjvopVrKnuCB1nVRM+eGijA4jzMA X-Received: by 10.182.246.225 with SMTP id xz1mr67167obc.14.1386279377547; Thu, 05 Dec 2013 13:36:17 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.15.70 with SMTP id v6ls976543qec.47.gmail; Thu, 05 Dec 2013 13:36:17 -0800 (PST) X-Received: by 10.52.253.103 with SMTP id zz7mr55114vdc.70.1386279377443; Thu, 05 Dec 2013 13:36:17 -0800 (PST) Received: from mail-ve0-f173.google.com (mail-ve0-f173.google.com [209.85.128.173]) by mx.google.com with ESMTPS id pu5si35378923veb.135.2013.12.05.13.36.17 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Dec 2013 13:36:17 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.173; Received: by mail-ve0-f173.google.com with SMTP id oz11so14730785veb.32 for ; Thu, 05 Dec 2013 13:36:17 -0800 (PST) X-Received: by 10.220.97.69 with SMTP id k5mr107031vcn.45.1386279377161; Thu, 05 Dec 2013 13:36:17 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp49279vcz; Thu, 5 Dec 2013 13:36:16 -0800 (PST) X-Received: by 10.69.18.234 with SMTP id gp10mr39017pbd.105.1386279376239; Thu, 05 Dec 2013 13:36:16 -0800 (PST) Received: from mail-pb0-f51.google.com (mail-pb0-f51.google.com [209.85.160.51]) by mx.google.com with ESMTPS id sj5si59165718pab.255.2013.12.05.13.36.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Dec 2013 13:36:16 -0800 (PST) Received-SPF: neutral (google.com: 209.85.160.51 is neither permitted nor denied by best guess record for domain of roy.franz@linaro.org) client-ip=209.85.160.51; Received: by mail-pb0-f51.google.com with SMTP id up15so26938896pbc.10 for ; Thu, 05 Dec 2013 13:36:15 -0800 (PST) X-Received: by 10.66.216.193 with SMTP id os1mr92000pac.29.1386279375838; Thu, 05 Dec 2013 13:36:15 -0800 (PST) Received: from rfranz-i7.local (c-24-10-97-91.hsd1.ca.comcast.net. [24.10.97.91]) by mx.google.com with ESMTPSA id xv2sm146889377pbb.39.2013.12.05.13.36.14 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Dec 2013 13:36:15 -0800 (PST) From: Roy Franz To: qemu-devel@nongnu.org, peter.maydell@linaro.org, kwolf@redhat.com, stefanha@redhat.com Cc: patches@linaro.org, Roy Franz Subject: [PATCH V5 7/7] Fix NOR flash device ID reading Date: Thu, 5 Dec 2013 13:35:59 -0800 Message-Id: <1386279359-32286-8-git-send-email-roy.franz@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1386279359-32286-1-git-send-email-roy.franz@linaro.org> References: <1386279359-32286-1-git-send-email-roy.franz@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: roy.franz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Fix NOR flash manufacturer and device ID reading. This now properly takes into account device widths and device max widths as required. The reading of these IDs uses the same max_width dependent addressing as CFI queries. The old code remains for chips that don't specify a device width, as the new code relies on a device width being set in order to properly operate. The existing code seems very broken. Only ident0 and ident1 are used in the new code, as other fields relate to the lock state of blocks in flash. The VExpress flash configuration has been updated to match the new code, as the existing definition was 'wrong' in order to return the expected results with the broken device ID code. Signed-off-by: Roy Franz Reviewed-by: Peter Maydell --- hw/arm/vexpress.c | 6 +-- hw/block/pflash_cfi01.c | 107 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 90 insertions(+), 23 deletions(-) diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 939b468..aaa863e 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -499,10 +499,10 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name, qdev_prop_set_uint8(dev, "width", 4); qdev_prop_set_uint8(dev, "device-width", 2); qdev_prop_set_uint8(dev, "big-endian", 0); - qdev_prop_set_uint16(dev, "id0", 0x00); - qdev_prop_set_uint16(dev, "id1", 0x89); + qdev_prop_set_uint16(dev, "id0", 0x89); + qdev_prop_set_uint16(dev, "id1", 0x18); qdev_prop_set_uint16(dev, "id2", 0x00); - qdev_prop_set_uint16(dev, "id3", 0x18); + qdev_prop_set_uint16(dev, "id3", 0x00); qdev_prop_set_string(dev, "name", name); qdev_init_nofail(dev); diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 564e6ee..15e4a64 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -179,6 +179,58 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) return resp; } + + +/* Perform a device id query based on the bank width of the flash. */ +static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) +{ + int i; + uint32_t resp; + hwaddr boff; + + /* Adjust incoming offset to match expected device-width + * addressing. Device ID read addresses are always specified in + * terms of the maximum supported width of the device. This means + * that x8 devices and x8/x16 devices in x8 mode behave + * differently. For devices that are not used at their max width, + * we will be provided with addresses that use higher address bits + * than expected (based on the max width), so we will shift them + * lower so that they will match the addresses used when + * device_width==max_device_width. + */ + boff = offset >> (ctz32(pfl->bank_width) + + ctz32(pfl->max_device_width) - ctz32(pfl->device_width)); + + /* Mask off upper bits which may be used in to query block + * or sector lock status at other addresses. + * Offsets 2/3 are block lock status, is not emulated. + */ + switch (boff & 0xFF) { + case 0: + resp = pfl->ident0; + DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); + break; + case 1: + resp = pfl->ident1; + DPRINTF("%s: Device ID Code %04x\n", __func__, ret); + break; + default: + DPRINTF("%s: Read Device Information offset=%x\n", __func__, + (unsigned)offset); + return 0; + break; + } + /* Replicate responses for each device in bank. */ + if (pfl->device_width < pfl->bank_width) { + for (i = pfl->device_width; + i < pfl->bank_width; i += pfl->device_width) { + resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp); + } + } + + return resp; +} + static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, int width, int be) { @@ -266,26 +318,41 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, DPRINTF("%s: status %x\n", __func__, ret); break; case 0x90: - boff = offset & 0xFF; - if (pfl->bank_width == 2) - boff = boff >> 1; - else if (pfl->bank_width == 4) - boff = boff >> 2; - - switch (boff) { - case 0: - ret = pfl->ident0 << 8 | pfl->ident1; - DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); - break; - case 1: - ret = pfl->ident2 << 8 | pfl->ident3; - DPRINTF("%s: Device ID Code %04x\n", __func__, ret); - break; - default: - DPRINTF("%s: Read Device Information boff=%x\n", __func__, - (unsigned)boff); - ret = 0; - break; + + if (!pfl->device_width) { + /* Preserve old behavior if device width not specified */ + boff = offset & 0xFF; + if (pfl->bank_width == 2) { + boff = boff >> 1; + } else if (pfl->bank_width == 4) { + boff = boff >> 2; + } + + switch (boff) { + case 0: + ret = pfl->ident0 << 8 | pfl->ident1; + DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); + break; + case 1: + ret = pfl->ident2 << 8 | pfl->ident3; + DPRINTF("%s: Device ID Code %04x\n", __func__, ret); + break; + default: + DPRINTF("%s: Read Device Information boff=%x\n", __func__, + (unsigned)boff); + ret = 0; + break; + } + } else { + /* If we have a read larger than the bank_width, combine multiple + * manufacturer/device ID queries into a single response. + */ + int i; + for (i = 0; i < width; i += pfl->bank_width) { + ret = deposit32(ret, i * 8, pfl->bank_width * 8, + pflash_devid_query(pfl, + offset + i * pfl->bank_width)); + } } break; case 0x98: /* Query mode */