Hi,

I've sent a new patch set which uses memcpy here. Thank you!


On Tue, Nov 2, 2021 at 11:25 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> From: Shengtan Mao <st...@google.com>
>
> Signed-off-by: Shengtan Mao <st...@google.com>
> Signed-off-by: Hao Wu <wuhao...@google.com>
> Reviewed-by: Hao Wu <wuhao...@google.com>
> Reviewed-by: Chris Rauer <cra...@google.com>
> Reviewed-by: Tyrone Ting <kft...@nuvoton.com>
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
> Message-Id: <20211008002628.1958285-5-wuhao...@google.com>
> Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
> ---
>  tests/qtest/libqos/sdhci-cmd.h |  70 ++++++++++++++++++++
>  tests/qtest/libqos/sdhci-cmd.c | 116 +++++++++++++++++++++++++++++++++
>  tests/qtest/libqos/meson.build |   1 +
>  3 files changed, 187 insertions(+)
>  create mode 100644 tests/qtest/libqos/sdhci-cmd.h
>  create mode 100644 tests/qtest/libqos/sdhci-cmd.c
>
> diff --git a/tests/qtest/libqos/sdhci-cmd.h
> b/tests/qtest/libqos/sdhci-cmd.h
> new file mode 100644
> index 0000000000..64763c5a2a
> --- /dev/null
> +++ b/tests/qtest/libqos/sdhci-cmd.h
> @@ -0,0 +1,70 @@
> +/*
> + * MMC Host Controller Commands
> + *
> + * Copyright (c) 2021 Google LLC
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +#include "libqtest.h"
> +
> +/* more details at hw/sd/sdhci-internal.h */
> +#define SDHC_BLKSIZE 0x04
> +#define SDHC_BLKCNT 0x06
> +#define SDHC_ARGUMENT 0x08
> +#define SDHC_TRNMOD 0x0C
> +#define SDHC_CMDREG 0x0E
> +#define SDHC_BDATA 0x20
> +#define SDHC_PRNSTS 0x24
> +#define SDHC_BLKGAP 0x2A
> +#define SDHC_CLKCON 0x2C
> +#define SDHC_SWRST 0x2F
> +#define SDHC_CAPAB 0x40
> +#define SDHC_MAXCURR 0x48
> +#define SDHC_HCVER 0xFE
> +
> +/* TRNSMOD Reg */
> +#define SDHC_TRNS_BLK_CNT_EN 0x0002
> +#define SDHC_TRNS_READ 0x0010
> +#define SDHC_TRNS_WRITE 0x0000
> +#define SDHC_TRNS_MULTI 0x0020
> +
> +/* CMD Reg */
> +#define SDHC_CMD_DATA_PRESENT (1 << 5)
> +#define SDHC_ALL_SEND_CID (2 << 8)
> +#define SDHC_SEND_RELATIVE_ADDR (3 << 8)
> +#define SDHC_SELECT_DESELECT_CARD (7 << 8)
> +#define SDHC_SEND_CSD (9 << 8)
> +#define SDHC_STOP_TRANSMISSION (12 << 8)
> +#define SDHC_READ_MULTIPLE_BLOCK (18 << 8)
> +#define SDHC_WRITE_MULTIPLE_BLOCK (25 << 8)
> +#define SDHC_APP_CMD (55 << 8)
> +
> +/* SWRST Reg */
> +#define SDHC_RESET_ALL 0x01
> +
> +/* CLKCTRL Reg */
> +#define SDHC_CLOCK_INT_EN 0x0001
> +#define SDHC_CLOCK_INT_STABLE 0x0002
> +#define SDHC_CLOCK_SDCLK_EN (1 << 2)
> +
> +/* Set registers needed to send commands to SD */
> +void sdhci_cmd_regs(QTestState *qts, uint64_t base_addr, uint16_t blksize,
> +                    uint16_t blkcnt, uint32_t argument, uint16_t trnmod,
> +                    uint16_t cmdreg);
> +
> +/* Read at most 1 block of SD using non-DMA  */
> +ssize_t sdhci_read_cmd(QTestState *qts, uint64_t base_addr, char *msg,
> +                       size_t count);
> +
> +/* Write at most 1 block of SD using non-DMA  */
> +void sdhci_write_cmd(QTestState *qts, uint64_t base_addr, const char *msg,
> +                     size_t count, size_t blksize);
> diff --git a/tests/qtest/libqos/sdhci-cmd.c
> b/tests/qtest/libqos/sdhci-cmd.c
> new file mode 100644
> index 0000000000..2d9e518341
> --- /dev/null
> +++ b/tests/qtest/libqos/sdhci-cmd.c
> @@ -0,0 +1,116 @@
> +/*
> + * MMC Host Controller Commands
> + *
> + * Copyright (c) 2021 Google LLC
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "sdhci-cmd.h"
> +#include "libqtest.h"
> +
> +static ssize_t read_fifo(QTestState *qts, uint64_t reg, char *msg, size_t
> count)
> +{
> +    uint32_t mask = 0xff;
> +    size_t index = 0;
> +    uint32_t msg_frag;
> +    int size;
> +    while (index < count) {
> +        size = count - index;
> +        if (size > 4) {
> +            size = 4;
> +        }
> +        msg_frag = qtest_readl(qts, reg);
> +        while (size > 0) {
> +            msg[index] = msg_frag & mask;
> +            if (msg[index++] == 0) {
> +                return index;
> +            }
> +            msg_frag >>= 8;
> +            --size;
> +        }
> +    }
> +    return index;
> +}
> +
> +static void write_fifo(QTestState *qts, uint64_t reg, const char *msg,
> +                       size_t count)
> +{
> +    size_t index = 0;
> +    uint32_t msg_frag;
> +    int size;
> +    int frag_i;
> +    while (index < count) {
> +        size = count - index;
> +        if (size > 4) {
> +            size = 4;
> +        }
> +        msg_frag = 0;
> +        frag_i = 0;
> +        while (frag_i < size) {
> +            msg_frag |= ((uint32_t)msg[index++]) << (frag_i * 8);
> +            ++frag_i;
> +        }
> +        qtest_writel(qts, reg, msg_frag);
> +    }
> +}
> +
> +static void fill_block(QTestState *qts, uint64_t reg, int count)
> +{
> +    while (--count >= 0) {
> +        qtest_writel(qts, reg, 0);
> +    }
> +}
> +
> +void sdhci_cmd_regs(QTestState *qts, uint64_t base_addr, uint16_t blksize,
> +                    uint16_t blkcnt, uint32_t argument, uint16_t trnmod,
> +                    uint16_t cmdreg)
> +{
> +    qtest_writew(qts, base_addr + SDHC_BLKSIZE, blksize);
> +    qtest_writew(qts, base_addr + SDHC_BLKCNT, blkcnt);
> +    qtest_writel(qts, base_addr + SDHC_ARGUMENT, argument);
> +    qtest_writew(qts, base_addr + SDHC_TRNMOD, trnmod);
> +    qtest_writew(qts, base_addr + SDHC_CMDREG, cmdreg);
> +}
> +
> +ssize_t sdhci_read_cmd(QTestState *qts, uint64_t base_addr, char *msg,
> +                       size_t count)
> +{
> +    sdhci_cmd_regs(qts, base_addr, count, 1, 0,
> +                   SDHC_TRNS_MULTI | SDHC_TRNS_READ |
> SDHC_TRNS_BLK_CNT_EN,
> +                   SDHC_READ_MULTIPLE_BLOCK | SDHC_CMD_DATA_PRESENT);
> +
> +    /* read sd fifo_buffer */
> +    ssize_t bytes_read = read_fifo(qts, base_addr + SDHC_BDATA, msg,
> count);
> +
> +    sdhci_cmd_regs(qts, base_addr, 0, 0, 0,
> +                   SDHC_TRNS_MULTI | SDHC_TRNS_READ |
> SDHC_TRNS_BLK_CNT_EN,
> +                   SDHC_STOP_TRANSMISSION);
> +
> +    return bytes_read;
> +}
> +
> +void sdhci_write_cmd(QTestState *qts, uint64_t base_addr, const char *msg,
> +                     size_t count, size_t blksize)
> +{
> +    sdhci_cmd_regs(qts, base_addr, blksize, 1, 0,
> +                   SDHC_TRNS_MULTI | SDHC_TRNS_WRITE |
> SDHC_TRNS_BLK_CNT_EN,
> +                   SDHC_WRITE_MULTIPLE_BLOCK | SDHC_CMD_DATA_PRESENT);
> +
> +    /* write to sd fifo_buffer */
> +    write_fifo(qts, base_addr + SDHC_BDATA, msg, count);
> +    fill_block(qts, base_addr + SDHC_BDATA, (blksize - count) / 4);
> +
> +    sdhci_cmd_regs(qts, base_addr, 0, 0, 0,
> +                   SDHC_TRNS_MULTI | SDHC_TRNS_WRITE |
> SDHC_TRNS_BLK_CNT_EN,
> +                   SDHC_STOP_TRANSMISSION);
> +}
> diff --git a/tests/qtest/libqos/meson.build
> b/tests/qtest/libqos/meson.build
> index 1f5c8f1053..4af1f04787 100644
> --- a/tests/qtest/libqos/meson.build
> +++ b/tests/qtest/libqos/meson.build
> @@ -5,6 +5,7 @@ libqos_srcs = files('../libqtest.c',
>          'fw_cfg.c',
>          'malloc.c',
>          'libqos.c',
> +        'sdhci-cmd.c',
>
>          # spapr
>          'malloc-spapr.c',
> --
> 2.25.1
>
>

Reply via email to