/*
 * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
 *
 * Copyright (c) 2022 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 "hw/sd/npcm7xx_sdhci.h"

#include "libqtest.h"
#include "libqtest-single.h"
#include "libqos/sdhci-cmd.h"

#define NPCM7XX_REG_SIZE 0x100
#define NPCM7XX_MMC_BA 0xF0842000
#define NPCM7XX_BLK_SIZE 512
#define NPCM7XX_TEST_IMAGE_SIZE (1 << 20)

char *sd_path;

static QTestState *setup_sd_card(void)
{
    QTestState *qts = qtest_initf(
        "-machine kudo-bmc "
        "-device sd-card,drive=drive0 "
        "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
        sd_path);

    qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
    qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
                 SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
                     SDHC_CLOCK_INT_EN);
    sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
    sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
    sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
    sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
    sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
                   SDHC_SELECT_DESELECT_CARD);

    return qts;
}

static void write_sdread(QTestState *qts, const char *msg)
{
    int fd, ret;
    size_t len = strlen(msg);
    char *rmsg = g_malloc(len);

    /* write message to sd */
    fd = open(sd_path, O_WRONLY);
    g_assert(fd >= 0);
    ret = write(fd, msg, len);
    close(fd);
    g_assert(ret == len);

    /* read message using sdhci */
    ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
    g_assert(ret == len);
    g_assert(!memcmp(rmsg, msg, len));

    g_free(rmsg);
}

/* Check MMC can read values from sd */
static void test_read_sd(void)
{
    QTestState *qts = setup_sd_card();

    write_sdread(qts, "hello world");
    write_sdread(qts, "goodbye");

    qtest_quit(qts);
}

static void sdwrite_read(QTestState *qts, const char *msg)
{
    int fd, ret;
    size_t len = strlen(msg);
    char *rmsg = g_malloc(len);

    /* write message using sdhci */
    sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);

    /* read message from sd */
    fd = open(sd_path, O_RDONLY);
    g_assert(fd >= 0);
    ret = read(fd, rmsg, len);
    close(fd);
    g_assert(ret == len);

    g_assert(!memcmp(rmsg, msg, len));

    g_free(rmsg);
}

/* Check MMC can write values to sd */
static void test_write_sd(void)
{
    QTestState *qts = setup_sd_card();

    sdwrite_read(qts, "hello world");
    sdwrite_read(qts, "goodbye");

    qtest_quit(qts);
}

/* Check SDHCI has correct default values. */
static void test_reset(void)
{
    QTestState *qts = qtest_init("-machine kudo-bmc");
    uint64_t addr = NPCM7XX_MMC_BA;
    uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
    uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
                                  NPCM7XX_PRSTVALS_1_RESET,
                                  0,
                                  NPCM7XX_PRSTVALS_3_RESET,
                                  0,
                                  0};
    int i;
    uint32_t mask;

    while (addr < end_addr) {
        switch (addr - NPCM7XX_MMC_BA) {
        case SDHC_PRNSTS:
            /*
             * ignores bits 20 to 24: they are changed when reading registers
             */
            mask = 0x1f00000;
            g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
                            NPCM7XX_PRSNTS_RESET | mask);
            addr += 4;
            break;
        case SDHC_BLKGAP:
            g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET);
            addr += 1;
            break;
        case SDHC_CAPAB:
            g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET);
            addr += 8;
            break;
        case SDHC_MAXCURR:
            g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET);
            addr += 8;
            break;
        case SDHC_HCVER:
            g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET);
            addr += 2;
            break;
        case NPCM7XX_PRSTVALS:
            for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) {
                g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==,
                                prstvals_resets[i]);
            }
            addr += NPCM7XX_PRSTVALS_SIZE * 2;
            break;
        default:
            g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
            addr += 1;
        }
    }

    qtest_quit(qts);
}

static void drive_destroy(void)
{
    unlink(sd_path);
    g_free(sd_path);
}

static void drive_create(void)
{
    int fd, ret;
    GError *error = NULL;

    /* Create a temporary raw image */
    fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error);
    if (fd == -1) {
        fprintf(stderr, "unable to create sdhci file: %s\n", error->message);
        g_error_free(error);
    }
    g_assert(sd_path != NULL);

    ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
    g_assert_cmpint(ret, ==, 0);
    g_message("%s", sd_path);
    close(fd);
}

int main(int argc, char **argv)
{
    int ret;

    drive_create();

    g_test_init(&argc, &argv, NULL);

    qtest_add_func("npcm7xx_sdhci/reset", test_reset);
    qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd);
    qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd);

    ret = g_test_run();
    drive_destroy();
    return ret;
}
