index ad8ab1233b4277a58dae8504ffeee3b36f19f054..33425a113eff1d7ba4bebadc3b141bdf33b708bb 100644 (file)
/*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
/*
* ======== rpc_task.c ========
*
- * Example of setting up a 'RPC' service with the ServiceMgr, allowing clients
- * to instantiate the example RPC instance.
- *
+ * Example of how to integrate the MxServer module with the
+ * MmService manager.
*/
#include <xdc/std.h>
-#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
-#include <xdc/runtime/Diags.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ti/ipc/MultiProc.h>
-#include <ti/sysbios/BIOS.h>
-#include <ti/sysbios/knl/Task.h>
-
-#include <ti/grcm/RcmTypes.h>
#include <ti/grcm/RcmServer.h>
+#include <ti/ipc/mm/MmType.h>
+#include <ti/ipc/mm/MmServiceMgr.h>
+#include <ti/sysbios/hal/Cache.h>
+#include <ti/ipc/MultiProc.h>
-#include <ti/srvmgr/ServiceMgr.h>
-#include <ti/srvmgr/omaprpc/OmapRpc.h>
-#include <ti/srvmgr/rpmsg_omx.h>
-#include <ti/srvmgr/omx_packet.h>
-
-/* Turn on/off printf's */
-#define CHATTER 0
-
-#define RPC_MGR_PORT 59
-
-/* Legacy function to allow Linux side rpmsg sample tests to work: */
-extern void start_rpc_task();
+#include "MxServer.h"
-/*
- * OMX packet expected to have its data payload start with a payload of
- * this value. Need to export this properly in a meaningful header file on
- * both HLOS and RTOS sides
- */
-typedef enum {
- RPC_OMX_MAP_INFO_NONE = 0,
- RPC_OMX_MAP_INFO_ONE_BUF = 1,
- RPC_OMX_MAP_INFO_TWO_BUF = 2,
- RPC_OMX_MAP_INFO_THREE_BUF = 3,
- RPC_OMX_MAP_INFO_MAX = 0x7FFFFFFF
-} map_info_type;
+/* turn on/off printf's */
+#define CHATTER 1
-/*
- * ======== fxnTriple used by omx_benchmark test app ========
- */
typedef struct {
Int a;
-} FxnTripleArgs;
+ Int b;
+ Int c;
+} FxnAdd3Args;
-#define H264_DECODER_NAME "H264_decoder"
+typedef struct {
+ Int num;
+ Int *array;
+} FxnAddXArgs;
-#define OMX_VIDEO_THREAD_PRIORITY 5
-typedef UInt32 OMX_HANDLETYPE;
+#define SERVICE_NAME "rpc_example"
-static Int32 RPC_SKEL_Init(Void *, UInt32 size, UInt32 *data);
+/* MxServer skel function declarations */
static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data);
-static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data);
-static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data);
-static Int32 fxnTriple(UInt32 size, UInt32 *data);
-
-#if 0
-/* RcmServer static function table */
-static RcmServer_FxnDesc RPCServerFxnAry[] = {
- {"RPC_SKEL_Init", NULL}, /* filled in dynamically */
- {"RPC_SKEL_SetParameter", RPC_SKEL_SetParameter},
- {"RPC_SKEL_GetParameter", RPC_SKEL_GetParameter},
- {"fxnTriple", fxnTriple },
+static Int32 MxServer_skel_triple(UInt32 size, UInt32 *data);
+static Int32 MxServer_skel_add(UInt32 size, UInt32 *data);
+static Int32 fxnAdd3(UInt32 size, UInt32 *data);
+static Int32 fxnAddX(UInt32 size, UInt32 *data);
+static Int32 MxServer_skel_compute(UInt32 size, UInt32 *data);
+static Int32 fxnFault(UInt32 size, UInt32 *data);
+
+/* MxServer skel function array */
+static RcmServer_FxnDesc mxSkelAry[] = {
+ { "RPC_SKEL_Init2", RPC_SKEL_Init2 },
+ { "MxServer_triple", MxServer_skel_triple },
+ { "MxServer_add", MxServer_skel_add },
+ { "fxnAdd3", fxnAdd3 },
+ { "fxnAddX", fxnAddX },
+ { "MxServer_compute", MxServer_skel_compute },
+ { "fxnFault", fxnFault }
};
-#define RPCServerFxnAryLen (sizeof RPCServerFxnAry / sizeof RPCServerFxnAry[0])
-
-static const RcmServer_FxnDescAry RPCServer_fxnTab = {
- RPCServerFxnAryLen,
- RPCServerFxnAry
+/* MxServer skel function table */
+static const RcmServer_FxnDescAry rpc_fxnTab = {
+ (sizeof(mxSkelAry) / sizeof(mxSkelAry[0])),
+ mxSkelAry
};
-#endif
-#define RPC_SVR_NUM_FXNS 2
-OmapRpc_FuncDeclaration RPCServerFxns[RPC_SVR_NUM_FXNS] =
-{
- { RPC_SKEL_Init2,
- { "RPC_SKEL_Init2", 3,
- {
- {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
- {OmapRpc_Direction_In, OmapRpc_Param_U32, 1},
- {OmapRpc_Direction_In, OmapRpc_PtrType(OmapRpc_Param_U32), 1},
- },
- },
+static MmType_FxnSig rpc_sigAry[] = {
+ { "RPC_SKEL_Init2", 3,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_Param_U32, 1 },
+ { MmType_Dir_In, MmType_PtrType(MmType_Param_U32), 1 }
+ }
+ },
+ { "MxServer_triple", 2,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_Param_U32, 1 }
+ }
+ },
+ { "MxServer_add", 3,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_Param_S32, 1 },
+ { MmType_Dir_In, MmType_Param_S32, 1 }
+ }
+ },
+ { "fxnAdd3", 2,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_PtrType(MmType_Param_U32), 1 }
+ }
+ },
+ { "fxnAddX", 2,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_PtrType(MmType_Param_U32), 1 }
+ }
},
- { fxnTriple,
- { "fxnTriple", 2,
- {
- {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
- {OmapRpc_Direction_In, OmapRpc_Param_U32, 1}, // return
- },
- },
+ { "MxServer_compute", 2,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_PtrType(MmType_Param_VOID), 1 }
+ }
},
+ { "fxnFault", 2,
+ {
+ { MmType_Dir_Out, MmType_Param_S32, 1 }, /* return */
+ { MmType_Dir_In, MmType_PtrType(MmType_Param_U32), 1 }
+ }
+ }
};
-static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data)
+static MmType_FxnSigTab rpc_fxnSigTab = {
+ MmType_NumElem(rpc_sigAry), rpc_sigAry
+};
+
+/* the server create parameters, must be in persistent memory */
+static RcmServer_Params rpc_Params;
+
+
+Void RPC_SKEL_SrvDelNotification(Void)
{
-#if CHATTER
- System_printf("RPC_SKEL_SetParameter: Called\n");
-#endif
+ System_printf("RPC_SKEL_SrvDelNotification: Nothing to cleanup for "
+ "MmRpc instance id=%d\n", MmServiceMgr_getId());
+}
+static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data)
+{
+ System_printf("RPC_SKEL_Init2: size=0x%x data=0x%x\n", size, data);
return(0);
}
-static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data)
+/*
+ * ======== MxServer_skel_triple ========
+ */
+Int32 MxServer_skel_triple(UInt32 size, UInt32 *data)
{
+ MmType_Param *payload = (MmType_Param *)data;
+ UInt32 a;
+ Int32 result;
+
+ a = (UInt32)payload[0].data;
+ result = MxServer_triple(a);
+
#if CHATTER
- System_printf("RPC_SKEL_GetParameter: Called\n");
+ System_printf("fxnTriple: a=%d, result=%d\n", a, result);
#endif
- return(0);
+ return(result);
}
-Void RPC_SKEL_SrvDelNotification()
+/*
+ * ======== MxServer_skel_add ========
+ */
+Int32 MxServer_skel_add(UInt32 size, UInt32 *data)
{
- System_printf("RPC_SKEL_SrvDelNotification: Nothing to cleanup\n");
-}
+ MmType_Param *payload = (MmType_Param *)data;
+ Int32 a, b;
+ Int32 result;
-#define CALLBACK_DATA "OMX_Callback"
-#define PAYLOAD_SIZE sizeof(CALLBACK_DATA)
-#define CALLBACK_DATA_SIZE (HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE)
+ a = (Int32)payload[0].data;
+ b = (Int32)payload[1].data;
-static Int32 RPC_SKEL_Init(Void *srvc, UInt32 size, UInt32 *data)
-{
- char cComponentName[128] = {0};
- OMX_HANDLETYPE hComp;
- Char cb_data[HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE] = {0};
+ result = MxServer_add(a, b);
+
+#if CHATTER
+ System_printf("fxnAdd: a=%d, b=%d, result=%d\n", a, b, result);
+#endif
- /*
- * Note: Currently, rpmsg_omx linux driver expects an omx_msg_hdr in front
- * of the omx_packet data, so we allow space for this:
- */
- struct omx_msg_hdr * hdr = (struct omx_msg_hdr *)cb_data;
- struct omx_packet * packet = (struct omx_packet *)hdr->data;
+ return(result);
+}
+
+/*
+ * ======== fxnAdd3 ========
+ */
+Int32 fxnAdd3(UInt32 size, UInt32 *data)
+{
+ MmType_Param *payload = (MmType_Param *)data;
+ FxnAdd3Args *args;
+ Int a, b, c;
+ args = (FxnAdd3Args *)payload[0].data;
- //Marshalled:[>offset(cParameterName)|>pAppData|>offset(RcmServerName)|>pid|
- //>--cComponentName--|>--CallingCorercmServerName--|
- //<hComp]
+ Cache_inv (args, sizeof(FxnAdd3Args), Cache_Type_ALL, TRUE);
- strcpy(cComponentName, (char *)data + sizeof(map_info_type));
+ a = args->a;
+ b = args->b;
+ c = args->c;
#if CHATTER
- System_printf("RPC_SKEL_GetHandle: Component Name received: %s\n",
- cComponentName);
+ System_printf("fxnAdd3: a=%d, b=%d, c=%d\n", a, b, c);
#endif
- /* Simulate sending an async OMX callback message, passing an omx_packet
- * structure.
- */
- packet->msg_id = 99; // Set to indicate callback instance, buffer id, etc.
- packet->fxn_idx = 5; // Set to indicate callback fxn
- packet->data_size = PAYLOAD_SIZE;
- strcpy((char *)packet->data, CALLBACK_DATA);
+ return(a + b + c);
+}
-#if CHATTER
- System_printf("RPC_SKEL_GetHandle: Sending callback message id: %d, "
- "fxn_id: %d, data: %s\n",
- packet->msg_id, packet->fxn_idx, packet->data);
-#endif
- ServiceMgr_send(srvc, cb_data, CALLBACK_DATA_SIZE);
+/*
+ * ======== fxnAddX ========
+ */
+Int32 fxnAddX(UInt32 size, UInt32 *data)
+{
+ MmType_Param *payload = (MmType_Param *)data;
+ FxnAddXArgs *args;
+ Int num, i, sum = 0;
+ Int *array;
+
+ args = (FxnAddXArgs *)payload[0].data;
+
+ Cache_inv (args, sizeof(FxnAddXArgs), Cache_Type_ALL, TRUE);
- /* Call OMX_Get_Handle() and return handle for future calls. */
- //eCompReturn = OMX_GetHandle(&hComp, (OMX_STRING)&cComponentName[0], pAppData,&rpcCallBackInfo);
- hComp = 0x5C0FFEE5;
- data[0] = hComp;
+ num = args->num;
+ array = args->array;
+ Cache_inv (array, sizeof(Int) * num, Cache_Type_ALL, TRUE);
+
+#if CHATTER
+ System_printf("fxnAddX: ");
+#endif
+ for (i = 0; i < num; i++) {
#if CHATTER
- System_printf("RPC_SKEL_GetHandle: returning hComp: 0x%x\n", hComp);
+ System_printf(" a[%d]=%d,", i, array[i]);
#endif
+ sum += array[i];
+ }
- return(0);
-}
+#if CHATTER
+ System_printf(" sum=%d\n", sum);
+#endif
-static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data)
-{
- System_printf("RPC_SKEL_Init2: size = 0x%x data = 0x%x\n", size,
- (UInt32)data);
+ return(sum);
}
/*
- * ======== fxnTriple ========
+ * ======== MxServer_skel_compute ========
*/
-Int32 fxnTriple(UInt32 size, UInt32 *data)
+Int32 MxServer_skel_compute(UInt32 size, UInt32 *data)
{
- FxnTripleArgs *args;
- Int a;
+ MmType_Param *payload;
+ MxServer_Compute *compute;
+ Int32 result = 0;
+
+ payload = (MmType_Param *)data;
+ compute = (MxServer_Compute *)payload[0].data;
+
+ Cache_inv(compute, sizeof(MxServer_Compute), Cache_Type_ALL, TRUE);
#if CHATTER
- System_printf("fxnTriple: Executing fxnTriple \n");
+ System_printf("skel_compute: compute=0x%x\n", compute);
+ System_printf("skel_compute: compute size=%d\n", (Int)payload[0].size);
+ System_printf("skel_compute: coef=0x%x\n", compute->coef);
+ System_printf("skel_compute: key=0x%x\n", compute->key);
+ System_printf("skel_compute: size=0x%x\n", compute->size);
+ System_printf("skel_compute: inBuf=0x%x\n", compute->inBuf);
+ System_printf("skel_compute: outBuf=0x%x\n", compute->outBuf);
#endif
- args = (FxnTripleArgs *)((UInt32)data + sizeof(map_info_type));
- a = args->a;
+ Cache_inv(compute->inBuf, compute->size * sizeof(uint32_t),
+ Cache_Type_ALL, TRUE);
+ Cache_inv(compute->outBuf, compute->size * sizeof(uint32_t),
+ Cache_Type_ALL, TRUE);
+
+#if CHATTER
+ System_printf("skel_compute: outBuf[0]=0x%x\n", compute->outBuf[0]);
+ System_printf("skel_compute: inBuf[0]=0x%x\n", compute->inBuf[0]);
+#endif
+
+ /* invoke the implementation function */
+ result = MxServer_compute(compute);
+
+ Cache_wbInv(compute->outBuf, compute->size * sizeof(uint32_t),
+ Cache_Type_ALL, TRUE);
- return a * 3;
+ return(result);
}
-Void start_rpc_task()
+/*
+ * ======== fxnAddX ========
+ */
+Int32 fxnFault(UInt32 size, UInt32 *data)
{
- /* Init service manager */
- System_printf("%s initializing OMAPRPC based service manager endpoint\n",
- MultiProc_getName(MultiProc_self()));
+ MmType_Param *payload = (MmType_Param *)data;
+ Int a;
+ typedef Int (*MyCode)();
+ MyCode fxn = (MyCode)0x96000000;
+ volatile Int dummy = 0;
+
+ a = (UInt32)payload[0].data;
+
+ switch (a) {
+ case 1:
+ System_printf("Generating read MMU Fault...\n");
+ a = *(volatile int *)(0x96000000);
+ break;
+ case 2:
+ System_printf("Generating write MMU Fault...\n");
+ *(volatile int *)(0x96000000) = 0x1;
+ break;
+ case 3:
+ System_printf("Generating program MMU Fault...\n");
+ fxn();
+ break;
+ case 4:
+ System_printf("Generating exception...\n");
+ dummy = dummy / dummy;
+ break;
+ case 5:
+ System_printf("Generating Watchdog interrupt...\n");
+ dummy = 1;
+ while(dummy);
+ break;
+ default:
+ System_printf("Invalid fxnFault test\n");
+ break;
+ }
+
+ return(0);
+}
- OmapRpc_createChannel("rpc_example", MultiProc_getId("HOST"),
- RPC_MGR_PORT, RPC_SVR_NUM_FXNS, RPCServerFxns,
- (OmapRpc_SrvDelNotifyFxn)RPC_SKEL_SrvDelNotification);
+/*
+ * ======== register_MxServer ========
+ *
+ * Bootstrap function, must be configured in BIOS.addUserStartupFunctions.
+ */
+void register_MxServer(void)
+{
+ Int status = MmServiceMgr_S_SUCCESS;
+ Char mMServerName[20];
+
+ System_printf("register_MxServer: -->\n");
+
+ /* must initialize these modules before using them */
+ RcmServer_init();
+ MmServiceMgr_init();
+
+ /* setup the server create params */
+ RcmServer_Params_init(&rpc_Params);
+ rpc_Params.priority = Thread_Priority_ABOVE_NORMAL;
+ rpc_Params.stackSize = 0x1000;
+ rpc_Params.fxns.length = rpc_fxnTab.length;
+ rpc_Params.fxns.elem = rpc_fxnTab.elem;
+
+ /* Construct an MMServiceMgr name adorned with core name: */
+ System_sprintf(mMServerName, "%s_%d", SERVICE_NAME,
+ MultiProc_self());
+
+ /* register an example service */
+ status = MmServiceMgr_register(mMServerName, &rpc_Params, &rpc_fxnSigTab,
+ RPC_SKEL_SrvDelNotification);
+
+ if (status < 0) {
+ System_printf("register_MxServer: MmServiceMgr_register failed, "
+ "status=%d\n", status);
+ status = -1;
+ goto leave;
+ }
+
+leave:
+ System_printf("register_MxServer: <--, status=%d\n", status);
}