/*
 * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
 * Description: sample for mailbox in liteOS
 */
#include "los_mbx.h"
#include "drv_mbx.h"

#define MBX_RET_ACPU_CMD      0x5A
#define MBX_TX_TEE_CMD        0x69
#define MBX_TX_TPP_CMD        0x47
#define MBX_DEFAULT_HANDLE    0xFFFFFFFF
#define MBX_DEFAULT_TIMEOUT   0x500

td_u32 g_handle_acpu2vmcu0 = MBX_DEFAULT_HANDLE;
td_u32 g_handle_tcpu2vmcu0 = MBX_DEFAULT_HANDLE;

void mailbox_callback_from_acpu(td_u32 handle, const void *data)
{
    td_u8 buf[MBX_RX_BUFF_SIZE];
    td_s32 ret;
    td_u32 rx_len;
    td_u32 tx_len;

    ret = drv_mbx_rx(handle, buf, MBX_RX_BUFF_SIZE, &rx_len, MBX_DEFAULT_TIMEOUT);
    if (ret < 0) {
        printf("drv_mbx_rx in callback failed, ret:0x%x\n", ret);
        return;
    }
    if (rx_len == 0) {
        printf("drv_mbx_rx get nothing!\n");
    } else {
        if (buf[0] == MBX_RET_ACPU_CMD) {
            ret = drv_mbx_tx(handle, buf, rx_len, &tx_len, MBX_DEFAULT_TIMEOUT);
            if ((ret < 0) || (tx_len != rx_len)) {
                printf("drv_mbx_tx failed, ret:0x%x\n", ret);
                return;
            }
        } else if (buf[0] == MBX_TX_TEE_CMD) {
            if (g_handle_tcpu2vmcu0 == MBX_DEFAULT_HANDLE) {
                printf("g_handle_tcpu2vmcu0 is invaild\n");
                return;
            }
            ret = drv_mbx_tx(g_handle_tcpu2vmcu0, buf, rx_len, &tx_len,
                MBX_DEFAULT_TIMEOUT * 100); /* 100: times for timeout based on default time */
            if ((ret < 0) || (tx_len != rx_len)) {
                printf("drv_mbx_tx g_handle_tcpu2vmcu0 failed, ret:0x%x\n", ret);
                return;
            }
        }
    }
}

void mailbox_callback_from_tcpu(td_u32 handle, const void *data)
{
    td_u8 buf[MBX_RX_BUFF_SIZE];
    td_s32 ret;
    td_u32 rx_len;
    td_u32 tx_len;

    ret = drv_mbx_rx(handle, buf, MBX_RX_BUFF_SIZE, &rx_len, MBX_DEFAULT_TIMEOUT);
    if (ret < 0) {
        printf("drv_mbx_rx in callback failed, ret:0x%x\n", ret);
        return;
    }
    if (rx_len == 0) {
        printf("drv_mbx_rx get nothing!\n");
    } else {
        if (buf[0] == MBX_RET_ACPU_CMD) {
            if (g_handle_acpu2vmcu0 == MBX_DEFAULT_HANDLE) {
                printf("g_handle_acpu2vmcu0 is invaild\n");
                return;
            }
            ret = drv_mbx_tx(g_handle_acpu2vmcu0, buf, rx_len, &tx_len,
                MBX_DEFAULT_TIMEOUT * 1000); /* 1000: times for timeout based on default time */
            if ((ret < 0) || (tx_len != rx_len)) {
                printf("drv_mbx_tx g_handle_acpu2vmcu0 failed, ret:0x%x\n", ret);
                return;
            }
        } else if (buf[0] == MBX_TX_TEE_CMD) {
            ret = drv_mbx_tx(handle, buf, rx_len, &tx_len,
                MBX_DEFAULT_TIMEOUT * 1000); /* 1000: times for timeout based on default time */
            if ((ret < 0) || (tx_len != rx_len)) {
                printf("drv_mbx_tx failed, ret:0x%x\n", ret);
                return;
            }
        }
    }
}

void sample_mailbox(void)
{
    td_s32 ret;

    /* sample for multiple open within EXT_MBX_ACPU2VMCU0_VFMW */
    ret = drv_mbx_open(EXT_MBX_ACPU2VMCU0_VFMW);
    if (ret < 0) {
        printf("mailbox_open EXT_MBX_ACPU2VMCU0_VFMW failed, ret:0x%x\n", ret);
        return;
    }
    ret = drv_mbx_open(EXT_MBX_ACPU2VMCU0_VFMW);
    if (ret < 0) {
        printf("mailbox_open EXT_MBX_ACPU2VMCU0_VFMW failed, ret:0x%x\n", ret);
        return;
    }
    g_handle_acpu2vmcu0 = ret;
    ret = drv_mbx_register_irq_callback(g_handle_acpu2vmcu0, mailbox_callback_from_acpu, TD_NULL);
    if (ret < 0) {
        printf("drv_mbx_register_irq_callback failed, ret:0x%x\n", ret);
        return;
    }
    ret = drv_mbx_open(EXT_MBX_TCPU2VMCU0_SSM);
    if (ret < 0) {
        printf("mailbox_open EXT_MBX_TCPU2VMCU0_SSM failed, ret:0x%x\n", ret);
        return;
    }
    g_handle_tcpu2vmcu0 = ret;
    ret = drv_mbx_register_irq_callback(g_handle_tcpu2vmcu0, mailbox_callback_from_tcpu, TD_NULL);
    if (ret < 0) {
        printf("drv_mbx_register_irq_callback failed, ret:0x%x\n", ret);
        return;
    }
}