disptest.c revision 1.4 1 /* $NetBSD: disptest.c,v 1.4 2001/03/04 05:08:29 takemura Exp $ */
2
3 /*-
4 * Copyright (c) 1999 Shin Takemura.
5 * All rights reserved.
6 *
7 * This software is part of the PocketBSD.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the PocketBSD project
20 * and its contributors.
21 * 4. Neither the name of the project nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 */
38 #include <pbsdboot.h>
39
40 #define ARRAYSIZEOF(a) (sizeof(a)/sizeof(*(a)))
41
42 static struct area {
43 long start, end;
44 } targets[] = {
45 { 0x0a000000, 0x0b000000 },
46 { 0x10000000, 0x14000000 },
47 };
48 int ntargets = ARRAYSIZEOF(targets);
49
50 void
51 flush_XX()
52 {
53 static volatile unsigned char tmp[1024*64];
54 int i, s;
55
56 for (i = 0; i < ARRAYSIZEOF(tmp); i++) {
57 s += tmp[i];
58 }
59 }
60
61 static void
62 gpio_test()
63 {
64 #define GIUBASE 0xab000000
65 #define GIUOFFSET 0x0100
66 volatile unsigned short *giusell;
67 volatile unsigned short *giuselh;
68 volatile unsigned short *giupiodl;
69 volatile unsigned short *giupiodh;
70 unsigned short sell = 0;
71 unsigned short selh = 0;
72 unsigned short piodl = 0;
73 unsigned short piodh = 0;
74 int res, i;
75 unsigned short regs[16];
76 unsigned short prev_regs[16];
77
78 unsigned char* p = (char*)VirtualAlloc(0, 1024, MEM_RESERVE,
79 PAGE_NOACCESS);
80 res = VirtualCopy((LPVOID)p, (LPVOID)(GIUBASE >> 8), 1024,
81 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
82 if (!res) {
83 win_printf(TEXT("VirtualCopy() failed."));
84 }
85
86 for (i = 0; i < 16; i++) {
87 prev_regs[i] = ~0;
88 }
89
90 giusell = (unsigned short*)(p + GIUOFFSET + 0);
91 giuselh = (unsigned short*)(p + GIUOFFSET + 2);
92 giupiodl = (unsigned short*)(p + GIUOFFSET + 4);
93 giupiodh = (unsigned short*)(p + GIUOFFSET + 6);
94
95 while (1) {
96 sell = *giusell;
97 selh = *giuselh;
98 *giusell = sell;
99 *giuselh = selh;
100
101 piodl = *giupiodl;
102 piodh = *giupiodh;
103 *giupiodl = piodl;
104 *giupiodh = piodh;
105 for (i = 0; i < 16; i++) {
106 regs[i] = *(unsigned short*)(p + GIUOFFSET + i * 2);
107 }
108 for (i = 0; i < 16; i++) {
109 if (i != 3 && i != 5 && regs[i] != prev_regs[i]) {
110 win_printf(TEXT("IOSEL=%04x%04x "),
111 regs[1], regs[0]);
112 win_printf(TEXT("PIOD=%04x%04x "),
113 regs[3], regs[2]);
114 win_printf(TEXT("STAT=%04x%04x "),
115 regs[5], regs[4]);
116 win_printf(TEXT("(%04x%04x) "),
117 regs[5]®s[7], regs[4]®s[6]);
118 win_printf(TEXT("EN=%04x%04x "),
119 regs[7], regs[6]);
120 win_printf(TEXT("TYP=%04x%04x "),
121 regs[9], regs[8]);
122 win_printf(TEXT("ALSEL=%04x%04x "),
123 regs[11], regs[10]);
124 win_printf(TEXT("HTSEL=%04x%04x "),
125 regs[13], regs[12]);
126 win_printf(TEXT("PODAT=%04x%04x "),
127 regs[15], regs[14]);
128 win_printf(TEXT("\n"));
129 for (i = 0; i < 16; i++) {
130 prev_regs[i] = regs[i];
131 }
132 break;
133 }
134 }
135 }
136 }
137
138 static struct regdesc {
139 TCHAR *name;
140 int physaddr;
141 int size;
142 int mask;
143 //void *addr;
144 unsigned long val;
145 unsigned long preval;
146 } test_regs[] = {
147 #if 0
148 /*
149 * Vrc4172 GPIO and PWM
150 */
151 { TEXT("EXGPDATA0"), 0x15001080, 2, 0xfffd },
152 { TEXT("EXGPDATA1"), 0x150010c0, 2, 0xffff },
153 { TEXT("LCDDUTYEN"), 0x15003880, 2, 0xffff },
154 { TEXT("LCDFREQ"), 0x15003882, 2, 0xffff },
155 { TEXT("LCDDUTY"), 0x15003884, 2, 0xffff },
156 #endif
157
158 #if 0
159 /*
160 * Vr41xx GPIO
161 */
162 { TEXT("GIUPIODL"), 0x0b000104, 2, 0xffff },
163 { TEXT("GIUPIODH"), 0x0b000106, 2, 0xffff },
164 { TEXT("GIUPODATL"), 0x0b00011c, 2, 0xffff },
165 { TEXT("GIUPODATH"), 0x0b00011e, 2, 0xffff },
166 { TEXT("GIUUSEUPDN"), 0x0b0002e0, 2, 0xffff },
167 { TEXT("GIUTERMUPDN"), 0x0b0002e2, 2, 0xffff },
168 #endif
169
170 /*
171 * MQ200
172 */
173 { TEXT("PM00R"), 0x0a600000, 4, 0xffffffff },
174 { TEXT("PM01R"), 0x0a600004, 4, 0xffffffff },
175 { TEXT("PM02R"), 0x0a600008, 4, 0xffffffff },
176 { TEXT("PM06R"), 0x0a600018, 4, 0xffffffff },
177 { TEXT("PM07R"), 0x0a60001c, 4, 0xffffffff },
178
179 { TEXT("CC00R"), 0x0a602000, 4, 0x0000003f },
180 { TEXT("CC01R"), 0x0a602004, 4, 0x00000000 },
181
182 { TEXT("MM00R"), 0x0a604000, 4, 0x00000007 },
183 { TEXT("MM01R"), 0x0a604004, 4, 0xffffffff },
184 { TEXT("MM02R"), 0x0a604008, 4, 0xffffffff },
185 { TEXT("MM03R"), 0x0a60400c, 4, 0x00000001 },
186 { TEXT("MM04R"), 0x0a604010, 4, 0x00000001 },
187
188 { TEXT("IN00R"), 0x0a608000, 4, 0x0000001f },
189 { TEXT("IN01R"), 0x0a608004, 4, 0x0000ffff },
190 { TEXT("IN02R"), 0x0a608008, 4, 0x00000000 },
191 { TEXT("IN03R"), 0x0a60800c, 4, 0x00000000 },
192
193 { TEXT("GC00R"), 0x0a60a000, 4, 0xfffff9ff },
194 { TEXT("GC01R"), 0x0a60a004, 4, 0x10ffffff },
195 { TEXT("GC20R"), 0x0a60a080, 4, 0xffffffff },
196 { TEXT("GC21R"), 0x0a60a084, 4, 0x0000007f },
197
198 { TEXT("FP00R"), 0x0a60e000, 4, 0xffffffff },
199 { TEXT("FP01R"), 0x0a60e004, 4, 0xffffffff },
200 { TEXT("FP02R"), 0x0a60e008, 4, 0x007fffff },
201 { TEXT("FP03R"), 0x0a60e00c, 4, 0x0707003f },
202 { TEXT("FP04R"), 0x0a60e010, 4, 0xffff3fff },
203 { TEXT("FP05R"), 0x0a60e014, 4, 0xffffffff },
204 { TEXT("FP0FR"), 0x0a60e03c, 4, 0xffffffff },
205
206 { TEXT("DC00R"), 0x0a614000, 4, 0xffffffff },
207 { TEXT("DC01R"), 0x0a614004, 4, 0x0000003f },
208 { TEXT("DC02R"), 0x0a614008, 4, 0xffffffff },
209 { TEXT("DC03R"), 0x0a61400c, 4, 0xffffffff },
210
211 { TEXT("PC00R"), 0x0a616000, 4, 0xffffffff },
212 { TEXT("PC04R"), 0x0a616004, 4, 0xffffffff },
213 { TEXT("PC08R"), 0x0a616008, 4, 0xffffffff },
214 { TEXT("PC0CR"), 0x0a61600c, 4, 0xffffffff },
215 { TEXT("PC10R"), 0x0a616010, 4, 0xffffffff },
216 { TEXT("PC14R"), 0x0a616014, 4, 0xffffffff },
217 { TEXT("PC2CR"), 0x0a61602c, 4, 0xffffffff },
218 { TEXT("PC3CR"), 0x0a61603c, 4, 0xffffffff },
219 { TEXT("PC40R"), 0x0a616040, 4, 0xffffffff },
220 { TEXT("PC44R"), 0x0a616044, 4, 0x00000003 },
221 };
222
223 extern int SetKMode(int);
224 static void
225 regfetch(struct regdesc* desc)
226 {
227 SetKMode(1);
228 switch (desc->size) {
229 case 1:
230 desc->val = *(unsigned char*)(desc->physaddr | 0xa0000000);
231 break;
232 case 2:
233 desc->val = *(unsigned short*)(desc->physaddr | 0xa0000000);
234 break;
235 case 4:
236 desc->val = *(unsigned long*)(desc->physaddr | 0xa0000000);
237 break;
238 default:
239 win_printf(TEXT("Invalid size"));
240 break;
241 }
242 SetKMode(0);
243 desc->val &= desc->mask;
244 }
245
246 static void
247 register_test()
248 {
249 int i;
250 int nregs = sizeof(test_regs)/sizeof(*test_regs);
251
252 for (i = 0; i < nregs; i++) {
253 regfetch(&test_regs[i]);
254 test_regs[i].preval = test_regs[i].val;
255 }
256
257 while (1) {
258 for (i = 0; i < nregs; i++) {
259 regfetch(&test_regs[i]);
260 if (test_regs[i].val != test_regs[i].preval) {
261 win_printf(TEXT("%20s(%08x) %08x -> %08x\n"),
262 test_regs[i].name,
263 test_regs[i].physaddr,
264 test_regs[i].preval,
265 test_regs[i].val);
266 test_regs[i].preval = test_regs[i].val;
267 }
268 }
269 Sleep(10); /* 10 msec */
270 }
271 }
272
273 static void
274 dump_memory()
275 {
276 HANDLE fh = INVALID_HANDLE_VALUE;
277 #define UNICODE_MEMORY_CARD \
278 TEXT('\\'), 0xff92, 0xff93, 0xff98, TEXT(' '), 0xff76, 0xff70, \
279 0xff84, 0xff9e
280 TCHAR filename[] = { UNICODE_MEMORY_CARD, TEXT('2'), TEXT('\\'),
281 TEXT('d'), TEXT('u'), TEXT('m'), TEXT('p'), 0 };
282 unsigned long *addr;
283 int found;
284
285 win_printf(TEXT("dump to %s\n"), filename);
286 fh = CreateFile(
287 filename, /* file name */
288 GENERIC_WRITE, /* access (read-write) mode */
289 FILE_SHARE_WRITE,/* share mode */
290 NULL, /* pointer to security attributes */
291 CREATE_ALWAYS, /* how to create */
292 FILE_ATTRIBUTE_NORMAL, /* file attributes*/
293 NULL /* handle to file with attributes to */
294 );
295 if (fh == INVALID_HANDLE_VALUE) {
296 return;
297 }
298
299 for (addr = (unsigned long*)0xbe000000;
300 addr < (unsigned long*)0xbfffffff;
301 addr += 2048) {
302 char buf[2048];
303 DWORD n;
304
305 SetKMode(1);
306 memcpy(buf, addr, 2048);
307 SetKMode(0);
308 if (WriteFile(fh, buf, 2048, &n, NULL) == 0 ||
309 n != 2048) {
310 win_printf(TEXT("dump failed\n"));
311 break;
312 }
313 }
314
315 CloseHandle(fh);
316 }
317
318 static void
319 serial_test()
320 {
321 #if 1
322 # define SIUADDR 0xac000000
323 # define REGOFFSET 0x0
324 #else
325 # define SIUADDR 0xab000000
326 # define REGOFFSET 0x1a0
327 #endif
328 #define REGSIZE 32
329 int i, changed, res;
330 unsigned char regs[REGSIZE], prev_regs[REGSIZE];
331 unsigned char* p = (char*)VirtualAlloc(0, 1024, MEM_RESERVE,
332 PAGE_NOACCESS);
333
334 for (i = 0; i < ARRAYSIZEOF(prev_regs); i++) {
335 prev_regs[i] = ~0;
336 }
337
338 res = VirtualCopy((LPVOID)p, (LPVOID)(SIUADDR >> 8), 1024,
339 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
340 if (!res) {
341 win_printf(TEXT("VirtualCopy() failed."));
342 }
343
344 while (1) {
345 flush_XX();
346
347 for (i = 0; i < ARRAYSIZEOF(regs); i++) {
348 regs[i] = p[REGOFFSET + i];
349 }
350
351 changed = 0;
352 for (i = 0; i < ARRAYSIZEOF(regs); i++) {
353 if (regs[i] != prev_regs[i]) {
354 changed++;
355 }
356 prev_regs[i] = regs[i];
357 }
358 if (changed) {
359 win_printf(TEXT("SIU regs: "));
360 for (i = 0; i < ARRAYSIZEOF(regs); i++) {
361 win_printf(TEXT("%02x "), regs[i]);
362 }
363 win_printf(TEXT("\n"));
364 }
365 }
366
367 VirtualFree(p, 0, MEM_RELEASE);
368 }
369
370 static long
371 checksum(char* addr, int size)
372 {
373 long sum = 0;
374 int i;
375
376 for (i = 0; i < size; i++) {
377 sum += *addr++ * i;
378 }
379 return (sum);
380 }
381
382 static int
383 examine(char* addr, int size)
384 {
385 long random_data[256];
386 long dijest;
387 int i;
388
389 for (i = 0; i < ARRAYSIZEOF(random_data); i++) {
390 random_data[i] = Random();
391 }
392 if (sizeof(random_data) < size) {
393 size = sizeof(random_data);
394 }
395 memcpy(addr, (char*)random_data, size);
396 dijest= checksum((char*)random_data, size);
397
398 return (dijest == checksum(addr, size));
399 }
400
401 void
402 display_search()
403 {
404 int step = 0x10000;
405 int i;
406 long addr;
407
408 for (i = 0; i < ntargets; i++) {
409 int prevres = -1;
410 for (addr = targets[i].start;
411 addr < targets[i].end;
412 addr += step) {
413 int res;
414 char* p = (char*)VirtualAlloc(0, step, MEM_RESERVE,
415 PAGE_NOACCESS);
416 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), step,
417 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
418 if (!res) {
419 win_printf(TEXT("VirtualCopy() failed."));
420 }
421 res = examine(p, step);
422 VirtualFree(p, 0, MEM_RELEASE);
423 if (res != prevres && prevres != -1) {
424 if (res) {
425 win_printf(TEXT("0x%x "), addr);
426 } else {
427 win_printf(TEXT("- 0x%x\n"), addr);
428 }
429 } else
430 if (res && prevres == -1) {
431 win_printf(TEXT("0x%x "), addr);
432 }
433 prevres = res;
434 }
435 if (prevres) {
436 win_printf(TEXT("\n"));
437 }
438 }
439 }
440
441 void
442 display_draw()
443 {
444 long addr = 0x13000000;
445 int size = 0x40000;
446 char* p;
447 int i, j, res;
448 int x, y;
449
450 p = (char*)VirtualAlloc(0, size, MEM_RESERVE,
451 PAGE_NOACCESS);
452 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), size,
453 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
454 if (!res) {
455 win_printf(TEXT("VirtualCopy() failed."));
456 }
457
458 for (i = 0; i < 10000; i++) {
459 p[i] = i;
460 }
461 for (x = 0; x < 640; x += 10) {
462 for (y = 0; y < 240; y += 1) {
463 p[1024 * y + x] = (char)0xff;
464 }
465 }
466 for (y = 0; y < 240; y += 10) {
467 for (x = 0; x < 640; x += 1) {
468 p[1024 * y + x] = (char)0xff;
469 }
470 }
471 for (i = 0; i < 16; i++) {
472 for (j = 0; j < 16; j++) {
473 for (x = i * 32; x < i * 32 + 32; x++) {
474 for (y = j * 15; y < j * 15 + 15; y++) {
475 p[1024 * y + x] = j * 16 + i;
476 }
477 }
478 }
479 }
480
481 VirtualFree(p, 0, MEM_RELEASE);
482 }
483
484 #define PCIC_IDENT 0x00
485 #define PCIC_REG_INDEX 0
486 #define PCIC_REG_DATA 1
487 #define PCIC_IDENT_EXPECTED 0x83
488
489 void
490 pcic_search()
491 {
492 long addr;
493 int window_size = 0x10000;
494 int i;
495
496 for (addr = 0x14000000; addr < 0x18000000; addr += window_size) {
497 int res;
498 unsigned char* p;
499 p = (char*)VirtualAlloc(0, window_size, MEM_RESERVE,
500 PAGE_NOACCESS);
501 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), window_size,
502 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
503 if (!res) {
504 win_printf(TEXT("VirtualCopy() failed."));
505 }
506
507 for (i = 0; i < window_size; i += 2) {
508 p[i + PCIC_REG_INDEX] = PCIC_IDENT;
509 if (p[i + PCIC_REG_DATA] == PCIC_IDENT_EXPECTED) {
510 win_printf(TEXT("pcic is found at 0x%x\n"),
511 addr + i);
512 }
513 }
514
515 VirtualFree(p, 0, MEM_RELEASE);
516 }
517 }
518
519 void
520 hardware_test()
521 {
522 int do_gpio_test = 0;
523 int do_register_test = 0;
524 int do_serial_test = 0;
525 int do_display_draw = 0;
526 int do_display_search = 0;
527 int do_pcic_search = 0;
528 int do_dump_memory = 0;
529
530 if (do_gpio_test) {
531 gpio_test();
532 }
533 if (do_register_test) {
534 register_test();
535 }
536 if (do_serial_test) {
537 serial_test();
538 }
539 if (do_display_draw) {
540 display_draw();
541 }
542 if (do_display_search) {
543 display_search();
544 }
545 if (do_pcic_search) {
546 pcic_search();
547 }
548 if (do_dump_memory) {
549 dump_memory();
550 }
551 }
552