First version
[3rdparty/ote_partner/tlk.git] / lib / debugcommands / debugcommands.c
1 /*
2  * Copyright (c) 2008-2012 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <ctype.h>
25 #include <debug.h>
26 #include <stdlib.h>
27 #include <printf.h>
28 #include <list.h>
29 #include <string.h>
30 #include <arch/ops.h>
31 #include <platform.h>
32 #include <platform/debug.h>
33 #include <kernel/thread.h>
34
35 #include <lib/console.h>
36
37 static int cmd_display_mem(int argc, const cmd_args *argv);
38 static int cmd_modify_mem(int argc, const cmd_args *argv);
39 static int cmd_fill_mem(int argc, const cmd_args *argv);
40 static int cmd_reset(int argc, const cmd_args *argv);
41 static int cmd_memtest(int argc, const cmd_args *argv);
42 static int cmd_copy_mem(int argc, const cmd_args *argv);
43
44 STATIC_COMMAND_START
45 #if DEBUGLEVEL > 0
46         { "dw", "display memory in words", &cmd_display_mem },
47         { "dh", "display memory in halfwords", &cmd_display_mem },
48         { "db", "display memory in bytes", &cmd_display_mem },
49         { "mw", "modify word of memory", &cmd_modify_mem },
50         { "mh", "modify halfword of memory", &cmd_modify_mem },
51         { "mb", "modify byte of memory", &cmd_modify_mem },
52         { "fw", "fill range of memory by word", &cmd_fill_mem },
53         { "fh", "fill range of memory by halfword", &cmd_fill_mem },
54         { "fb", "fill range of memory by byte", &cmd_fill_mem },
55         { "mc", "copy a range of memory", &cmd_copy_mem },
56 #endif
57 #if DEBUGLEVEL > 1
58         { "mtest", "simple memory test", &cmd_memtest },
59 #endif
60 STATIC_COMMAND_END(mem);
61
62 static int cmd_display_mem(int argc, const cmd_args *argv)
63 {
64         int size;
65
66         if (argc < 3) {
67                 printf("not enough arguments\n");
68                 printf("%s <address> <length>\n", argv[0].str);
69                 return -1;
70         }
71
72         if (strcmp(argv[0].str, "dw") == 0) {
73                 size = 4;
74         } else if (strcmp(argv[0].str, "dh") == 0) {
75                 size = 2;
76         } else {
77                 size = 1;
78         }
79
80         unsigned long address = argv[1].u;
81         size_t len = argv[2].u;
82         unsigned long stop = address + len;
83         int count = 0;
84
85         if ((address & (size - 1)) != 0) {
86                 printf("unaligned address, cannot display\n");
87                 return -1;
88         }
89
90         for ( ; address < stop; address += size) {
91                 if (count == 0)
92                         printf("0x%08lx: ", address);
93                 switch (size) {
94                         case 4:
95                                 printf("%08x ", *(uint32_t *)address);
96                                 break;
97                         case 2:
98                                 printf("%04hx ", *(uint16_t *)address);
99                                 break;
100                         case 1:
101                                 printf("%02hhx ", *(uint8_t *)address);
102                                 break;
103                 }
104                 count += size;
105                 if (count == 16) {
106                         printf("\n");
107                         count = 0;
108                 }
109         }       
110
111         if (count != 0)
112                 printf("\n");
113
114         return 0;
115 }
116
117 static int cmd_modify_mem(int argc, const cmd_args *argv)
118 {
119         int size;
120
121         if (argc < 3) {
122                 printf("not enough arguments\n");
123                 printf("%s <address> <val>\n", argv[0].str);
124                 return -1;
125         }
126
127         if (strcmp(argv[0].str, "mw") == 0) {
128                 size = 4;
129         } else if (strcmp(argv[0].str, "mh") == 0) {
130                 size = 2;
131         } else {
132                 size = 1;
133         }
134
135         unsigned long address = argv[1].u;
136         unsigned int val = argv[2].u;
137
138         if ((address & (size - 1)) != 0) {
139                 printf("unaligned address, cannot modify\n");
140                 return -1;
141         }
142
143         switch (size) {
144                 case 4:
145                         *(uint32_t *)address = (uint32_t)val;
146                         break;
147                 case 2:
148                         *(uint16_t *)address = (uint16_t)val;
149                         break;
150                 case 1:
151                         *(uint8_t *)address = (uint8_t)val;
152                         break;
153         }
154
155         return 0;
156 }
157
158 static int cmd_fill_mem(int argc, const cmd_args *argv)
159 {
160         int size;
161
162         if (argc < 4) {
163                 printf("not enough arguments\n");
164                 printf("%s <address> <len> <val>\n", argv[0].str);
165                 return -1;
166         }
167
168         if (strcmp(argv[0].str, "fw") == 0) {
169                 size = 4;
170         } else if (strcmp(argv[0].str, "fh") == 0) {
171                 size = 2;
172         } else {
173                 size = 1;
174         }
175
176         unsigned long address = argv[1].u;
177         unsigned long len = argv[2].u;
178         unsigned long stop = address + len;
179         unsigned int val = argv[3].u;
180
181         if ((address & (size - 1)) != 0) {
182                 printf("unaligned address, cannot modify\n");
183                 return -1;
184         }
185
186         for ( ; address < stop; address += size) {
187                 switch (size) {
188                 case 4:
189                         *(uint32_t *)address = (uint32_t)val;
190                         break;
191                 case 2:
192                         *(uint16_t *)address = (uint16_t)val;
193                         break;
194                 case 1:
195                         *(uint8_t *)address = (uint8_t)val;
196                         break;
197                 }
198         }
199
200         return 0;
201 }
202
203 static int cmd_copy_mem(int argc, const cmd_args *argv)
204 {
205         if (argc < 4) {
206                 printf("not enough arguments\n");
207                 printf("%s <source address> <target address> <len>\n", argv[0].str);
208                 return -1;
209         }
210         
211         addr_t source = argv[1].u;
212         addr_t target = argv[2].u;
213         size_t len = argv[3].u;
214
215         memcpy((void *)target, (const void *)source, len);
216
217         return 0;
218 }
219
220 static int cmd_memtest(int argc, const cmd_args *argv)
221 {
222         if (argc < 3) {
223                 printf("not enough arguments\n");
224                 printf("%s <base> <len>\n", argv[0].str);
225                 return -1;
226         }
227
228         uint32_t *ptr;
229         size_t len;
230
231         ptr = (uint32_t *)argv[1].u;
232         len = (size_t)argv[2].u;
233
234         size_t i;
235         // write out
236         printf("writing first pass...");
237         for (i = 0; i < len / 4; i++) {
238                 ptr[i] = i;
239         }
240         printf("done\n");
241
242         // verify
243         printf("verifying...");
244         for (i = 0; i < len / 4; i++) {
245                 if (ptr[i] != i)
246                         printf("error at %p\n", &ptr[i]);
247         }
248         printf("done\n");
249
250         return 0;
251 }
252