diff options
-rw-r--r-- | firmware/test/fat/main.c | 266 |
1 files changed, 238 insertions, 28 deletions
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 58f83f45dc..ca288322d3 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c | |||
@@ -2,6 +2,8 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <stdarg.h> | 4 | #include <stdarg.h> |
5 | #include <time.h> | ||
6 | #include <sys/time.h> | ||
5 | #include "fat.h" | 7 | #include "fat.h" |
6 | #include "debug.h" | 8 | #include "debug.h" |
7 | #include "disk.h" | 9 | #include "disk.h" |
@@ -84,13 +86,15 @@ void dbg_dir(char* currdir) | |||
84 | } | 86 | } |
85 | 87 | ||
86 | #define CHUNKSIZE 8 | 88 | #define CHUNKSIZE 8 |
89 | #define BUFSIZE 8192 | ||
87 | 90 | ||
88 | int dbg_mkfile(char* name, int num) | 91 | int dbg_mkfile(char* name, int num) |
89 | { | 92 | { |
90 | char text[8192]; | 93 | char text[BUFSIZE+1]; |
91 | int i; | 94 | int i; |
92 | int fd; | 95 | int fd; |
93 | int x=0; | 96 | int x=0; |
97 | bool stop = false; | ||
94 | 98 | ||
95 | fd = open(name,O_WRONLY); | 99 | fd = open(name,O_WRONLY); |
96 | if (fd<0) { | 100 | if (fd<0) { |
@@ -100,7 +104,7 @@ int dbg_mkfile(char* name, int num) | |||
100 | num *= 1024; | 104 | num *= 1024; |
101 | while ( num ) { | 105 | while ( num ) { |
102 | int rc; | 106 | int rc; |
103 | int len = num > sizeof text ? sizeof text : num; | 107 | int len = num > BUFSIZE ? BUFSIZE : num; |
104 | 108 | ||
105 | for (i=0; i<len/CHUNKSIZE; i++ ) | 109 | for (i=0; i<len/CHUNKSIZE; i++ ) |
106 | sprintf(text+i*CHUNKSIZE,"%c%06x,",name[1],x++); | 110 | sprintf(text+i*CHUNKSIZE,"%c%06x,",name[1],x++); |
@@ -113,23 +117,35 @@ int dbg_mkfile(char* name, int num) | |||
113 | else | 117 | else |
114 | if ( rc == 0 ) { | 118 | if ( rc == 0 ) { |
115 | DEBUGF("No space left\n"); | 119 | DEBUGF("No space left\n"); |
116 | break; | 120 | return -2; |
117 | } | 121 | } |
118 | else | 122 | else |
119 | DEBUGF("wrote %d bytes\n",rc); | 123 | DEBUGF("wrote %d bytes\n",rc); |
120 | 124 | ||
121 | num -= len; | 125 | num -= len; |
126 | |||
127 | if ( !num ) { | ||
128 | if ( stop ) | ||
129 | break; | ||
130 | |||
131 | /* add a random number of chunks to test byte-copy code */ | ||
132 | num = ((int) rand() % SECTOR_SIZE) & ~7; | ||
133 | LDEBUGF("Adding random size %d\n",num); | ||
134 | stop = true; | ||
135 | } | ||
122 | } | 136 | } |
123 | 137 | ||
124 | close(fd); | 138 | close(fd); |
125 | return 0; | 139 | return 0; |
126 | } | 140 | } |
127 | 141 | ||
142 | |||
128 | int dbg_chkfile(char* name, int size) | 143 | int dbg_chkfile(char* name, int size) |
129 | { | 144 | { |
130 | char text[81920]; | 145 | char text[81920]; |
131 | int i; | 146 | int i; |
132 | int x=0; | 147 | int x=0; |
148 | int pos = 0; | ||
133 | int block=0; | 149 | int block=0; |
134 | int fd = open(name,O_RDONLY); | 150 | int fd = open(name,O_RDONLY); |
135 | if (fd<0) { | 151 | if (fd<0) { |
@@ -137,18 +153,21 @@ int dbg_chkfile(char* name, int size) | |||
137 | return -1; | 153 | return -1; |
138 | } | 154 | } |
139 | 155 | ||
140 | if (size) { | 156 | size = lseek(fd, 0, SEEK_END); |
141 | lseek(fd, size*512, SEEK_SET); | 157 | DEBUGF("File is %d bytes\n", size); |
142 | x = size * 1024 / 16; | 158 | /* random start position */ |
143 | LDEBUGF("Check base is %x\n",x); | 159 | if ( size ) |
144 | } | 160 | pos = ((int)rand() % size) & ~7; |
161 | lseek(fd, pos, SEEK_SET); | ||
162 | x = pos / CHUNKSIZE; | ||
163 | |||
164 | LDEBUGF("Check base is %x (%d)\n",x,pos); | ||
145 | 165 | ||
146 | while (1) { | 166 | while (1) { |
147 | int rc = read(fd, text, sizeof text); | 167 | int rc = read(fd, text, sizeof text); |
148 | DEBUGF("read %d bytes\n",rc); | 168 | DEBUGF("read %d bytes\n",rc); |
149 | if (rc < 0) { | 169 | if (rc < 0) { |
150 | DEBUGF("Failed writing data\n"); | 170 | panicf("Failed reading data\n"); |
151 | return -1; | ||
152 | } | 171 | } |
153 | else { | 172 | else { |
154 | char tmp[CHUNKSIZE+1]; | 173 | char tmp[CHUNKSIZE+1]; |
@@ -157,13 +176,86 @@ int dbg_chkfile(char* name, int size) | |||
157 | for (i=0; i<rc/CHUNKSIZE; i++ ) { | 176 | for (i=0; i<rc/CHUNKSIZE; i++ ) { |
158 | sprintf(tmp,"%c%06x,",name[1],x++); | 177 | sprintf(tmp,"%c%06x,",name[1],x++); |
159 | if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) { | 178 | if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) { |
160 | DEBUGF("Mismatch in byte %x (sector %d). Expected %.8s found %.8s\n", | 179 | int idx = pos + block*sizeof(text) + i*CHUNKSIZE; |
161 | block*sizeof(text)+i*CHUNKSIZE, | 180 | DEBUGF("Mismatch in byte 0x%x (byte 0x%x of sector 0x%x)." |
162 | (block*sizeof(text)+i*CHUNKSIZE) / SECTOR_SIZE, | 181 | "\nExpected %.8s found %.8s\n", |
182 | idx, idx % SECTOR_SIZE, idx / SECTOR_SIZE, | ||
163 | tmp, | 183 | tmp, |
164 | text+i*CHUNKSIZE); | 184 | text+i*CHUNKSIZE); |
165 | dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, | 185 | DEBUGF("i=%x, idx=%x\n",i,idx); |
166 | block*sizeof(text)+i*CHUNKSIZE - 0x20); | 186 | dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, idx - 0x20); |
187 | return -1; | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | block++; | ||
192 | } | ||
193 | |||
194 | close(fd); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | int dbg_wrtest(char* name) | ||
200 | { | ||
201 | char text[81920]; | ||
202 | int i; | ||
203 | int x=0; | ||
204 | int pos = 0; | ||
205 | int block=0; | ||
206 | int size, fd, rc; | ||
207 | char tmp[CHUNKSIZE+1]; | ||
208 | |||
209 | fd = open(name,O_RDWR); | ||
210 | if (fd<0) { | ||
211 | DEBUGF("Failed opening file\n"); | ||
212 | return -1; | ||
213 | } | ||
214 | |||
215 | size = lseek(fd, 0, SEEK_END); | ||
216 | DEBUGF("File is %d bytes\n", size); | ||
217 | /* random start position */ | ||
218 | if ( size ) | ||
219 | pos = ((int)rand() % size) & ~7; | ||
220 | rc = lseek(fd, pos, SEEK_SET); | ||
221 | if ( rc < 0 ) | ||
222 | panicf("Failed seeking\n"); | ||
223 | x = pos / CHUNKSIZE; | ||
224 | LDEBUGF("Check base is %x (%d)\n",x,pos); | ||
225 | |||
226 | sprintf(tmp,"%c%06x,",name[1],x++); | ||
227 | rc = write(fd, tmp, 8); | ||
228 | if ( rc < 0 ) | ||
229 | panicf("Failed writing data\n"); | ||
230 | |||
231 | if ( size ) | ||
232 | pos = ((int)rand() % size) & ~7; | ||
233 | rc = lseek(fd, pos, SEEK_SET); | ||
234 | if ( rc < 0 ) | ||
235 | panicf("Failed seeking\n"); | ||
236 | x = pos / CHUNKSIZE; | ||
237 | LDEBUGF("Check base 2 is %x (%d)\n",x,pos); | ||
238 | |||
239 | while (1) { | ||
240 | rc = read(fd, text, sizeof text); | ||
241 | DEBUGF("read %d bytes\n",rc); | ||
242 | if (rc < 0) { | ||
243 | panicf("Failed reading data\n"); | ||
244 | } | ||
245 | else { | ||
246 | if (!rc) | ||
247 | break; | ||
248 | for (i=0; i<rc/CHUNKSIZE; i++ ) { | ||
249 | sprintf(tmp,"%c%06x,",name[1],x++); | ||
250 | if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) { | ||
251 | int idx = pos + block*sizeof(text) + i*CHUNKSIZE; | ||
252 | DEBUGF("Mismatch in byte 0x%x (byte 0x%x of sector 0x%x)." | ||
253 | "\nExpected %.8s found %.8s\n", | ||
254 | idx, idx % SECTOR_SIZE, idx / SECTOR_SIZE, | ||
255 | tmp, | ||
256 | text+i*CHUNKSIZE); | ||
257 | DEBUGF("i=%x, idx=%x\n",i,idx); | ||
258 | dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, idx - 0x20); | ||
167 | return -1; | 259 | return -1; |
168 | } | 260 | } |
169 | } | 261 | } |
@@ -207,6 +299,64 @@ void dbg_type(char* name) | |||
207 | close(fd); | 299 | close(fd); |
208 | } | 300 | } |
209 | 301 | ||
302 | int dbg_append(char* name) | ||
303 | { | ||
304 | int x=0; | ||
305 | int size, fd, rc; | ||
306 | char tmp[CHUNKSIZE+1]; | ||
307 | |||
308 | fd = open(name,O_RDONLY); | ||
309 | if (fd<0) { | ||
310 | DEBUGF("Failed opening file\n"); | ||
311 | return -1; | ||
312 | } | ||
313 | |||
314 | size = lseek(fd, 0, SEEK_END); | ||
315 | DEBUGF("File is %d bytes\n", size); | ||
316 | x = size / CHUNKSIZE; | ||
317 | LDEBUGF("Check base is %x (%d)\n",x,size); | ||
318 | |||
319 | close(fd); | ||
320 | |||
321 | fd = open(name,O_RDWR|O_APPEND); | ||
322 | if (fd<0) { | ||
323 | DEBUGF("Failed opening file\n"); | ||
324 | return -1; | ||
325 | } | ||
326 | |||
327 | sprintf(tmp,"%c%06x,",name[1],x++); | ||
328 | rc = write(fd, tmp, 8); | ||
329 | if ( rc < 0 ) | ||
330 | panicf("Failed writing data\n"); | ||
331 | |||
332 | close(fd); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | int dbg_dump(char* name, int offset) | ||
338 | { | ||
339 | char buf[SECTOR_SIZE]; | ||
340 | |||
341 | int rc; | ||
342 | int fd = open(name,O_RDONLY); | ||
343 | if (fd<0) { | ||
344 | DEBUGF("Failed opening file\n"); | ||
345 | return -1; | ||
346 | } | ||
347 | lseek(fd, offset, SEEK_SET); | ||
348 | rc = read(fd, buf, sizeof buf); | ||
349 | |||
350 | if ( rc < 0 ) | ||
351 | panicf("Error reading data\n"); | ||
352 | |||
353 | close(fd); | ||
354 | |||
355 | dbg_dump_buffer(buf, rc, offset); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
210 | void dbg_tail(char* name) | 360 | void dbg_tail(char* name) |
211 | { | 361 | { |
212 | unsigned char buf[SECTOR_SIZE*5]; | 362 | unsigned char buf[SECTOR_SIZE*5]; |
@@ -240,14 +390,14 @@ void dbg_tail(char* name) | |||
240 | close(fd); | 390 | close(fd); |
241 | } | 391 | } |
242 | 392 | ||
243 | void dbg_head(char* name) | 393 | int dbg_head(char* name) |
244 | { | 394 | { |
245 | unsigned char buf[SECTOR_SIZE*5]; | 395 | unsigned char buf[SECTOR_SIZE*5]; |
246 | int fd,rc; | 396 | int fd,rc; |
247 | 397 | ||
248 | fd = open(name,O_RDONLY); | 398 | fd = open(name,O_RDONLY); |
249 | if (fd<0) | 399 | if (fd<0) |
250 | return; | 400 | return -1; |
251 | DEBUGF("Got file descriptor %d\n",fd); | 401 | DEBUGF("Got file descriptor %d\n",fd); |
252 | 402 | ||
253 | rc = read(fd, buf, SECTOR_SIZE*3); | 403 | rc = read(fd, buf, SECTOR_SIZE*3); |
@@ -265,19 +415,36 @@ void dbg_head(char* name) | |||
265 | } | 415 | } |
266 | 416 | ||
267 | close(fd); | 417 | close(fd); |
418 | return 0; | ||
268 | } | 419 | } |
269 | 420 | ||
270 | int dbg_del(char* name) | 421 | int dbg_trunc(char* name, int size) |
271 | { | 422 | { |
272 | return remove(name); | 423 | int fd,rc; |
273 | } | ||
274 | 424 | ||
275 | char current_directory[256] = "\\"; | 425 | #if 1 |
276 | int last_secnum = 0; | 426 | fd = open(name,O_RDWR); |
427 | if (fd<0) | ||
428 | return -1; | ||
277 | 429 | ||
278 | void dbg_prompt(void) | 430 | rc = ftruncate(fd, size); |
279 | { | 431 | if (rc<0) { |
280 | DEBUGF("C:%s> ", current_directory); | 432 | DEBUGF("ftruncate(%d) failed\n", size); |
433 | return -2; | ||
434 | } | ||
435 | |||
436 | #else | ||
437 | fd = open(name,O_RDWR|O_TRUNC); | ||
438 | if (fd<0) | ||
439 | return -1; | ||
440 | |||
441 | rc = lseek(fd, size, SEEK_SET); | ||
442 | if (fd<0) | ||
443 | return -2; | ||
444 | #endif | ||
445 | |||
446 | close(fd); | ||
447 | return 0; | ||
281 | } | 448 | } |
282 | 449 | ||
283 | int dbg_cmd(int argc, char *argv[]) | 450 | int dbg_cmd(int argc, char *argv[]) |
@@ -306,6 +473,11 @@ int dbg_cmd(int argc, char *argv[]) | |||
306 | " mkfile <file> <size (KB)>\n" | 473 | " mkfile <file> <size (KB)>\n" |
307 | " chkfile <file>\n" | 474 | " chkfile <file>\n" |
308 | " del <file>\n" | 475 | " del <file>\n" |
476 | " dump <file> <offset>\n" | ||
477 | " mkdir <dir>\n" | ||
478 | " trunc <file> <size>\n" | ||
479 | " wrtest <file>\n" | ||
480 | " append <file>\n" | ||
309 | ); | 481 | ); |
310 | return -1; | 482 | return -1; |
311 | } | 483 | } |
@@ -335,7 +507,7 @@ int dbg_cmd(int argc, char *argv[]) | |||
335 | if (!strcasecmp(cmd, "head")) | 507 | if (!strcasecmp(cmd, "head")) |
336 | { | 508 | { |
337 | if (arg1) | 509 | if (arg1) |
338 | dbg_head(arg1); | 510 | return dbg_head(arg1); |
339 | } | 511 | } |
340 | 512 | ||
341 | if (!strcasecmp(cmd, "tail")) | 513 | if (!strcasecmp(cmd, "tail")) |
@@ -367,7 +539,41 @@ int dbg_cmd(int argc, char *argv[]) | |||
367 | if (!strcasecmp(cmd, "del")) | 539 | if (!strcasecmp(cmd, "del")) |
368 | { | 540 | { |
369 | if (arg1) | 541 | if (arg1) |
370 | return dbg_del(arg1); | 542 | return remove(arg1); |
543 | } | ||
544 | |||
545 | if (!strcasecmp(cmd, "dump")) | ||
546 | { | ||
547 | if (arg1) { | ||
548 | if (arg2) | ||
549 | return dbg_dump(arg1, atoi(arg2)); | ||
550 | else | ||
551 | return dbg_dump(arg1, 0); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | if (!strcasecmp(cmd, "dump")) | ||
556 | { | ||
557 | if (arg1) | ||
558 | return mkdir(arg1); | ||
559 | } | ||
560 | |||
561 | if (!strcasecmp(cmd, "wrtest")) | ||
562 | { | ||
563 | if (arg1) | ||
564 | return dbg_wrtest(arg1); | ||
565 | } | ||
566 | |||
567 | if (!strcasecmp(cmd, "append")) | ||
568 | { | ||
569 | if (arg1) | ||
570 | return dbg_append(arg1); | ||
571 | } | ||
572 | |||
573 | if (!strcasecmp(cmd, "trunc")) | ||
574 | { | ||
575 | if (arg1 && arg2) | ||
576 | return dbg_trunc(arg1, atoi(arg2)); | ||
371 | } | 577 | } |
372 | 578 | ||
373 | return 0; | 579 | return 0; |
@@ -379,6 +585,10 @@ int main(int argc, char *argv[]) | |||
379 | { | 585 | { |
380 | int rc,i; | 586 | int rc,i; |
381 | struct partinfo* pinfo; | 587 | struct partinfo* pinfo; |
588 | struct timeval tv; | ||
589 | |||
590 | gettimeofday(&tv, NULL); | ||
591 | srand(tv.tv_usec); | ||
382 | 592 | ||
383 | if(ata_init("disk.img")) { | 593 | if(ata_init("disk.img")) { |
384 | DEBUGF("*** Warning! The disk is uninitialized\n"); | 594 | DEBUGF("*** Warning! The disk is uninitialized\n"); |