qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 4/4] tests: add a m25p80 test


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH 4/4] tests: add a m25p80 test
Date: Fri, 17 Jun 2016 11:53:14 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0


On 17/06/2016 10:35, Cédric Le Goater wrote:
> This test uses the palmetto platform and the AST2400 SPI controller to
> test the m25p80 flash module device model. The flash model is defined
> by the platform (n25q256a) and it would be nice to find way to control
> it, using a property probably.
> 
> Signed-off-by: Cédric Le Goater <address@hidden>
> ---
> 
>  This ugly message polutes the log. How could we fix it ? 
> 
> WARNING: Image format was not specified for '/tmp/qtest.qFpMyW' and probing 
> guessed raw.
>          Automatically detecting the format is dangerous for raw images, 
> write operations on block 0 will be restricted.
>          Specify the 'raw' format explicitly to remove the restrictions.

Instead of -mtdblock, use "-drive if=mtd,format=raw,file=%s".

Paolo

>  tests/Makefile.include |   2 +
>  tests/m25p80-test.c    | 241 
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 243 insertions(+)
>  create mode 100644 tests/m25p80-test.c
> 
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 6135875c37f6..81264fbdf7e7 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -252,6 +252,7 @@ gcov-files-sparc-y += hw/timer/m48t59.c
>  gcov-files-sparc64-y += hw/timer/m48t59.c
>  check-qtest-arm-y = tests/tmp105-test$(EXESUF)
>  check-qtest-arm-y = tests/ds1338-test$(EXESUF)
> +check-qtest-arm-y = tests/m25p80-test$(EXESUF)
>  gcov-files-arm-y += hw/misc/tmp105.c
>  check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
>  gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
> @@ -562,6 +563,7 @@ tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o 
> \
>  tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
>  tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
>  tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
> +tests/m25p80-test$(EXESUF): tests/m25p80-test.o
>  tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
>  tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
>  tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
> diff --git a/tests/m25p80-test.c b/tests/m25p80-test.c
> new file mode 100644
> index 000000000000..5ab493ae9373
> --- /dev/null
> +++ b/tests/m25p80-test.c
> @@ -0,0 +1,241 @@
> +/*
> + * QTest testcase for the M25P80 Flash (Using the AST2400 SPI Controller)
> + *
> + * Copyright (C) 2016 IBM Corp.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/bswap.h"
> +#include "libqtest.h"
> +
> +/*
> + * AST2400 SPI Controller registers
> + */
> +#define R_CONF              0x00
> +#define   CONF_ENABLE_W0       (1 << 16)
> +#define R_CE_CTRL           0x04
> +#define   CRTL_EXTENDED0       0  /* 32 bit addressing for SPI */
> +#define R_CTRL0             0x10
> +#define   CTRL_CE_STOP_ACTIVE  (1 << 2)
> +#define   CTRL_USERMODE        0x3
> +
> +#define AST2400_FMC_BASE    0x1E620000
> +#define AST2400_FLASH_BASE  0x20000000
> +
> +/*
> + * Flash commands
> + */
> +enum {
> +    JEDEC_READ = 0x9f,
> +    BULK_ERASE = 0xc7,
> +    READ = 0x03,
> +    PP = 0x02,
> +    WREN = 0x6,
> +    EN_4BYTE_ADDR = 0xB7,
> +    ERASE_SECTOR = 0xd8,
> +};
> +
> +#define FLASH_JEDEC         0x20ba19  /* n25q256a */
> +#define FLASH_SIZE          (32 * 1024 * 1024)
> +
> +#define PAGE_SIZE           256
> +
> +static void spi_conf(uint32_t value)
> +{
> +    uint32_t conf = readl(AST2400_FMC_BASE + R_CONF);
> +
> +    conf |= value;
> +    writel(AST2400_FMC_BASE + R_CONF, conf);
> +}
> +
> +static void spi_ctrl_start_user(void)
> +{
> +    uint32_t ctrl = readl(AST2400_FMC_BASE + R_CTRL0);
> +
> +    ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
> +    writel(AST2400_FMC_BASE + R_CTRL0, ctrl);
> +
> +    ctrl &= ~CTRL_CE_STOP_ACTIVE;
> +    writel(AST2400_FMC_BASE + R_CTRL0, ctrl);
> +}
> +
> +static void spi_ctrl_stop_user(void)
> +{
> +    uint32_t ctrl = readl(AST2400_FMC_BASE + R_CTRL0);
> +
> +    ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
> +    writel(AST2400_FMC_BASE + R_CTRL0, ctrl);
> +}
> +
> +static void test_read_jedec(void)
> +{
> +    uint32_t jedec = 0x0;
> +
> +    spi_conf(CONF_ENABLE_W0);
> +
> +    spi_ctrl_start_user();
> +    writeb(AST2400_FLASH_BASE, JEDEC_READ);
> +    jedec |= readb(AST2400_FLASH_BASE) << 16;
> +    jedec |= readb(AST2400_FLASH_BASE) << 8;
> +    jedec |= readb(AST2400_FLASH_BASE);
> +    spi_ctrl_stop_user();
> +
> +    g_assert_cmphex(jedec, ==, FLASH_JEDEC);
> +}
> +
> +static void read_page(uint32_t addr, uint32_t *page)
> +{
> +    int i;
> +
> +    spi_ctrl_start_user();
> +
> +    writeb(AST2400_FLASH_BASE, EN_4BYTE_ADDR);
> +    writeb(AST2400_FLASH_BASE, READ);
> +    writel(AST2400_FLASH_BASE, cpu_to_be32(addr));
> +
> +    /* Continuous read are supported */
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        page[i] = be32_to_cpu(readl(AST2400_FLASH_BASE));
> +    }
> +    spi_ctrl_stop_user();
> +}
> +
> +static void test_erase_sector(void)
> +{
> +    uint32_t some_page_addr = 0x600 * PAGE_SIZE;
> +    uint32_t page[PAGE_SIZE / 4];
> +    int i;
> +
> +    spi_conf(CONF_ENABLE_W0);
> +
> +    spi_ctrl_start_user();
> +    writeb(AST2400_FLASH_BASE, WREN);
> +    writeb(AST2400_FLASH_BASE, EN_4BYTE_ADDR);
> +    writeb(AST2400_FLASH_BASE, ERASE_SECTOR);
> +    writel(AST2400_FLASH_BASE, cpu_to_be32(some_page_addr));
> +    spi_ctrl_stop_user();
> +
> +    /* Previous page should be full of zeroes as backend is not
> +     * initialized */
> +    read_page(some_page_addr - PAGE_SIZE, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, 0x0);
> +    }
> +
> +    /* But this one was erased */
> +    read_page(some_page_addr, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, 0xffffffff);
> +    }
> +}
> +
> +static void test_erase_all(void)
> +{
> +    uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
> +    uint32_t page[PAGE_SIZE / 4];
> +    int i;
> +
> +    spi_conf(CONF_ENABLE_W0);
> +
> +    /* Check some random page. Should be full of zeroes as backend is
> +     * not initialized */
> +    read_page(some_page_addr, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, 0x0);
> +    }
> +
> +    spi_ctrl_start_user();
> +    writeb(AST2400_FLASH_BASE, WREN);
> +    writeb(AST2400_FLASH_BASE, BULK_ERASE);
> +    spi_ctrl_stop_user();
> +
> +    /* Recheck that some random page */
> +    read_page(some_page_addr, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, 0xffffffff);
> +    }
> +}
> +
> +static void test_write_page(void)
> +{
> +    uint32_t my_page_addr = 0x14000 * PAGE_SIZE; /* beyond 16MB */
> +    uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
> +    uint32_t page[PAGE_SIZE / 4];
> +    int i;
> +
> +    spi_conf(CONF_ENABLE_W0);
> +
> +    spi_ctrl_start_user();
> +    writeb(AST2400_FLASH_BASE, EN_4BYTE_ADDR);
> +    writeb(AST2400_FLASH_BASE, PP);
> +    writel(AST2400_FLASH_BASE, cpu_to_be32(my_page_addr));
> +
> +    /* Fill the page with its own addresses */
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        writel(AST2400_FLASH_BASE, cpu_to_be32(my_page_addr + i * 4));
> +    }
> +    spi_ctrl_stop_user();
> +
> +    /* Check what was written */
> +    read_page(my_page_addr, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
> +    }
> +
> +    /* Check some other page. It should be full of 0xff */
> +    read_page(some_page_addr, page);
> +    for (i = 0; i < PAGE_SIZE / 4; i++) {
> +        g_assert_cmphex(page[i], ==, 0xffffffff);
> +    }
> +}
> +
> +static char tmp_path[] = "/tmp/qtest.XXXXXX";
> +
> +int main(int argc, char **argv)
> +{
> +    int ret;
> +    int fd;
> +    char *args;
> +
> +    g_test_init(&argc, &argv, NULL);
> +
> +    fd = mkstemp(tmp_path);
> +    g_assert(fd >= 0);
> +    ret = ftruncate(fd, FLASH_SIZE);
> +    g_assert(ret == 0);
> +    close(fd);
> +
> +    args = g_strdup_printf("-M 256 -machine palmetto-bmc -mtdblock %s",
> +                           tmp_path);
> +    qtest_start(args);
> +
> +    qtest_add_func("/m25p80/read_jedec", test_read_jedec);
> +    qtest_add_func("/m25p80/erase_sector", test_erase_sector);
> +    qtest_add_func("/m25p80/erase_all",  test_erase_all);
> +    qtest_add_func("/m25p80/write_page", test_write_page);
> +
> +    ret = g_test_run();
> +
> +    qtest_quit(global_qtest);
> +    unlink(tmp_path);
> +    g_free(args);
> +    return ret;
> +}
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]