comparison gsm-fw/services/etm/etm_tmcore.c @ 164:d78219c43fbf

gsm-fw/services/etm: initial import from the Leonardo semi-src
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 18 Nov 2013 06:39:44 +0000
parents
children 13af69b6a3dc
comparison
equal deleted inserted replaced
163:5e0e41cd7c9f 164:d78219c43fbf
1 /********************************************************************************
2 * Enhanced TestMode (ETM)
3 * @file tmcore.c
4 *
5 * @author Kim T. Peteren (ktp@ti.com)
6 * @version 0.1
7 *
8
9 *
10 * History:
11 *
12 * Date Modification
13 * ------------------------------------
14 * 16/06/2003 Creation
15 * 02/07/2003 Removed l1_config.TestMode check from CODEC Write
16 * 17/03/2004 Updated etm_version
17 * 30/03/2004 Updated etm_dieID_read() func. regarding get die id for 16 bits
18 * instead of 8 bits.
19 *
20 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
21 *********************************************************************************/
22
23 #include "rv/rv_defined_swe.h"
24 #include "rv/rv_general.h"
25
26 #include "etm/etm.h"
27 #include "etm/etm_api.h"
28 #include "etm/etm_trace.h"
29 #include "etm/etm_version.h"
30
31 #include "abb/abb.h"
32
33 #include "spi/spi_drv.h"
34 extern void tr_etm_init(unsigned int mask);
35
36 // Version of the ETM CORE module
37 // See the file etm_version.h
38
39 /******************************************************************************
40 * DIE ID settings
41 *****************************************************************************/
42
43 #define BE_STREAM_TO_ARRAY(a, p, l) {register INT32 i; for (i = 0; i < l; i++) a[i] = *(UINT8*)(p)++;}
44
45 /* DIE ID register */
46 #if ((CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11)) //For D-Sample: $CHIPSET = 8 (=10 for D-sample AMR, 11 for GSMLITE).
47 #define DIE_ID_REG (MEM_DEV_ID0 | 0xF010) //+ 0xFFFEF010 for Calypso
48 #else
49 #if (CHIPSET == 12) //For E-Sample: $CHIPSET = 12.
50 #define DIE_ID_REG (0xFFFE0000 | 0xF004) //+ 0xFFFEF004 for Calypso Plus
51 #endif
52 #endif
53
54 /* DIE ID SIZE is 4 words (16 bits)long */
55 #define DIE_ID_SIZE 4
56
57 //Copied from rv_general.h:
58 //#define BE_STREAM_TO_ARRAY(a, p, l) {register INT32 i; for (i = 0; i < l; i++) a[i] = *(UINT16*)(p)++;}
59
60
61 /******************************************************************************
62 * Internal prototypes
63 *****************************************************************************/
64
65 T_ETM_PKT *etm_core_setup(uint8 fid);
66 int etm_core(uint8 *buf, int size);
67
68 /******************************************************************************
69 * Register the Core Module to the ETM database
70 *****************************************************************************/
71
72 int etm_core_init(void)
73 {
74 int result;
75
76 result = etm_register("CORE", ETM_CORE, 0, 0, etm_core);
77 return result;
78 }
79
80
81 /******************************************************************************
82 * Memory read/write Functions
83 *****************************************************************************/
84
85 // Describe the payload of the mem protocol !!!!!!
86 // |--type(1)-|--partnum(1)-|--addr(4)-|--data(?)-|
87
88 int etm_mem(T_ETM_PKT *pkt, uint8 *buf)
89 {
90 int num, unitsize, error;
91 uint8 type, param;
92 uint8 *mem8;
93 uint16 *mem16;
94 uint32 *mem32;
95 uint32 addr, tmp;
96 static unsigned char test_buf[64];
97
98 param = unitsize = *buf & 0x3;
99 if (unitsize == 0)
100 unitsize = 4;
101
102 type = *buf & 0x10;
103 buf++;
104
105 num = *buf++;
106 addr = etm_get32(buf);
107 buf += 4;
108
109 tr_etm(TgTrCore, "ETM CORE: _mem: type(0x%x) addr(0x%x) partnum(%d)", type, addr, num);
110
111 // Put 'parameter' in return packet
112 if ((error = etm_pkt_put8(pkt, param)) < 0) {
113 return error;
114 }
115
116 switch (type) {
117 case 0: // READ(0x00)
118 switch (unitsize) {
119 case 1:
120 mem8 = (uint8 *) addr;
121 while (num--) {
122 if ((error = etm_pkt_put8(pkt, *mem8++)) < 0)
123 break;
124 }
125 break;
126 case 2:
127 mem16 = (uint16 *) addr;
128 while (num--) {
129 if ((error = etm_pkt_put16(pkt, *mem16++)) < 0)
130 break;
131 }
132 break;
133 case 4:
134 mem32 = (uint32 *) addr;
135 while (num--) {
136 if ((error = etm_pkt_put32(pkt, *mem32++)) < 0)
137 break;
138 }
139 break;
140 }
141 break;
142
143 case 16: // WRITE(0x10)
144 switch (unitsize) {
145 case 1:
146 mem8 = (uint8 *) addr;
147 while (num--) {
148 *mem8++ = etm_get8(buf);
149 buf += 1;
150 }
151 break;
152 case 2:
153 mem16 = (uint16 *) addr;
154 while (num--) {
155 *mem16++ = tmp = etm_get16(buf);
156 buf += 2;
157 }
158 break;
159 case 4:
160 mem32 = (uint32 *) addr;
161 while (num--) {
162 *mem32++ = etm_get32(buf);
163 buf += 4;
164 }
165 break;
166 }
167 break;
168 default:
169 return ETM_NOSYS;
170 }
171
172 if (error < 0)
173 return error;
174
175 return ETM_OK;
176 }
177
178
179 /******************************************************************************
180 * CODEC Functions
181 *****************************************************************************/
182
183 // ETM sends both page value and register address in one byte.
184 // Bit field is: PPPR RRRR
185 // where P = page bit, R = register address bits and X = don't care bits.
186
187 int etm_codec_write(T_ETM_PKT *pkt, uint8 *buf)
188 {
189 extern void ABB_Write_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id, SYS_UWORD16 value);
190 uint16 page, reg, data;
191 int result, reg_data;
192
193 reg_data = *buf++;
194 if ((result = etm_pkt_put8(pkt, reg_data)) < 0)
195 return result;
196
197 page = (reg_data >> 5) & 0x3;
198 reg = reg_data & 0x1F;
199 data = etm_get16(buf);
200
201 tr_etm(TgTrCore, "ETM CORE: _codec_write: page(%d) reg(%d) data(0x%x)",
202 page, reg, (data & 0x3ff));
203
204 if (page > 7 && reg > 32)
205 return ETM_INVAL;
206 else {
207 // The function below expects a 1 for page 0 and a 2 for page 1.
208 // The register address value is left-shifted by 1 since LSB is read/write command bit.
209 // The value is written in the 10 MSB's of register.
210 ABB_Write_Register_on_page(page + 1, reg << 1, (data & 0x3ff));
211 }
212
213 return ETM_OK;
214 }
215
216
217 int etm_codec_read(T_ETM_PKT *pkt, uint8 *buf)
218 {
219 extern SYS_UWORD16 ABB_Read_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id);
220 volatile uint16 value;
221 uint16 page, reg;
222 int result, reg_data;
223
224 reg_data = *buf;
225 if ((result = etm_pkt_put8(pkt, reg_data)) < 0)
226 return result;
227
228 page = (reg_data >> 5) & 0x3;
229 reg = reg_data & 0x1F;
230
231 if (page > 7 && reg > 32)
232 return ETM_INVAL;
233
234 // The function below expects a 1 for page 0 and a 2 for page 1.
235 // The register value is left-shifted by 1 since LSB is read/write command bit.
236 value = ABB_Read_Register_on_page(page + 1, (reg << 1));
237
238 tr_etm(TgTrCore, "ETM CORE: _codec_read: page(%d) reg(%d) value(0x%x)", page, reg, value);
239
240 result = etm_pkt_put16(pkt, value);
241 return result;
242 }
243
244
245 /******************************************************************************
246 * Echo and Reset Functions
247 *****************************************************************************/
248
249 //structur of data dl: |delay|recvsize|num| = 3x2 bytes
250 int etm_echo(T_ETM_PKT *pkt, uint8 *data)
251 {
252 int delay, sendsize, i, num, count;
253
254 tr_etm(TgTrCore, "etm_echo:");
255
256 delay = etm_get16(data);
257 data += 2;
258
259 sendsize = etm_get16(data);
260 if (sendsize > 240)
261 return ETM_INVAL;
262
263 data += 2;
264 num = etm_get16(data);
265
266 tr_etm(TgTrCore, "ETM CORE: _echo: delay(%d) sendsize(%d) num(%d)",
267 delay, sendsize, num);
268
269 if (delay > 0) {
270 rvf_delay((delay + 32) * 14 / 64);
271 }
272
273 for (i = 0; i < sendsize; i++) {
274 pkt->data[i+1] = i; // data[0] = fid
275 }
276
277 pkt->size = sendsize;
278
279 return ETM_OK;
280 }
281
282
283 int etm_reset(void)
284 {
285 // The reset code is taken form Fluid->cmd.c
286 int i;
287
288 tr_etm(TgTrCore, "ETM CORE: _reset: Target is Reset");
289
290 // Setup watchdog timer and let it timeout to make a reset
291 *(volatile uint16*) 0xfffff804 = 0xFFFF; // Timer to watchdog
292 *(volatile uint16*) 0xfffff800 = 0x0080; // Start timer
293 // Apparently works it only if we read this register?
294 i = *(volatile uint16*) 0xfffff802;
295 *(volatile uint16*) 0xfffff802 = 0x0001; // Load timer
296
297 return ETM_OK;
298 }
299
300
301 /******************************************************************************
302 * Set Test Controls
303 *****************************************************************************/
304
305 int etm_debug(T_ETM_PKT *pkt, uint8 *buf)
306 {
307 int type, error, data;
308
309 static char *p;
310
311 type = *buf & 0x0F;
312 buf++;
313
314 data = etm_get32(buf);
315
316 tr_etm(TgTrCore, "ETM CORE: _debug: type(%d) data(0x%x)", type, data);
317
318 switch (type) {
319 case 0: // (0x00) Allocate Test Buffer
320 if ((p = etm_malloc(data)) == NULL)
321 error = ETM_NOMEM;
322 error = etm_pkt_put32(pkt, (int) p);
323 break;
324 case 1: // (0x01) Free Test Buffer.
325 p = (char *) data;
326 etm_free(p);
327 break;
328 case 2: // (0x02) Set ETM Trace mask
329 tr_etm_init(data);
330 break;
331 case 3: // (0x03) Set read all mem banks stat
332 rvf_dump_mem();
333 rvf_dump_pool();
334 rvf_dump_tasks();
335 break;
336 default:
337 error = ETM_NOSYS;
338 }
339
340 if (error < 0)
341 return error;
342
343 return ETM_OK;
344 }
345
346 /******************************************************************************
347 * Get Version of ...
348 *****************************************************************************/
349 // This is in development ...
350
351 int etm_version(T_ETM_PKT *pkt, uint8 *buf)
352 {
353 extern uint16 etm_audio_revision;
354 extern uint16 etm_task_revision;
355 int error, fid, ffs_tm_version;
356 volatile int revision = 0;
357 T_VERSION *l1s_version;
358
359 fid = etm_get32(buf);
360
361 tr_etm(TgTrCore, "ETM CORE: _version: fid(0x%x)", fid);
362
363 l1s_version = (T_VERSION*) l1s_get_version();
364
365 switch (fid) {
366 // Code Versions related to ETM modules
367 case SW_REV_ETM_CORE:
368 error = etm_pkt_put32(pkt, ETM_CORE_VERSION);
369 break;
370 case SW_REV_ETM_AUDIO:
371 error = etm_pkt_put32(pkt, ETM_AUDIO_VERSION);
372 break;
373 // case SW_REV_ETM_FFS:
374 // ffs_query(Q_FFS_TM_VERSION, &ffs_tm_version);
375 // error = etm_pkt_put32(pkt, ffs_tm_version);
376 break;
377 // case SW_REV_ETM_RF: // Layer1 Testmode Version
378 // error = etm_pkt_put32(pkt, TESTMODEVERSION);
379 // break;
380 case SW_REV_ETM_PWR:
381 error = etm_pkt_put32(pkt, ETM_PWR_VERSION);
382 break;
383 case SW_REV_ETM_BT:
384 error = ETM_NOSYS;
385 break;
386 case SW_REV_ETM_TASK:
387 error = etm_pkt_put32(pkt, ETM_VERSION);
388 break;
389 case SW_REV_ETM_API:
390 error = etm_pkt_put32(pkt, ETM_API_VERSION);
391 break;
392 // Code Versions related to L1, see in l1_defty.h
393 // Get the version on this way "revision = l1s.version.dsp_code_version;"
394 // doesn't work because of struct aligment -> compile flag -mw !!!!
395 case SW_DSP_CODE_VERSION:
396 revision = ((T_VERSION*) l1s_version)->dsp_code_version;
397 error = etm_pkt_put32(pkt, revision);
398 break;
399 case SW_DSP_PATCH_VERSION:
400 revision = ((T_VERSION*) l1s_version)->dsp_patch_version;
401 error = etm_pkt_put32(pkt, revision);
402 break;
403 case SW_MCU_TCS_PROGRAM_RELEASE:
404 revision = ((T_VERSION*) l1s_version)->mcu_tcs_program_release;
405 error = etm_pkt_put32(pkt, revision);
406 break;
407 case SW_MCU_TCS_OFFICIAL: // This version allso identify version of Layer1
408 revision = ((T_VERSION*) l1s_version)->mcu_tcs_official;
409 error = etm_pkt_put32(pkt, revision);
410 break;
411 case SW_MCU_TCS_INTERNAL:
412 revision = ((T_VERSION*) l1s_version)->mcu_tcs_internal;
413 error = etm_pkt_put32(pkt, revision);
414 break;
415 case SW_MCU_TM_VERSION:
416 revision = ((T_VERSION*) l1s_version)->mcu_tm_version;
417 error = etm_pkt_put32(pkt, revision);
418 break;
419 default:
420 error = ETM_NOSYS;
421 }
422
423 tr_etm(TgTrCore, "ETM CORE: _version: version(%d)", revision);
424
425 if (error < 0)
426 return error;
427
428 return ETM_OK;
429 }
430
431
432 /******************************************************************************
433 * Function for reading the Die-ID from base band processor.
434 *****************************************************************************/
435
436 int etm_dieID_read(T_ETM_PKT *pkt, uint8 *inbuf)
437 {
438 T_RV_RET result;
439 int8 byteCount;
440 UINT16 dieID[DIE_ID_SIZE];
441 int16 index;
442 volatile UINT16 *reg_p = (UINT16 *) DIE_ID_REG;
443
444 tr_etm(TgTrCore, "ETM CORE: _dieID_read: started - Die-ID address(0x%x)", DIE_ID_REG);
445
446 BE_STREAM_TO_ARRAY(dieID, reg_p, DIE_ID_SIZE);
447
448 for (byteCount = 0; byteCount < DIE_ID_SIZE; byteCount++) {
449
450 tr_etm(TgTrCore, "ETM CORE: Die-ID[%i] Byte Read(0x%x)", byteCount, (UINT16)dieID[byteCount]);
451 result = etm_pkt_put16(pkt, (UINT8)(((dieID[byteCount]) & 0xFFFF)));
452 if (result < 0)
453 return result;
454 }
455
456
457 return ETM_OK;
458 }
459
460
461 /******************************************************************************
462 * ETM CORE Main Function - Module
463 *****************************************************************************/
464
465 int etm_core(uint8 *buf, int size)
466 {
467 // Structur of protocol data dl-link: |fid|index|data|
468
469 uint8 mid;
470 uint8 fid;
471 int error = 0;
472 T_ETM_PKT *pkt = NULL;
473
474 fid = *buf++;
475
476 tr_etm(TgTrCore, "ETM CORE: _core: fid(%c):", fid);
477
478 /* Create TestMode return Packet */
479 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) {
480 return ETM_NOMEM;
481 }
482
483 // Init. of return packet
484 pkt->mid = ETM_CORE;
485 pkt->status = ETM_OK;
486 pkt->size = 0;
487 pkt->index = 0;
488 etm_pkt_put8(pkt, fid);
489
490 switch (fid) {
491 #ifdef RVM_ATP_SWE
492 case 0x60: // old 'G'
493 error = etm_at(pkt, (char *) buf);
494 break;
495 #endif
496 case 0x61: // old 'M'
497 error = etm_mem(pkt, buf);
498 break;
499 case 0x62: // old 'E'
500 error = etm_echo(pkt, buf);
501 break;
502 case 0x63: // old 'R'
503 error = etm_reset();
504 break;
505 case 0x64: // old 'T'
506 error = etm_debug(pkt, buf);
507 break;
508 case 0x65: // old 'V'
509 error = etm_version(pkt, buf);
510 break;
511 case 0x66: // old 'C'
512 error = etm_codec_read(pkt, buf);
513 break;
514 case 0x67: // old 'D'
515 error = etm_codec_write(pkt, buf);
516 break;
517 case 0x68: // old 'd'
518 error = etm_dieID_read(pkt, buf);
519 break;
520 default:
521 tr_etm(TgTrCore,"ETM CORE: _core: fid ERROR");
522 error = ETM_NOSYS;
523 break;
524 }
525
526 if (error < 0) {
527 tr_etm(TgTrCore,"ETM CORE: _core: FAILED");
528 pkt->status = -error;
529 }
530
531 // etm_at(): send func. is controlled by primitive
532 if (fid == 'G' && error >= RV_OK) {}
533 else
534 etm_pkt_send(pkt);
535
536 etm_free(pkt);
537 return ETM_OK;
538 }