/*
 * QTest testcase for parallel flash with AMD command set
 *
 * Copyright (c) 2019 Stephen Checkoway
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "libqtest.h"

/*
 * To test the pflash_cfi02 device, we run QEMU with the musicpal machine with
 * a pflash drive. This enables us to test some flash configurations, but not
 * all. In particular, we're limited to a 16-bit wide flash device.
 */

#define MP_FLASH_SIZE_MAX (32 * 1024 * 1024)
#define BASE_ADDR (0x100000000ULL - MP_FLASH_SIZE_MAX)

#define UNIFORM_FLASH_SIZE (8 * 1024 * 1024)
#define UNIFORM_FLASH_SECTOR_SIZE (64 * 1024)

/* Use a newtype to keep flash addresses separate from byte addresses. */
typedef struct {
    uint64_t addr;
} faddr;
#define FLASH_ADDR(x) ((faddr) { .addr = (x) })

#define CFI_ADDR FLASH_ADDR(0x55)
#define UNLOCK0_ADDR FLASH_ADDR(0x555)
#define UNLOCK1_ADDR FLASH_ADDR(0x2AA)

#define CFI_CMD 0x98
#define UNLOCK0_CMD 0xAA
#define UNLOCK1_CMD 0x55
#define SECOND_UNLOCK_CMD 0x80
#define AUTOSELECT_CMD 0x90
#define RESET_CMD 0xF0
#define PROGRAM_CMD 0xA0
#define SECTOR_ERASE_CMD 0x30
#define CHIP_ERASE_CMD 0x10
#define UNLOCK_BYPASS_CMD 0x20
#define UNLOCK_BYPASS_RESET_CMD 0x00
#define ERASE_SUSPEND_CMD 0xB0
#define ERASE_RESUME_CMD SECTOR_ERASE_CMD

typedef struct {
    int bank_width;

    /* Nonuniform block size. */
    int nb_blocs[4];
    int sector_len[4];

    QTestState *qtest;
} FlashConfig;

static char image_path[] = "/tmp/qtest.XXXXXX";

/*
 * The pflash implementation allows some parameters to be unspecified. We want
 * to test those configurations but we also need to know the real values in
 * our testing code. So after we launch qemu, we'll need a new FlashConfig
 * with the correct values filled in.
 */
static FlashConfig expand_config_defaults(const FlashConfig *c)
{
    FlashConfig ret = *c;

    if (ret.bank_width == 0) {
        ret.bank_width = 2;
    }
    if (ret.nb_blocs[0] == 0 && ret.sector_len[0] == 0) {
        ret.sector_len[0] = UNIFORM_FLASH_SECTOR_SIZE;
        ret.nb_blocs[0] = UNIFORM_FLASH_SIZE / UNIFORM_FLASH_SECTOR_SIZE;
    }

    /* XXX: Limitations of test harness. */
    assert(ret.bank_width == 2);
    return ret;
}

/*
 * Return a bit mask suitable for extracting the least significant
 * status/query response from an interleaved response.
 */
static inline uint64_t device_mask(const FlashConfig *c)
{
    return (uint64_t)-1;
}

/*
 * Return a bit mask exactly as long as the bank_width.
 */
static inline uint64_t bank_mask(const FlashConfig *c)
{
    if (c->bank_width == 8) {
        return (uint64_t)-1;
    }
    return (1ULL << (c->bank_width * 8)) - 1ULL;
}

static inline void flash_write(const FlashConfig *c, uint64_t byte_addr,
                               uint64_t data)
{
    /* Sanity check our tests. */
    assert((data & ~bank_mask(c)) == 0);
    uint64_t addr = BASE_ADDR + byte_addr;
    switch (c->bank_width) {
    case 1:
        qtest_writeb(c->qtest, addr, data);
        break;
    case 2:
        qtest_writew(c->qtest, addr, data);
        break;
    case 4:
        qtest_writel(c->qtest, addr, data);
        break;
    case 8:
        qtest_writeq(c->qtest, addr, data);
        break;
    default:
        abort();
    }
}

static inline uint64_t flash_read(const FlashConfig *c, uint64_t byte_addr)
{
    uint64_t addr = BASE_ADDR + byte_addr;
    switch (c->bank_width) {
    case 1:
        return qtest_readb(c->qtest, addr);
    case 2:
        return qtest_readw(c->qtest, addr);
    case 4:
        return qtest_readl(c->qtest, addr);
    case 8:
        return qtest_readq(c->qtest, addr);
    default:
        abort();
    }
}

/*
 * Convert a flash address expressed in the maximum width of the device as a
 * byte address.
 */
static inline uint64_t as_byte_addr(const FlashConfig *c, faddr flash_addr)
{
    /*
     * Command addresses are always given as addresses in the maximum
     * supported bus size for the flash chip. So an x8/x16 chip in x8 mode
     * uses addresses 0xAAA and 0x555 to unlock because the least significant
     * bit is ignored. (0x555 rather than 0x554 is traditional.)
     *
     * In general we need to multiply by the maximum device width.
     */
    return flash_addr.addr * c->bank_width;
}

/*
 * Return the command value or expected status replicated across all devices.
 */
static inline uint64_t replicate(const FlashConfig *c, uint64_t data)
{
    /* Sanity check our tests. */
    assert((data & ~device_mask(c)) == 0);
    return data;
}

static inline void flash_cmd(const FlashConfig *c, faddr cmd_addr,
                             uint8_t cmd)
{
    flash_write(c, as_byte_addr(c, cmd_addr), replicate(c, cmd));
}

static inline uint64_t flash_query(const FlashConfig *c, faddr query_addr)
{
    return flash_read(c, as_byte_addr(c, query_addr));
}

static inline uint64_t flash_query_1(const FlashConfig *c, faddr query_addr)
{
    return flash_query(c, query_addr) & device_mask(c);
}

static void unlock(const FlashConfig *c)
{
    flash_cmd(c, UNLOCK0_ADDR, UNLOCK0_CMD);
    flash_cmd(c, UNLOCK1_ADDR, UNLOCK1_CMD);
}

static void reset(const FlashConfig *c)
{
    flash_cmd(c, FLASH_ADDR(0), RESET_CMD);
}

static void sector_erase(const FlashConfig *c, uint64_t byte_addr)
{
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
    unlock(c);
    flash_write(c, byte_addr, replicate(c, SECTOR_ERASE_CMD));
}

static void wait_for_completion(const FlashConfig *c, uint64_t byte_addr)
{
    /* If DQ6 is toggling, step the clock and ensure the toggle stops. */
    const uint64_t dq6 = replicate(c, 0x40);
    if ((flash_read(c, byte_addr) & dq6) ^ (flash_read(c, byte_addr) & dq6)) {
        /* Wait for erase or program to finish. */
        qtest_clock_step_next(c->qtest);
        /* Ensure that DQ6 has stopped toggling. */
        g_assert_cmphex(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));
    }
}

static void bypass_program(const FlashConfig *c, uint64_t byte_addr,
                           uint16_t data)
{
    flash_cmd(c, UNLOCK0_ADDR, PROGRAM_CMD);
    flash_write(c, byte_addr, data);
    /*
     * Data isn't valid until DQ6 stops toggling. We don't model this as
     * writes are immediate, but if this changes in the future, we can wait
     * until the program is complete.
     */
    wait_for_completion(c, byte_addr);
}

static void program(const FlashConfig *c, uint64_t byte_addr, uint16_t data)
{
    unlock(c);
    bypass_program(c, byte_addr, data);
}

static void chip_erase(const FlashConfig *c)
{
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, CHIP_ERASE_CMD);
}

static void erase_suspend(const FlashConfig *c)
{
    flash_cmd(c, FLASH_ADDR(0), ERASE_SUSPEND_CMD);
}

static void erase_resume(const FlashConfig *c)
{
    flash_cmd(c, FLASH_ADDR(0), ERASE_RESUME_CMD);
}

/*
 * Test flash commands with a variety of device geometry.
 */
static void test_geometry(const void *opaque)
{
    const FlashConfig *config = opaque;
    QTestState *qtest;
    qtest = qtest_initf("-M musicpal"
                        " -drive if=pflash,file=%s,format=raw,copy-on-read=on"
                        /* Device geometry properties. */
                        " -global driver=cfi.pflash02,"
                        "property=num-blocks0,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=sector-length0,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=num-blocks1,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=sector-length1,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=num-blocks2,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=sector-length2,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=num-blocks3,value=%d"
                        " -global driver=cfi.pflash02,"
                        "property=sector-length3,value=%d",
                        image_path,
                        config->nb_blocs[0],
                        config->sector_len[0],
                        config->nb_blocs[1],
                        config->sector_len[1],
                        config->nb_blocs[2],
                        config->sector_len[2],
                        config->nb_blocs[3],
                        config->sector_len[3]);
    FlashConfig explicit_config = expand_config_defaults(config);
    explicit_config.qtest = qtest;
    const FlashConfig *c = &explicit_config;

    /* Check the IDs. */
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, AUTOSELECT_CMD);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
    if (c->bank_width >= 2) {
        /*
         * XXX: The ID returned by the musicpal flash chip is 16 bits which
         * wouldn't happen with an 8-bit device. It would probably be best to
         * prohibit addresses larger than the device width in pflash_cfi02.c,
         * but then we couldn't test smaller device widths at all.
         */
        g_assert_cmphex(flash_query(c, FLASH_ADDR(1)), ==,
                        replicate(c, 0x236D));
    }
    reset(c);

    /* Check the erase blocks. */
    flash_cmd(c, CFI_ADDR, CFI_CMD);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x10)), ==, replicate(c, 'Q'));
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x11)), ==, replicate(c, 'R'));
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x12)), ==, replicate(c, 'Y'));

    /* Num erase regions. */
    int nb_erase_regions = flash_query_1(c, FLASH_ADDR(0x2C));
    g_assert_cmphex(nb_erase_regions, ==,
                    !!c->nb_blocs[0] + !!c->nb_blocs[1] + !!c->nb_blocs[2] +
                    !!c->nb_blocs[3]);

    /* Check device length. */
    uint32_t device_len = 1 << flash_query_1(c, FLASH_ADDR(0x27));
    g_assert_cmphex(device_len, ==, UNIFORM_FLASH_SIZE);

    /* Check that erase suspend to read/write is supported. */
    uint16_t pri = flash_query_1(c, FLASH_ADDR(0x15)) +
                   (flash_query_1(c, FLASH_ADDR(0x16)) << 8);
    g_assert_cmpint(pri, >=, 0x2D + 4 * nb_erase_regions);
    g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 0)), ==, replicate(c, 'P'));
    g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 1)), ==, replicate(c, 'R'));
    g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 2)), ==, replicate(c, 'I'));
    g_assert_cmpint(flash_query_1(c, FLASH_ADDR(pri + 6)), ==, 2); /* R/W */
    reset(c);

    const uint64_t dq7 = replicate(c, 0x80);
    const uint64_t dq6 = replicate(c, 0x40);
    const uint64_t dq3 = replicate(c, 0x08);
    const uint64_t dq2 = replicate(c, 0x04);

    uint64_t byte_addr = 0;
    for (int region = 0; region < nb_erase_regions; ++region) {
        uint64_t base = 0x2D + 4 * region;
        flash_cmd(c, CFI_ADDR, CFI_CMD);
        uint32_t nb_sectors = flash_query_1(c, FLASH_ADDR(base + 0)) +
                              (flash_query_1(c, FLASH_ADDR(base + 1)) << 8) + 1;
        uint32_t sector_len = (flash_query_1(c, FLASH_ADDR(base + 2)) << 8) +
                              (flash_query_1(c, FLASH_ADDR(base + 3)) << 16);
        g_assert_cmphex(nb_sectors, ==, c->nb_blocs[region]);
        g_assert_cmphex(sector_len, ==, c->sector_len[region]);
        reset(c);

        /* Erase and program sector. */
        for (uint32_t i = 0; i < nb_sectors; ++i) {
            sector_erase(c, byte_addr);

            /* Check that DQ3 is 0. */
            g_assert_cmphex(flash_read(c, byte_addr) & dq3, ==, 0);
            qtest_clock_step_next(c->qtest); /* Step over the 50 us timeout. */

            /* Check that DQ3 is 1. */
            uint64_t status0 = flash_read(c, byte_addr);
            g_assert_cmphex(status0 & dq3, ==, dq3);

            /* DQ7 is 0 during an erase. */
            g_assert_cmphex(status0 & dq7, ==, 0);
            uint64_t status1 = flash_read(c, byte_addr);

            /* DQ6 toggles during an erase. */
            g_assert_cmphex(status0 & dq6, ==, ~status1 & dq6);

            /* Wait for erase to complete. */
            wait_for_completion(c, byte_addr);

            /* Ensure DQ6 has stopped toggling. */
            g_assert_cmphex(flash_read(c, byte_addr), ==,
                            flash_read(c, byte_addr));

            /* Now the data should be valid. */
            g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));

            /* Program a bit pattern. */
            program(c, byte_addr, 0x55);
            g_assert_cmphex(flash_read(c, byte_addr) & 0xFF, ==, 0x55);
            program(c, byte_addr, 0xA5);
            g_assert_cmphex(flash_read(c, byte_addr) & 0xFF, ==, 0x05);
            byte_addr += sector_len;
        }
    }

    /* Erase the chip. */
    chip_erase(c);
    /* Read toggle. */
    uint64_t status0 = flash_read(c, 0);
    /* DQ7 is 0 during an erase. */
    g_assert_cmphex(status0 & dq7, ==, 0);
    uint64_t status1 = flash_read(c, 0);
    /* DQ6 toggles during an erase. */
    g_assert_cmphex(status0 & dq6, ==, ~status1 & dq6);
    /* Wait for erase to complete. */
    qtest_clock_step_next(c->qtest);
    /* Ensure DQ6 has stopped toggling. */
    g_assert_cmphex(flash_read(c, 0), ==, flash_read(c, 0));
    /* Now the data should be valid. */

    for (int region = 0; region < nb_erase_regions; ++region) {
        for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) {
            uint64_t byte_addr = (uint64_t)i * c->sector_len[region];
            g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
        }
    }

    /* Unlock bypass */
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, UNLOCK_BYPASS_CMD);
    bypass_program(c, 0 * c->bank_width, 0x01);
    bypass_program(c, 1 * c->bank_width, 0x23);
    bypass_program(c, 2 * c->bank_width, 0x45);
    /*
     * Test that bypass programming, unlike normal programming can use any
     * address for the PROGRAM_CMD.
     */
    flash_cmd(c, FLASH_ADDR(3 * c->bank_width), PROGRAM_CMD);
    flash_write(c, 3 * c->bank_width, 0x67);
    wait_for_completion(c, 3 * c->bank_width);
    flash_cmd(c, FLASH_ADDR(0), UNLOCK_BYPASS_RESET_CMD);
    bypass_program(c, 4 * c->bank_width, 0x89); /* Should fail. */
    g_assert_cmphex(flash_read(c, 0 * c->bank_width), ==, 0x01);
    g_assert_cmphex(flash_read(c, 1 * c->bank_width), ==, 0x23);
    g_assert_cmphex(flash_read(c, 2 * c->bank_width), ==, 0x45);
    g_assert_cmphex(flash_read(c, 3 * c->bank_width), ==, 0x67);
    g_assert_cmphex(flash_read(c, 4 * c->bank_width), ==, bank_mask(c));

    /* Test ignored high order bits of address. */
    flash_cmd(c, FLASH_ADDR(0x5555), UNLOCK0_CMD);
    flash_cmd(c, FLASH_ADDR(0x2AAA), UNLOCK1_CMD);
    flash_cmd(c, FLASH_ADDR(0x5555), AUTOSELECT_CMD);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
    reset(c);

    /*
     * Program a word on each sector, erase one or two sectors per region, and
     * verify that all of those, and only those, are erased.
     */
    byte_addr = 0;
    for (int region = 0; region < nb_erase_regions; ++region) {
        for (int i = 0; i < config->nb_blocs[region]; ++i) {
            program(c, byte_addr, 0);
            byte_addr += config->sector_len[region];
        }
    }
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
    unlock(c);
    byte_addr = 0;
    const uint64_t erase_cmd = replicate(c, SECTOR_ERASE_CMD);
    for (int region = 0; region < nb_erase_regions; ++region) {
        flash_write(c, byte_addr, erase_cmd);
        if (c->nb_blocs[region] > 1) {
            flash_write(c, byte_addr + c->sector_len[region], erase_cmd);
        }
        byte_addr += c->sector_len[region] * c->nb_blocs[region];
    }

    qtest_clock_step_next(c->qtest); /* Step over the 50 us timeout. */
    wait_for_completion(c, 0);
    byte_addr = 0;
    for (int region = 0; region < nb_erase_regions; ++region) {
        for (int i = 0; i < config->nb_blocs[region]; ++i) {
            if (i < 2) {
                g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
            } else {
                g_assert_cmphex(flash_read(c, byte_addr), ==, 0);
            }
            byte_addr += config->sector_len[region];
        }
    }

    /* Test erase suspend/resume during erase timeout. */
    sector_erase(c, 0);
    /*
     * Check that DQ 3 is 0 and DQ6 and DQ2 are toggling in the sector being
     * erased as well as in a sector not being erased.
     */
    byte_addr = c->sector_len[0];
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq3, ==, 0);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    status0 = flash_read(c, byte_addr);
    status1 = flash_read(c, byte_addr);
    g_assert_cmpint(status0 & dq3, ==, 0);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);

    /*
     * Check that after suspending, DQ6 does not toggle but DQ2 does toggle in
     * an erase suspended sector but that neither toggle (we should be
     * getting data) in a sector not being erased.
     */
    erase_suspend(c);
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq6, ==, status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    g_assert_cmpint(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));

    /* Check that after resuming, DQ3 is 1 and DQ6 and DQ2 toggle. */
    erase_resume(c);
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    status0 = flash_read(c, byte_addr);
    status1 = flash_read(c, byte_addr);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    wait_for_completion(c, 0);

    /* Repeat this process but this time suspend after the timeout. */
    sector_erase(c, 0);
    qtest_clock_step_next(c->qtest);
    /*
     * Check that DQ 3 is 1 and DQ6 and DQ2 are toggling in the sector being
     * erased as well as in a sector not being erased.
     */
    byte_addr = c->sector_len[0];
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    status0 = flash_read(c, byte_addr);
    status1 = flash_read(c, byte_addr);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);

    /*
     * Check that after suspending, DQ6 does not toggle but DQ2 does toggle in
     * an erase suspended sector but that neither toggle (we should be
     * getting data) in a sector not being erased.
     */
    erase_suspend(c);
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq6, ==, status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    g_assert_cmpint(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));

    /* Check that after resuming, DQ3 is 1 and DQ6 and DQ2 toggle. */
    erase_resume(c);
    status0 = flash_read(c, 0);
    status1 = flash_read(c, 0);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    status0 = flash_read(c, byte_addr);
    status1 = flash_read(c, byte_addr);
    g_assert_cmpint(status0 & dq3, ==, dq3);
    g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
    g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
    wait_for_completion(c, 0);

    qtest_quit(qtest);
}

/*
 * Test that
 * 1. enter autoselect mode;
 * 2. enter CFI mode; and then
 * 3. exit CFI mode
 * leaves the flash device in autoselect mode.
 */
static void test_cfi_in_autoselect(const void *opaque)
{
    const FlashConfig *config = opaque;
    QTestState *qtest;
    qtest = qtest_initf("-M musicpal"
                        " -drive if=pflash,file=%s,format=raw,copy-on-read=on",
                        image_path);
    FlashConfig explicit_config = expand_config_defaults(config);
    explicit_config.qtest = qtest;
    const FlashConfig *c = &explicit_config;

    /* 1. Enter autoselect. */
    unlock(c);
    flash_cmd(c, UNLOCK0_ADDR, AUTOSELECT_CMD);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));

    /* 2. Enter CFI. */
    flash_cmd(c, CFI_ADDR, CFI_CMD);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x10)), ==, replicate(c, 'Q'));
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x11)), ==, replicate(c, 'R'));
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0x12)), ==, replicate(c, 'Y'));

    /* 3. Exit CFI. */
    reset(c);
    g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));

    qtest_quit(qtest);
}

static void cleanup(void *opaque)
{
    unlink(image_path);
}

/*
 * XXX: Tests are limited to bank_width = 2 for now because that's what
 * hw/arm/musicpal.c has.
 */
static const FlashConfig configuration[] = {
    /* One x16 device. */
    {
        .bank_width = 2,
    },
    /* Nonuniform sectors (top boot). */
    {
        .bank_width = 2,
        .nb_blocs = { 127, 1, 2, 1 },
        .sector_len = { 0x10000, 0x08000, 0x02000, 0x04000 },
    },
    /* Nonuniform sectors (bottom boot). */
    {
        .bank_width = 2,
        .nb_blocs = { 1, 2, 1, 127 },
        .sector_len = { 0x04000, 0x02000, 0x08000, 0x10000 },
    },
};

int main(int argc, char **argv)
{
    int fd = mkstemp(image_path);
    if (fd == -1) {
        g_printerr("Failed to create temporary file %s: %s\n", image_path,
                   strerror(errno));
        exit(EXIT_FAILURE);
    }
    if (ftruncate(fd, UNIFORM_FLASH_SIZE) < 0) {
        int error_code = errno;
        close(fd);
        unlink(image_path);
        g_printerr("Failed to truncate file %s to %u MB: %s\n", image_path,
                   UNIFORM_FLASH_SIZE, strerror(error_code));
        exit(EXIT_FAILURE);
    }
    close(fd);

    qtest_add_abrt_handler(cleanup, NULL);
    g_test_init(&argc, &argv, NULL);

    size_t nb_configurations = sizeof configuration / sizeof configuration[0];
    for (size_t i = 0; i < nb_configurations; ++i) {
        const FlashConfig *config = &configuration[i];
        char *path = g_strdup_printf("pflash-cfi02"
                                     "/geometry/%dx%x-%dx%x-%dx%x-%dx%x"
                                     "/%d",
                                     config->nb_blocs[0],
                                     config->sector_len[0],
                                     config->nb_blocs[1],
                                     config->sector_len[1],
                                     config->nb_blocs[2],
                                     config->sector_len[2],
                                     config->nb_blocs[3],
                                     config->sector_len[3],
                                     config->bank_width);
        qtest_add_data_func(path, config, test_geometry);
        g_free(path);
    }

    qtest_add_data_func("pflash-cfi02/cfi-in-autoselect", &configuration[0],
                        test_cfi_in_autoselect);
    int result = g_test_run();
    cleanup(NULL);
    return result;
}
