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