Home | History | Annotate | Line # | Download | only in pbsdboot
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]&regs[7], regs[4]&regs[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