Commit fea8f3ed authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/philmd-gitlab/tags/pflash-next-20200522' into staging



- Remove unused timer in CFI01 flash,
- Clean up code documentation,
- Silent a long-standing Coverity warning (2016-07-15).

# gpg: Signature made Fri 22 May 2020 18:43:03 BST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* remotes/philmd-gitlab/tags/pflash-next-20200522:
  hw/block/pflash: Check return value of blk_pwrite()
  hw/block/pflash_cfi01: Rename 'reset_flash' label as 'mode_read_array'
  hw/block/pflash_cfi01: Document use of non-CFI compliant command '0x00'
  hw/block/pflash_cfi01: Removed an unused timer

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 1cc9c62e 1857b9db
Loading
Loading
Loading
Loading
+35 −36
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@
#include "hw/qdev-properties.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"
@@ -91,7 +91,6 @@ struct PFlashCFI01 {
    uint8_t cfi_table[0x52];
    uint64_t counter;
    unsigned int writeblock_size;
    QEMUTimer *timer;
    MemoryRegion mem;
    char *name;
    void *storage;
@@ -115,18 +114,6 @@ static const VMStateDescription vmstate_pflash = {
    }
};

static void pflash_timer (void *opaque)
{
    PFlashCFI01 *pfl = opaque;

    trace_pflash_timer_expired(pfl->cmd);
    /* Reset flash */
    pfl->status ^= 0x80;
    memory_region_rom_device_set_romd(&pfl->mem, true);
    pfl->wcycle = 0;
    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.
@@ -292,9 +279,13 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
        /* This should never happen : reset state & treat it as a read */
        DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
        pfl->wcycle = 0;
        pfl->cmd = 0;
        /*
         * The command 0x00 is not assigned by the CFI open standard,
         * but QEMU historically uses it for the READ_ARRAY command (0xff).
         */
        pfl->cmd = 0x00;
        /* fall through to read code */
    case 0x00:
    case 0x00: /* This model reset value for READ_ARRAY (not CFI compliant) */
        /* Flash area read */
        ret = pflash_data_read(pfl, offset, width, be);
        break;
@@ -399,13 +390,18 @@ static void pflash_update(PFlashCFI01 *pfl, int offset,
                          int size)
{
    int offset_end;
    int ret;
    if (pfl->blk) {
        offset_end = offset + size;
        /* widen to sector boundaries */
        offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
        offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
        blk_pwrite(pfl->blk, offset, pfl->storage + offset,
        ret = blk_pwrite(pfl->blk, offset, pfl->storage + offset,
                   offset_end - offset, 0);
        if (ret < 0) {
            /* TODO set error bit in status */
            error_report("Could not update PFLASH: %s", strerror(-ret));
        }
    }
}

@@ -463,8 +459,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
    case 0:
        /* read mode */
        switch (cmd) {
        case 0x00: /* ??? */
            goto reset_flash;
        case 0x00: /* This model reset value for READ_ARRAY (not CFI) */
            goto mode_read_array;
        case 0x10: /* Single Byte Program */
        case 0x40: /* Single Byte Program */
            DPRINTF("%s: Single Byte Program\n", __func__);
@@ -487,7 +483,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
        case 0x50: /* Clear status bits */
            DPRINTF("%s: Clear status bits\n", __func__);
            pfl->status = 0x0;
            goto reset_flash;
            goto mode_read_array;
        case 0x60: /* Block (un)lock */
            DPRINTF("%s: Block unlock\n", __func__);
            break;
@@ -512,10 +508,10 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
            break;
        case 0xf0: /* Probe for AMD flash */
            DPRINTF("%s: Probe for AMD flash\n", __func__);
            goto reset_flash;
        case 0xff: /* Read array mode */
            goto mode_read_array;
        case 0xff: /* Read Array */
            DPRINTF("%s: Read array mode\n", __func__);
            goto reset_flash;
            goto mode_read_array;
        default:
            goto error_flash;
        }
@@ -541,8 +537,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
            if (cmd == 0xd0) { /* confirm */
                pfl->wcycle = 0;
                pfl->status |= 0x80;
            } else if (cmd == 0xff) { /* read array mode */
                goto reset_flash;
            } else if (cmd == 0xff) { /* Read Array */
                goto mode_read_array;
            } else
                goto error_flash;

@@ -568,16 +564,16 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
            } else if (cmd == 0x01) {
                pfl->wcycle = 0;
                pfl->status |= 0x80;
            } else if (cmd == 0xff) {
                goto reset_flash;
            } else if (cmd == 0xff) { /* Read Array */
                goto mode_read_array;
            } else {
                DPRINTF("%s: Unknown (un)locking command\n", __func__);
                goto reset_flash;
                goto mode_read_array;
            }
            break;
        case 0x98:
            if (cmd == 0xff) {
                goto reset_flash;
            if (cmd == 0xff) { /* Read Array */
                goto mode_read_array;
            } else {
                DPRINTF("%s: leaving query mode\n", __func__);
            }
@@ -637,7 +633,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
                    " the data is already written to storage!\n"
                    "Flash device reset into READ mode.\n",
                    __func__);
                goto reset_flash;
                goto mode_read_array;
            }
            break;
        default:
@@ -647,7 +643,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
    default:
        /* Should never happen */
        DPRINTF("%s: invalid write state\n",  __func__);
        goto reset_flash;
        goto mode_read_array;
    }
    return;

@@ -656,11 +652,11 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
                  "(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 0x%x)"
                  "\n", __func__, offset, pfl->wcycle, pfl->cmd, value);

 reset_flash:
 mode_read_array:
    trace_pflash_reset();
    memory_region_rom_device_set_romd(&pfl->mem, true);
    pfl->wcycle = 0;
    pfl->cmd = 0;
    pfl->cmd = 0x00; /* This model reset value for READ_ARRAY (not CFI) */
}


@@ -775,9 +771,12 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
        pfl->max_device_width = pfl->device_width;
    }

    pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
    pfl->wcycle = 0;
    pfl->cmd = 0;
    /*
     * The command 0x00 is not assigned by the CFI open standard,
     * but QEMU historically uses it for the READ_ARRAY command (0xff).
     */
    pfl->cmd = 0x00;
    pfl->status = 0x80; /* WSM ready */
    /* Hardcoded CFI table */
    /* Standard "QRY" string */
+7 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "hw/block/flash.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/bitmap.h"
#include "qemu/timer.h"
#include "sysemu/block-backend.h"
@@ -393,13 +394,18 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
static void pflash_update(PFlashCFI02 *pfl, int offset, int size)
{
    int offset_end;
    int ret;
    if (pfl->blk) {
        offset_end = offset + size;
        /* widen to sector boundaries */
        offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
        offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
        blk_pwrite(pfl->blk, offset, pfl->storage + offset,
        ret = blk_pwrite(pfl->blk, offset, pfl->storage + offset,
                   offset_end - offset, 0);
        if (ret < 0) {
            /* TODO set error bit in status */
            error_report("Could not update PFLASH: %s", strerror(-ret));
        }
    }
}