comparison services/etm/etm_task.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /********************************************************************************
2 * Enhanced TestMode (ETM)
3 * @file etm.c
4 *
5 * @author Kim T. Peteren (ktp@ti.com)
6 * @version 0.1
7 *
8
9
10 *
11 * History:
12 *
13 * Date Modification
14 * ------------------------------------
15 * 16/06/2003 Creation
16 * 03/03/2004 Upadted regarding the ATP + minor ETM DB handling updates
17 * 28/07/2004 Fixed ETM database issue
18 *
19 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
20 *********************************************************************************/
21
22
23 #include "etm.h"
24 #include "etm_config.h"
25 #include "etm_api.h"
26 #include "etm_messages_i.h"
27 #include "etm_trace.h"
28 #include "etm_env.h"
29
30 #if ETM_AUDIO_SUPPORT
31 #include "audio/audio_api.h"
32 #endif
33
34 #include "../../riviera/rv/rv_general.h"
35 #include "../../riviera/rvf/rvf_api.h"
36 #include "../../riviera/rvt/rvt_gen.h"
37 #include "../../riviera/rvf/rvf_target.h"
38 #include "../../riviera/rv/rv_defined_swe.h"
39
40 #include <string.h>
41
42 #if ETM_LCC_SUPPORT
43 #include "lcc/lcc_api.h"
44 #include "lcc/lcc_cfg_i.h"
45 #include "lcc/lcc.h"
46 #include "lcc/lcc_env.h"
47 #include "lcc/lcc_trace.h"
48 #endif
49
50 // Version of the ETM TASK moved to etm_version.h
51 //const uint16 etm_task_revision = (1<<12) | (0x1);
52
53 /******************************************************************************
54 * Globals
55 *****************************************************************************/
56
57 #define ETM_DB_MAX 16 // Limited of registered SWEntities into ETM DB
58 #define ETM_DB_NO_USE 0xFFFFFFFF //
59
60 typedef struct
61 {
62 char swe_name[ETM_NAME_MAX_LEN];
63 int mid;
64 int task_id;
65 T_RVF_ADDR_ID addr_id; // Unique mailbox (ID) of the SWE which will
66 //receive the message
67 ETM_CALLBACK_FUNC rx_callback_func;
68 } T_ETM_USER_DB;
69
70
71 static T_ETM_USER_DB etm_user_db[ETM_DB_MAX];
72
73 static int etm_db_counter = 0;
74
75
76 /******************************************************************************
77 * Prototypes
78 *****************************************************************************/
79
80 extern T_ETM_ENV_CTRL_BLK *etm_env_ctrl_blk;
81 #if ETM_LCC_SUPPORT
82 extern T_PWR_CTRL_BLOCK *pwr_ctrl;
83 #endif
84
85 int etm_database_manager(T_RV_HDR *msg_p);
86 int etm_forward_packet(int mid, T_RV_HDR *msg);
87 void etm_error_packet_send(int mid, int error);
88 void etm_receive(unsigned char *inbuf, unsigned short size);
89
90 #if ETM_ATP_SUPPORT
91 extern int etm_at_atp_message(void *msg);
92 #endif
93
94 #if ETM_LCC_SUPPORT
95 extern int etm_pwr_ul(void *msg);
96 extern int etm_pwr_dl(T_ETM_PKT *pkt, uint8 *buf, int insize);
97 #endif
98
99 /******************************************************************************
100 * Main Testmode Task Loop
101 *****************************************************************************/
102
103 T_RV_RET etm_task(void)
104 {
105 extern int etm_core_init(void);
106 #if ETM_AUDIO_SUPPORT
107 extern int etm_audio_init(void);
108 #endif
109 #if ETM_LCC_SUPPORT
110 extern int etm_pwr_init(void);
111 #endif
112
113 T_RV_HDR *msg = NULL;
114 T_ETM_PKT *pkt = NULL;
115 UINT32 start_time = 0;
116 UINT32 end_time = 0;
117 UINT16 recv_event, i;
118
119 int status = RV_OK, buf_size;
120
121 /* Entity registration to ETM */
122 /* This should be in the individual SWE init. function*/
123 status = etm_core_init();
124 #if ETM_AUDIO_SUPPORT
125 status = etm_audio_init();
126 #endif
127 #if ETM_LCC_SUPPORT
128 status = etm_pwr_init();
129 #endif
130
131 while (1)
132 {
133 recv_event = rvf_wait(0xffff,0); /* Wait (infinite) for all events. */
134
135 start_time = rvf_get_tick_count();
136 tr_etm(TgTrEtmLow,"ETM: _task: Time Waiting (%d) tick", start_time - end_time);
137 tr_etm(TgTrEtmLow,"ETM: _task: Time Start(%d)", start_time);
138
139 tr_etm(TgTrEtmLow,"ETM: _task: Got message passing to bit filter (0x%x)", recv_event);
140
141
142 if (!(recv_event & RVF_TASK_MBOX_0_EVT_MASK))
143 continue;
144
145 /* Read the message in the ETM mailbox */
146 if ((msg = rvf_read_mbox(ETM_MAILBOX)) == NULL)
147 continue;
148
149 tr_etm(TgTrEtmLow,"ETM: _task: msg_id(0x%x)", msg->msg_id);
150
151 switch (msg->msg_id) {
152 /* Entity registration request or unregistration */
153 case ETM_REGISTER_REQ:
154 case ETM_UNREGISTER:
155 status = etm_database_manager(msg);
156 break;
157 /* ETM packet received */
158 case ETM_DATA_FWR:
159 if ((status = etm_forward_packet(((T_ETM_DATA_FWR *) msg)->mid, msg))
160 != ETM_OK)
161 etm_error_packet_send(((T_ETM_DATA_FWR *) msg)->mid, status);
162 break;
163 /* TM3 packet received */
164 case ETM_TM3_DATA_FWR:
165 if ((status = etm_forward_packet(ETM_TM3, msg)) != ETM_OK)
166 etm_error_packet_send(ETM_TM3, status);
167 break;
168 default:
169 tr_etm(TgTrEtmLow,"ETM: _task: msg_id '0x%x' NOT supported",
170 msg->msg_id);
171 }
172
173 if (status != ETM_OK) {
174 tr_etm(TgTrFatal,"ETM: _task: mid(0x%x) ERROR(%d)",
175 ((T_ETM_DATA_FWR *) msg)->mid, status);
176 etm_free(msg); // Free the message
177 }
178
179 end_time = rvf_get_tick_count();
180 tr_etm(TgTrEtmLow,"ETM: _task: Time End (%d)", end_time);
181 tr_etm(TgTrEtmLow,"ETM: _task: Time Total (%d) tick", end_time - start_time);
182 }
183
184 return RV_OK;
185 }
186
187
188 void etm_error_packet_send(int mid, int error)
189 {
190 T_ETM_PKT *pkt;
191
192 tr_etm(TgTrFatal,"ETM: _error_packet_send: Module(0x%x) ERROR(%d)", mid, error);
193
194 if (error == ETM_NOMEM) {
195 rvf_dump_mem();
196 }
197
198 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) {
199 rvf_dump_mem();
200 return;
201 }
202
203 // Init. of return packet
204 pkt->mid = mid;
205 pkt->status = -error;
206 pkt->size = 0;
207 pkt->index = 0;
208
209 etm_pkt_send(pkt);
210 etm_free(pkt); // Free return packet
211 }
212
213
214 /* Forwarding of DATA to the SWE can either be done by message/primitive or callback */
215 int etm_forward_packet(int mid, T_RV_HDR* msg)
216 {
217 ETM_CALLBACK_FUNC rx_callback_func = NULL;
218 int i, cid, status = ETM_OK;
219 T_ETM_DATA_READY* message_p;
220 T_RVF_ADDR_ID swe_addr_id = 0;
221
222 // Search for supported MID in the table
223 for (i = 0; etm_user_db[i].mid != TABLE_END; i++)
224 {
225 tr_etm(TgTrEtmLow,"ETM: _forward_packet: Lookup in db for mid(0x%x)", mid);
226
227 if (etm_user_db[i].mid == mid) {
228 rx_callback_func = etm_user_db[i].rx_callback_func;
229 swe_addr_id = etm_user_db[i].addr_id;
230 break;
231 }
232 }
233
234 tr_etm(TgTrEtmLow,"ETM: _forward_packet: rx_callback_func(%d) swe_addr_id(%d)",
235 *rx_callback_func, swe_addr_id);
236
237 // Invoke the SWE mailbox
238 if (swe_addr_id) {
239 /* Allocate the memory for the message to send */
240 if ((message_p = (T_ETM_DATA_READY*) etm_malloc(sizeof(T_ETM_DATA_READY))) == NULL)
241 return ETM_NOMEM;
242
243 /* Fill the header of the message */
244 message_p->header.msg_id = ETM_DATA_READY;
245
246 /* Fill the address source id */
247 message_p->header.src_addr_id = rvf_get_taskid();
248 message_p->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
249 message_p->header.callback_func = NULL;
250
251 /* Fill the data in the message */
252 memcpy(((T_ETM_DATA_READY*) message_p)->data, ((T_ETM_DATA_FWR*) msg)->data,
253 ((T_ETM_DATA_FWR*) msg)->size);
254
255 /* Send the message to the entity */
256 if ((status = rvf_send_msg(swe_addr_id, message_p)) != RV_OK) {
257 tr_etm(TgTrFatal,"ETM: _forward_packet: Failed to sent message - ERROR(%d)",
258 status);
259 return ETM_RV_FATAL;
260 }
261 etm_free(msg); // Free the message
262 }
263 // Invoke the SWE callback function
264 else if (rx_callback_func) {
265 tr_etm(TgTrEtmLow,"ETM: _forward_packet: to mid(0x%x)", mid);
266 status = rx_callback_func (((T_ETM_DATA_FWR*) msg)->data, ((T_ETM_DATA_FWR*) msg)->size);
267 rx_callback_func = NULL;
268 if (status != ETM_OK)
269 return status;
270 etm_free(msg); // Free the message
271 }
272 else {
273 return ETM_NOSYS;
274 }
275
276 return ETM_OK;
277 }
278
279
280 /******************************************************************************
281 * Get and Free buffer (Internal Functions)
282 *****************************************************************************/
283
284 void *etm_malloc(int size)
285 {
286 /* Memory bank status (red, yellow, green) */
287 T_RVF_MB_STATUS mb_status;
288 void *addr;
289
290 mb_status = rvf_get_buf(etm_env_ctrl_blk->prim_id, size, &addr);
291
292 /* The flag returned by rvf_get_buf is red, there is not enough
293 * memory to allocate the buffer. */
294 if (mb_status == RVF_RED) {
295 tr_etm(TgTrFatal, "ETM: _malloc: Error to get memory");
296 return NULL;
297 }
298 /* The flag is yellow, there will soon be not enough memory anymore. */
299 else if (mb_status == RVF_YELLOW) {
300 tr_etm(TgTrFatal, "ETM: _malloc: Getting short on memory");
301 }
302
303 tr_etm(TgTrEtmLow,"ETM: _malloc: size(%d) at addr(0x%x)", size, addr);
304 return addr;
305 }
306
307 int etm_free(void *addr)
308 {
309 int status;
310
311 tr_etm(TgTrEtmLow,"ETM: _free: addr(0x%x)", addr);
312
313 if ((status = rvf_free_buf(addr)) != RV_OK) {
314 tr_etm(TgTrFatal, "ETM: _free: ERROR(%d)", status);
315 }
316
317 return ETM_RV_FATAL;
318 }
319
320
321 /******************************************************************************
322 * ETM receive Functions API (Internal Functions)
323 ******************************************************************************/
324
325 /* The input pointer buf point at a complete TM3 packet. */
326 int etm_tm3_data_forward(uint8 *buf, int size)
327 {
328 /* Type for a registration event. */
329 T_ETM_TM3_DATA_FWR *msg;
330
331 tr_etm(TgTrEtmLow, "ETM: _tm3_data_forward: cid(0x%x) size(%d)", *buf, size);
332
333 /* Allocate the memory for the message to send */
334 if ((msg = (T_ETM_TM3_DATA_FWR*) etm_malloc(sizeof(T_ETM_TM3_DATA_FWR))) == NULL)
335 return ETM_NOMEM;
336
337 /* Fill the message id */
338 msg->header.msg_id = ETM_TM3_DATA_FWR;
339
340 /* Fill the address source id */
341 msg->header.src_addr_id = rvf_get_taskid();
342 msg->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
343 msg->header.callback_func = NULL;
344
345 /* Fill the message parameters */
346 msg->size = size;
347 msg->cid = *buf;
348 memcpy(&msg->data, buf, size);
349
350 // At this point, all the data have been parsed and copied into
351 // the ETM primitive. Now we send the primitive to the ETM task.
352 if (rvf_send_msg(etm_env_ctrl_blk->addr_id, msg) != RV_OK) {
353 tr_etm(TgTrFatal, "ETM: _tm3_data_forward: FAILED");
354 return ETM_RV_FATAL; // msg is auto freed by rvf_send_msg() if error
355 }
356
357 return ETM_OK;
358 }
359
360
361 /* The input pointer buf point at payload of the TM packet, minus mid and cksum. */
362 int etm_data_forward(char mid, uint8 *inbuf, int size)
363 {
364 /* Type for a registration event. */
365 T_ETM_DATA_FWR *msg;
366
367 tr_etm(TgTrEtmLow, "ETM: _data_forward: mid(0x%x) size(%d)", mid, size);
368
369 /* Allocate the memory for the message to send */
370 if ((msg = (T_ETM_DATA_FWR*) etm_malloc(sizeof(T_ETM_DATA_FWR))) == NULL)
371 return ETM_NOMEM;
372
373 /* Fill the message id */
374 msg->header.msg_id = ETM_DATA_FWR;
375
376 /* Fill the address source id */
377 msg->header.src_addr_id = rvf_get_taskid();
378 msg->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
379 msg->header.callback_func = NULL;
380
381 /* Fill the message parameters */
382 msg->size = size;
383 msg->mid = mid;
384 memcpy(&msg->data, inbuf, size);
385
386 // At this point, all the data have been parsed and copied into
387 // the ETM primitive. Now we send the primitive to the ETM task.
388 if (rvf_send_msg(etm_env_ctrl_blk->addr_id, msg) != RV_OK) {
389 tr_etm(TgTrFatal, "ETM: _data_forward: FAILED");
390 return ETM_RV_FATAL; // msg is auto freed by rvf_send_msg() if error
391 }
392
393 return ETM_OK;
394 }
395
396
397 /* This function is registred in the RVT module as the TestMode receive function */
398 /* It's called every time a TestMode packet is received on the UART and the */
399 /* data is forwarded to the ETM Entity via a message/primitiv */
400 /* The function is a callback func. used by the RVT TASK -> UART RX. */
401
402 void etm_receive(uint8 *inbuf, unsigned short size)
403 {
404 int error = ETM_NOSYS, i, index;
405 char mid;
406 unsigned char cksum;
407 T_ETM_PKT *pkt;
408
409 tr_etm(TgTrEtmLow, "ETM: _receive: inbuf size(%d)", size);
410
411 // Copy data payload size (size minus MID/CID byte and checksum byte)
412 mid = *inbuf++;
413
414 cksum = mid;
415 for (i = 0; i < size - 1; i++) {
416 cksum ^= inbuf[i];
417 }
418
419 if (cksum != 0) {
420 error = ETM_PACKET;
421 goto ETM_RECEIVE_END;
422 }
423
424 // Check it's a TM3 packet
425 if ((0x20 <= mid && mid < 0x27) ||
426 (0x30 <= mid && mid < 0x3A) ||
427 (0x40 <= mid && mid < 0x49) ||
428 (0x50 <= mid && mid < 0x57)) {
429 // Forward complete TM3 packet
430 error = etm_tm3_data_forward(--inbuf, size);
431 }
432 else {
433 /* Controlling of receptor for regisration */
434 for (index=0; index < etm_db_counter; index++)
435 {
436 if (etm_user_db[index].mid == mid) {
437 // Forward ETM packet without <mid> and <cksum>, -2 in size
438 error = etm_data_forward(mid, inbuf, size - 2);
439 break;
440 }
441 else if ((index == etm_db_counter) && (etm_user_db[index].mid != mid)) {
442 tr_etm(TgTrFatal, "ETM: _receive: mid(0x%x) not supported", mid);
443 }
444 }
445 }
446
447 ETM_RECEIVE_END:
448 /* Fill in Error status in ETM packet and send */
449 if (error) {
450 if (error == ETM_NOMEM) {
451 rvf_dump_mem();
452 return;
453 }
454
455 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL)
456 return;
457 pkt->size = 0;
458 pkt->mid = mid;
459 pkt->status = -error;
460
461 etm_pkt_send(pkt);
462 etm_free(pkt); // Free return Packet
463 }
464 }
465
466
467 /******************************************************************************
468 * Registration manager Functions API (Internal function)
469 ******************************************************************************/
470
471 int etm_database_add(T_ETM_REGISTER_REQ *msg_p, int index)
472 {
473
474 memcpy(etm_user_db[index].swe_name, msg_p->name, strlen(msg_p->name));
475 etm_user_db[index].mid = msg_p->mid;
476 etm_user_db[index].task_id = msg_p->task_id;
477 etm_user_db[index].addr_id = msg_p->addr_id;
478 etm_user_db[index].rx_callback_func = msg_p->rx_callback_func;
479
480 etm_user_db[index+1].mid = TABLE_END;
481
482 return ETM_OK;
483 }
484
485
486 int etm_database_manager(T_RV_HDR *msg_p)
487 {
488 int index, mid, status;
489
490 if (msg_p->msg_id == ETM_REGISTER_REQ) {
491 mid = ((T_ETM_REGISTER_REQ *) msg_p)->mid;
492
493 tr_etm(TgTrEtmLow,"ETM: _database_manager: _REGISTER_REQ reguest is received from (%s)",
494 ((T_ETM_REGISTER_REQ *) msg_p)->name);
495
496 /* Lookup in the ETM DB array */
497 for (index=0; index < ETM_DB_MAX; index++)
498 {
499 /* Use unregistrered space */
500 if ((etm_user_db[index].mid == ETM_DB_NO_USE) && (etm_user_db[index].addr_id == 0) &&
501 (etm_user_db[index].rx_callback_func == NULL)) {
502 status = etm_database_add((T_ETM_REGISTER_REQ*) msg_p, index);
503 etm_db_counter++;
504 etm_free(msg_p); // Free Message
505 return ETM_OK;
506 }
507 /* Reject double registration */
508 else if ((etm_user_db[index].mid == mid) &&
509 ((etm_user_db[index].addr_id != 0) || (etm_user_db[index].rx_callback_func != NULL))) {
510 tr_etm(TgTrFatal,"ETM: _database_manager: The Module(0x%x) is registrered", mid);
511 etm_free(msg_p); // Free Message
512 return ETM_OK;
513 }
514 }
515
516 /* Add the entity to the etm database */
517 if (etm_db_counter < ETM_DB_MAX) {
518 status = etm_database_add((T_ETM_REGISTER_REQ*) msg_p, etm_db_counter);
519 etm_db_counter++;
520 etm_free(msg_p); // Free Message
521 return ETM_OK;
522 }
523
524 etm_free(msg_p); // Free Message
525 return ETM_DB_LIMIT;
526 }
527
528
529 if (msg_p->msg_id == ETM_UNREGISTER) {
530 mid = ((T_ETM_UNREGISTER *) msg_p)->mid;
531 tr_etm(TgTrEtmLow,"ETM: _database_manager: _UNREGISTER reguest is received from (%s)",
532 ((T_ETM_REGISTER_REQ *) msg_p)->name);
533
534 /* Lookup in the array, if the SWE is stocked then clean it*/
535 for (index=0; index < ETM_DB_MAX; index++) {
536 if (etm_user_db[index].mid == mid) {
537 etm_user_db[index].mid = ETM_DB_NO_USE;
538 etm_user_db[index].addr_id = 0;
539 etm_user_db[index].rx_callback_func = NULL;
540 etm_db_counter--;
541 etm_free(msg_p); // Free Message
542 return ETM_OK;
543 }
544 }
545
546 etm_free(msg_p); // Free Message
547 return ETM_INVAL;
548 }
549
550 etm_free(msg_p); // Free Message
551 return ETM_OK;
552 }