dbg: add db_incorect_format
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / cmnos / dbg_api.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include "sys_cfg.h"
36 #include "athos_api.h"
37
38 #if defined(PROJECT_K2)
39 #if SYSTEM_MODULE_SFLASH
40 #include "sflash_api.h"
41 #endif
42 #endif /* #if defined(PROJECT_K2) */
43
44 #if defined(SYSTEM_MODULE_DBG)
45
46 /* Function prototypes */
47 static int db_help_cmd(char *, char *, char *, char *);
48 static int db_ldr_cmd(char *, char *, char *, char *);
49 static int db_str_cmd(char *, char *, char *, char *);
50 static int db_info_cmd(char *, char *, char *, char *);
51 static int db_usb_cmd(char *, char *, char *, char *);
52 static int db_intr_cmd(char *, char *, char *, char *);
53
54 static int db_cmd_starthtc(char *cmd, char *param1, char *param2, char *param3);
55
56 static int db_wdt_cmd(char *cmd, char *param1, char *param2, char *param3);
57
58 #if defined(PROJECT_K2)
59 #if SYSTEM_MODULE_SFLASH
60 static int db_cmd_sferase(char *cmd, char *param1, char *param2, char *param3);
61 static int db_cmd_sfpg(char *cmd, char *param1, char *param2, char *param3);
62 static int db_cmd_sfru(char *cmd, char *param1, char *param2, char *param3);
63 static int db_cmd_sfrm(char *cmd, char *param1, char *param2, char *param3);
64 static int db_cmd_sfrdsr(char *cmd, char *param1, char *param2, char *param3);
65 #endif
66 #endif /* #if defined(PROJECT_K2) */
67 static int db_cmd_memcmp(char *cmd, char *param1, char *param2, char *param3);
68 static int db_cmd_memdump(char *cmd, char *param1, char *param2, char *param3);
69
70 static int db_clock_cmd(char *cmd, char *param1, char *param2, char *param3);
71
72 static uint16_t db_get_cmd_line(uint8_t ch, char *cmd_line, uint16_t *i);
73 static int db_formalize_command(char *, char *);
74 static int db_ascii_to_hex(char *, unsigned long *);
75 static int db_hex_to_ascii(unsigned long, char *);
76 static void zf_debug_task(void);
77
78 /* Console debug command table */
79 const struct DB_COMMAND_STRUCT command_table[] =
80 {
81         {"HELP",   ", List all debug commands", db_help_cmd},
82         {"?",      ", Equal to HELP comamnd", db_help_cmd},
83
84         /* Basic load/store/dump command */
85         {"LDR",    "<Hex addr>, Load word", db_ldr_cmd},
86         {"LDRH",   "<Hex addr>, Load half word", db_ldr_cmd},
87         {"LDRB",   "<Hex addr>, Load byte", db_ldr_cmd},
88         {"STR",    "<Hex addr> <Hex value>, Store word", db_str_cmd},
89         {"STRH",   "<Hex addr> <Hex value>, Store half word", db_str_cmd},
90         {"STRB",   "<Hex addr> <Hex value>, Store byte", db_str_cmd},
91         {"INFO",   ", Print debug information", db_info_cmd},
92         {"USB",   ", usb releated command", db_usb_cmd},
93         {"INTR",   ", intr releated command", db_intr_cmd},
94         {"CLOCK",    ", change the clock...", db_clock_cmd},
95         {"HTCR", "Issue HTC ready to host", db_cmd_starthtc},
96         {"WDT",   ", wdt debug command", db_wdt_cmd},
97 #if defined(PROJECT_K2)
98 #if SYSTEM_MODULE_SFLASH
99         {"SFE", ", S<Hex>/B<Hex>/C, SPI Flash chip erase", db_cmd_sferase},
100         {"SFPG", "<Hex addr> <Hex len> <Hex buf>, SPI Flash program", db_cmd_sfpg},
101         {"SFRU", "f/r <Hex addr> <Hex addr>, SPI Flash fast read/read to UART", db_cmd_sfru},
102         {"SFRM", "f/r <Hex addr> <Hex addr>, SPI Flash fast read/read to Memory 0x520000", db_cmd_sfrm},
103         {"SFRDSR", ", SPI Flash status register read", db_cmd_sfrdsr},
104 #endif
105 #endif /* #if defined(PROJECT_K2) */
106         {"MEMCMP", "<Hex addr> <Hex addr> <Hex len>, memory comparison", db_cmd_memcmp},
107         {"MEMDMP", "<Hex addr> <Hex addr>, memory dump", db_cmd_memdump},
108         {"", "", 0}
109         /* {Command, Help description, function} */
110 };
111
112 char cmd_buffer[COMMAND_BUFFER_SIZE][DB_MAX_COMMAND_LENGTH]; /* Backup previous command */
113 int cmd_buf_ptr;
114 int cmd_buf_full;
115 char raw_cmd[DB_MAX_COMMAND_LENGTH];
116 char cmd_str[DB_MAX_COMMAND_LENGTH*4];
117 int cmd_not_found;
118 uint16_t gvLen;
119 int pressed_time;
120
121 static void db_incorect_format(void)
122 {
123         A_PRINTF("Error! Incorrect format.\n\r");
124 }
125
126 static void zf_debug_init(void)
127 {
128         uint8_t ch;
129
130         /* Purge Rx FIFO */
131         while ((zm_get_char(&ch)) != 0)
132         {
133         }
134
135         cmd_buf_ptr = 0;
136         cmd_buf_full = FALSE;
137         gvLen = 0;
138         pressed_time = 0;
139 }
140
141 static void zf_debug_task(void)
142 {
143         int i;
144         uint8_t ch;
145
146         if ((zm_get_char(&ch)) == 0)
147         {
148                 return;
149         }
150
151         if (db_get_cmd_line(ch, raw_cmd, &gvLen) == 0)
152         {
153                 return;
154         }
155
156         if (db_formalize_command(raw_cmd, cmd_str))
157         {
158                 gvLen = 0;
159                 i = 0;
160
161                 cmd_not_found = TRUE;
162                 while(command_table[i].cmd_func)
163                 {
164                         if (!strcmp(command_table[i].cmd_str, cmd_str))
165                         {
166                                 cmd_not_found = FALSE;
167                                 command_table[i].cmd_func(cmd_str,
168                                                           cmd_str+DB_MAX_COMMAND_LENGTH,
169                                                           cmd_str+DB_MAX_COMMAND_LENGTH*2,
170                                                           cmd_str+DB_MAX_COMMAND_LENGTH*3);
171                                 break;
172                         }
173                         i++;
174                 }
175                 if (cmd_not_found)
176                 {
177                         A_PRINTF("Error, HELP for command list.\n\r");
178                 }
179
180         }
181
182         A_PRINTF(">");
183         return;
184 }
185
186 static uint16_t db_get_cmd_line(uint8_t ch, char *cmd_line, uint16_t *i)
187 {
188         int cmd_buf_loc;
189
190         switch (ch)
191         {
192         case '\\' : /* Last command */
193                 pressed_time++;
194                 if (pressed_time >= COMMAND_BUFFER_SIZE)
195                 {
196                         pressed_time--;
197                 }
198                 cmd_buf_loc = cmd_buf_ptr - pressed_time;
199                 if (cmd_buf_loc < 0)
200                 {
201                         if (cmd_buf_full == TRUE)
202                         {
203                                 cmd_buf_loc += COMMAND_BUFFER_SIZE;
204                         }
205                         else
206                         {
207                                 cmd_buf_loc = 0;
208                         }
209                 }
210
211                 if (A_STRLEN(cmd_buffer[cmd_buf_loc]) != 0)
212                 {
213                         A_STRCPY(cmd_line, cmd_buffer[cmd_buf_loc]);
214                         *i = A_STRLEN(cmd_buffer[cmd_buf_loc]);
215                         A_PRINTF("\r>");
216                         A_PRINTF("%s", cmd_line);
217                 }
218                 break;
219         case 13 : /* Return */
220                 pressed_time = 0;
221                 cmd_line[*i] = 0;
222                 A_PRINTF("\n\r");
223                 if (*i != 0)
224                 {
225                         //Filter duplicated string in command history
226                         if (strcmp(cmd_buffer[(cmd_buf_ptr==0)?(COMMAND_BUFFER_SIZE-1):(cmd_buf_ptr-1)], cmd_line) != 0)
227                         {
228                                 A_STRCPY(cmd_buffer[cmd_buf_ptr++], cmd_line);
229                         }
230                 }
231                 if (cmd_buf_ptr >= COMMAND_BUFFER_SIZE)
232                 {
233                         cmd_buf_ptr = 0;
234                         cmd_buf_full = TRUE;
235                 }
236                 return 1;
237         case '\b' : /* Backspace */
238                 pressed_time = 0;
239                 if (*i > 0)
240                 {
241                         *i = *i-1;
242                         A_PRINTF("\b \b");
243                 }
244                 break;
245         case 0 : //None
246                 break;
247         default :
248                 if ((ch >= ' ') && (ch <= '~'))
249                 {
250                         pressed_time = 0;
251                         if (*i < DB_MAX_COMMAND_LENGTH-2)
252                         {
253                                 if ((ch >= 0x11) && (ch <= 0x7e))
254                                 {
255                                         //if ((buf <= 'z') && (buf >= 'a'))
256                                         //{
257                                         //    buf -= 'a' - 'A';
258                                         //}
259                                         cmd_line[*i] = ch;
260                                         *i = *i + 1;
261                                         A_PRINTF("%c", ch);
262                                 }
263                         }
264                 }
265                 else
266                 {
267                         ch = 7; /* Beep */
268                         A_PRINTF("%c", ch);
269                 }
270                 break;
271         } /* end of switch */
272
273         return 0;
274
275 }
276
277 static int db_formalize_command(char *raw_str,  char *cmd_str)
278 {
279         int i = 0;
280         int j;
281         int k;
282
283
284         for (k=0; k<4; k++)
285         {
286                 /* Remove preceeding spaces */
287                 while (raw_str[i++] == ' '){}
288                 i--;
289
290                 /* Copy command string */
291                 j = 0;
292                 while(raw_str[i] && (raw_str[i] != ' '))
293                 {
294                         if (k == 0)
295                         {
296                                 if ((raw_str[i] <= 'z') && (raw_str[i] >= 'a'))
297                                 {
298                                         raw_str[i] -= 'a' - 'A';
299                                 }
300                                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j++] = raw_str[i++];
301                         }
302                         else
303                         {
304                                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j++] = raw_str[i++];
305                         }
306                 }
307                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j] = 0;
308         }
309         return (int)A_STRLEN(cmd_str);
310 }
311
312 static int db_ascii_to_hex(char *num_str, unsigned long *hex_num)
313 {
314         int i = 0;
315
316         *hex_num = 0;
317         while (num_str[i])
318         {
319                 if ((num_str[i] >= '0') && (num_str[i] <= '9'))
320                 {
321                         *hex_num <<= 4;
322                         *hex_num += (num_str[i] - '0');
323                 }
324                 else if ((num_str[i] >= 'A') && (num_str[i] <= 'F'))
325                 {
326                         *hex_num <<= 4;
327                         *hex_num += (num_str[i] - 'A' + 10);
328                 }
329                 else if ((num_str[i] >= 'a') && (num_str[i] <= 'f'))
330                 {
331                         *hex_num <<= 4;
332                         *hex_num += (num_str[i] - 'a' + 10);
333                 }
334                 else
335                 {
336                         return -1;
337                 }
338                 i++;
339         }
340         return 0;
341 }
342
343 int db_ascii_to_int(char *num_str, unsigned long *int_num)
344 {
345         int i = 0;
346
347         *int_num = 0;
348         while (num_str[i])
349         {
350                 if ((num_str[i] >= '0') && (num_str[i] <= '9'))
351                 {
352                         *int_num *= 10;
353                         *int_num += (num_str[i] - '0');
354                 }
355                 else
356                 {
357                         return -1;
358                 }
359                 i++;
360         }
361         return 0;
362 }
363
364 static int db_hex_to_ascii(unsigned long hex_num, char *num_str)
365 {
366         int i;
367         unsigned long four_bits;
368
369         for (i=7; i>=0; i--)
370         {
371                 four_bits = (hex_num >> i*4) & 0xf;
372                 if (four_bits < 10)
373                 {
374                         num_str[7-i] = four_bits + '0';
375                 }
376                 else
377                 {
378                         num_str[7-i] = four_bits - 10 + 'A';
379                 }
380         }
381         num_str[8] = 0;
382         return 0;
383 }
384
385 int db_help_cmd(char *cmd, char *param1, char *param2, char *param3)
386 {
387         int i;
388
389         i = 0;
390
391         A_PRINTF("%s %s\n", ATH_DEBUGGER_VERSION_STR, ATH_COMMAND_LIST_STR);
392
393         while (command_table[i].cmd_func)
394         {
395                 A_PRINTF("%s\t%s\n\r", command_table[i].cmd_str,
396                                        command_table[i].help_str);
397                 i++;
398         }
399         return i;
400 }
401
402 static int db_ldr_cmd(char *cmd, char *param1, char *param2, char *param3)
403 {
404         unsigned long val;
405         unsigned long addr;
406         char val_str[20];
407         char addr_str[20];
408
409         if (db_ascii_to_hex(param1, &addr) != -1)
410         {
411                 if( addr == 0 )
412                 {
413                         A_PRINTF("Error! bad address 0x%08x.\n\r",
414                                  (unsigned long)addr);
415                         return -1;
416                 }
417                 if (strcmp(cmd, "LDR") == 0)
418                 {
419                         addr &= 0xfffffffc;
420                         //val = *(unsigned long *)addr;
421
422                         val = HAL_WORD_REG_READ(addr);
423                 }
424                 else if (strcmp(cmd, "LDRH") == 0)
425                 {
426                         addr &= 0xfffffffe;
427                         val = HAL_HALF_WORD_REG_READ(addr);
428                 }
429                 else if (strcmp(cmd, "LDRB") == 0)
430                 {
431                 }
432
433                 db_hex_to_ascii(val, val_str);
434                 db_hex_to_ascii(addr, addr_str);
435
436                 A_PRINTF("%s : %s\n\r", addr_str, val_str);
437                 return 0;
438         }
439
440         db_incorect_format();
441         return -1;
442 }
443
444 static int db_str_cmd(char *cmd, char *param1, char *param2, char *param3)
445 {
446         unsigned long val;
447         unsigned long addr;
448         char val_str[20];
449         char addr_str[20];
450
451         if ((A_STRLEN(param2) > 0) &&
452             (db_ascii_to_hex(param1, &addr) != -1) &&
453             (db_ascii_to_hex(param2, &val) != -1))
454         {
455                 if (strcmp(cmd, "STR") == 0)
456                 {
457                         addr &= 0xfffffffc;
458                         //HAL_WORD_REG_WRITE(addr, val);
459                         HAL_WORD_REG_WRITE(addr, val);
460                         //*(volatile unsigned long *)(addr & 0xfffffffc) = (unsigned long)val;
461                 }
462
463                 else if (strcmp(cmd, "STRH") == 0)
464                 {
465                         addr &= 0xfffffffe;
466                         //*(volatile unsigned short *)(addr & 0xfffffffe) = (unsigned short)val;
467                         HAL_HALF_WORD_REG_WRITE(addr, val);
468                 }
469                 else if (strcmp(cmd, "STRB") == 0)
470                 {
471                         if( addr & 0x00f00000 )
472                                 HAL_BYTE_REG_WRITE(addr, val);
473                         else
474                                 HAL_BYTE_REG_WRITE(addr^3, val);
475                         //*(volatile unsigned char *)addr = (unsigned char)val;
476                 }
477
478                 db_hex_to_ascii(val, val_str);
479                 db_hex_to_ascii(addr, addr_str);
480
481                 A_PRINTF("%s : %s\n\r", addr_str, val_str);
482                 return 0;
483         }
484
485         db_incorect_format();
486         return -1;
487 }
488
489 LOCAL void dbg_timer_func(A_HANDLE alarm, void *data)
490 {
491         A_PRINTF("this is a timer alarm function 0x%08x\n\r", xthal_get_ccount());
492 }
493
494 uint32_t delay = 0;
495
496 static int db_intr_cmd(char *cmd, char *param1, char *param2, char *param3)
497 {
498 #if SYSTEM_MODULE_INTR
499         uint32_t pending_intrs;
500
501         if(strcmp(param1, "read") == 0 )
502         {
503                 {
504                         /* Update snapshot of pending interrupts */
505
506                         pending_intrs = A_INTR_GET_INTRPENDING();
507
508                         A_PRINTF("intr mask [0x%08x]\n\r", xthal_get_intenable());
509                         A_PRINTF("intr on [0x%08x]\n\r", pending_intrs);
510                 }
511         }
512         else if (strcmp(param1, "timer") == 0 )
513         {
514                 uint32_t data = 0;
515
516                 if (strcmp(param2, "on") == 0 )
517                 {
518                         /* TODO: this part is probably dead. */
519                         pending_intrs = A_INTR_GET_INTRENABLE()|CMNOS_IMASK_XTTIMER;
520                         A_INTR_SET_INTRENABLE(pending_intrs);
521                         A_PRINTF("- intr [0x%08x]\n\r", pending_intrs);
522                 }
523                 else if ( strcmp(param2, "off") == 0 )
524                 {
525                         pending_intrs = A_INTR_GET_INTRENABLE()&(~CMNOS_IMASK_XTTIMER);
526                         A_INTR_SET_INTRENABLE(pending_intrs);
527                         A_PRINTF("- intr [0x%08x]\n\r", pending_intrs);
528             
529                 }
530                 else if( db_ascii_to_hex(param2, &data)==0 )
531                 {
532                         if( data>=0 && data <=10 )
533                                 delay = data;
534                         else
535                                 delay = 3;
536             
537                         A_PRINTF("==>set cb to %d seconds \n\r", delay);
538                 }
539
540         }
541         else
542         {
543                 A_PRINTF("\tintr read - read the interrenable status\n\r");
544                 A_PRINTF("\tintr timer on/off/tick - timer attach on/off/ticks\n\r");
545
546         }
547
548 #endif //#if SYSTEM_MODULE_INTR
549         return 0;
550 }
551
552 static int db_usb_cmd(char *cmd, char *param1, char *param2, char *param3)
553 {
554         A_PRINTF("THIS IS USB COMMAND\n\r");
555
556         if( strcmp(param1, "que") == 0 )
557         {
558                 HIFusb_DescTraceDump();
559         }
560         else
561         {
562                 A_PRINTF("\tusb que - dump descriptor queue\n\r");
563                 A_PRINTF("\tusb fw on/off - enable/disable write fw download to ram\n\r");
564
565         }
566         return 0;
567 }
568
569 static void clk_change(uint32_t clk, uint32_t ratio, uint32_t baud)
570 {
571         uint32_t clk_sel = 0;
572
573         switch(clk){
574         case 22:
575                 clk_sel = 0;
576                 break;
577         case 88:
578                 clk_sel = 1;
579                 break;
580         case 44:
581                 clk_sel = 2;
582                 break;
583         case 117:
584                 clk_sel = 4;
585                 break;
586         case 40:
587                 clk_sel = 6;            
588                 break;
589         default:
590                 clk_sel = 6;
591                 break;
592         }
593
594         HAL_WORD_REG_WRITE(0x50040, (0x300|clk_sel|(ratio>>1)<<12));
595         A_UART_HWINIT((clk*1000*1000)/ratio, baud);
596
597 }
598
599 static int db_clock_cmd(char *cmd, char *param1, char *param2, char *param3)
600 {
601         uint32_t ratio = 1;
602         uint32_t baud = 19200;
603         uint32_t clk = 0;
604     
605         if( db_ascii_to_int(param1, &clk) != -1 )
606         {
607                 A_PRINTF("changing clock to %d\n", clk);
608                 clk_change(clk, ratio, baud);
609         }
610 }
611
612 static int db_info_cmd(char *cmd, char *param1, char *param2, char *param3)
613 {
614 #if 1
615
616         if(strcmp(param1, "ram") == 0 )
617         {
618                 A_ALLOCRAM_DEBUG();
619         }
620 #if 0  /* TODO: SYSTEM_MODULE_SYS_MONITOR depends on _ROM_ or _RAM_ which
621         * is dead too */
622         else if(strcmp(param1, "cpu") == 0)
623                 zfPrintCpuUtilization();
624 #endif
625         else   // defalut dump
626                 HIFusb_DescTraceDump();
627
628         return 1;
629
630 #else
631     
632         {
633                 uint32_t ccount1;
634                 uint32_t ccount2;
635
636                 uint32_t data;
637                 register uint32_t data1;
638                 if( db_ascii_to_hex(param1, &data1)==0 )
639                 {
640                         __asm__ __volatile__ (
641                                 "rsr     %0, ccount"
642                                 : "=a" (ccount1) : : "memory"
643                                 );
644                         data = *(volatile uint32_t *)(data1);
645                         __asm__ __volatile__ (
646                                 "rsr     %0, ccount"
647                                 : "=a" (ccount2) : : "memory"
648                                 );
649                         A_PRINTF("\n\rread 0x%08x (0x%08x) use %d clocks\n\r", data1, data, ccount2-ccount1);
650                 }
651
652                 __asm__ __volatile__ (
653                         "rsr     %0, ccount"
654                         : "=a" (ccount1) : : "memory"
655                         );
656                 data = *(volatile uint32_t *)(data1);
657                 __asm__ __volatile__ (
658                         "rsr     %0, ccount"
659                         : "=a" (ccount2) : : "memory"
660                         );
661                 A_PRINTF("\n\rread 0x%08x (0x%08x) use %d clocks\n\r", data1, data, ccount2-ccount1);
662
663
664                 __asm__ __volatile__ (
665                         "rsr     %0, ccount"
666                         : "=a" (ccount1) : : "memory"
667                         );
668                 data = *(volatile uint32_t *)(data2);
669                 __asm__ __volatile__ (
670                         "rsr     %0, ccount"
671                         : "=a" (ccount2) : : "memory"
672                         );
673                 A_PRINTF("read 0x%08x (0x%08x) use %d clocks\n\r", data2, data, ccount2-ccount1);
674
675
676                 __asm__ __volatile__ (
677                         "rsr     %0, ccount"
678                         : "=a" (ccount1) : : "memory"
679                         );
680                 data = *(volatile uint32_t *)(data3);
681                 __asm__ __volatile__ (
682                         "rsr     %0, ccount"
683                         : "=a" (ccount2) : : "memory"
684                         );
685                 A_PRINTF("read 0x%08x (0x%08x) use %d clocks\n\r", data3, data, ccount2-ccount1);
686
687         }
688 #endif
689         return 1;
690 }
691
692 static int db_cmd_starthtc(char *cmd, char *param1, char *param2, char *param3)
693 {
694     extern htc_handle_t htc_handle;
695     HTC_Ready(htc_handle);
696 }
697
698 static int db_wdt_cmd(char *cmd, char *param1, char *param2, char *param3)
699 {
700         if ( strcmp(param1, "rst") == 0 )
701         {
702                 A_PRINTF(" reseting.....................\n\n\r");
703                 A_WDT_RESET();
704         }
705         else if( strcmp(param1, "on") == 0 )
706         {
707                 A_WDT_ENABLE();
708         }
709         else if (strcmp(param1, "off") == 0 )
710         {
711                 A_WDT_DISABLE();
712         }
713         else if ( strcmp(param1, "boot") == 0 )
714         {
715                 if (ENUM_WDT_BOOT == A_WDT_LASTBOOT() )
716                         A_PRINTF("LAST BOOT IS %s", "wdt");
717                 else
718                         A_PRINTF("LAST BOOT IS %s", "normal boot");
719         }
720         else if (strcmp(param1, "loop") == 0 )
721         {
722                 T_WDT_CMD wdt_cmd;
723                 uint32_t time_offset;
724                 A_PRINTF(" doing the wdt reseting................\n\n\r");
725
726                 if( db_ascii_to_hex(param2, &time_offset)!=0 )
727                 {
728                         if( time_offset < 0 || time_offset >0xffffffff )
729                                 time_offset = 0xffffff;
730                 }
731                 A_PRINTF(" doing the wdt reseting (wdt tick: 0x%08x................\n\n\r", time_offset);
732                 wdt_cmd.cmd = WDT_TIMEOUT;
733                 wdt_cmd.timeout = time_offset;
734
735                 A_WDT_SET(wdt_cmd);
736                 while(1) ;
737         }
738         else if (strcmp(param1, "noloop") == 0 )
739         {
740                 T_WDT_CMD wdt_cmd;
741                 uint32_t time_offset;
742                 A_PRINTF(" doing the wdt reseting................\n\n\r");
743
744                 if( db_ascii_to_hex(param3, &time_offset)!=0 )
745                 {
746                         if( time_offset < 0 || time_offset >0xffffffff )
747                                 time_offset = 0xffffff;
748                 }
749                 A_PRINTF(" doing the wdt reseting (wdt tick: 0x%08x................\n\n\r", time_offset);
750
751                 wdt_cmd.cmd = WDT_TIMEOUT;
752                 wdt_cmd.timeout = time_offset;
753
754                 A_WDT_SET(wdt_cmd);
755         }
756         else if( strcmp(param1, "event") == 0 )
757         {
758                 uint32_t event= 0x00123400;
759 #define USB_BYTE_REG_WRITE(addr, val)           HAL_BYTE_REG_WRITE(USB_CTRL_BASE_ADDRESS|(uint8_t)(addr^3), (val))
760 #define USB_BYTE_REG_READ(addr)                 HAL_BYTE_REG_READ(USB_CTRL_BASE_ADDRESS|(uint8_t)(addr^3))
761
762 #define USB_WORD_REG_WRITE(addr, val)           HAL_WORD_REG_WRITE(USB_CTRL_BASE_ADDRESS|(uint32_t)(addr), (val))
763 #define USB_WORD_REG_READ(addr)                 HAL_WORD_REG_READ(USB_CTRL_BASE_ADDRESS|(uint32_t)(addr))
764
765                 // disable ep3 intr
766                 USB_BYTE_REG_WRITE(0x17, USB_BYTE_REG_READ(0x17)|0xc0);
767
768                 //ZM_CBUS_FIFO_SIZE_REG = 0xf;
769                 USB_WORD_REG_WRITE(0x100, 0x0f);
770
771                 //ZM_EP3_DATA_REG = event;
772                 USB_WORD_REG_WRITE(0xF8, event);
773
774                 // tx done
775                 USB_BYTE_REG_WRITE(0xAE, USB_BYTE_REG_READ(0xAE)|0x08);
776
777                 // enable ep3 intr
778                 USB_BYTE_REG_WRITE(0x17, USB_BYTE_REG_READ(0x17)&0xbf);
779         }
780 }
781
782 #if defined(PROJECT_K2)
783 #if SYSTEM_MODULE_SFLASH
784 /* Serial Flash -> Chip Erase, Sector Erase, Block Erase */
785 static int db_cmd_sferase(char *cmd, char *param1, char *param2, char *param3)
786 {
787         unsigned long       addr;
788
789         if (strcmp(param1, "s") == 0)
790         {
791                 if (db_ascii_to_hex(param2, &addr) != -1 && addr < SPI_FLASH_MAX_SIZE)
792                 {
793                         /* Sector size is 4K (0x1000) */
794                         A_PRINTF("Sector addr : 0x%08X\n\r", addr - addr%0x1000);
795                         A_SFLASH_ERASE(ZM_SFLASH_SECTOR_ERASE, addr);
796
797                         return 0;
798                 }
799
800                 db_incorect_format();
801                 return -1;
802         }
803         else if (strcmp(param2, "b") == 0)
804         {
805                 if (db_ascii_to_hex(param2, &addr) != -1 && addr < SPI_FLASH_MAX_SIZE)
806                 {
807                         /* Sector size is 64K (0x10000) */
808                         A_PRINTF("Block addr : 0x%08X\n\r", addr - addr%0x10000);
809                         A_SFLASH_ERASE(ZM_SFLASH_BLOCK_ERASE, addr);
810
811                         return 0;
812                 }
813
814                 db_incorect_format();
815                 return -1;
816
817         }
818         else if (strcmp(param1, "c") == 0)
819         {
820                 A_SFLASH_ERASE(ZM_SFLASH_CHIP_ERASE, addr);
821
822                 A_PRINTF("\n\r");
823                 return 0;
824         }
825         else
826         {
827                 A_PRINTF("Error! Unknown command.\n\r");
828                 return -1;
829         }
830 }
831
832 /* Serial Flash -> Program */
833 static int db_cmd_sfpg(char *cmd, char *param1, char *param2, char *param3)
834 {
835         unsigned long       addr, len, buf;
836
837         if (db_ascii_to_hex(param1, &addr) != -1 &&
838             db_ascii_to_hex(param2, &len) != -1 &&
839             db_ascii_to_hex(param3, &buf) != -1 &&
840             ((addr+len) <= SPI_FLASH_MAX_SIZE) &&
841             addr%4 == 0 && len%4 == 0 && buf%4 == 0 &&
842             ((buf >=0x500000 && buf < 0x528000) || (buf >=0x4e0000 && buf < 0x4e6000)) )
843         {
844                 A_SFLASH_PROG(addr, len, (A_UINT8 *)buf);
845
846                 A_PRINTF("\n\r");
847                 return 0;
848         }
849
850         db_incorect_format();
851         return -1;
852 }
853
854 /* Serial Flash -> Read, Fast Read to UART */
855 static int db_cmd_sfru(char *cmd, char *param1, char *param2, char *param3)
856 {
857         A_UINT32            i;
858         unsigned long       addr1, addr2, t_addr;
859         A_UINT32            fast, val;
860
861         if (strcmp(param1, "r") == 0)
862                 fast = 0;
863         else if (strcmp(param1, "f") == 0)
864                 fast = 1;
865         else
866         {
867                 A_PRINTF("Error! Unknown command.\n\r");
868                 return -1;
869         }
870
871         if (db_ascii_to_hex(param2, &addr1) != -1 &&
872             db_ascii_to_hex(param3, &addr2) != -1 &&
873             addr1 < addr2 && addr1 < SPI_FLASH_MAX_SIZE &&
874             addr2 < SPI_FLASH_MAX_SIZE && addr1%4 == 0)
875         {
876                 A_PRINTF("addr    data     data     data     data     data     data     data     data\n\r");
877                 A_PRINTF("======  ======== ======== ======== ======== ======== ======== ======== ========");
878
879                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
880                 {
881                         if ((i%8) == 0)
882                                 A_PRINTF("\n\r%06X  ", t_addr);
883
884                         A_SFLASH_READ(fast, t_addr, 4, (A_UINT8 *)&val);
885                         A_PRINTF("%08X ", val);
886                 }
887
888                 A_PRINTF("\n\r");
889                 return 0;
890         }
891
892         db_incorect_format();
893         return -1;
894 }
895
896 /* Serial Flash -> Read, Fast Read to Memory */
897 static int db_cmd_sfrm(char *cmd, char *param1, char *param2, char *param3)
898 {
899         A_UINT32            i;
900         unsigned long       addr1, addr2, t_addr;
901         A_UINT32            fast;
902         A_UINT8             *buf = (A_UINT8 *)0x520000;
903
904         if (strcmp(param1, "r") == 0)
905                 fast = 0;
906         else if (strcmp(param1, "f") == 0)
907                 fast = 1;
908         else
909         {
910                 A_PRINTF("Error! Unknown command.\n\r");
911                 return -1;
912         }
913
914         if (db_ascii_to_hex(param2, &addr1) != -1 &&
915             db_ascii_to_hex(param3, &addr2) != -1 &&
916             addr1 < addr2 && addr1 < SPI_FLASH_MAX_SIZE &&
917             addr2 < SPI_FLASH_MAX_SIZE && addr1%4 == 0)
918         {
919                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
920                 {
921                         A_SFLASH_READ(fast, t_addr, 4, buf + i*4);
922                 }
923
924                 A_PRINTF("\n\r");
925                 return 0;
926         }
927
928         db_incorect_format();
929         return -1;
930 }
931
932 /* Serial Flash -> Read Status Register */
933 static int db_cmd_sfrdsr(char *cmd, char *param1, char *param2, char *param3)
934 {
935         A_PRINTF("0x%02X\n\r", A_SFLASH_RDSR());
936         return 0;
937 }
938 #endif
939 #endif /* #if defined(PROJECT_K2) */
940
941 /* Memory Comparison */
942 static int db_cmd_memcmp(char *cmd, char *param1, char *param2, char *param3)
943 {
944         unsigned long       addr1, addr2, len;
945         A_UINT8             *buf1, *buf2;
946
947         if (db_ascii_to_hex(param1, &addr1) != -1 &&
948             db_ascii_to_hex(param2, &addr2) != -1 &&
949             db_ascii_to_hex(param3, &len) != -1 &&
950             addr1 != addr2 && addr1%4 == 0 && addr2%4 == 0 && len%4 == 0)
951         {
952                 buf1 = (A_UINT8 *)addr1;
953                 buf2 = (A_UINT8 *)addr2;        ;
954
955                 A_PRINTF("memcmp(buf1, buf2, len) = %d\n\r", A_MEMCMP(buf1, buf2, len));
956                 return 0;
957         }
958
959         db_incorect_format();
960         return -1;
961 }
962
963 /* Memory Dump */
964 static int db_cmd_memdump(char *cmd, char *param1, char *param2, char *param3)
965 {
966         A_UINT32            i;
967         unsigned long       addr1, addr2, t_addr;
968         A_UINT32            *val;
969
970         if (db_ascii_to_hex(param1, &addr1) != -1 && db_ascii_to_hex(param2, &addr2) != -1 && addr1 < addr2 && addr1%4 == 0)
971         {
972                 A_PRINTF("addr    data     data     data     data     data     data     data     data\n\r");
973                 A_PRINTF("======  ======== ======== ======== ======== ======== ======== ======== ========");
974
975                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
976                 {
977                         if ((i%8) == 0)
978                                 A_PRINTF("\n\r%06X  ", t_addr);
979
980                         val = (A_UINT32 *)t_addr;
981                         A_PRINTF("%08X ", *val);
982                 }
983
984                 A_PRINTF("\n\r");
985                 return 0;
986         }
987
988         db_incorect_format();
989         return -1;
990 }
991 void cmnos_dbg_module_install(struct dbg_api *apis)
992 {
993         apis->_dbg_init = zf_debug_init;
994         apis->_dbg_task = zf_debug_task;
995 }
996
997 #endif  /* SYSTEM_MODULE_DBG */
998