[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 07/62] Fix CFI query responses for NOR flash
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 07/62] Fix CFI query responses for NOR flash |
Date: |
Tue, 17 Dec 2013 20:28:25 +0000 |
From: Roy Franz <address@hidden>
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 <address@hidden>
Message-id: address@hidden
[PMM: fixed a few formatting nits]
Signed-off-by: Peter Maydell <address@hidden>
---
hw/block/pflash_cfi01.c | 105 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 94 insertions(+), 11 deletions(-)
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index de7a6c0..8fd50fb 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -119,6 +119,67 @@ 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 +188,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 +267,13 @@ 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 +291,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;
--
1.8.5
- [Qemu-devel] [PULL 49/62] target-arm: A64: add support for 1-src CLS insn, (continued)
- [Qemu-devel] [PULL 49/62] target-arm: A64: add support for 1-src CLS insn, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 41/62] target-arm: A64: add support for EXTR, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 22/62] configure: Enable KVM for aarch64 host/target combination, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 26/62] target-arm: Split A64 from A32/T32 gen_intermediate_code_internal(), Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 02/62] rename pflash_t member width to bank_width, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 24/62] hw/arm/boot: Add boot support for AArch64 processor, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 13/62] arm/highbank: Fix CBAR initialisation, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 03/62] Add device-width property to pflash_cfi01, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 23/62] hw/arm/boot: Allow easier swapping in of different loader code, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 21/62] target-arm: Add minimal KVM AArch64 support, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 07/62] Fix CFI query responses for NOR flash,
Peter Maydell <=
- [Qemu-devel] [PULL 14/62] arm/xilinx_zynq: Use object_new() rather than cpu_arm_init(), Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 04/62] return status for each NOR flash device, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 12/62] arm/highbank: Use object_new() rather than cpu_arm_init(), Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 05/62] Set proper device-width for vexpress flash, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 60/62] hw/arm: add allwinner a10 SoC support, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 18/62] ARM: arm_cpu_reset: make it possible to use high vectors for reset_exc, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 11/62] target-arm/cpu: Convert reset CBAR to a property, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 20/62] target-arm: Clean up handling of AArch64 PSTATE, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 17/62] ARM: cpu: add "reset_hivecs" property, Peter Maydell, 2013/12/17
- [Qemu-devel] [PULL 09/62] target-arm/helper.c: Allow cp15.c15 dummy override, Peter Maydell, 2013/12/17