1 /* $NetBSD: disptest.c,v 1.5 2001/09/24 10:42:02 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 extern BOOL SetKMode(BOOL); 41 #define ARRAYSIZEOF(a) (sizeof(a)/sizeof(*(a))) 42 43 static struct area { 44 long start, end; 45 } targets[] = { 46 { 0x0a000000, 0x0b000000 }, 47 { 0x10000000, 0x14000000 }, 48 }; 49 int ntargets = ARRAYSIZEOF(targets); 50 51 void 52 flush_XX() 53 { 54 static volatile unsigned char tmp[1024*64]; 55 int i, s; 56 57 for (i = 0; i < ARRAYSIZEOF(tmp); i++) { 58 s += tmp[i]; 59 } 60 } 61 62 static void 63 gpio_test() 64 { 65 #define GIUBASE 0xab000000 66 #define GIUOFFSET 0x0100 67 volatile unsigned short *giusell; 68 volatile unsigned short *giuselh; 69 volatile unsigned short *giupiodl; 70 volatile unsigned short *giupiodh; 71 unsigned short sell = 0; 72 unsigned short selh = 0; 73 unsigned short piodl = 0; 74 unsigned short piodh = 0; 75 int res, i; 76 unsigned short regs[16]; 77 unsigned short prev_regs[16]; 78 79 unsigned char* p = (char*)VirtualAlloc(0, 1024, MEM_RESERVE, 80 PAGE_NOACCESS); 81 res = VirtualCopy((LPVOID)p, (LPVOID)(GIUBASE >> 8), 1024, 82 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 83 if (!res) { 84 win_printf(TEXT("VirtualCopy() failed.")); 85 } 86 87 for (i = 0; i < 16; i++) { 88 prev_regs[i] = ~0; 89 } 90 91 giusell = (unsigned short*)(p + GIUOFFSET + 0); 92 giuselh = (unsigned short*)(p + GIUOFFSET + 2); 93 giupiodl = (unsigned short*)(p + GIUOFFSET + 4); 94 giupiodh = (unsigned short*)(p + GIUOFFSET + 6); 95 96 while (1) { 97 sell = *giusell; 98 selh = *giuselh; 99 *giusell = sell; 100 *giuselh = selh; 101 102 piodl = *giupiodl; 103 piodh = *giupiodh; 104 *giupiodl = piodl; 105 *giupiodh = piodh; 106 for (i = 0; i < 16; i++) { 107 regs[i] = *(unsigned short*)(p + GIUOFFSET + i * 2); 108 } 109 for (i = 0; i < 16; i++) { 110 if (i != 3 && i != 5 && regs[i] != prev_regs[i]) { 111 win_printf(TEXT("IOSEL=%04x%04x "), 112 regs[1], regs[0]); 113 win_printf(TEXT("PIOD=%04x%04x "), 114 regs[3], regs[2]); 115 win_printf(TEXT("STAT=%04x%04x "), 116 regs[5], regs[4]); 117 win_printf(TEXT("(%04x%04x) "), 118 regs[5]®s[7], regs[4]®s[6]); 119 win_printf(TEXT("EN=%04x%04x "), 120 regs[7], regs[6]); 121 win_printf(TEXT("TYP=%04x%04x "), 122 regs[9], regs[8]); 123 win_printf(TEXT("ALSEL=%04x%04x "), 124 regs[11], regs[10]); 125 win_printf(TEXT("HTSEL=%04x%04x "), 126 regs[13], regs[12]); 127 win_printf(TEXT("PODAT=%04x%04x "), 128 regs[15], regs[14]); 129 win_printf(TEXT("\n")); 130 for (i = 0; i < 16; i++) { 131 prev_regs[i] = regs[i]; 132 } 133 break; 134 } 135 } 136 } 137 } 138 139 static struct regdesc { 140 TCHAR *name; 141 int physaddr; 142 int size; 143 int mask; 144 //void *addr; 145 unsigned long val; 146 unsigned long preval; 147 } test_regs[] = { 148 #if 0 149 /* 150 * Vrc4172 GPIO and PWM 151 */ 152 { TEXT("EXGPDATA0"), 0x15001080, 2, 0xfffd }, 153 { TEXT("EXGPDATA1"), 0x150010c0, 2, 0xffff }, 154 { TEXT("LCDDUTYEN"), 0x15003880, 2, 0xffff }, 155 { TEXT("LCDFREQ"), 0x15003882, 2, 0xffff }, 156 { TEXT("LCDDUTY"), 0x15003884, 2, 0xffff }, 157 #endif 158 159 #if 0 160 /* 161 * Vr41xx GPIO 162 */ 163 { TEXT("GIUPIODL"), 0x0b000104, 2, 0xffff }, 164 { TEXT("GIUPIODH"), 0x0b000106, 2, 0xffff }, 165 { TEXT("GIUPODATL"), 0x0b00011c, 2, 0xffff }, 166 { TEXT("GIUPODATH"), 0x0b00011e, 2, 0xffff }, 167 { TEXT("GIUUSEUPDN"), 0x0b0002e0, 2, 0xffff }, 168 { TEXT("GIUTERMUPDN"), 0x0b0002e2, 2, 0xffff }, 169 #endif 170 171 /* 172 * MQ200 173 */ 174 { TEXT("PM00R"), 0x0a600000, 4, 0xffffffff }, 175 { TEXT("PM01R"), 0x0a600004, 4, 0xffffffff }, 176 { TEXT("PM02R"), 0x0a600008, 4, 0xffffffff }, 177 { TEXT("PM06R"), 0x0a600018, 4, 0xffffffff }, 178 { TEXT("PM07R"), 0x0a60001c, 4, 0xffffffff }, 179 180 { TEXT("CC00R"), 0x0a602000, 4, 0x0000003f }, 181 { TEXT("CC01R"), 0x0a602004, 4, 0x00000000 }, 182 183 { TEXT("MM00R"), 0x0a604000, 4, 0x00000007 }, 184 { TEXT("MM01R"), 0x0a604004, 4, 0xffffffff }, 185 { TEXT("MM02R"), 0x0a604008, 4, 0xffffffff }, 186 { TEXT("MM03R"), 0x0a60400c, 4, 0x00000001 }, 187 { TEXT("MM04R"), 0x0a604010, 4, 0x00000001 }, 188 189 { TEXT("IN00R"), 0x0a608000, 4, 0x0000001f }, 190 { TEXT("IN01R"), 0x0a608004, 4, 0x0000ffff }, 191 { TEXT("IN02R"), 0x0a608008, 4, 0x00000000 }, 192 { TEXT("IN03R"), 0x0a60800c, 4, 0x00000000 }, 193 194 { TEXT("GC00R"), 0x0a60a000, 4, 0xfffff9ff }, 195 { TEXT("GC01R"), 0x0a60a004, 4, 0x10ffffff }, 196 { TEXT("GC20R"), 0x0a60a080, 4, 0xffffffff }, 197 { TEXT("GC21R"), 0x0a60a084, 4, 0x0000007f }, 198 199 { TEXT("FP00R"), 0x0a60e000, 4, 0xffffffff }, 200 { TEXT("FP01R"), 0x0a60e004, 4, 0xffffffff }, 201 { TEXT("FP02R"), 0x0a60e008, 4, 0x007fffff }, 202 { TEXT("FP03R"), 0x0a60e00c, 4, 0x0707003f }, 203 { TEXT("FP04R"), 0x0a60e010, 4, 0xffff3fff }, 204 { TEXT("FP05R"), 0x0a60e014, 4, 0xffffffff }, 205 { TEXT("FP0FR"), 0x0a60e03c, 4, 0xffffffff }, 206 207 { TEXT("DC00R"), 0x0a614000, 4, 0xffffffff }, 208 { TEXT("DC01R"), 0x0a614004, 4, 0x0000003f }, 209 { TEXT("DC02R"), 0x0a614008, 4, 0xffffffff }, 210 { TEXT("DC03R"), 0x0a61400c, 4, 0xffffffff }, 211 212 { TEXT("PC00R"), 0x0a616000, 4, 0xffffffff }, 213 { TEXT("PC04R"), 0x0a616004, 4, 0xffffffff }, 214 { TEXT("PC08R"), 0x0a616008, 4, 0xffffffff }, 215 { TEXT("PC0CR"), 0x0a61600c, 4, 0xffffffff }, 216 { TEXT("PC10R"), 0x0a616010, 4, 0xffffffff }, 217 { TEXT("PC14R"), 0x0a616014, 4, 0xffffffff }, 218 { TEXT("PC2CR"), 0x0a61602c, 4, 0xffffffff }, 219 { TEXT("PC3CR"), 0x0a61603c, 4, 0xffffffff }, 220 { TEXT("PC40R"), 0x0a616040, 4, 0xffffffff }, 221 { TEXT("PC44R"), 0x0a616044, 4, 0x00000003 }, 222 }; 223 224 extern int SetKMode(int); 225 static void 226 regfetch(struct regdesc* desc) 227 { 228 SetKMode(1); 229 switch (desc->size) { 230 case 1: 231 desc->val = *(unsigned char*)(desc->physaddr | 0xa0000000); 232 break; 233 case 2: 234 desc->val = *(unsigned short*)(desc->physaddr | 0xa0000000); 235 break; 236 case 4: 237 desc->val = *(unsigned long*)(desc->physaddr | 0xa0000000); 238 break; 239 default: 240 win_printf(TEXT("Invalid size")); 241 break; 242 } 243 SetKMode(0); 244 desc->val &= desc->mask; 245 } 246 247 static void 248 register_test() 249 { 250 int i; 251 int nregs = sizeof(test_regs)/sizeof(*test_regs); 252 253 for (i = 0; i < nregs; i++) { 254 regfetch(&test_regs[i]); 255 test_regs[i].preval = test_regs[i].val; 256 } 257 258 while (1) { 259 for (i = 0; i < nregs; i++) { 260 regfetch(&test_regs[i]); 261 if (test_regs[i].val != test_regs[i].preval) { 262 win_printf(TEXT("%20s(%08x) %08x -> %08x\n"), 263 test_regs[i].name, 264 test_regs[i].physaddr, 265 test_regs[i].preval, 266 test_regs[i].val); 267 test_regs[i].preval = test_regs[i].val; 268 } 269 } 270 Sleep(10); /* 10 msec */ 271 } 272 } 273 274 static void 275 dump_memory() 276 { 277 HANDLE fh = INVALID_HANDLE_VALUE; 278 #define UNICODE_MEMORY_CARD \ 279 TEXT('\\'), 0xff92, 0xff93, 0xff98, TEXT(' '), 0xff76, 0xff70, \ 280 0xff84, 0xff9e 281 TCHAR filename[] = { UNICODE_MEMORY_CARD, TEXT('2'), TEXT('\\'), 282 TEXT('d'), TEXT('u'), TEXT('m'), TEXT('p'), 0 }; 283 unsigned long *addr; 284 int found; 285 286 win_printf(TEXT("dump to %s\n"), filename); 287 fh = CreateFile( 288 filename, /* file name */ 289 GENERIC_WRITE, /* access (read-write) mode */ 290 FILE_SHARE_WRITE,/* share mode */ 291 NULL, /* pointer to security attributes */ 292 CREATE_ALWAYS, /* how to create */ 293 FILE_ATTRIBUTE_NORMAL, /* file attributes*/ 294 NULL /* handle to file with attributes to */ 295 ); 296 if (fh == INVALID_HANDLE_VALUE) { 297 return; 298 } 299 300 for (addr = (unsigned long*)0xbe000000; 301 addr < (unsigned long*)0xbfffffff; 302 addr += 2048) { 303 char buf[2048]; 304 DWORD n; 305 306 SetKMode(1); 307 memcpy(buf, addr, 2048); 308 SetKMode(0); 309 if (WriteFile(fh, buf, 2048, &n, NULL) == 0 || 310 n != 2048) { 311 win_printf(TEXT("dump failed\n")); 312 break; 313 } 314 } 315 316 CloseHandle(fh); 317 } 318 319 static void 320 serial_test() 321 { 322 #if 1 323 # define SIUADDR 0xac000000 324 # define REGOFFSET 0x0 325 #else 326 # define SIUADDR 0xab000000 327 # define REGOFFSET 0x1a0 328 #endif 329 #define REGSIZE 32 330 int i, changed, res; 331 unsigned char regs[REGSIZE], prev_regs[REGSIZE]; 332 unsigned char* p = (char*)VirtualAlloc(0, 1024, MEM_RESERVE, 333 PAGE_NOACCESS); 334 335 for (i = 0; i < ARRAYSIZEOF(prev_regs); i++) { 336 prev_regs[i] = ~0; 337 } 338 339 res = VirtualCopy((LPVOID)p, (LPVOID)(SIUADDR >> 8), 1024, 340 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 341 if (!res) { 342 win_printf(TEXT("VirtualCopy() failed.")); 343 } 344 345 while (1) { 346 flush_XX(); 347 348 for (i = 0; i < ARRAYSIZEOF(regs); i++) { 349 regs[i] = p[REGOFFSET + i]; 350 } 351 352 changed = 0; 353 for (i = 0; i < ARRAYSIZEOF(regs); i++) { 354 if (regs[i] != prev_regs[i]) { 355 changed++; 356 } 357 prev_regs[i] = regs[i]; 358 } 359 if (changed) { 360 win_printf(TEXT("SIU regs: ")); 361 for (i = 0; i < ARRAYSIZEOF(regs); i++) { 362 win_printf(TEXT("%02x "), regs[i]); 363 } 364 win_printf(TEXT("\n")); 365 } 366 } 367 368 VirtualFree(p, 0, MEM_RELEASE); 369 } 370 371 static long 372 checksum(char* addr, int size) 373 { 374 long sum = 0; 375 int i; 376 377 for (i = 0; i < size; i++) { 378 sum += *addr++ * i; 379 } 380 return (sum); 381 } 382 383 static int 384 examine(char* addr, int size) 385 { 386 long random_data[256]; 387 long dijest; 388 int i; 389 390 for (i = 0; i < ARRAYSIZEOF(random_data); i++) { 391 random_data[i] = Random(); 392 } 393 if (sizeof(random_data) < size) { 394 size = sizeof(random_data); 395 } 396 memcpy(addr, (char*)random_data, size); 397 dijest= checksum((char*)random_data, size); 398 399 return (dijest == checksum(addr, size)); 400 } 401 402 void 403 display_search() 404 { 405 int step = 0x10000; 406 int i; 407 long addr; 408 409 for (i = 0; i < ntargets; i++) { 410 int prevres = -1; 411 for (addr = targets[i].start; 412 addr < targets[i].end; 413 addr += step) { 414 int res; 415 #if 0 416 char* p = (char*)VirtualAlloc(0, step, MEM_RESERVE, 417 PAGE_NOACCESS); 418 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), step, 419 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 420 if (!res) { 421 win_printf(TEXT("VirtualCopy() failed.")); 422 } 423 res = examine(p, step); 424 VirtualFree(p, 0, MEM_RELEASE); 425 #else 426 SetKMode(1); 427 res = examine((char*)((int)addr | 0xa0000000), step); 428 SetKMode(0); 429 #endif 430 if (res != prevres && prevres != -1) { 431 if (res) { 432 win_printf(TEXT("0x%x "), addr); 433 } else { 434 win_printf(TEXT("- 0x%x\n"), addr); 435 } 436 } else 437 if (res && prevres == -1) { 438 win_printf(TEXT("0x%x "), addr); 439 } 440 prevres = res; 441 } 442 if (prevres) { 443 win_printf(TEXT("\n")); 444 } 445 } 446 } 447 448 void 449 display_draw() 450 { 451 long addr = 0x13000000; 452 int size = 0x80000; 453 char* p; 454 int i, j, res; 455 int x, y; 456 int stride = 1280; 457 458 p = (char*)VirtualAlloc(0, size, MEM_RESERVE, 459 PAGE_NOACCESS); 460 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), size, 461 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 462 if (!res) { 463 win_printf(TEXT("VirtualCopy() failed.")); 464 } 465 466 for (i = 0; i < 10000; i++) { 467 p[i] = i; 468 } 469 for (x = 0; x < 640; x += 10) { 470 for (y = 0; y < 240; y += 1) { 471 p[stride * y + x] = (char)0xff; 472 } 473 } 474 for (y = 0; y < 240; y += 10) { 475 for (x = 0; x < 640; x += 1) { 476 p[stride * y + x] = (char)0xff; 477 } 478 } 479 for (i = 0; i < 16; i++) { 480 for (j = 0; j < 16; j++) { 481 for (x = i * 32; x < i * 32 + 32; x++) { 482 for (y = j * 15; y < j * 15 + 15; y++) { 483 p[stride * y + x] = j * 16 + i; 484 } 485 } 486 } 487 } 488 489 VirtualFree(p, 0, MEM_RELEASE); 490 } 491 492 #define PCIC_IDENT 0x00 493 #define PCIC_REG_INDEX 0 494 #define PCIC_REG_DATA 1 495 #define PCIC_IDENT_EXPECTED 0x83 496 497 void 498 pcic_search() 499 { 500 long addr; 501 int window_size = 0x10000; 502 int i; 503 504 for (addr = 0x14000000; addr < 0x18000000; addr += window_size) { 505 int res; 506 unsigned char* p; 507 p = (char*)VirtualAlloc(0, window_size, MEM_RESERVE, 508 PAGE_NOACCESS); 509 res = VirtualCopy((LPVOID)p, (LPVOID)(addr >> 8), window_size, 510 PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 511 if (!res) { 512 win_printf(TEXT("VirtualCopy() failed.")); 513 } 514 515 for (i = 0; i < window_size; i += 2) { 516 p[i + PCIC_REG_INDEX] = PCIC_IDENT; 517 if (p[i + PCIC_REG_DATA] == PCIC_IDENT_EXPECTED) { 518 win_printf(TEXT("pcic is found at 0x%x\n"), 519 addr + i); 520 } 521 } 522 523 VirtualFree(p, 0, MEM_RELEASE); 524 } 525 } 526 527 #define VRPCIU_CONFA (*(u_int32_t*)0xaf000c18) 528 #define VRPCIU_CONFD (*(u_int32_t*)0xaf000c14) 529 530 void 531 pci_dump() 532 { 533 int mode, i; 534 BOOL SetKMode(BOOL); 535 int bus, dev; 536 u_int32_t addr, val; 537 u_int32_t addrs[] = { 538 0x00000800, 539 0x00001000, 540 0x00002000, 541 0x00004000, 542 0x00008000, 543 0x00010000, 544 0x00020000, 545 0x00040000, 546 0x00080000, 547 0x00100000, 548 0x00200000, 549 0x00400000, 550 0x00800000, 551 0x01000000, 552 0x02000000, 553 0x04000000, 554 0x08000000, 555 0x10000000, 556 0x20000000, 557 0x40000000, 558 0x80000000, 559 }; 560 561 #if 0 /* You can find Vrc4173 BCU at 0xb6010000 on Sigmarion II */ 562 win_printf(TEXT("Vrc4173 CMUCLKMSK: %04X\n"), 563 *(u_int16_t*)0xb6010040); 564 win_printf(TEXT("Vrc4173 CMUSRST: %04X\n"), 565 *(u_int16_t*)0xb6010042); 566 567 /* enable CARDU clock */ 568 *(u_int16_t*)0xb6010042 = 0x0006; /* enable CARD1RST and CARD2RST */ 569 *(u_int16_t*)0xb6010040 = *(u_int16_t*)0xb6010040 | 0x00c0; 570 *(u_int16_t*)0xb6010042 = 0x0000; /* disable CARD1RST and CARD2RST */ 571 572 win_printf(TEXT("Vrc4173 CMUCLKMSK: %04X\n"), 573 *(u_int16_t*)0xb6010040); 574 win_printf(TEXT("Vrc4173 CMUSRST: %04X\n"), 575 *(u_int16_t*)0xb6010042); 576 #endif 577 578 for (i = 0; i < sizeof(addrs)/sizeof(*addrs); i++) { 579 VRPCIU_CONFA = addrs[i]; 580 val = VRPCIU_CONFD; 581 win_printf(TEXT("%2d: %08X %04X %04X\n"), 582 i, addrs[i], val & 0xffff, (val >> 16) & 0xffff); 583 } 584 585 mode = SetKMode(1); 586 SetKMode(mode); 587 } 588 589 void 590 hardware_test() 591 { 592 int do_gpio_test = 0; 593 int do_register_test = 0; 594 int do_serial_test = 0; 595 int do_display_draw = 0; 596 int do_display_search = 0; 597 int do_pcic_search = 0; 598 int do_dump_memory = 0; 599 int do_pci_dump = 0; 600 601 if (do_gpio_test) { 602 gpio_test(); 603 } 604 if (do_register_test) { 605 register_test(); 606 } 607 if (do_serial_test) { 608 serial_test(); 609 } 610 if (do_display_draw) { 611 display_draw(); 612 } 613 if (do_display_search) { 614 display_search(); 615 } 616 if (do_pcic_search) { 617 pcic_search(); 618 } 619 if (do_dump_memory) { 620 dump_memory(); 621 } 622 if (do_pci_dump) { 623 pci_dump(); 624 } 625 } 626