initial release
[apps/tidep0074.git] / host / App.c
1 /*
2  * Copyright (c) 2013-2014, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
33 /*
34  *  ======== App.c ========
35  *
36  */
38 /* host header files */
39 #include <stdio.h>
40 #include <unistd.h>
41 #include <string.h>
43 /* package header files */
44 #include <ti/ipc/Std.h>
45 #include <ti/ipc/MessageQ.h>
46 #include <ti/cmem.h>
48 /* local header files */
49 #include "../shared/AppCommon.h"
50 #include "App.h"
52 #include <time.h>
54 /* module structure */
55 typedef struct {
56         MessageQ_Handle         hostQue;    // created locally
57         MessageQ_QueueId        slaveQue;   // opened remotely
58         UInt16                  heapId;     // MessageQ heapId
59         UInt32                  msgSize;
60 } App_Module;
62 /* private data */
63 static App_Module Module;
66 typedef struct  bufmgrDesc_s {
67         UInt32 physAddr;            /* physical address */
68         char *userAddr;             /* Host user space Virtual address */
69         UInt32 length;              /* Length of host buffer */
71 } bufmgrDesc_t;
74 #define MAX_TEST_MSG_NUM  256
76 #define TEST_PORT 0
77 #define MAX_MII_PORTS_NUM 3
78 #define MAX_PACKET_FRAME_SIZE 1536 
80 //#define GOOSE_FILTER_DISABLE
81 #define GOOSE_PARA_LEN 1024
83 /* testing packets from host if needed */
84 #define TEST_PKT_SIZE       64
85 static const char test_pkt[2][TEST_PKT_SIZE] = {
86         {
87                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* broadcast mac */
88                 0x01, 0x55, 0x55, 0x55, 0x55, 0x55,
89                 0x08, 0x06, 0x00, 0x01,
90                 0x08, 0x00, 0x06, 0x04, 0x00,0x01,
91                 0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
92                 0xc0, 0xa8, 0x01, 0x16,
93                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94                 0xc0, 0xa8,0x01, 0x02
95         },
96         {
97                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* broadcast mac */
98                 0x01, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
99                 0x08, 0x06, 0x00, 0x01,
100                 0x08, 0x00, 0x06, 0x04, 0x00,0x01,
101                 0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
102                 0xc0, 0xa8, 0x01, 0x16,
103                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104                 0xc0, 0xa8,0x01, 0x02
105         }
106 };
108 CMEM_AllocParams  alloc_params;
109 bufmgrDesc_t  cmem_buf_desc;
111 bufmgrDesc_t  RxPacketBuf[MAX_MII_PORTS_NUM][2];
112 bufmgrDesc_t  TxPacketBuf[MAX_MII_PORTS_NUM][2];
113 bufmgrDesc_t  GoosePara;
115 char *pGoosePara;
117 /*
118  *  ======== parse /etc/goose if available for filtering parameters ========
119  */
120 Void Read_Goose_para()
122         FILE *fp;
123         unsigned int gooseFlag;
124         unsigned char destMacAddr[4][6];
125         unsigned short appId[4];
126         int i;
129         fp = fopen("/etc/goose", "r");
130         if(fp == NULL) {
131                 printf("/etc/goose doesn't exsit," 
132                                 "use default goose parameters\n");
133                 return;
134         }
136         fscanf(fp, "%x", &gooseFlag);
138         pGoosePara = GoosePara.userAddr;
139         memcpy(pGoosePara, &gooseFlag, 4);
141         for (i=0; i<4; i++)
142                 fscanf(fp, "%x %x %x %x %x %x", 
143                                 (unsigned int *)&destMacAddr[i][0],
144                                 (unsigned int *)&destMacAddr[i][1],
145                                 (unsigned int *)&destMacAddr[i][2],
146                                 (unsigned int *)&destMacAddr[i][3],
147                                 (unsigned int *)&destMacAddr[i][4],
148                                 (unsigned int *)&destMacAddr[i][5]);
149         memcpy(pGoosePara + 4, &destMacAddr[0][0], 24);
151         fscanf(fp, "%x %x %x %x", (unsigned int *)&appId[0],
152                         (unsigned int *)&appId[1],
153                         (unsigned int *)&appId[2],
154                         (unsigned int *)&appId[3]);
156         memcpy(pGoosePara + 28, &appId[0], 16);
158         printf("GooseFlag = 0x%x\n", *(unsigned int *)pGoosePara);
160         for(i=0; i<4; i++)
161                 printf("Goose destMacAddr[%d] =" 
162                                 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", i, 
163                                 *(pGoosePara + i*6 + 4),
164                                 *(pGoosePara + i*6 + 5),
165                                 *(pGoosePara + i*6 + 6),
166                                 *(pGoosePara + i*6 + 7),
167                                 *(pGoosePara + i*6 + 8),
168                                 *(pGoosePara + i*6 + 9));
170         printf("Goose AppID = 0x%x 0x%x 0x%x 0x%x\n", 
171                         *(unsigned short *)(pGoosePara + 28),
172                         *(unsigned short *)(pGoosePara + 30),
173                         *(unsigned short *)(pGoosePara + 32),
174                         *(unsigned short *)(pGoosePara + 34));
175         fclose(fp);                                             
178 /*
179  *  ======== initialize CMEM buffers ========
180  */
181 Void initCmemBufs()
183         CMEM_AllocParams  alloc_params;
184         Int i;
186         printf("--->App_Create: CMEM_allocPhys and map\n");
187         alloc_params.flags = CMEM_NONCACHED;
188         alloc_params.type = CMEM_POOL;
189         alloc_params.alignment = 0;
190         if(CMEM_init() != 0)
191                 printf("--->App_Create: ERROR: CMEM_init()\n");
193         cmem_buf_desc.physAddr = CMEM_allocPhys(4 * MAX_MII_PORTS_NUM * 
194                         MAX_PACKET_FRAME_SIZE + GOOSE_PARA_LEN, &alloc_params);
196         if(cmem_buf_desc.physAddr == 0 )
197                 printf("--->App_Create: ERROR: CMEM_allocPhys()\n");
198         else
199                 printf("--->App_Create: cmem_buf_desc.physAddr = 0x%x\n", 
200                                 cmem_buf_desc.physAddr);
202         cmem_buf_desc.length = 4 * MAX_MII_PORTS_NUM * MAX_PACKET_FRAME_SIZE + 
203                 GOOSE_PARA_LEN;
205         cmem_buf_desc.userAddr = CMEM_map((UInt32)cmem_buf_desc.physAddr, 
206                         cmem_buf_desc.length);
207         if(cmem_buf_desc.userAddr == NULL)
208                 printf("--->App_Create: ERROR: CMEM_map()\n");
210         for (i = 0; i < MAX_MII_PORTS_NUM; i++)
211         { 
212                 RxPacketBuf[i][0].length = MAX_PACKET_FRAME_SIZE;
213                 RxPacketBuf[i][0].userAddr = 
214                         (char *)((UInt32)(cmem_buf_desc.userAddr + 
215                                                 (i*4+0)*MAX_PACKET_FRAME_SIZE));
217                 RxPacketBuf[i][0].physAddr = (UInt32)((cmem_buf_desc.physAddr +
218                                         (i*4+0)*MAX_PACKET_FRAME_SIZE));
220                 RxPacketBuf[i][1].length = MAX_PACKET_FRAME_SIZE;
221                 RxPacketBuf[i][1].userAddr = 
222                         (char *)((UInt32)(cmem_buf_desc.userAddr + 
223                                                 (i*4+1)*MAX_PACKET_FRAME_SIZE));
225                 RxPacketBuf[i][1].physAddr = (UInt32)((cmem_buf_desc.physAddr +
226                                         (i*4+1)*MAX_PACKET_FRAME_SIZE));
228                 TxPacketBuf[i][0].length = MAX_PACKET_FRAME_SIZE;
229                 TxPacketBuf[i][0].userAddr = 
230                         (char *)((UInt32)cmem_buf_desc.userAddr + 
231                                         (i*4+2)*MAX_PACKET_FRAME_SIZE);
233                 TxPacketBuf[i][0].physAddr = (UInt32)((cmem_buf_desc.physAddr + 
234                                         (i*4+2)*MAX_PACKET_FRAME_SIZE)); 
237                 TxPacketBuf[i][1].length = MAX_PACKET_FRAME_SIZE;
238                 TxPacketBuf[i][1].userAddr = 
239                         (char *)((UInt32)cmem_buf_desc.userAddr + 
240                                         (i*4+3)*MAX_PACKET_FRAME_SIZE);
242                 TxPacketBuf[i][1].physAddr = (UInt32)((cmem_buf_desc.physAddr + 
243                                         (i*4+3)*MAX_PACKET_FRAME_SIZE)); 
245         }
247         GoosePara.length = GOOSE_PARA_LEN;
248         GoosePara.userAddr = (char *)((UInt32)cmem_buf_desc.userAddr + 
249                         MAX_MII_PORTS_NUM*4*MAX_PACKET_FRAME_SIZE);
250         GoosePara.physAddr = (UInt32)(cmem_buf_desc.physAddr + 
251                         MAX_MII_PORTS_NUM*4*MAX_PACKET_FRAME_SIZE); 
253         Read_Goose_para();
256 /*
257  *  ======== App_create ========
258  */
260 Int App_create(UInt16 remoteProcId)
262         Int                 status = 0;
263         MessageQ_Params     msgqParams;
264         char                msgqName[32];
266         printf("--> App_create:\n");
268         /* setting default values */
269         Module.hostQue = NULL;
270         Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
271         Module.heapId = App_MsgHeapId;
272         Module.msgSize = sizeof(App_Msg);
274         initCmemBufs();
275         /* create local message queue (inbound messages) */
276         MessageQ_Params_init(&msgqParams);
278         Module.hostQue = MessageQ_create(App_HostMsgQueName, &msgqParams);
280         if (Module.hostQue == NULL) {
281                 printf("App_create: Failed creating MessageQ\n");
282                 status = -1;
283                 goto leave;
284         }
286         /* open the remote message queue */
287         sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(remoteProcId));
289         do {
290                 status = MessageQ_open(msgqName, &Module.slaveQue);
291                 sleep(1);
292         } while (status == MessageQ_E_NOTFOUND);
294         if (status < 0) {
295                 printf("App_create: Failed opening MessageQ\n");
296                 goto leave;
297         }
299         printf("App_create: Host is ready\n");
301 leave:
302         printf("<-- App_create:\n");
303         return(status);
307 /*
308  *  ======== App_delete ========
309  */
310 Int App_delete(Void)
312         Int         status;
314         printf("--> App_delete:\n");
316         /* close remote resources */
317         status = MessageQ_close(&Module.slaveQue);
319         if (status < 0) {
320                 goto leave;
321         }
323         /* delete the host message queue */
324         status = MessageQ_delete(&Module.hostQue);
326         if (status < 0) {
327                 goto leave;
328         }
330 leave:
331         printf("<-- App_delete:\n");
332         return(status);
336 /*
337  *  ======== App_exec ========
338  */
339 Int App_exec(Void)
341         Int         status;
342         Int     ethPort, nPktBuf, pktLen;
343         char    *pRxPkt;
344         char    *pTxPkt, *pTxPkt0, *pTxPkt1;
345         Int         i,j;
346         App_Msg *   msg;
348         printf("--> App_exec:\n");
350         /* fill process pipeline */
351         for (i = 1; i <= 4; i++) {
352                 printf("App_exec: sending message %d\n", i);
354                 /* allocate message */
355                 msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
357                 if (msg == NULL) {
358                         status = -1;
359                         goto leave;
360                 }
362                 /* set the return address in the message header */
363                 MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
365                 /* fill in message payload */
366                 msg->cmd = App_CMD_NOP;
368 #ifdef GOOSE_FILTER_DISABLE     
369                 /* disable Goose filtering */
370                 if (i == 3) 
371                         msg->cmd = App_CMD_GOOSE_DISABLE;
372 #endif
374                 if (i == 4) {
375                         msg->cmd = App_CMD_CMEMBUF;
376                         msg->port = 0;
377                         msg->nRxBuf = 0;
378                         for (j = 0; j < MAX_MII_PORTS_NUM; j++) {
379                                 msg->RxPhysAddr[j][0] = 
380                                         RxPacketBuf[j][0].physAddr;
381                                 msg->RxPktLen[j][0] = 0;
383                                 msg->RxPhysAddr[j][1] = 
384                                         RxPacketBuf[j][1].physAddr;
385                                 msg->RxPktLen[j][1] = 0;
387                                 msg->TxPhysAddr[j][0] = 
388                                         TxPacketBuf[j][0].physAddr;
389                                 msg->TxPktLen[j][0] = 0;
391                                 msg->TxPhysAddr[j][1] = 
392                                         TxPacketBuf[j][1].physAddr;
393                                 msg->TxPktLen[j][1] = 0;
394                         }
395                         msg->GooseParaPhysAddr = GoosePara.physAddr;
397                         pTxPkt0 = TxPacketBuf[TEST_PORT][0].userAddr;
398                         pTxPkt1 = TxPacketBuf[TEST_PORT][1].userAddr;
399                         pTxPkt = pTxPkt0;
400                 }
402                 /* send message */
403                 MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
404         }
406         /* process steady state (keep pipeline full) */
407         for (i = 5; i <= MAX_TEST_MSG_NUM; i++) {
409                 /* wait for return message */
410                 status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
411                                 MessageQ_FOREVER);
413                 if (status < 0) {
414                         goto leave;
415                 }
417                 /* extract message payload */
418                 if(msg->cmd == App_CMD_PACKET)
419                 {
420                         printf("App_exec: packet received: \n");
421                         ethPort = msg->port;
422                         nPktBuf = msg->nRxBuf;
423                         pktLen = msg->RxPktLen[ethPort][nPktBuf];
425                         pRxPkt = (char *)RxPacketBuf[ethPort][nPktBuf].userAddr;
427                         for(j=0; j<msg->RxPktLen[ethPort][nPktBuf]; j++)
428                                 printf("%02x", *(pRxPkt+j));
430                         printf("\nreceived packet frame size: %d\n", pktLen);
431                 }
433                 /* free the message */
434                 MessageQ_free((MessageQ_Msg)msg);
436                 printf("\nApp_exec: message received, sending message %d\n", i);
438                 /* allocate message */
439                 msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
441                 if (msg == NULL) {
442                         status = -1;
443                         goto leave;
444                 }
446                 /* set the return address in the message header */
447                 MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
449                 /* fill in message payload */
450                 if (i == MAX_TEST_MSG_NUM) {
451                         /* Last message will tell the slave to shutdown */
452                         msg->cmd = App_CMD_SHUTDOWN;
453                 }
454                 else {
455                         msg->cmd = App_CMD_PACKET;
456                 }
458                 /* send message */
459                 if(pTxPkt == pTxPkt0) {
460                         msg->TxPktLen[TEST_PORT][0] = TEST_PKT_SIZE;
461                         memcpy(pTxPkt, test_pkt[0], TEST_PKT_SIZE);
462                         msg->nTxBuf = 0;
463                         pTxPkt = pTxPkt1;
464                 }
465                 else {
466                         msg->TxPktLen[TEST_PORT][1] = TEST_PKT_SIZE;
467                         memcpy(pTxPkt, test_pkt[1], TEST_PKT_SIZE);
468                         msg->nTxBuf = 1;
469                         pTxPkt = pTxPkt0;
470                 }
471                 MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
472         }
474         /* drain process pipeline */
475         for (i = 1; i <= 4; i++) {
476                 printf("App_exec: message received\n");
478                 /* wait for return message */
479                 status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
480                                 MessageQ_FOREVER);
482                 if (status < 0) {
483                         goto leave;
484                 }
486                 /* extract message payload */
487                 if(msg->cmd == App_CMD_PACKET)
488                 {
489                         printf("App_exec: packet received: \n");
490                         ethPort = msg->port;
491                         nPktBuf = msg->nRxBuf;
492                         pktLen = msg->RxPktLen[ethPort][nPktBuf];
494                         pRxPkt = (char *)RxPacketBuf[ethPort][nPktBuf].userAddr;
496                         for(j=0; j<msg->RxPktLen[ethPort][nPktBuf]; j++)
497                                 printf("%02x", *(pRxPkt+j));
499                         printf("\nreceived packet frame size: %d\n", pktLen);
501                 }
503                 /* free the message */
504                 MessageQ_free((MessageQ_Msg)msg);
505         }
507 leave:
508         CMEM_unmap(cmem_buf_desc.userAddr, cmem_buf_desc.length);
509         CMEM_freePhys(cmem_buf_desc.physAddr, &alloc_params);
511         printf("<-- App_exec: %d\n", status);
512         return(status);