/*
 * CXL Utility library for devices
 *
 * Copyright(C) 2020 Intel Corporation.
 *
 * This work is licensed under the terms of the GNU GPL, version 2. See the
 * COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/cxl/cxl.h"

/*
 * Device registers have no restrictions per the spec, and so fall back to the
 * default memory mapped register rules in CXL r3.1 Section 8.2:
 *   Software shall use CXL.io Memory Read and Write to access memory mapped
 *   register defined in this section. Unless otherwise specified, software
 *   shall restrict the accesses width based on the following:
 *   • A 32 bit register shall be accessed as a 1 Byte, 2 Bytes or 4 Bytes
 *     quantity.
 *   • A 64 bit register shall be accessed as a 1 Byte, 2 Bytes, 4 Bytes or 8
 *     Bytes
 *   • The address shall be a multiple of the access width, e.g. when
 *     accessing a register as a 4 Byte quantity, the address shall be
 *     multiple of 4.
 *   • The accesses shall map to contiguous bytes.If these rules are not
 *     followed, the behavior is undefined
 */

static uint64_t caps_reg_read(void *opaque, hwaddr offset, unsigned size)
{
    CXLDeviceState *cxl_dstate = opaque;

    switch (size) {
    case 4:
        return cxl_dstate->caps_reg_state32[offset / size];
    case 8:
        return cxl_dstate->caps_reg_state64[offset / size];
    default:
        g_assert_not_reached();
    }
}

static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size)
{
    CXLDeviceState *cxl_dstate = opaque;

    switch (size) {
    case 1:
        return cxl_dstate->dev_reg_state[offset];
    case 2:
        return cxl_dstate->dev_reg_state16[offset / size];
    case 4:
        return cxl_dstate->dev_reg_state32[offset / size];
    case 8:
        return cxl_dstate->dev_reg_state64[offset / size];
    default:
        g_assert_not_reached();
    }
}

static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
{
    CXLDeviceState *cxl_dstate;
    CXLCCI *cci = opaque;

    if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
        cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
    } else if (object_dynamic_cast(OBJECT(cci->intf),
                                   TYPE_CXL_SWITCH_MAILBOX_CCI)) {
        cxl_dstate = &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate;
    } else {
        return 0;
    }

    switch (size) {
    case 1:
        return cxl_dstate->mbox_reg_state[offset];
    case 2:
        return cxl_dstate->mbox_reg_state16[offset / size];
    case 4:
        return cxl_dstate->mbox_reg_state32[offset / size];
    case 8:
        if (offset == A_CXL_DEV_BG_CMD_STS) {
            uint64_t bg_status_reg;
            bg_status_reg = FIELD_DP64(0, CXL_DEV_BG_CMD_STS, OP,
                                       cci->bg.opcode);
            bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
                                       PERCENTAGE_COMP, cci->bg.complete_pct);
            bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
                                       RET_CODE, cci->bg.ret_code);
            /* endian? */
            cxl_dstate->mbox_reg_state64[offset / size] = bg_status_reg;
        }
        if (offset == A_CXL_DEV_MAILBOX_STS) {
            uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
            if (cci->bg.complete_pct) {
                status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
                                        0);
                cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
            }
        }
        return cxl_dstate->mbox_reg_state64[offset / size];
    default:
        g_assert_not_reached();
    }
}

static void mailbox_mem_writel(uint32_t *reg_state, hwaddr offset,
                               uint64_t value)
{
    switch (offset) {
    case A_CXL_DEV_MAILBOX_CTRL:
        /* fallthrough */
    case A_CXL_DEV_MAILBOX_CAP:
        /* RO register */
        break;
    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s Unexpected 32-bit access to 0x%" PRIx64 " (WI)\n",
                      __func__, offset);
        return;
    }

    reg_state[offset / sizeof(*reg_state)] = value;
}

static void mailbox_mem_writeq(uint64_t *reg_state, hwaddr offset,
                               uint64_t value)
{
    switch (offset) {
    case A_CXL_DEV_MAILBOX_CMD:
        break;
    case A_CXL_DEV_BG_CMD_STS:
        break;
    case A_CXL_DEV_MAILBOX_STS:
        /* Read only register, will get updated by the state machine */
        return;
    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s Unexpected 64-bit access to 0x%" PRIx64 " (WI)\n",
                      __func__, offset);
        return;
    }


    reg_state[offset / sizeof(*reg_state)] = value;
}

static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
                              unsigned size)
{
    CXLDeviceState *cxl_dstate;
    CXLCCI *cci = opaque;

    if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
        cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
    } else if (object_dynamic_cast(OBJECT(cci->intf),
                                   TYPE_CXL_SWITCH_MAILBOX_CCI)) {
        cxl_dstate = &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate;
    } else {
        return;
    }

    if (offset >= A_CXL_DEV_CMD_PAYLOAD) {
        memcpy(cxl_dstate->mbox_reg_state + offset, &value, size);
        return;
    }

    switch (size) {
    case 4:
        mailbox_mem_writel(cxl_dstate->mbox_reg_state32, offset, value);
        break;
    case 8:
        mailbox_mem_writeq(cxl_dstate->mbox_reg_state64, offset, value);
        break;
    default:
        g_assert_not_reached();
    }

    if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
                         DOORBELL)) {
        uint64_t command_reg =
            cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
        uint8_t cmd_set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD,
                                     COMMAND_SET);
        uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
        size_t len_in = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
        uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
        /*
         * Copy taken to avoid need for individual command handlers to care
         * about aliasing.
         */
        g_autofree uint8_t *pl_in_copy = NULL;
        size_t len_out = 0;
        uint64_t status_reg;
        bool bg_started = false;
        int rc;

        pl_in_copy = g_memdup2(pl, len_in);
        if (len_in == 0 || pl_in_copy) {
            /* Avoid stale data  - including from earlier cmds */
            memset(pl, 0, CXL_MAILBOX_MAX_PAYLOAD_SIZE);
            rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl_in_copy,
                                         &len_out, pl, &bg_started);
        } else {
            rc = CXL_MBOX_INTERNAL_ERROR;
        }

        /* Set bg and the return code */
        status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP,
                                bg_started ? 1 : 0);
        status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, ERRNO, rc);
        /* Set the return length */
        command_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_CMD, COMMAND_SET, cmd_set);
        command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
                                 COMMAND, cmd);
        command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
                                 LENGTH, len_out);

        cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD] = command_reg;
        cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_STS] = status_reg;
        /* Tell the host we're done */
        ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
                         DOORBELL, 0);
    }
}

static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size)
{
    CXLDeviceState *cxl_dstate = opaque;

    return cxl_dstate->memdev_status;
}

static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
                           unsigned size)
{
    /* Many register sets are read only */
}

static const MemoryRegionOps mdev_ops = {
    .read = mdev_reg_read,
    .write = ro_reg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
        .unaligned = false,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static const MemoryRegionOps mailbox_ops = {
    .read = mailbox_reg_read,
    .write = mailbox_reg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
        .unaligned = false,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
};

static const MemoryRegionOps dev_ops = {
    .read = dev_reg_read,
    .write = ro_reg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
        .unaligned = false,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
};

static const MemoryRegionOps caps_ops = {
    .read = caps_reg_read,
    .write = ro_reg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
        .unaligned = false,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
};

void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate,
                                    CXLCCI *cci)
{
    /* This will be a BAR, so needs to be rounded up to pow2 for PCI spec */
    memory_region_init(&cxl_dstate->device_registers, obj, "device-registers",
                       pow2ceil(CXL_MMIO_SIZE));

    memory_region_init_io(&cxl_dstate->caps, obj, &caps_ops, cxl_dstate,
                          "cap-array", CXL_CAPS_SIZE);
    memory_region_init_io(&cxl_dstate->device, obj, &dev_ops, cxl_dstate,
                          "device-status", CXL_DEVICE_STATUS_REGISTERS_LENGTH);
    memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cci,
                          "mailbox", CXL_MAILBOX_REGISTERS_LENGTH);
    memory_region_init_io(&cxl_dstate->memory_device, obj, &mdev_ops,
                          cxl_dstate, "memory device caps",
                          CXL_MEMORY_DEVICE_REGISTERS_LENGTH);

    memory_region_add_subregion(&cxl_dstate->device_registers, 0,
                                &cxl_dstate->caps);
    memory_region_add_subregion(&cxl_dstate->device_registers,
                                CXL_DEVICE_STATUS_REGISTERS_OFFSET,
                                &cxl_dstate->device);
    memory_region_add_subregion(&cxl_dstate->device_registers,
                                CXL_MAILBOX_REGISTERS_OFFSET,
                                &cxl_dstate->mailbox);
    memory_region_add_subregion(&cxl_dstate->device_registers,
                                CXL_MEMORY_DEVICE_REGISTERS_OFFSET,
                                &cxl_dstate->memory_device);
}

void cxl_event_set_status(CXLDeviceState *cxl_dstate, CXLEventLogType log_type,
                          bool available)
{
    if (available) {
        cxl_dstate->event_status |= (1 << log_type);
    } else {
        cxl_dstate->event_status &= ~(1 << log_type);
    }

    ARRAY_FIELD_DP64(cxl_dstate->dev_reg_state64, CXL_DEV_EVENT_STATUS,
                     EVENT_STATUS, cxl_dstate->event_status);
}

static void device_reg_init_common(CXLDeviceState *cxl_dstate)
{
    CXLEventLogType log;

    for (log = 0; log < CXL_EVENT_TYPE_MAX; log++) {
        cxl_event_set_status(cxl_dstate, log, false);
    }
}

static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
{
    const uint8_t msi_n = 9;

    /* 2048 payload size */
    ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
                     PAYLOAD_SIZE, CXL_MAILBOX_PAYLOAD_SHIFT);
    cxl_dstate->payload_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE;
    /* irq support */
    ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
                     BG_INT_CAP, 1);
    ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
                     MSI_N, msi_n);
    cxl_dstate->mbox_msi_n = msi_n;
    ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
                     MBOX_READY_TIME, 0); /* Not reported */
    ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
                     TYPE, 0); /* Inferred from class code */
}

static void memdev_reg_init_common(CXLDeviceState *cxl_dstate)
{
    uint64_t memdev_status_reg;

    memdev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
    memdev_status_reg = FIELD_DP64(memdev_status_reg, CXL_MEM_DEV_STS,
                                   MBOX_READY, 1);
    cxl_dstate->memdev_status = memdev_status_reg;
}

void cxl_device_register_init_t3(CXLType3Dev *ct3d)
{
    CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
    uint64_t *cap_h = cxl_dstate->caps_reg_state64;
    const int cap_count = 3;

    /* CXL Device Capabilities Array Register */
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_ID, 0);
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1);
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count);

    cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1,
                        CXL_DEVICE_STATUS_VERSION);
    device_reg_init_common(cxl_dstate);

    cxl_device_cap_init(cxl_dstate, MAILBOX, 2, CXL_DEV_MAILBOX_VERSION);
    mailbox_reg_init_common(cxl_dstate);

    cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000,
        CXL_MEM_DEV_STATUS_VERSION);
    memdev_reg_init_common(cxl_dstate);

    cxl_initialize_mailbox_t3(&ct3d->cci, DEVICE(ct3d),
                              CXL_MAILBOX_MAX_PAYLOAD_SIZE);
}

void cxl_device_register_init_swcci(CSWMBCCIDev *sw)
{
    CXLDeviceState *cxl_dstate = &sw->cxl_dstate;
    uint64_t *cap_h = cxl_dstate->caps_reg_state64;
    const int cap_count = 3;

    /* CXL Device Capabilities Array Register */
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_ID, 0);
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1);
    ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count);

    cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1, 2);
    device_reg_init_common(cxl_dstate);

    cxl_device_cap_init(cxl_dstate, MAILBOX, 2, 1);
    mailbox_reg_init_common(cxl_dstate);

    cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
    memdev_reg_init_common(cxl_dstate);
}

uint64_t cxl_device_get_timestamp(CXLDeviceState *cxl_dstate)
{
    uint64_t time, delta;
    uint64_t final_time = 0;

    if (cxl_dstate->timestamp.set) {
        /* Find the delta from the last time the host set the time. */
        time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        delta = time - cxl_dstate->timestamp.last_set;
        final_time = cxl_dstate->timestamp.host_set + delta;
    }

    return final_time;
}
