diff --git a/qnx/src/ipc3x_dev/ti/syslink/rpmsg-rpc/rpmsg-rpc.c b/qnx/src/ipc3x_dev/ti/syslink/rpmsg-rpc/rpmsg-rpc.c
index 74ec0a5c275750e19aa727604202f97c79537915..19403fcc4a2410923fd8aa7049355cb56f500a4a 100644 (file)
/*
- * @file rpmsg-rpc.c
- *
- * @brief devctl handler for RPC component.
- *
- * ============================================================================
- *
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * Contact information for paper mail:
- * Texas Instruments
- * Post Office Box 655303
- * Dallas, Texas 75265
- * Contact information:
- * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
- * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
- * ============================================================================
- *
*/
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <sys/netmgr.h>
+#include <sys/mman.h>
#include <devctl.h>
/* Module headers */
-//#include <ti/ipc/omap_rpc.h>
+#include <ti/syslink/ProcMgr.h>
#include <ti/ipc/rpmsg_rpc.h>
#include <ti/ipc/MessageQCopy.h>
#include <_MessageQCopy.h>
#include "std_qnx.h"
#include <pthread.h>
-#include <memmgr/tilermem.h>
-#include <memmgr/tiler.h>
-
#include "rpmsg-rpc.h"
#include <rpmsg.h>
UInt16 procId;
ProcMgr_Handle procH;
UInt32 numFuncs;
+ Bool destroy;
} rpmsg_rpc_conn_object;
/*!
/*!< Process Identifier for user process. */
} rpmsg_rpc_EventCbck ;
+/*!
+ * @brief Structure of Fxn Info for reverse translations.
+ */
+typedef struct rpmsg_rpc_FxnInfo_tag {
+ List_Elem element;
+ /*!< List element header */
+ UInt16 msgId;
+ /*!< Unique msgId of the rpc fxn call */
+ struct rppc_function func;
+ /*!< rpc function information. */
+} rpmsg_rpc_FxnInfo ;
+
/*!
* @brief Keeps the information related to Event.
*/
typedef struct rpmsg_rpc_EventState_tag {
List_Handle bufList;
/*!< Head of received event list. */
+ List_Handle fxnList;
+ /*!< Head of received msg list. */
UInt32 pid;
/*!< User process ID. */
rpmsg_rpc_object * rpc;
return;
}
+/** ============================================================================
+ * Function Prototypes
+ * ============================================================================
+ */
+int
+_rpmsg_rpc_translate (ProcMgr_Handle handle, char *data, pid_t pid,
+ bool reverse);
/** ============================================================================
* Globals
.run = 0
};
+static uint16_t msg_id = 0xFFFF;
+
extern dispatch_t * syslink_dpp;
@@ -662,7 +669,7 @@ _rpmsg_rpc_create(resmgr_context_t *ctp, io_devctl_t *msg, rpmsg_rpc_ocb_t *ocb)
{
Int status = EOK;
struct rppc_create_instance * cargs =
- (struct rppc_create_instance *)(_DEVCTL_DATA (msg->i));
+ (struct rppc_create_instance *)(_DEVCTL_DATA (msg->i));
struct rppc_msg_header * msg_hdr = NULL;
rpmsg_rpc_object * rpc = ocb->rpc;
Char * msg_data = NULL;
GT_0trace(curTrace, GT_4CLASS, "Already destroyed.");
status = (EINVAL);
}
- else {
+ else if (!rpc->conn->destroy) {
hdr = (struct rppc_msg_header *)buf;
hdr->msg_type = RPPC_MSG_DESTROY_INSTANCE;
hdr->msg_len = sizeof(struct rppc_instance_handle);
}
}
}
+ else {
+ /* This is the shutdown, remote proc has already been stopped,
+ * so just set created to false. */
+ rpc->created = FALSE;
+ }
return status;
}
Bool flag = FALSE;
Bool isInit = FALSE;
List_Object * bufList = NULL;
+ List_Object * fxnList = NULL;
IArg key = 0;
List_Params listparams;
UInt32 i;
if (isInit == FALSE) {
List_Params_init (&listparams);
bufList = List_create (&listparams) ;
+ fxnList = List_create (&listparams) ;
/* Search for an available slot for user process. */
for (i = 0 ; i < MAX_PROCESSES ; i++) {
if (rpmsg_rpc_state.eventState [i].rpc == NULL) {
rpmsg_rpc_state.eventState [i].rpc = rpc;
rpmsg_rpc_state.eventState [i].refCount = 1;
rpmsg_rpc_state.eventState [i].bufList = bufList;
+ rpmsg_rpc_state.eventState [i].fxnList = fxnList;
flag = TRUE;
break;
}
if (bufList != NULL) {
List_delete (&bufList);
}
+ if (fxnList != NULL) {
+ List_delete (&fxnList);
+ }
}
}
IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
- GT_1trace (curTrace, GT_LEAVE, "rpmsgDrv_attach", status);
+ GT_1trace (curTrace, GT_LEAVE, "_rpmsg_rpc_attach", status);
/*! @retval Notify_S_SUCCESS Operation successfully completed. */
return status ;
_rpmsg_rpc_addBufByPid (rpmsg_rpc_object *rpc,
UInt32 src,
UInt32 pid,
+ UInt16 msgId,
void * data,
UInt32 len)
{
UInt32 i;
WaitingReaders_t *item;
MsgList_t *msgItem;
+ List_Elem * elem = NULL;
+ List_Elem * temp = NULL;
GT_5trace (curTrace,
GT_ENTER,
}
else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ key = IGateProvider_enter (rpmsg_rpc_state.gateHandle);
+ List_traverse_safe(elem, temp, rpmsg_rpc_state.eventState [i].fxnList) {
+ if (((rpmsg_rpc_FxnInfo *)elem)->msgId == msgId) {
+ List_remove(rpmsg_rpc_state.eventState [i].fxnList, elem);
+ break;
+ }
+ }
+ IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
+
+ if (elem != (List_Elem *)rpmsg_rpc_state.eventState [i].fxnList) {
+ struct rppc_function * function;
+ function = &(((rpmsg_rpc_FxnInfo *)elem)->func);
+ _rpmsg_rpc_translate(NULL, (char *)function, pid, true);
+ Memory_free(NULL, elem, sizeof(rpmsg_rpc_FxnInfo) +\
+ RPPC_TRANS_SIZE(function->num_translations));
+ }
+
List_elemClear (&(uBuf->element));
GT_assert (curTrace,
(rpmsg_rpc_state.eventState [i].bufList != NULL));
_rpmsg_rpc_addBufByPid (rpc,
src,
rpc->pid,
+ packet->msg_id,
&packet->fxn_id,
sizeof(packet->fxn_id) + sizeof(packet->result));
#if !defined(SYSLINK_BUILD_OPTIMIZE)
Int32 tmpStatus = EOK;
Bool flag = FALSE;
List_Object * bufList = NULL;
+ List_Object * fxnList = NULL;
UInt32 i;
IArg key;
MsgList_t * item;
rpmsg_rpc_state.eventState [i].bufList = NULL;
+ /* Store in local variable to delete outside lock. */
+ fxnList = rpmsg_rpc_state.eventState [i].fxnList;
+
+ rpmsg_rpc_state.eventState [i].fxnList = NULL;
+
IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
}
/* Last client being unregistered with Notify module. */
List_delete (&bufList);
}
+ if (fxnList != NULL) {
+ key = IGateProvider_enter (rpmsg_rpc_state.gateHandle);
+ rpmsg_rpc_FxnInfo * fxnInfo = NULL;
+ while ((fxnInfo = (rpmsg_rpc_FxnInfo *)List_dequeue (fxnList))) {
+ Memory_free (NULL, fxnInfo, sizeof(rpmsg_rpc_FxnInfo) +\
+ RPPC_TRANS_SIZE(fxnInfo->func.num_translations));
+ }
+ IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
+ List_delete (&fxnList);
+ }
#if !defined(SYSLINK_BUILD_OPTIMIZE)
if ((tmpStatus < 0) && (status >= 0)) {
Int status = 0;
uint32_t da;
- if (pa >= TILER_MEM_8BIT && pa < TILER_MEM_END) {
- return pa;
+ status = ProcMgr_translateAddr(handle, (Ptr *)&da,
+ ProcMgr_AddrType_SlaveVirt,
+ (Ptr)pa, ProcMgr_AddrType_MasterPhys);
+ if (status >= 0) {
+ return da;
}
else {
- status = ProcMgr_translateAddr(handle, (Ptr *)&da,
- ProcMgr_AddrType_SlaveVirt,
- (Ptr)pa, ProcMgr_AddrType_MasterPhys);
- if (status >= 0)
- return da;
- else
- return 0;
+ return 0;
}
}
int
-_rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, uint32_t bytes, pid_t pid)
+_rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, pid_t pid, bool reverse)
{
int status = EOK;
struct rppc_function * function = NULL;
@@ -1642,7 +1694,7 @@ _rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, uint32_t bytes, pid_t pi
if (!vptr[idx]) {
/* get the physical address of ptr */
status = mem_offset64_peer(pid,
- function->params[idx].data,
+ reverse ? function->params[idx].base : function->params[idx].data,
function->params[idx].size,
&paddr[idx], &phys_len);
if (status >= 0 && phys_len == function->params[idx].size) {
@@ -1650,7 +1702,8 @@ _rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, uint32_t bytes, pid_t pi
vptr[idx] = mmap64(NULL, function->params[idx].size,
PROT_NOCACHE | PROT_READ | PROT_WRITE,
MAP_PHYS, NOFD, paddr[idx]);
- if (vptr == MAP_FAILED) {
+ if (vptr[idx] == MAP_FAILED) {
+ vptr[idx] = 0;
status = -ENOMEM;
break;
}
@@ -1662,26 +1715,33 @@ _rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, uint32_t bytes, pid_t pi
}
/* Get physical address of the contents */
ptr = (uint32_t)vptr[idx] + translation[i].offset;
- status = mem_offset64_peer(pid, *(uint32_t *)ptr, sizeof(uint32_t),
- &phys_addr, &phys_len);
- if (status >= 0 && phys_len == sizeof(uint32_t)) {
- /* translate pa2da */
- if ((ipu_addr =
- _rpmsg_rpc_pa2da(handle, (uint32_t)phys_addr)) != 0)
- /* update vptr contents */
- *(uint32_t *)ptr = ipu_addr;
+ if (reverse) {
+ *(uint32_t *)ptr = translation[i].base;
+ }
+ else {
+ translation[i].base = *(uint32_t *)ptr;
+ status = mem_offset64_peer(pid, *(uint32_t *)ptr, sizeof(uint32_t),
+ &phys_addr, &phys_len);
+ if (status >= 0 && phys_len == sizeof(uint32_t)) {
+ /* translate pa2da */
+ if ((ipu_addr =
+ _rpmsg_rpc_pa2da(handle, (uint32_t)phys_addr)) != 0)
+ /* update vptr contents */
+ *(uint32_t *)ptr = ipu_addr;
+ else {
+ status = -EINVAL;
+ break;
+ }
+ }
else {
status = -EINVAL;
break;
}
}
- else {
- status = -EINVAL;
- break;
- }
}
- for (i = 0; i < function->num_params && status >= 0; i++) {
+ /* No need to do this for reverse translations */
+ for (i = 0; i < function->num_params && status >= 0 && !reverse; i++) {
if (function->params[i].type == RPPC_PARAM_TYPE_PTR) {
if (paddr[i]) {
phys_addr = paddr[i];
@@ -1690,12 +1750,15 @@ _rpmsg_rpc_translate(ProcMgr_Handle handle, char *data, uint32_t bytes, pid_t pi
/* translate the param pointer */
status = mem_offset64_peer(pid,
(uintptr_t)(function->params[i].data),
- function->params[i].size, &phys_addr, &phys_len);
+ function->params[i].size, &phys_addr,
+ &phys_len);
}
if (status >= 0) {
if ((ipu_addr =
- _rpmsg_rpc_pa2da(handle, (uint32_t)phys_addr)) != 0)
+ _rpmsg_rpc_pa2da(handle, (uint32_t)phys_addr)) != 0) {
+ function->params[i].base = function->params[i].data;
function->params[i].data = ipu_addr;
+ }
else {
status = -EINVAL;
break;
struct rppc_function *function = NULL;
char usr_msg[MessageQCopy_BUFSIZE];
int i = 0;
+ rpmsg_rpc_EventState * event_state = NULL;
+ rpmsg_rpc_FxnInfo * fxn_info = NULL;
+ IArg key = 0;
if ((status = iofunc_write_verify(ctp, msg, io_ocb, NULL)) != EOK) {
return (status);
@@ -1760,6 +1826,16 @@ rpmsg_rpc_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *io_ocb)
}
_IO_SET_WRITE_NBYTES (ctp, bytes);
+ for (i = 0 ; i < MAX_PROCESSES ; i++) {
+ if (rpmsg_rpc_state.eventState [i].rpc == rpc) {
+ break;
+ }
+ }
+ if (i == MAX_PROCESSES) {
+ return EINVAL;
+ }
+ event_state = &rpmsg_rpc_state.eventState[i];
+
msg_hdr = (struct rppc_msg_header *)buf;
packet = (struct rppc_packet *)((UInt32)msg_hdr + sizeof(struct rppc_msg_header));
}
function = (struct rppc_function *)usr_msg;
- if (bytes < sizeof(struct rppc_function) +
- (function->num_translations * \
- sizeof(struct rppc_param_translation))) {
+ if (bytes < RPPC_PARAM_SIZE(function->num_translations)) {
return (EINVAL);
}
@@ -1783,9 +1857,19 @@ rpmsg_rpc_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *io_ocb)
return (EINVAL);
}
- status = _rpmsg_rpc_translate(rpc->conn->procH, (char *)function, bytes,
- ctp->info.pid);
+ /* store the fxn info for use with reverse translation */
+ fxn_info = Memory_alloc (NULL, sizeof(rpmsg_rpc_FxnInfo) +\
+ RPPC_TRANS_SIZE(function->num_translations),
+ 0, NULL);
+ List_elemClear(&(fxn_info->element));
+ Memory_copy (&(fxn_info->func), function,
+ RPPC_PARAM_SIZE(function->num_translations));
+
+ status = _rpmsg_rpc_translate(rpc->conn->procH, (char *)&(fxn_info->func),
+ ctp->info.pid, false);
if (status < 0) {
+ Memory_free(NULL, fxn_info, sizeof(rpmsg_rpc_FxnInfo) +\
+ RPPC_TRANS_SIZE(function->num_translations));
return -status;
}
/* initialize the packet structure */
packet->desc = RPPC_DESC_EXEC_SYNC;
- packet->msg_id = 0;
+ packet->msg_id = msg_id == 0xFFFF ? msg_id = 1 : ++(msg_id);
packet->flags = (0x8000);//OMAPRPC_POOLID_DEFAULT;
packet->fxn_id = RPPC_SET_FXN_IDX(function->fxn_id);
packet->result = 0;
@@ -1802,15 +1886,26 @@ rpmsg_rpc_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *io_ocb)
for (i = 0; i < function->num_params; i++) {
((UInt32 *)(packet->data))[i*2] = function->params[i].size;
- ((UInt32 *)(packet->data))[(i*2)+1] = function->params[i].data;
+ ((UInt32 *)(packet->data))[(i*2)+1] = fxn_info->func.params[i].data;
packet->data_size += (sizeof(UInt32) * 2);
}
msg_hdr->msg_len += packet->data_size;
+ fxn_info->msgId = packet->msg_id;
+ key = IGateProvider_enter (rpmsg_rpc_state.gateHandle);
+ List_enqueue(event_state->fxnList, &(fxn_info->element));
+ IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
+
status = MessageQCopy_send(rpc->conn->procId, MultiProc_self(),
- rpc->remoteAddr, rpc->addr, buf,
- msg_hdr->msg_len + sizeof(struct rppc_msg_header), TRUE);
+ rpc->remoteAddr, rpc->addr, buf,
+ msg_hdr->msg_len + sizeof(struct rppc_msg_header),
+ TRUE);
if (status < 0) {
+ key = IGateProvider_enter (rpmsg_rpc_state.gateHandle);
+ List_remove(event_state->fxnList, &(fxn_info->element));
+ IGateProvider_leave (rpmsg_rpc_state.gateHandle, key);
+ Memory_free(NULL, fxn_info, sizeof(rpmsg_rpc_FxnInfo) +\
+ RPPC_TRANS_SIZE(function->num_translations));
return (EIO);
}
WaitingReaders_t * wr = NULL;
struct _msg_info info;
- GT_0trace (curTrace, GT_ENTER, "_rpmsg_rpc_destroy");
+ GT_0trace (curTrace, GT_ENTER, "rpmsg_rpc_destroy");
for (i = 0; i < MAX_CONNS; i++) {
if (rpmsg_rpc_state.objects[i]) {
rpmsg_rpc_conn_object * obj = rpmsg_rpc_state.objects[i];
+ obj->destroy = TRUE;
_deinit_rpmsg_rpc_device(obj->dev);
ProcMgr_close(&obj->procH);
Memory_free(NULL, obj, sizeof(rpmsg_rpc_conn_object));