FreeCalypso > hg > freecalypso-citrine
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 } |