// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "component-proxy.h"

#include <ddk/debug.h>
#include <lib/sync/completion.h>

#include <memory>

namespace component {

zx_status_t ComponentProxy::Create(void* ctx, zx_device_t* parent, const char* name,
                                   const char* args, zx_handle_t raw_rpc) {
    zx::channel rpc(raw_rpc);
    auto dev = std::make_unique<ComponentProxy>(parent, std::move(rpc));
    auto status = dev->DdkAdd("component-proxy", DEVICE_ADD_NON_BINDABLE);
    if (status == ZX_OK) {
        // devmgr owns the memory now
        __UNUSED auto ptr = dev.release();
    }
    return status;
}

zx_status_t ComponentProxy::DdkGetProtocol(uint32_t proto_id, void* out) {
    auto* proto = static_cast<ddk::AnyProtocol*>(out);
    proto->ctx = this;

    switch (proto_id) {
    case ZX_PROTOCOL_AMLOGIC_CANVAS:
        proto->ops = &amlogic_canvas_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_CLOCK:
        proto->ops = &clock_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_ETH_BOARD:
        proto->ops = &eth_board_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_GPIO:
        proto->ops = &gpio_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_I2C:
        proto->ops = &i2c_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_MIPI_CSI:
        proto->ops = &mipi_csi_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_PDEV:
        proto->ops = &pdev_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_POWER:
        proto->ops = &power_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_SYSMEM:
        proto->ops = &sysmem_protocol_ops_;
        return ZX_OK;
    case ZX_PROTOCOL_USB_MODE_SWITCH:
        proto->ops = &usb_mode_switch_protocol_ops_;
        return ZX_OK;
    default:
        zxlogf(ERROR, "%s unsupported protocol \'%u\'\n", __func__, proto_id);
        return ZX_ERR_NOT_SUPPORTED;
    }
}

void ComponentProxy::DdkUnbind() {
    DdkRemove();
}

void ComponentProxy::DdkRelease() {
    delete this;
}

zx_status_t ComponentProxy::Rpc(const ProxyRequest* req, size_t req_length, ProxyResponse* resp,
                                size_t resp_length, const zx_handle_t* in_handles,
                                size_t in_handle_count, zx_handle_t* out_handles,
                                size_t out_handle_count, size_t* out_actual) {
    uint32_t resp_size, handle_count;

    zx_channel_call_args_t args = {
        .wr_bytes = req,
        .wr_handles = in_handles,
        .rd_bytes = resp,
        .rd_handles = out_handles,
        .wr_num_bytes = static_cast<uint32_t>(req_length),
        .wr_num_handles = static_cast<uint32_t>(in_handle_count),
        .rd_num_bytes = static_cast<uint32_t>(resp_length),
        .rd_num_handles = static_cast<uint32_t>(out_handle_count),
    };
    auto status = rpc_.call(0, zx::time::infinite(), &args, &resp_size, &handle_count);
    if (status != ZX_OK) {
        return status;
    }

    status = resp->status;

    if (status == ZX_OK && resp_size < sizeof(*resp)) {
        zxlogf(ERROR, "PlatformProxy::Rpc resp_size too short: %u\n", resp_size);
        status = ZX_ERR_INTERNAL;
        goto fail;
    } else if (status == ZX_OK && handle_count != out_handle_count) {
        zxlogf(ERROR, "PlatformProxy::Rpc handle count %u expected %zu\n", handle_count,
               out_handle_count);
        status = ZX_ERR_INTERNAL;
        goto fail;
    }

    if (out_actual) {
        *out_actual = resp_size;
    }

fail:
    if (status != ZX_OK) {
        for (uint32_t i = 0; i < handle_count; i++) {
            zx_handle_close(out_handles[i]);
        }
    }
    return status;
}

zx_status_t ComponentProxy::AmlogicCanvasConfig(zx::vmo vmo, size_t offset,
                                                const canvas_info_t* info,
                                                uint8_t* out_canvas_idx) {
    AmlogicCanvasProxyRequest req = {};
    AmlogicCanvasProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_AMLOGIC_CANVAS;
    req.op = AmlogicCanvasOp::CONFIG;
    req.offset = offset;
    req.info = *info;
    zx_handle_t handle = vmo.release();

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), &handle, 1, nullptr, 0,
                      nullptr);
    if (status != ZX_OK) {
        return status;
    }
    *out_canvas_idx = resp.canvas_idx;
    return ZX_OK;
}

zx_status_t ComponentProxy::AmlogicCanvasFree(uint8_t canvas_idx) {
    AmlogicCanvasProxyRequest req = {};
    AmlogicCanvasProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_AMLOGIC_CANVAS;
    req.op = AmlogicCanvasOp::FREE;
    req.canvas_idx = canvas_idx;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::ClockEnable() {
    ClockProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_CLOCK;
    req.op = ClockOp::ENABLE;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

zx_status_t ComponentProxy::ClockDisable() {
    ClockProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_CLOCK;
    req.op = ClockOp::DISABLE;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

zx_status_t ComponentProxy::EthBoardResetPhy() {
    EthBoardProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_ETH_BOARD;
    req.op = EthBoardOp::RESET_PHY;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

zx_status_t ComponentProxy::MipiCsiInit(const mipi_info_t* mipi_info,
                                        const mipi_adap_info_t* adap_info) {
    MipiCsiProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_MIPI_CSI;
    req.op = MipiCsiOp::INIT;
    req.mipi_info = *mipi_info;
    req.adap_info = *adap_info;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

zx_status_t ComponentProxy::MipiCsiDeInit() {
    MipiCsiProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_MIPI_CSI;
    req.op = MipiCsiOp::DEINIT;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

zx_status_t ComponentProxy::GpioConfigIn(uint32_t flags) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::CONFIG_IN;
    req.flags = flags;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::GpioConfigOut(uint8_t initial_value) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::CONFIG_OUT;
    req.value = initial_value;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::GpioSetAltFunction(uint64_t function) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::SET_ALT_FUNCTION;
    req.alt_function = function;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::GpioGetInterrupt(uint32_t flags, zx::interrupt* out_irq) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::GET_INTERRUPT;
    req.flags = flags;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
               out_irq->reset_and_get_address(), 1, nullptr);
}

zx_status_t ComponentProxy::GpioSetPolarity(uint32_t polarity) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::SET_POLARITY;
    req.polarity = polarity;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::GpioReleaseInterrupt() {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::RELEASE_INTERRUPT;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::GpioRead(uint8_t* out_value) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::READ;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));

    if (status != ZX_OK) {
        return status;
    }
    *out_value = resp.value;
    return ZX_OK;
}

zx_status_t ComponentProxy::GpioWrite(uint8_t value) {
    GpioProxyRequest req = {};
    GpioProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_GPIO;
    req.op = GpioOp::WRITE;
    req.value = value;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

void ComponentProxy::I2cTransact(const i2c_op_t* op_list, size_t op_count,
                                 i2c_transact_callback callback, void* cookie) {
    size_t writes_length = 0;
    size_t reads_length = 0;
    for (size_t i = 0; i < op_count; ++i) {
        if (op_list[i].is_read) {
            reads_length += op_list[i].data_size;
        } else {
            writes_length += op_list[i].data_size;
        }
    }
    if (!writes_length && !reads_length) {
        callback(cookie, ZX_ERR_INVALID_ARGS, nullptr, 0);
        return;
    }

    size_t req_length = sizeof(I2cProxyRequest) + op_count * sizeof(I2cProxyOp) + writes_length;
    if (req_length >= kProxyMaxTransferSize) {
        return callback(cookie, ZX_ERR_BUFFER_TOO_SMALL, nullptr, 0);
    }

    uint8_t req_buffer[kProxyMaxTransferSize];
    auto req = reinterpret_cast<I2cProxyRequest*>(req_buffer);
    req->header.proto_id = ZX_PROTOCOL_I2C;
    req->op = I2cOp::TRANSACT;
    req->op_count = op_count;

    auto rpc_ops = reinterpret_cast<I2cProxyOp*>(&req[1]);
    ZX_ASSERT(op_count < I2C_MAX_RW_OPS);
    for (size_t i = 0; i < op_count; ++i) {
        rpc_ops[i].length = op_list[i].data_size;
        rpc_ops[i].is_read = op_list[i].is_read;
        rpc_ops[i].stop = op_list[i].stop;
    }
    uint8_t* p_writes = reinterpret_cast<uint8_t*>(rpc_ops) + op_count * sizeof(I2cProxyOp);
    for (size_t i = 0; i < op_count; ++i) {
        if (!op_list[i].is_read) {
            memcpy(p_writes, op_list[i].data_buffer, op_list[i].data_size);
            p_writes += op_list[i].data_size;
        }
    }

    const size_t resp_length = sizeof(I2cProxyResponse) + reads_length;
    if (resp_length >= kProxyMaxTransferSize) {
        callback(cookie, ZX_ERR_INVALID_ARGS, nullptr, 0);
        return;
    }
    uint8_t resp_buffer[kProxyMaxTransferSize];
    auto* rsp = reinterpret_cast<I2cProxyResponse*>(resp_buffer);
    size_t actual;
    auto status = Rpc(&req->header, static_cast<uint32_t>(req_length),
                      &rsp->header, static_cast<uint32_t>(resp_length), nullptr, 0, nullptr,
                      0, &actual);
    if (status != ZX_OK) {
        callback(cookie, status, nullptr, 0);
        return;
    }

    // TODO(voydanoff) This proxying code actually implements i2c_transact synchronously
    // due to the fact that it is unsafe to respond asynchronously on the devmgr rxrpc channel.
    // In the future we may want to redo the plumbing to allow this to be truly asynchronous.

    if (actual != resp_length) {
        status = ZX_ERR_INTERNAL;
    } else {
        status = rsp->header.status;
    }
    i2c_op_t read_ops[I2C_MAX_RW_OPS];
    size_t read_ops_cnt = 0;
    uint8_t* p_reads = reinterpret_cast<uint8_t*>(rsp + 1);
    for (size_t i = 0; i < op_count; ++i) {
        if (op_list[i].is_read) {
            read_ops[read_ops_cnt] = op_list[i];
            read_ops[read_ops_cnt].data_buffer = p_reads;
            read_ops_cnt++;
            p_reads += op_list[i].data_size;
        }
    }
    callback(cookie, status, read_ops, read_ops_cnt);
}

zx_status_t ComponentProxy::I2cGetMaxTransferSize(size_t* out_size) {
    I2cProxyRequest req = {};
    I2cProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_I2C;
    req.op = I2cOp::GET_MAX_TRANSFER_SIZE;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    *out_size = resp.size;
    return ZX_OK;
}

zx_status_t ComponentProxy::I2cGetInterrupt(uint32_t flags, zx::interrupt* out_irq) {
    I2cProxyRequest req = {};
    I2cProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_I2C;
    req.op = I2cOp::GET_INTERRUPT;
    req.flags = flags;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
               out_irq->reset_and_get_address(), 1, nullptr);
}

zx_status_t ComponentProxy::PDevGetMmio(uint32_t index, pdev_mmio_t* out_mmio) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_MMIO;
    req.index = index;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
                      &out_mmio->vmo, 1, nullptr);
    if (status == ZX_OK) {
        out_mmio->offset = resp.offset;
        out_mmio->size = resp.size;
    }
    return status;
}

zx_status_t ComponentProxy::PDevGetInterrupt(uint32_t index, uint32_t flags,
                                             zx::interrupt* out_irq) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_INTERRUPT;
    req.index = index;
    req.flags = flags;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
               out_irq->reset_and_get_address(), 1, nullptr);
}

zx_status_t ComponentProxy::PDevGetBti(uint32_t index, zx::bti* out_bti) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_BTI;
    req.index = index;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
               out_bti->reset_and_get_address(), 1, nullptr);
}

zx_status_t ComponentProxy::PDevGetSmc(uint32_t index, zx::resource* out_resource) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_SMC;
    req.index = index;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp), nullptr, 0,
               out_resource->reset_and_get_address(), 1, nullptr);
}

zx_status_t ComponentProxy::PDevGetDeviceInfo(pdev_device_info_t* out_info) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_DEVICE_INFO;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    memcpy(out_info, &resp.device_info, sizeof(*out_info));
    return ZX_OK;
}

zx_status_t ComponentProxy::PDevGetBoardInfo(pdev_board_info_t* out_info) {
    PdevProxyRequest req = {};
    PdevProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_PDEV;
    req.op = PdevOp::GET_BOARD_INFO;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    memcpy(out_info, &resp.board_info, sizeof(*out_info));
    return ZX_OK;
}

zx_status_t ComponentProxy::PDevDeviceAdd(uint32_t index, const device_add_args_t* args,
                                          zx_device_t** device) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t ComponentProxy::PDevGetProtocol(uint32_t proto_id, uint32_t index, void* out_protocol,
                                            size_t protocol_size, size_t* protocol_actual) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t ComponentProxy::PowerEnablePowerDomain() {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::ENABLE;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::PowerDisablePowerDomain() {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::DISABLE;

    return Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
}

zx_status_t ComponentProxy::PowerGetPowerDomainStatus(power_domain_status_t* out_status) {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::GET_STATUS;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    *out_status = resp.status;
    return status;
}

zx_status_t ComponentProxy::PowerGetSupportedVoltageRange(uint32_t* min_voltage,
                                                          uint32_t* max_voltage) {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::GET_SUPPORTED_VOLTAGE_RANGE;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    *min_voltage = resp.min_voltage;
    *max_voltage = resp.max_voltage;
    return status;
}

zx_status_t ComponentProxy::PowerRequestVoltage(uint32_t voltage, uint32_t* actual_voltage) {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::REQUEST_VOLTAGE;
    req.set_voltage = voltage;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    *actual_voltage = resp.actual_voltage;
    return status;
}

zx_status_t ComponentProxy::PowerWritePmicCtrlReg(uint32_t reg_addr, uint32_t value) {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::WRITE_PMIC_CTRL_REG;
    req.reg_addr = reg_addr;
    req.reg_value = value;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    return status;
}

zx_status_t ComponentProxy::PowerReadPmicCtrlReg(uint32_t reg_addr, uint32_t* out_value) {
    PowerProxyRequest req = {};
    PowerProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_POWER;
    req.op = PowerOp::READ_PMIC_CTRL_REG;
    req.reg_addr = reg_addr;

    auto status = Rpc(&req.header, sizeof(req), &resp.header, sizeof(resp));
    if (status != ZX_OK) {
        return status;
    }
    *out_value = resp.reg_value;
    return status;
}

zx_status_t ComponentProxy::SysmemConnect(zx::channel allocator2_request) {
    SysmemProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_SYSMEM;
    req.op = SysmemOp::CONNECT;
    zx_handle_t handle = allocator2_request.release();

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp), &handle, 1, nullptr, 0, nullptr);
}

zx_status_t ComponentProxy::UsbModeSwitchSetMode(usb_mode_t mode) {
    UsbModeSwitchProxyRequest req = {};
    ProxyResponse resp = {};
    req.header.proto_id = ZX_PROTOCOL_USB_MODE_SWITCH;
    req.op = UsbModeSwitchOp::SET_MODE;
    req.mode = mode;

    return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}

const zx_driver_ops_t driver_ops = []() {
    zx_driver_ops_t ops = {};
    ops.version = DRIVER_OPS_VERSION;
    ops.create = ComponentProxy::Create;
    return ops;
}();

} // namespace component

ZIRCON_DRIVER_BEGIN(component_proxy, component::driver_ops, "zircon", "0.1", 1)
// Unmatchable.  This is loaded via the proxy driver mechanism instead of the binding process
BI_ABORT()
ZIRCON_DRIVER_END(component_proxy)
