ZY1000 code
[openocd.git] / src / jtag / zy1000.c
1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23
24 #include "log.h"
25 #include "jtag.h"
26 #include "bitbang.h"
27 #include "../target/embeddedice.h"
28
29
30 #include <cyg/hal/hal_io.h> // low level i/o
31 #include <cyg/hal/var_io.h> // common registers
32 #include <cyg/hal/plf_io.h> // platform registers
33 #include <cyg/hal/hal_diag.h>
34
35 #include <stdlib.h>
36
37
38 extern int jtag_error;
39
40 /* low level command set
41 */
42 int eCosBoard_read(void);
43 static void eCosBoard_write(int tck, int tms, int tdi);
44 void eCosBoard_reset(int trst, int srst);
45
46
47 int eCosBoard_speed(int speed);
48 int eCosBoard_register_commands(struct command_context_s *cmd_ctx);
49 int eCosBoard_init(void);
50 int eCosBoard_quit(void);
51
52 /* interface commands */
53 int eCosBoard_handle_eCosBoard_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54
55 static int eCosBoard_khz(int khz, int *jtag_speed)
56 {
57 if (khz==0)
58 {
59 *jtag_speed=0;
60 }
61 else
62 {
63 *jtag_speed=64000/khz;
64 }
65 return ERROR_OK;
66 }
67
68 static int eCosBoard_speed_div(int speed, int *khz)
69 {
70 if (speed==0)
71 {
72 *khz = 0;
73 }
74 else
75 {
76 *khz=64000/speed;
77 }
78
79 return ERROR_OK;
80 }
81
82
83 jtag_interface_t eCosBoard_interface =
84 {
85 .name = "ZY1000",
86 .execute_queue = bitbang_execute_queue,
87 .speed = eCosBoard_speed,
88 .register_commands = eCosBoard_register_commands,
89 .init = eCosBoard_init,
90 .quit = eCosBoard_quit,
91 .khz = eCosBoard_khz,
92 .speed_div = eCosBoard_speed_div,
93 };
94
95 bitbang_interface_t eCosBoard_bitbang =
96 {
97 .read = eCosBoard_read,
98 .write = eCosBoard_write,
99 .reset = eCosBoard_reset
100 };
101
102
103
104 static void eCosBoard_write(int tck, int tms, int tdi)
105 {
106
107 }
108
109 int eCosBoard_read(void)
110 {
111 return -1;
112 }
113
114 extern bool readSRST();
115
116 void eCosBoard_reset(int trst, int srst)
117 {
118 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
119 if(!srst)
120 {
121 ZY1000_POKE(0x08000014, 0x00000001);
122 }
123 else
124 {
125 /* Danger!!! if clk!=0 when in
126 * idle in TAP_RTI, reset halt on str912 will fail.
127 */
128 ZY1000_POKE(0x08000010, 0x00000001);
129 }
130
131 if(!trst)
132 {
133 ZY1000_POKE(0x08000014, 0x00000002);
134 }
135 else
136 {
137 /* assert reset */
138 ZY1000_POKE(0x08000010, 0x00000002);
139 }
140
141 if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))
142 {
143 waitIdle();
144 /* we're now in the TLR state until trst is deasserted */
145 ZY1000_POKE(0x08000020, TAP_TLR);
146 } else
147 {
148 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
149 ZY1000_POKE(0x08000014, 0x400);
150 }
151
152 /* wait for srst to float back up */
153 if (!srst)
154 {
155 int i;
156 for (i=0; i<1000; i++)
157 {
158 // We don't want to sense our own reset, so we clear here.
159 // There is of course a timing hole where we could loose
160 // a "real" reset.
161 if (!readSRST())
162 break;
163
164 /* wait 1ms */
165 alive_sleep(1);
166 }
167
168 if (i==1000)
169 {
170 LOG_USER("SRST didn't deassert after %dms", i);
171 } else if (i>1)
172 {
173 LOG_USER("SRST took %dms to deassert", i);
174 }
175 }
176 }
177
178 int eCosBoard_speed(int speed)
179 {
180 if(speed == 0)
181 {
182 /*0 means RCLK*/
183 speed = 0;
184 ZY1000_POKE(0x08000010, 0x100);
185 LOG_DEBUG("jtag_speed using RCLK");
186 }
187 else
188 {
189 if(speed > 8190 || speed < 2)
190 {
191 LOG_ERROR("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
192 return ERROR_INVALID_ARGUMENTS;
193 }
194
195 LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
196 ZY1000_POKE(0x08000014, 0x100);
197 ZY1000_POKE(0x0800001c, speed&~1);
198 }
199 return ERROR_OK;
200 }
201
202 int eCosBoard_register_commands(struct command_context_s *cmd_ctx)
203 {
204 return ERROR_OK;
205 }
206
207
208 int eCosBoard_init(void)
209 {
210 ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2
211
212 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
213 eCosBoard_reset(0, 0);
214 eCosBoard_speed(jtag_speed);
215
216 bitbang_interface = &eCosBoard_bitbang;
217
218 return ERROR_OK;
219 }
220
221 int eCosBoard_quit(void)
222 {
223
224 return ERROR_OK;
225 }
226
227
228
229 /* loads a file and returns a pointer to it in memory. The file contains
230 * a 0 byte(sentinel) after len bytes - the length of the file. */
231 int loadFile(const char *fileName, void **data, int *len)
232 {
233 FILE * pFile;
234 pFile = fopen (fileName,"rb");
235 if (pFile==NULL)
236 {
237 LOG_ERROR("Can't open %s\n", fileName);
238 return ERROR_JTAG_DEVICE_ERROR;
239 }
240 if (fseek (pFile, 0, SEEK_END)!=0)
241 {
242 LOG_ERROR("Can't open %s\n", fileName);
243 fclose(pFile);
244 return ERROR_JTAG_DEVICE_ERROR;
245 }
246 *len=ftell (pFile);
247 if (*len==-1)
248 {
249 LOG_ERROR("Can't open %s\n", fileName);
250 fclose(pFile);
251 return ERROR_JTAG_DEVICE_ERROR;
252 }
253
254 if (fseek (pFile, 0, SEEK_SET)!=0)
255 {
256 LOG_ERROR("Can't open %s\n", fileName);
257 fclose(pFile);
258 return ERROR_JTAG_DEVICE_ERROR;
259 }
260 *data=malloc(*len+1);
261 if (*data==NULL)
262 {
263 LOG_ERROR("Can't open %s\n", fileName);
264 fclose(pFile);
265 return ERROR_JTAG_DEVICE_ERROR;
266 }
267
268 if (fread(*data, 1, *len, pFile)!=*len)
269 {
270 fclose(pFile);
271 free(*data);
272 LOG_ERROR("Can't open %s\n", fileName);
273 return ERROR_JTAG_DEVICE_ERROR;
274 }
275 fclose (pFile);
276 *(((char *)(*data))+*len)=0; /* sentinel */
277
278 return ERROR_OK;
279
280
281
282 }
283
284
285
286
287 int interface_jtag_execute_queue(void)
288 {
289 cyg_uint32 empty;
290
291 waitIdle();
292 ZY1000_PEEK(0x08000010, empty);
293 /* clear JTAG error register */
294 ZY1000_POKE(0x08000014, 0x400);
295
296 if ((empty&0x400)!=0)
297 {
298 LOG_WARNING("RCLK timeout");
299 /* the error is informative only as we don't want to break the firmware if there
300 * is a false positive.
301 */
302 // return ERROR_FAIL;
303 }
304 return ERROR_OK;
305 }
306
307
308
309
310
311 static cyg_uint32 getShiftValue()
312 {
313 cyg_uint32 value;
314 waitIdle();
315 ZY1000_PEEK(0x0800000c, value);
316 VERBOSE(LOG_INFO("getShiftValue %08x", value));
317 return value;
318 }
319 #if 0
320 static cyg_uint32 getShiftValueFlip()
321 {
322 cyg_uint32 value;
323 waitIdle();
324 ZY1000_PEEK(0x08000018, value);
325 VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));
326 return value;
327 }
328 #endif
329
330 #if 0
331 static void shiftValueInnerFlip(const enum tap_state state, const enum tap_state endState, int repeat, cyg_uint32 value)
332 {
333 VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_strings[state], tap_state_strings[endState], repeat, value));
334 cyg_uint32 a,b;
335 a=state;
336 b=endState;
337 ZY1000_POKE(0x0800000c, value);
338 ZY1000_POKE(0x08000008, (1<<15)|(repeat<<8)|(a<<4)|b);
339 VERBOSE(getShiftValueFlip());
340 }
341 #endif
342
343 extern int jtag_check_value(u8 *captured, void *priv);
344
345 static void gotoEndState()
346 {
347 setCurrentState(cmd_queue_end_state);
348 }
349
350 static __inline void scanFields(int num_fields, scan_field_t *fields, enum tap_state shiftState, int pause)
351 {
352 int i;
353 int j;
354 int k;
355
356 for (i = 0; i < num_fields; i++)
357 {
358 cyg_uint32 value;
359
360 static u8 *in_buff=NULL; /* pointer to buffer for scanned data */
361 static int in_buff_size=0;
362 u8 *inBuffer=NULL;
363
364
365 // figure out where to store the input data
366 int num_bits=fields[i].num_bits;
367 if (fields[i].in_value!=NULL)
368 {
369 inBuffer=fields[i].in_value;
370 } else if (fields[i].in_handler!=NULL)
371 {
372 if (in_buff_size*8<num_bits)
373 {
374 // we need more space
375 if (in_buff!=NULL)
376 free(in_buff);
377 in_buff=NULL;
378 in_buff_size=(num_bits+7)/8;
379 in_buff=malloc(in_buff_size);
380 if (in_buff==NULL)
381 {
382 LOG_ERROR("Out of memory");
383 jtag_error=ERROR_JTAG_QUEUE_FAILED;
384 return;
385 }
386 }
387 inBuffer=in_buff;
388 }
389
390 // here we shuffle N bits out/in
391 j=0;
392 while (j<num_bits)
393 {
394 enum tap_state pause_state;
395 int l;
396 k=num_bits-j;
397 pause_state=(shiftState==TAP_SD)?TAP_SD:TAP_SI;
398 if (k>32)
399 {
400 k=32;
401 /* we have more to shift out */
402 } else if (pause&&(i == num_fields-1))
403 {
404 /* this was the last to shift out this time */
405 pause_state=(shiftState==TAP_SD)?TAP_PD:TAP_PI;
406 }
407
408 // we have (num_bits+7)/8 bytes of bits to toggle out.
409 // bits are pushed out LSB to MSB
410 value=0;
411 if (fields[i].out_value!=NULL)
412 {
413 for (l=0; l<k; l+=8)
414 {
415 value|=fields[i].out_value[(j+l)/8]<<l;
416 }
417 }
418 /* mask away unused bits for easier debugging */
419 value&=~(((u32)0xffffffff)<<k);
420
421 shiftValueInner(shiftState, pause_state, k, value);
422
423 if (inBuffer!=NULL)
424 {
425 // data in, LSB to MSB
426 value=getShiftValue();
427 // we're shifting in data to MSB, shift data to be aligned for returning the value
428 value >>= 32-k;
429
430 for (l=0; l<k; l+=8)
431 {
432 inBuffer[(j+l)/8]=(value>>l)&0xff;
433 }
434 }
435 j+=k;
436 }
437
438 if (fields[i].in_handler!=NULL)
439 {
440 // invoke callback
441 int r=fields[i].in_handler(inBuffer, fields[i].in_handler_priv, fields+i);
442 if (r!=ERROR_OK)
443 {
444 /* this will cause jtag_execute_queue() to return an error */
445 jtag_error=r;
446 }
447 }
448 }
449 }
450
451 int interface_jtag_add_end_state(enum tap_state state)
452 {
453 return ERROR_OK;
454 }
455
456
457 int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
458 {
459
460 int i, j;
461 int scan_size = 0;
462 jtag_device_t *device;
463
464 for (i=0; i < jtag_num_devices; i++)
465 {
466 int pause=i==(jtag_num_devices-1);
467 int found = 0;
468 device = jtag_get_device(i);
469 scan_size = device->ir_length;
470
471 /* search the list */
472 for (j=0; j < num_fields; j++)
473 {
474 if (i == fields[j].device)
475 {
476 found = 1;
477
478 if ((jtag_verify_capture_ir)&&(fields[j].in_handler==NULL))
479 {
480 jtag_set_check_value(fields+j, device->expected, device->expected_mask, NULL);
481 } else if (jtag_verify_capture_ir)
482 {
483 fields[j].in_check_value = device->expected;
484 fields[j].in_check_mask = device->expected_mask;
485 }
486
487 scanFields(1, fields+j, TAP_SI, pause);
488 /* update device information */
489 buf_cpy(fields[j].out_value, jtag_get_device(i)->cur_instr, scan_size);
490
491 device->bypass = 0;
492 break;
493 }
494 }
495
496 if (!found)
497 {
498 /* if a device isn't listed, set it to BYPASS */
499 u8 ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
500
501 scan_field_t tmp;
502 memset(&tmp, 0, sizeof(tmp));
503 tmp.out_value = ones;
504 tmp.num_bits = scan_size;
505 scanFields(1, &tmp, TAP_SI, pause);
506 /* update device information */
507 buf_cpy(tmp.out_value, jtag_get_device(i)->cur_instr, scan_size);
508 device->bypass = 1;
509 }
510 }
511 gotoEndState();
512
513 return ERROR_OK;
514 }
515
516
517
518
519
520 int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
521 {
522 scanFields(num_fields, fields, TAP_SI, 1);
523 gotoEndState();
524
525 return ERROR_OK;
526 }
527
528 /*extern jtag_command_t **jtag_get_last_command_p(void);*/
529
530 int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
531 {
532 int i, j;
533 for (i=0; i < jtag_num_devices; i++)
534 {
535 int found = 0;
536 int pause = (i==(jtag_num_devices-1));
537
538 for (j=0; j < num_fields; j++)
539 {
540 if (i == fields[j].device)
541 {
542 found = 1;
543
544 scanFields(1, fields+j, TAP_SD, pause);
545 }
546 }
547 if (!found)
548 {
549 #ifdef _DEBUG_JTAG_IO_
550 /* if a device isn't listed, the BYPASS register should be selected */
551 if (!jtag_get_device(i)->bypass)
552 {
553 LOG_ERROR("BUG: no scan data for a device not in BYPASS");
554 exit(-1);
555 }
556 #endif
557
558 scan_field_t tmp;
559 /* program the scan field to 1 bit length, and ignore it's value */
560 tmp.num_bits = 1;
561 tmp.out_value = NULL;
562 tmp.out_mask = NULL;
563 tmp.in_value = NULL;
564 tmp.in_check_value = NULL;
565 tmp.in_check_mask = NULL;
566 tmp.in_handler = NULL;
567 tmp.in_handler_priv = NULL;
568
569 scanFields(1, &tmp, TAP_SD, pause);
570 }
571 else
572 {
573 #ifdef _DEBUG_JTAG_IO_
574 /* if a device is listed, the BYPASS register must not be selected */
575 if (jtag_get_device(i)->bypass)
576 {
577 LOG_WARNING("scan data for a device in BYPASS");
578 }
579 #endif
580 }
581 }
582 gotoEndState();
583 return ERROR_OK;
584 }
585
586 int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
587 {
588 scanFields(num_fields, fields, TAP_SD, 1);
589 gotoEndState();
590 return ERROR_OK;
591 }
592
593
594 int interface_jtag_add_tlr()
595 {
596 setCurrentState(TAP_TLR);
597 return ERROR_OK;
598 }
599
600
601
602
603 extern int jtag_nsrst_delay;
604 extern int jtag_ntrst_delay;
605
606 int interface_jtag_add_reset(int req_trst, int req_srst)
607 {
608 eCosBoard_reset(req_trst, req_srst);
609 return ERROR_OK;
610 }
611
612 int interface_jtag_add_runtest(int num_cycles, enum tap_state state)
613 {
614 /* num_cycles can be 0 */
615 setCurrentState(TAP_RTI);
616
617 /* execute num_cycles, 32 at the time. */
618 int i;
619 for (i=0; i<num_cycles; i+=32)
620 {
621 int num;
622 num=32;
623 if (num_cycles-i<num)
624 {
625 num=num_cycles-i;
626 }
627 shiftValueInner(TAP_RTI, TAP_RTI, num, 0);
628 }
629
630 #if !TEST_MANUAL()
631 /* finish in end_state */
632 setCurrentState(state);
633 #else
634 enum tap_state t=TAP_RTI;
635 /* test manual drive code on any target */
636 int tms;
637 u8 tms_scan = TAP_MOVE(t, state);
638
639 for (i = 0; i < 7; i++)
640 {
641 tms = (tms_scan >> i) & 1;
642 waitIdle();
643 ZY1000_POKE(0x08000028, tms);
644 }
645 waitIdle();
646 ZY1000_POKE(0x08000020, state);
647 #endif
648
649
650 return ERROR_OK;
651 }
652
653 int interface_jtag_add_sleep(u32 us)
654 {
655 jtag_sleep(us);
656 return ERROR_OK;
657 }
658
659 int interface_jtag_add_pathmove(int num_states, enum tap_state *path)
660 {
661 int state_count;
662 int tms = 0;
663
664 /*wait for the fifo to be empty*/
665 waitIdle();
666
667 state_count = 0;
668
669 enum tap_state cur_state=cmd_queue_cur_state;
670
671 while (num_states)
672 {
673 if (tap_transitions[cur_state].low == path[state_count])
674 {
675 tms = 0;
676 }
677 else if (tap_transitions[cur_state].high == path[state_count])
678 {
679 tms = 1;
680 }
681 else
682 {
683 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[state_count]]);
684 exit(-1);
685 }
686
687 waitIdle();
688 ZY1000_POKE(0x08000028, tms);
689
690 cur_state = path[state_count];
691 state_count++;
692 num_states--;
693 }
694
695 waitIdle();
696 ZY1000_POKE(0x08000020, cur_state);
697 return ERROR_OK;
698 }
699
700
701
702 void embeddedice_write_dcc(int chain_pos, int reg_addr, u8 *buffer, int little, int count)
703 {
704 // static int const reg_addr=0x5;
705 enum tap_state end_state=cmd_queue_end_state;
706 if (jtag_num_devices==1)
707 {
708 /* better performance via code duplication */
709 if (little)
710 {
711 int i;
712 for (i = 0; i < count; i++)
713 {
714 shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 1));
715 shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));
716 buffer+=4;
717 }
718 } else
719 {
720 int i;
721 for (i = 0; i < count; i++)
722 {
723 shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 0));
724 shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));
725 buffer+=4;
726 }
727 }
728 }
729 else
730 {
731 int i;
732 for (i = 0; i < count; i++)
733 {
734 embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
735 buffer += 4;
736 }
737 }
738 }
739

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)