/* * Copyright 2020, Data61 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) * ABN 41 687 119 230. * * This software may be distributed and modified according to the terms of * the BSD 2-Clause license. Note that NO WARRANTY is provided. * See "LICENSE_BSD2.txt" for details. * * @TAG(DATA61_BSD) */ #include #include #include #include typedef struct bpmpserver_interface_data { void *bpmpserver_shared_mem; int (*bpmpserver_call)(int mrq, size_t tx_size, size_t *bytes_rxd); size_t shared_mem_size; } bpmpserver_interface_data_t; static bpmpserver_interface_data_t bpmpserver_private_data; static int bpmpserver_call_wrapper(void *data, int mrq, void *tx_msg, size_t tx_size, void *rx_msg, size_t rx_size) { if (!tx_msg) { ZF_LOGE("tx_msg is NULL!"); return -EINVAL; } bpmpserver_interface_data_t *bpmpserver_data = data; if (tx_size >= bpmpserver_data->shared_mem_size) { ZF_LOGE("Supplied buffer is too large!"); return -EINVAL; } /* Clean up the shared memory buffer */ memset(bpmpserver_data->bpmpserver_shared_mem, 0, bpmpserver_data->shared_mem_size); /* Copy the tx_msg contents into the shared memory buffer, the buffers * shouldn't overlap so memcpy should be safe */ memcpy(bpmpserver_data->bpmpserver_shared_mem, tx_msg, tx_size); size_t bytes_received = 0; int ret = bpmpserver_data->bpmpserver_call(mrq, tx_size, &bytes_received); if (ret >= 0 && rx_msg) { /* Copy the contents of the shared memory region (response from BPMP) * into the rx buffer */ if (bytes_received > rx_size) { ZF_LOGW("Response received is larger than the buffer supplied"); } memcpy(rx_msg, bpmpserver_data->bpmpserver_shared_mem, bytes_received); /* No error, return the amount of bytes received */ return bytes_received; } /* Encountered an error so we return the error code */ return ret; } int bpmpserver_interface_init(void *bpmpserver_shared_mem, size_t shared_mem_size, int (*bpmpserver_call)(int mrq, size_t tx_size, size_t *bytes_rxd), struct tx2_bpmp *bpmp) { if (!bpmpserver_shared_mem) { ZF_LOGE("bpmpserver_shared_mem is NULL"); return -EINVAL; } if (!bpmpserver_call) { ZF_LOGE("bpmpserver_call is NULL"); return -EINVAL; } if (!bpmp) { ZF_LOGE("bpmp is NULL"); return -EINVAL; } /* Setup the private data */ bpmpserver_private_data.bpmpserver_shared_mem = bpmpserver_shared_mem; bpmpserver_private_data.bpmpserver_call = bpmpserver_call; bpmpserver_private_data.shared_mem_size = shared_mem_size; /* Setup the function pointer */ bpmp->call = bpmpserver_call_wrapper; bpmp->data = &bpmpserver_private_data; return 0; }