From patchwork Thu Dec 5 21:35:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roy Franz X-Patchwork-Id: 22098 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f70.google.com (mail-pb0-f70.google.com [209.85.160.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4A10C23FD0 for ; Thu, 5 Dec 2013 21:36:17 +0000 (UTC) Received: by mail-pb0-f70.google.com with SMTP id rq2sf52800852pbb.9 for ; Thu, 05 Dec 2013 13:36:16 -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=A9YCFmmdYXtr8n0fSslTHHMT3fVa09NAMBksYHMLkYM=; b=bUnRPLjrQKlW49d0OQFwg9mMnBnoXhqEpjGl0ZBHN2lvB4HKcKVd4kVW49iz/g+kns AQLd4U0OA5I5WMympIhBtqTfBs1dIst0MNSo4BfdABkKSKdaKh6ZR0LEl0AHY+dfvXb6 TZcXyS2yyy1G+toPkapMjiSxZUW3OsQW1bK84sQ6S51U7HDq1bG7eL5Pmp6i84LVpHtW PFcca6YR3nVGcZkhAycBFH63iBylhESSCl8KuQWvxYNjApAR6RJ9TKwew5rJGUU/KrNY kt05IiRvqDH2ssD2/FzJsDFsZBG1hkoPttMdjAJtXGnig/9R6orTGmMSRLT1gmF8NWqW 4tDA== X-Gm-Message-State: ALoCoQmaCrXV+3D1DXf3h1CU4trboeTI4LD3D11yyoOAhZqWGmErziMXUS1MBDX4GrEhS2FoTXW+ X-Received: by 10.66.220.163 with SMTP id px3mr97530pac.38.1386279376193; Thu, 05 Dec 2013 13:36:16 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.118.233 with SMTP id kp9ls1009001qeb.4.gmail; Thu, 05 Dec 2013 13:36:16 -0800 (PST) X-Received: by 10.52.0.33 with SMTP id 1mr89252vdb.81.1386279376054; Thu, 05 Dec 2013 13:36:16 -0800 (PST) Received: from mail-ve0-f171.google.com (mail-ve0-f171.google.com [209.85.128.171]) by mx.google.com with ESMTPS id ta5si35386106veb.107.2013.12.05.13.36.16 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.128.171 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.171; Received: by mail-ve0-f171.google.com with SMTP id pa12so14317453veb.2 for ; Thu, 05 Dec 2013 13:36:16 -0800 (PST) X-Received: by 10.220.199.5 with SMTP id eq5mr93673vcb.16.1386279375864; Thu, 05 Dec 2013 13:36:15 -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 u4csp49275vcz; Thu, 5 Dec 2013 13:36:15 -0800 (PST) X-Received: by 10.69.21.1 with SMTP id hg1mr69246pbd.67.1386279375003; Thu, 05 Dec 2013 13:36:15 -0800 (PST) Received: from mail-pd0-f178.google.com (mail-pd0-f178.google.com [209.85.192.178]) by mx.google.com with ESMTPS id nu5si19369563pbc.118.2013.12.05.13.36.14 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Dec 2013 13:36:14 -0800 (PST) Received-SPF: neutral (google.com: 209.85.192.178 is neither permitted nor denied by best guess record for domain of roy.franz@linaro.org) client-ip=209.85.192.178; Received: by mail-pd0-f178.google.com with SMTP id y10so25449811pdj.37 for ; Thu, 05 Dec 2013 13:36:14 -0800 (PST) X-Received: by 10.66.157.167 with SMTP id wn7mr29069pab.93.1386279374557; Thu, 05 Dec 2013 13:36:14 -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.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Dec 2013 13:36:13 -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 6/7] Fix CFI query responses for NOR flash Date: Thu, 5 Dec 2013 13:35:58 -0800 Message-Id: <1386279359-32286-7-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.171 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: , This change fixes the CFI query responses to handle NOR device widths that are different from the bank width. Support is also added for multi-width devices in a x8 configuration. This is typically x8/x16 devices, but the CFI specification mentions x8/x32 devices so those should be supported as well if they exist. The query response data is now replicated per-device in the bank, and is adjusted for x16 or x32 parts configured in x8 mode. The existing code is left in place for boards that have not been updated to specify an explicit device_width. The VExpress board has been updated in an earlier patch in this series so this is the only board currently affected. Signed-off-by: Roy Franz Reviewed-by: Peter Maydell --- hw/block/pflash_cfi01.c | 103 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 8f81341..564e6ee 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -119,6 +119,66 @@ static void pflash_timer (void *opaque) pfl->cmd = 0; } +/* Perform a CFI query based on the bank width of the flash. + * If this code is called we know we have a device_width set for + * this flash. + */ +static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) +{ + int i; + uint32_t resp = 0; + hwaddr boff; + + /* Adjust incoming offset to match expected device-width + * addressing. CFI query 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)); + + if (boff > pfl->cfi_len) { + return 0; + } + /* Now we will construct the CFI response generated by a single + * device, then replicate that for all devices that make up the + * bus. For wide parts used in x8 mode, CFI query responses + * are different than native byte-wide parts. + */ + resp = pfl->cfi_table[boff]; + if (pfl->device_width != pfl->max_device_width) { + /* The only case currently supported is x8 mode for a + * wider part. + */ + if (pfl->device_width != 1 || pfl->bank_width > 4) { + DPRINTF("%s: Unsupported device configuration: device_width=%d, max_device_width=%d\n", + __func__, pfl->device_width, + pfl->max_device_width); + return 0; + } + /* CFI query data is repeated, rather than zero padded for + * wide devices used in x8 mode. + */ + for (i = 1; i < pfl->max_device_width; i++) { + resp = deposit32(resp, 8 * i, 8, pfl->cfi_table[boff]); + } + } + /* 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) { @@ -127,13 +187,6 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, uint8_t *p; ret = -1; - boff = offset & 0xFF; /* why this here ?? */ - - if (pfl->bank_width == 2) { - boff = boff >> 1; - } else if (pfl->bank_width == 4) { - boff = boff >> 2; - } #if 0 DPRINTF("%s: reading offset " TARGET_FMT_plx " under cmd %02x width %d\n", @@ -213,6 +266,12 @@ 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; @@ -230,10 +289,32 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, } break; case 0x98: /* Query mode */ - if (boff > pfl->cfi_len) - ret = 0; - else - ret = pfl->cfi_table[boff]; + 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; + } + + if (boff > pfl->cfi_len) { + ret = 0; + } else { + ret = pfl->cfi_table[boff]; + } + } else { + /* If we have a read larger than the bank_width, combine multiple + * CFI 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_cfi_query(pfl, + offset + i * pfl->bank_width)); + } + } + break; } return ret;