dbg: add new db_unknown_command function to reduce redundand code
[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 db_unknown_command(void)
127 {
128         A_PRINTF("Error! Unknown command.\n\r");
129 }
130
131 static void zf_debug_init(void)
132 {
133         uint8_t ch;
134
135         /* Purge Rx FIFO */
136         while ((zm_get_char(&ch)) != 0)
137         {
138         }
139
140         cmd_buf_ptr = 0;
141         cmd_buf_full = FALSE;
142         gvLen = 0;
143         pressed_time = 0;
144 }
145
146 static void zf_debug_task(void)
147 {
148         int i;
149         uint8_t ch;
150
151         if ((zm_get_char(&ch)) == 0)
152         {
153                 return;
154         }
155
156         if (db_get_cmd_line(ch, raw_cmd, &gvLen) == 0)
157         {
158                 return;
159         }
160
161         if (db_formalize_command(raw_cmd, cmd_str))
162         {
163                 gvLen = 0;
164                 i = 0;
165
166                 cmd_not_found = TRUE;
167                 while(command_table[i].cmd_func)
168                 {
169                         if (!strcmp(command_table[i].cmd_str, cmd_str))
170                         {
171                                 cmd_not_found = FALSE;
172                                 command_table[i].cmd_func(cmd_str,
173                                                           cmd_str+DB_MAX_COMMAND_LENGTH,
174                                                           cmd_str+DB_MAX_COMMAND_LENGTH*2,
175                                                           cmd_str+DB_MAX_COMMAND_LENGTH*3);
176                                 break;
177                         }
178                         i++;
179                 }
180                 if (cmd_not_found)
181                 {
182                         A_PRINTF("Error, HELP for command list.\n\r");
183                 }
184
185         }
186
187         A_PRINTF(">");
188         return;
189 }
190
191 static uint16_t db_get_cmd_line(uint8_t ch, char *cmd_line, uint16_t *i)
192 {
193         int cmd_buf_loc;
194
195         switch (ch)
196         {
197         case '\\' : /* Last command */
198                 pressed_time++;
199                 if (pressed_time >= COMMAND_BUFFER_SIZE)
200                 {
201                         pressed_time--;
202                 }
203                 cmd_buf_loc = cmd_buf_ptr - pressed_time;
204                 if (cmd_buf_loc < 0)
205                 {
206                         if (cmd_buf_full == TRUE)
207                         {
208                                 cmd_buf_loc += COMMAND_BUFFER_SIZE;
209                         }
210                         else
211                         {
212                                 cmd_buf_loc = 0;
213                         }
214                 }
215
216                 if (A_STRLEN(cmd_buffer[cmd_buf_loc]) != 0)
217                 {
218                         A_STRCPY(cmd_line, cmd_buffer[cmd_buf_loc]);
219                         *i = A_STRLEN(cmd_buffer[cmd_buf_loc]);
220                         A_PRINTF("\r>");
221                         A_PRINTF("%s", cmd_line);
222                 }
223                 break;
224         case 13 : /* Return */
225                 pressed_time = 0;
226                 cmd_line[*i] = 0;
227                 A_PRINTF("\n\r");
228                 if (*i != 0)
229                 {
230                         //Filter duplicated string in command history
231                         if (strcmp(cmd_buffer[(cmd_buf_ptr==0)?(COMMAND_BUFFER_SIZE-1):(cmd_buf_ptr-1)], cmd_line) != 0)
232                         {
233                                 A_STRCPY(cmd_buffer[cmd_buf_ptr++], cmd_line);
234                         }
235                 }
236                 if (cmd_buf_ptr >= COMMAND_BUFFER_SIZE)
237                 {
238                         cmd_buf_ptr = 0;
239                         cmd_buf_full = TRUE;
240                 }
241                 return 1;
242         case '\b' : /* Backspace */
243                 pressed_time = 0;
244                 if (*i > 0)
245                 {
246                         *i = *i-1;
247                         A_PRINTF("\b \b");
248                 }
249                 break;
250         case 0 : //None
251                 break;
252         default :
253                 if ((ch >= ' ') && (ch <= '~'))
254                 {
255                         pressed_time = 0;
256                         if (*i < DB_MAX_COMMAND_LENGTH-2)
257                         {
258                                 if ((ch >= 0x11) && (ch <= 0x7e))
259                                 {
260                                         //if ((buf <= 'z') && (buf >= 'a'))
261                                         //{
262                                         //    buf -= 'a' - 'A';
263                                         //}
264                                         cmd_line[*i] = ch;
265                                         *i = *i + 1;
266                                         A_PRINTF("%c", ch);
267                                 }
268                         }
269                 }
270                 else
271                 {
272                         ch = 7; /* Beep */
273                         A_PRINTF("%c", ch);
274                 }
275                 break;
276         } /* end of switch */
277
278         return 0;
279
280 }
281
282 static int db_formalize_command(char *raw_str,  char *cmd_str)
283 {
284         int i = 0;
285         int j;
286         int k;
287
288
289         for (k=0; k<4; k++)
290         {
291                 /* Remove preceeding spaces */
292                 while (raw_str[i++] == ' '){}
293                 i--;
294
295                 /* Copy command string */
296                 j = 0;
297                 while(raw_str[i] && (raw_str[i] != ' '))
298                 {
299                         if (k == 0)
300                         {
301                                 if ((raw_str[i] <= 'z') && (raw_str[i] >= 'a'))
302                                 {
303                                         raw_str[i] -= 'a' - 'A';
304                                 }
305                                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j++] = raw_str[i++];
306                         }
307                         else
308                         {
309                                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j++] = raw_str[i++];
310                         }
311                 }
312                 cmd_str[k*DB_MAX_COMMAND_LENGTH + j] = 0;
313         }
314         return (int)A_STRLEN(cmd_str);
315 }
316
317 static int db_ascii_to_hex(char *num_str, unsigned long *hex_num)
318 {
319         int i = 0;
320
321         *hex_num = 0;
322         while (num_str[i])
323         {
324                 if ((num_str[i] >= '0') && (num_str[i] <= '9'))
325                 {
326                         *hex_num <<= 4;
327                         *hex_num += (num_str[i] - '0');
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 if ((num_str[i] >= 'a') && (num_str[i] <= 'f'))
335                 {
336                         *hex_num <<= 4;
337                         *hex_num += (num_str[i] - 'a' + 10);
338                 }
339                 else
340                 {
341                         return -1;
342                 }
343                 i++;
344         }
345         return 0;
346 }
347
348 int db_ascii_to_int(char *num_str, unsigned long *int_num)
349 {
350         int i = 0;
351
352         *int_num = 0;
353         while (num_str[i])
354         {
355                 if ((num_str[i] >= '0') && (num_str[i] <= '9'))
356                 {
357                         *int_num *= 10;
358                         *int_num += (num_str[i] - '0');
359                 }
360                 else
361                 {
362                         return -1;
363                 }
364                 i++;
365         }
366         return 0;
367 }
368
369 static int db_hex_to_ascii(unsigned long hex_num, char *num_str)
370 {
371         int i;
372         unsigned long four_bits;
373
374         for (i=7; i>=0; i--)
375         {
376                 four_bits = (hex_num >> i*4) & 0xf;
377                 if (four_bits < 10)
378                 {
379                         num_str[7-i] = four_bits + '0';
380                 }
381                 else
382                 {
383                         num_str[7-i] = four_bits - 10 + 'A';
384                 }
385         }
386         num_str[8] = 0;
387         return 0;
388 }
389
390 int db_help_cmd(char *cmd, char *param1, char *param2, char *param3)
391 {
392         int i;
393
394         i = 0;
395
396         A_PRINTF("%s %s\n", ATH_DEBUGGER_VERSION_STR, ATH_COMMAND_LIST_STR);
397
398         while (command_table[i].cmd_func)
399         {
400                 A_PRINTF("%s\t%s\n\r", command_table[i].cmd_str,
401                                        command_table[i].help_str);
402                 i++;
403         }
404         return i;
405 }
406
407 static int db_ldr_cmd(char *cmd, char *param1, char *param2, char *param3)
408 {
409         unsigned long val;
410         unsigned long addr;
411         char val_str[20];
412         char addr_str[20];
413
414         if (db_ascii_to_hex(param1, &addr) != -1)
415         {
416                 if( addr == 0 )
417                 {
418                         A_PRINTF("Error! bad address 0x%08x.\n\r",
419                                  (unsigned long)addr);
420                         return -1;
421                 }
422                 if (strcmp(cmd, "LDR") == 0)
423                 {
424                         addr &= 0xfffffffc;
425                         //val = *(unsigned long *)addr;
426
427                         val = HAL_WORD_REG_READ(addr);
428                 }
429                 else if (strcmp(cmd, "LDRH") == 0)
430                 {
431                         addr &= 0xfffffffe;
432                         val = HAL_HALF_WORD_REG_READ(addr);
433                 }
434                 else if (strcmp(cmd, "LDRB") == 0)
435                 {
436                 }
437
438                 db_hex_to_ascii(val, val_str);
439                 db_hex_to_ascii(addr, addr_str);
440
441                 A_PRINTF("%s : %s\n\r", addr_str, val_str);
442                 return 0;
443         }
444
445         db_incorect_format();
446         return -1;
447 }
448
449 static int db_str_cmd(char *cmd, char *param1, char *param2, char *param3)
450 {
451         unsigned long val;
452         unsigned long addr;
453         char val_str[20];
454         char addr_str[20];
455
456         if ((A_STRLEN(param2) > 0) &&
457             (db_ascii_to_hex(param1, &addr) != -1) &&
458             (db_ascii_to_hex(param2, &val) != -1))
459         {
460                 if (strcmp(cmd, "STR") == 0)
461                 {
462                         addr &= 0xfffffffc;
463                         //HAL_WORD_REG_WRITE(addr, val);
464                         HAL_WORD_REG_WRITE(addr, val);
465                         //*(volatile unsigned long *)(addr & 0xfffffffc) = (unsigned long)val;
466                 }
467
468                 else if (strcmp(cmd, "STRH") == 0)
469                 {
470                         addr &= 0xfffffffe;
471                         //*(volatile unsigned short *)(addr & 0xfffffffe) = (unsigned short)val;
472                         HAL_HALF_WORD_REG_WRITE(addr, val);
473                 }
474                 else if (strcmp(cmd, "STRB") == 0)
475                 {
476                         if( addr & 0x00f00000 )
477                                 HAL_BYTE_REG_WRITE(addr, val);
478                         else
479                                 HAL_BYTE_REG_WRITE(addr^3, val);
480                         //*(volatile unsigned char *)addr = (unsigned char)val;
481                 }
482
483                 db_hex_to_ascii(val, val_str);
484                 db_hex_to_ascii(addr, addr_str);
485
486                 A_PRINTF("%s : %s\n\r", addr_str, val_str);
487                 return 0;
488         }
489
490         db_incorect_format();
491         return -1;
492 }
493
494 LOCAL void dbg_timer_func(A_HANDLE alarm, void *data)
495 {
496         A_PRINTF("this is a timer alarm function 0x%08x\n\r", xthal_get_ccount());
497 }
498
499 uint32_t delay = 0;
500
501 static int db_intr_cmd(char *cmd, char *param1, char *param2, char *param3)
502 {
503 #if SYSTEM_MODULE_INTR
504         uint32_t pending_intrs;
505
506         if(strcmp(param1, "read") == 0 )
507         {
508                 {
509                         /* Update snapshot of pending interrupts */
510
511                         pending_intrs = A_INTR_GET_INTRPENDING();
512
513                         A_PRINTF("intr mask [0x%08x]\n\r", xthal_get_intenable());
514                         A_PRINTF("intr on [0x%08x]\n\r", pending_intrs);
515                 }
516         }
517         else if (strcmp(param1, "timer") == 0 )
518         {
519                 uint32_t data = 0;
520
521                 if (strcmp(param2, "on") == 0 )
522                 {
523                         /* TODO: this part is probably dead. */
524                         pending_intrs = A_INTR_GET_INTRENABLE()|CMNOS_IMASK_XTTIMER;
525                         A_INTR_SET_INTRENABLE(pending_intrs);
526                         A_PRINTF("- intr [0x%08x]\n\r", pending_intrs);
527                 }
528                 else if ( strcmp(param2, "off") == 0 )
529                 {
530                         pending_intrs = A_INTR_GET_INTRENABLE()&(~CMNOS_IMASK_XTTIMER);
531                         A_INTR_SET_INTRENABLE(pending_intrs);
532                         A_PRINTF("- intr [0x%08x]\n\r", pending_intrs);
533             
534                 }
535                 else if( db_ascii_to_hex(param2, &data)==0 )
536                 {
537                         if( data>=0 && data <=10 )
538                                 delay = data;
539                         else
540                                 delay = 3;
541             
542                         A_PRINTF("==>set cb to %d seconds \n\r", delay);
543                 }
544
545         }
546         else
547         {
548                 A_PRINTF("\tintr read - read the interrenable status\n\r");
549                 A_PRINTF("\tintr timer on/off/tick - timer attach on/off/ticks\n\r");
550
551         }
552
553 #endif //#if SYSTEM_MODULE_INTR
554         return 0;
555 }
556
557 static int db_usb_cmd(char *cmd, char *param1, char *param2, char *param3)
558 {
559         A_PRINTF("THIS IS USB COMMAND\n\r");
560
561         if( strcmp(param1, "que") == 0 )
562         {
563                 HIFusb_DescTraceDump();
564         }
565         else
566         {
567                 A_PRINTF("\tusb que - dump descriptor queue\n\r");
568                 A_PRINTF("\tusb fw on/off - enable/disable write fw download to ram\n\r");
569
570         }
571         return 0;
572 }
573
574 static void clk_change(uint32_t clk, uint32_t ratio, uint32_t baud)
575 {
576         uint32_t clk_sel = 0;
577
578         switch(clk){
579         case 22:
580                 clk_sel = 0;
581                 break;
582         case 88:
583                 clk_sel = 1;
584                 break;
585         case 44:
586                 clk_sel = 2;
587                 break;
588         case 117:
589                 clk_sel = 4;
590                 break;
591         case 40:
592                 clk_sel = 6;            
593                 break;
594         default:
595                 clk_sel = 6;
596                 break;
597         }
598
599         HAL_WORD_REG_WRITE(0x50040, (0x300|clk_sel|(ratio>>1)<<12));
600         A_UART_HWINIT((clk*1000*1000)/ratio, baud);
601
602 }
603
604 static int db_clock_cmd(char *cmd, char *param1, char *param2, char *param3)
605 {
606         uint32_t ratio = 1;
607         uint32_t baud = 19200;
608         uint32_t clk = 0;
609     
610         if( db_ascii_to_int(param1, &clk) != -1 )
611         {
612                 A_PRINTF("changing clock to %d\n", clk);
613                 clk_change(clk, ratio, baud);
614         }
615 }
616
617 static int db_info_cmd(char *cmd, char *param1, char *param2, char *param3)
618 {
619 #if 1
620
621         if(strcmp(param1, "ram") == 0 )
622         {
623                 A_ALLOCRAM_DEBUG();
624         }
625 #if 0  /* TODO: SYSTEM_MODULE_SYS_MONITOR depends on _ROM_ or _RAM_ which
626         * is dead too */
627         else if(strcmp(param1, "cpu") == 0)
628                 zfPrintCpuUtilization();
629 #endif
630         else   // defalut dump
631                 HIFusb_DescTraceDump();
632
633         return 1;
634
635 #else
636     
637         {
638                 uint32_t ccount1;
639                 uint32_t ccount2;
640
641                 uint32_t data;
642                 register uint32_t data1;
643                 if( db_ascii_to_hex(param1, &data1)==0 )
644                 {
645                         __asm__ __volatile__ (
646                                 "rsr     %0, ccount"
647                                 : "=a" (ccount1) : : "memory"
648                                 );
649                         data = *(volatile uint32_t *)(data1);
650                         __asm__ __volatile__ (
651                                 "rsr     %0, ccount"
652                                 : "=a" (ccount2) : : "memory"
653                                 );
654                         A_PRINTF("\n\rread 0x%08x (0x%08x) use %d clocks\n\r", data1, data, ccount2-ccount1);
655                 }
656
657                 __asm__ __volatile__ (
658                         "rsr     %0, ccount"
659                         : "=a" (ccount1) : : "memory"
660                         );
661                 data = *(volatile uint32_t *)(data1);
662                 __asm__ __volatile__ (
663                         "rsr     %0, ccount"
664                         : "=a" (ccount2) : : "memory"
665                         );
666                 A_PRINTF("\n\rread 0x%08x (0x%08x) use %d clocks\n\r", data1, data, ccount2-ccount1);
667
668
669                 __asm__ __volatile__ (
670                         "rsr     %0, ccount"
671                         : "=a" (ccount1) : : "memory"
672                         );
673                 data = *(volatile uint32_t *)(data2);
674                 __asm__ __volatile__ (
675                         "rsr     %0, ccount"
676                         : "=a" (ccount2) : : "memory"
677                         );
678                 A_PRINTF("read 0x%08x (0x%08x) use %d clocks\n\r", data2, data, ccount2-ccount1);
679
680
681                 __asm__ __volatile__ (
682                         "rsr     %0, ccount"
683                         : "=a" (ccount1) : : "memory"
684                         );
685                 data = *(volatile uint32_t *)(data3);
686                 __asm__ __volatile__ (
687                         "rsr     %0, ccount"
688                         : "=a" (ccount2) : : "memory"
689                         );
690                 A_PRINTF("read 0x%08x (0x%08x) use %d clocks\n\r", data3, data, ccount2-ccount1);
691
692         }
693 #endif
694         return 1;
695 }
696
697 static int db_cmd_starthtc(char *cmd, char *param1, char *param2, char *param3)
698 {
699     extern htc_handle_t htc_handle;
700     HTC_Ready(htc_handle);
701 }
702
703 static int db_wdt_cmd(char *cmd, char *param1, char *param2, char *param3)
704 {
705         if ( strcmp(param1, "rst") == 0 )
706         {
707                 A_PRINTF(" reseting...\n\n\r");
708                 A_WDT_RESET();
709         }
710         else if( strcmp(param1, "on") == 0 )
711         {
712                 A_WDT_ENABLE();
713         }
714         else if (strcmp(param1, "off") == 0 )
715         {
716                 A_WDT_DISABLE();
717         }
718         else if ( strcmp(param1, "boot") == 0 )
719         {
720                 A_PRINTF("Last BOOT is ");
721                 if (ENUM_WDT_BOOT == A_WDT_LASTBOOT() )
722                         A_PRINTF("wdt");
723                 else
724                         A_PRINTF("normal boot");
725         }
726         else if (strcmp(param1, "loop") == 0 )
727         {
728                 T_WDT_CMD wdt_cmd;
729                 uint32_t time_offset;
730                 A_PRINTF(" doing the wdt reseting...");
731
732                 if( db_ascii_to_hex(param2, &time_offset)!=0 )
733                 {
734                         if( time_offset < 0 || time_offset >0xffffffff )
735                                 time_offset = 0xffffff;
736                 }
737                 A_PRINTF(" (wdt tick: 0x%08x...\n\n\r", time_offset);
738                 wdt_cmd.cmd = WDT_TIMEOUT;
739                 wdt_cmd.timeout = time_offset;
740
741                 A_WDT_SET(wdt_cmd);
742                 while(1) ;
743         }
744         else if (strcmp(param1, "noloop") == 0 )
745         {
746                 T_WDT_CMD wdt_cmd;
747                 uint32_t time_offset;
748                 A_PRINTF(" doing the wdt reseting...");
749
750                 if( db_ascii_to_hex(param3, &time_offset)!=0 )
751                 {
752                         if( time_offset < 0 || time_offset >0xffffffff )
753                                 time_offset = 0xffffff;
754                 }
755                 A_PRINTF(" (wdt tick: 0x%08x...\n\n\r", time_offset);
756
757                 wdt_cmd.cmd = WDT_TIMEOUT;
758                 wdt_cmd.timeout = time_offset;
759
760                 A_WDT_SET(wdt_cmd);
761         }
762         else if( strcmp(param1, "event") == 0 )
763         {
764                 uint32_t event= 0x00123400;
765 #define USB_BYTE_REG_WRITE(addr, val)           HAL_BYTE_REG_WRITE(USB_CTRL_BASE_ADDRESS|(uint8_t)(addr^3), (val))
766 #define USB_BYTE_REG_READ(addr)                 HAL_BYTE_REG_READ(USB_CTRL_BASE_ADDRESS|(uint8_t)(addr^3))
767
768 #define USB_WORD_REG_WRITE(addr, val)           HAL_WORD_REG_WRITE(USB_CTRL_BASE_ADDRESS|(uint32_t)(addr), (val))
769 #define USB_WORD_REG_READ(addr)                 HAL_WORD_REG_READ(USB_CTRL_BASE_ADDRESS|(uint32_t)(addr))
770
771                 // disable ep3 intr
772                 USB_BYTE_REG_WRITE(0x17, USB_BYTE_REG_READ(0x17)|0xc0);
773
774                 //ZM_CBUS_FIFO_SIZE_REG = 0xf;
775                 USB_WORD_REG_WRITE(0x100, 0x0f);
776
777                 //ZM_EP3_DATA_REG = event;
778                 USB_WORD_REG_WRITE(0xF8, event);
779
780                 // tx done
781                 USB_BYTE_REG_WRITE(0xAE, USB_BYTE_REG_READ(0xAE)|0x08);
782
783                 // enable ep3 intr
784                 USB_BYTE_REG_WRITE(0x17, USB_BYTE_REG_READ(0x17)&0xbf);
785         }
786 }
787
788 #if defined(PROJECT_K2)
789 #if SYSTEM_MODULE_SFLASH
790 /* Serial Flash -> Chip Erase, Sector Erase, Block Erase */
791 static int db_cmd_sferase(char *cmd, char *param1, char *param2, char *param3)
792 {
793         unsigned long       addr;
794
795         if (strcmp(param1, "s") == 0)
796         {
797                 if (db_ascii_to_hex(param2, &addr) != -1 && addr < SPI_FLASH_MAX_SIZE)
798                 {
799                         /* Sector size is 4K (0x1000) */
800                         A_PRINTF("Sector addr : 0x%08X\n\r", addr - addr%0x1000);
801                         A_SFLASH_ERASE(ZM_SFLASH_SECTOR_ERASE, addr);
802
803                         return 0;
804                 }
805
806                 db_incorect_format();
807                 return -1;
808         }
809         else if (strcmp(param2, "b") == 0)
810         {
811                 if (db_ascii_to_hex(param2, &addr) != -1 && addr < SPI_FLASH_MAX_SIZE)
812                 {
813                         /* Sector size is 64K (0x10000) */
814                         A_PRINTF("Block addr : 0x%08X\n\r", addr - addr%0x10000);
815                         A_SFLASH_ERASE(ZM_SFLASH_BLOCK_ERASE, addr);
816
817                         return 0;
818                 }
819
820                 db_incorect_format();
821                 return -1;
822
823         }
824         else if (strcmp(param1, "c") == 0)
825         {
826                 A_SFLASH_ERASE(ZM_SFLASH_CHIP_ERASE, addr);
827
828                 A_PRINTF("\n\r");
829                 return 0;
830         }
831
832         db_unknown_command();
833         return -1;
834 }
835
836 /* Serial Flash -> Program */
837 static int db_cmd_sfpg(char *cmd, char *param1, char *param2, char *param3)
838 {
839         unsigned long       addr, len, buf;
840
841         if (db_ascii_to_hex(param1, &addr) != -1 &&
842             db_ascii_to_hex(param2, &len) != -1 &&
843             db_ascii_to_hex(param3, &buf) != -1 &&
844             ((addr+len) <= SPI_FLASH_MAX_SIZE) &&
845             addr%4 == 0 && len%4 == 0 && buf%4 == 0 &&
846             ((buf >=0x500000 && buf < 0x528000) || (buf >=0x4e0000 && buf < 0x4e6000)) )
847         {
848                 A_SFLASH_PROG(addr, len, (A_UINT8 *)buf);
849
850                 A_PRINTF("\n\r");
851                 return 0;
852         }
853
854         db_incorect_format();
855         return -1;
856 }
857
858 /* Serial Flash -> Read, Fast Read to UART */
859 static int db_cmd_sfru(char *cmd, char *param1, char *param2, char *param3)
860 {
861         A_UINT32            i;
862         unsigned long       addr1, addr2, t_addr;
863         A_UINT32            fast, val;
864
865         if (strcmp(param1, "r") == 0)
866                 fast = 0;
867         else if (strcmp(param1, "f") == 0)
868                 fast = 1;
869         else
870         {
871                 db_unknown_command();
872                 return -1;
873         }
874
875         if (db_ascii_to_hex(param2, &addr1) != -1 &&
876             db_ascii_to_hex(param3, &addr2) != -1 &&
877             addr1 < addr2 && addr1 < SPI_FLASH_MAX_SIZE &&
878             addr2 < SPI_FLASH_MAX_SIZE && addr1%4 == 0)
879         {
880                 A_PRINTF("addr    data     data     data     data     data     data     data     data\n\r");
881                 A_PRINTF("======  ======== ======== ======== ======== ======== ======== ======== ========");
882
883                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
884                 {
885                         if ((i%8) == 0)
886                                 A_PRINTF("\n\r%06X  ", t_addr);
887
888                         A_SFLASH_READ(fast, t_addr, 4, (A_UINT8 *)&val);
889                         A_PRINTF("%08X ", val);
890                 }
891
892                 A_PRINTF("\n\r");
893                 return 0;
894         }
895
896         db_incorect_format();
897         return -1;
898 }
899
900 /* Serial Flash -> Read, Fast Read to Memory */
901 static int db_cmd_sfrm(char *cmd, char *param1, char *param2, char *param3)
902 {
903         A_UINT32            i;
904         unsigned long       addr1, addr2, t_addr;
905         A_UINT32            fast;
906         A_UINT8             *buf = (A_UINT8 *)0x520000;
907
908         if (strcmp(param1, "r") == 0)
909                 fast = 0;
910         else if (strcmp(param1, "f") == 0)
911                 fast = 1;
912         else
913         {
914                 db_unknown_command();
915                 return -1;
916         }
917
918         if (db_ascii_to_hex(param2, &addr1) != -1 &&
919             db_ascii_to_hex(param3, &addr2) != -1 &&
920             addr1 < addr2 && addr1 < SPI_FLASH_MAX_SIZE &&
921             addr2 < SPI_FLASH_MAX_SIZE && addr1%4 == 0)
922         {
923                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
924                 {
925                         A_SFLASH_READ(fast, t_addr, 4, buf + i*4);
926                 }
927
928                 A_PRINTF("\n\r");
929                 return 0;
930         }
931
932         db_incorect_format();
933         return -1;
934 }
935
936 /* Serial Flash -> Read Status Register */
937 static int db_cmd_sfrdsr(char *cmd, char *param1, char *param2, char *param3)
938 {
939         A_PRINTF("0x%02X\n\r", A_SFLASH_RDSR());
940         return 0;
941 }
942 #endif
943 #endif /* #if defined(PROJECT_K2) */
944
945 /* Memory Comparison */
946 static int db_cmd_memcmp(char *cmd, char *param1, char *param2, char *param3)
947 {
948         unsigned long       addr1, addr2, len;
949         A_UINT8             *buf1, *buf2;
950
951         if (db_ascii_to_hex(param1, &addr1) != -1 &&
952             db_ascii_to_hex(param2, &addr2) != -1 &&
953             db_ascii_to_hex(param3, &len) != -1 &&
954             addr1 != addr2 && addr1%4 == 0 && addr2%4 == 0 && len%4 == 0)
955         {
956                 buf1 = (A_UINT8 *)addr1;
957                 buf2 = (A_UINT8 *)addr2;        ;
958
959                 A_PRINTF("memcmp(buf1, buf2, len) = %d\n\r", A_MEMCMP(buf1, buf2, len));
960                 return 0;
961         }
962
963         db_incorect_format();
964         return -1;
965 }
966
967 /* Memory Dump */
968 static int db_cmd_memdump(char *cmd, char *param1, char *param2, char *param3)
969 {
970         A_UINT32            i;
971         unsigned long       addr1, addr2, t_addr;
972         A_UINT32            *val;
973
974         if (db_ascii_to_hex(param1, &addr1) != -1 && db_ascii_to_hex(param2, &addr2) != -1 && addr1 < addr2 && addr1%4 == 0)
975         {
976                 A_PRINTF("addr    data     data     data     data     data     data     data     data\n\r");
977                 A_PRINTF("======  ======== ======== ======== ======== ======== ======== ======== ========");
978
979                 for (i = 0, t_addr = addr1; t_addr < addr2; i++, t_addr += 4)
980                 {
981                         if ((i%8) == 0)
982                                 A_PRINTF("\n\r%06X  ", t_addr);
983
984                         val = (A_UINT32 *)t_addr;
985                         A_PRINTF("%08X ", *val);
986                 }
987
988                 A_PRINTF("\n\r");
989                 return 0;
990         }
991
992         db_incorect_format();
993         return -1;
994 }
995 void cmnos_dbg_module_install(struct dbg_api *apis)
996 {
997         apis->_dbg_init = zf_debug_init;
998         apis->_dbg_task = zf_debug_task;
999 }
1000
1001 #endif  /* SYSTEM_MODULE_DBG */
1002