machdep.c revision 1.33
1/* $NetBSD: machdep.c,v 1.33 2002/02/28 01:56:59 uch Exp $ */ 2 3/*- 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 9 * Simulation Facility, NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40/*- 41 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 42 * All rights reserved. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * William Jolitz. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed by the University of 58 * California, Berkeley and its contributors. 59 * 4. Neither the name of the University nor the names of its contributors 60 * may be used to endorse or promote products derived from this software 61 * without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * SUCH DAMAGE. 74 * 75 * @(#)machdep.c 7.4 (Berkeley) 6/3/91 76 */ 77 78#include "opt_ddb.h" 79#include "opt_kgdb.h" 80#include "opt_syscall_debug.h" 81#include "opt_memsize.h" 82#include "opt_initbsc.h" 83 84#include <sys/param.h> 85#include <sys/systm.h> 86#include <sys/signalvar.h> 87#include <sys/kernel.h> 88#include <sys/map.h> 89#include <sys/proc.h> 90#include <sys/user.h> 91#include <sys/exec.h> 92#include <sys/buf.h> 93#include <sys/reboot.h> 94#include <sys/conf.h> 95#include <sys/file.h> 96#include <sys/malloc.h> 97#include <sys/mbuf.h> 98#include <sys/msgbuf.h> 99#include <sys/mount.h> 100#include <sys/vnode.h> 101#include <sys/device.h> 102#include <sys/extent.h> 103#include <sys/syscallargs.h> 104 105#ifdef KGDB 106#include <sys/kgdb.h> 107#endif 108 109#include <dev/cons.h> 110 111#include <uvm/uvm_extern.h> 112 113#include <sys/sysctl.h> 114 115#include <machine/cpu.h> 116#include <machine/cpufunc.h> 117#include <machine/psl.h> 118#include <machine/bootinfo.h> 119#include <machine/bus.h> 120#include <sh3/cpgreg.h> 121#include <sh3/bscreg.h> 122#include <sh3/mmu.h> 123#include <sh3/cache_sh3.h> 124#include <sh3/cache_sh4.h> 125 126#include <sys/termios.h> 127#include "sci.h" 128 129/* the following is used externally (sysctl_hw) */ 130char machine[] = MACHINE; /* cpu "architecture" */ 131char machine_arch[] = MACHINE_ARCH; /* machine_arch = "sh3" */ 132 133#ifdef sh3_debug 134int cpu_debug_mode = 1; 135#else 136int cpu_debug_mode = 0; 137#endif 138 139char bootinfo[BOOTINFO_MAXSIZE]; 140 141int physmem; 142int dumpmem_low; 143int dumpmem_high; 144vaddr_t atdevbase; /* location of start of iomem in virtual */ 145paddr_t msgbuf_paddr; 146struct user *proc0paddr; 147 148extern int boothowto; 149extern paddr_t avail_start, avail_end; 150 151#ifdef SYSCALL_DEBUG 152#define SCDEBUG_ALL 0x0004 153extern int scdebug; 154#endif 155 156#define IOM_RAM_END ((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1) 157 158/* 159 * Extent maps to manage I/O and ISA memory hole space. Allocate 160 * storage for 8 regions in each, initially. Later, ioport_malloc_safe 161 * will indicate that it's safe to use malloc() to dynamically allocate 162 * region descriptors. 163 * 164 * N.B. At least two regions are _always_ allocated from the iomem 165 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 166 * 167 * The extent maps are not static! Machine-dependent ISA and EISA 168 * routines need access to them for bus address space allocation. 169 */ 170static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 171struct extent *ioport_ex; 172struct extent *iomem_ex; 173static int ioport_malloc_safe; 174 175void setup_bootinfo __P((void)); 176void dumpsys __P((void)); 177void initSH3 __P((void *)); 178void LoadAndReset __P((char *)); 179void XLoadAndReset __P((char *)); 180void cpu_reset(void); 181 182void consinit __P((void)); 183 184/* 185 * Machine-dependent startup code 186 * 187 * This is called from main() in kern/main.c. 188 */ 189void 190cpu_startup() 191{ 192 193 sh3_startup(); 194 195 /* Safe for i/o port allocation to use malloc now. */ 196 ioport_malloc_safe = 1; 197 198#ifdef SYSCALL_DEBUG 199 scdebug |= SCDEBUG_ALL; 200#endif 201 202#ifdef FORCE_RB_SINGLE 203 boothowto |= RB_SINGLE; 204#endif 205} 206 207#define CPUDEBUG 208 209/* 210 * machine dependent system variables. 211 */ 212int 213cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 214 int *name; 215 u_int namelen; 216 void *oldp; 217 size_t *oldlenp; 218 void *newp; 219 size_t newlen; 220 struct proc *p; 221{ 222 dev_t consdev; 223 struct btinfo_bootpath *bibp; 224 struct trapframe *tf; 225 char *osimage; 226 227 /* all sysctl names at this level are terminal */ 228 if (namelen != 1) 229 return (ENOTDIR); /* overloaded */ 230 231 switch (name[0]) { 232 case CPU_CONSDEV: 233 if (cn_tab != NULL) 234 consdev = cn_tab->cn_dev; 235 else 236 consdev = NODEV; 237 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 238 sizeof consdev)); 239 240 case CPU_NKPDE: 241 return (sysctl_rdint(oldp, oldlenp, newp, nkpde)); 242 243 case CPU_BOOTED_KERNEL: 244 bibp = lookup_bootinfo(BTINFO_BOOTPATH); 245 if (!bibp) 246 return (ENOENT); /* ??? */ 247 return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath)); 248 249 case CPU_SETPRIVPROC: 250 if (newp == NULL) 251 return (0); 252 253 /* set current process to priviledged process */ 254 tf = p->p_md.md_regs; 255 tf->tf_ssr |= PSL_MD; 256 return (0); 257 258 case CPU_DEBUGMODE: 259 return (sysctl_int(oldp, oldlenp, newp, newlen, 260 &cpu_debug_mode)); 261 262 case CPU_LOADANDRESET: 263 if (newp != NULL) { 264 osimage = (char *)(*(u_long *)newp); 265 266 LoadAndReset(osimage); 267 /* not reach here */ 268 } 269 return (0); 270 271 default: 272 return (EOPNOTSUPP); 273 } 274 /* NOTREACHED */ 275} 276 277int waittime = -1; 278struct pcb dumppcb; 279 280void 281cpu_reboot(howto, bootstr) 282 int howto; 283 char *bootstr; 284{ 285 286 if (cold) { 287 howto |= RB_HALT; 288 goto haltsys; 289 } 290 291 boothowto = howto; 292 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 293 waittime = 0; 294 vfs_shutdown(); 295 /* 296 * If we've been adjusting the clock, the todr 297 * will be out of synch; adjust it now. 298 */ 299 /* resettodr(); */ 300 } 301 302 /* Disable interrupts. */ 303 splhigh(); 304 305 /* Do a dump if requested. */ 306 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 307 dumpsys(); 308 309haltsys: 310 doshutdownhooks(); 311 312 if (howto & RB_HALT) { 313 printf("\n"); 314 printf("The operating system has halted.\n"); 315 printf("Please press any key to reboot.\n\n"); 316 cngetc(); 317 } 318 319 printf("rebooting...\n"); 320 cpu_reset(); 321 for(;;) 322 ; 323 /*NOTREACHED*/ 324} 325 326/* 327 * These variables are needed by /sbin/savecore 328 */ 329u_long dumpmag = 0x8fca0101; /* magic number */ 330int dumpsize = 0; /* pages */ 331long dumplo = 0; /* blocks */ 332 333/* 334 * This is called by main to set dumplo and dumpsize. 335 * Dumps always skip the first CLBYTES of disk space 336 * in case there might be a disk label stored there. 337 * If there is extra space, put dump at the end to 338 * reduce the chance that swapping trashes it. 339 */ 340void 341cpu_dumpconf() 342{ 343#ifdef TODO 344 int nblks; /* size of dump area */ 345 int maj; 346 347 if (dumpdev == NODEV) 348 return; 349 maj = major(dumpdev); 350 if (maj < 0 || maj >= nblkdev) 351 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 352 if (bdevsw[maj].d_psize == NULL) 353 return; 354 nblks = (*bdevsw[maj].d_psize)(dumpdev); 355 if (nblks <= ctod(1)) 356 return; 357 358 dumpsize = btoc(IOM_END + ctob(dumpmem_high)); 359 360 /* Always skip the first CLBYTES, in case there is a label there. */ 361 if (dumplo < ctod(1)) 362 dumplo = ctod(1); 363 364 /* Put dump at end of partition, and make it fit. */ 365 if (dumpsize > dtoc(nblks - dumplo)) 366 dumpsize = dtoc(nblks - dumplo); 367 if (dumplo < nblks - ctod(dumpsize)) 368 dumplo = nblks - ctod(dumpsize); 369#endif 370} 371 372/* 373 * Doadump comes here after turning off memory management and 374 * getting on the dump stack, either when called above, or by 375 * the auto-restart code. 376 */ 377#define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */ 378static vaddr_t dumpspace; 379 380vaddr_t 381reserve_dumppages(p) 382 vaddr_t p; 383{ 384 385 dumpspace = p; 386 return (p + BYTES_PER_DUMP); 387} 388 389void 390dumpsys() 391{ 392#ifdef TODO 393 unsigned bytes, i, n; 394 int maddr, psize; 395 daddr_t blkno; 396 int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 397 int error; 398 399 /* Save registers. */ 400 savectx(&dumppcb); 401 402 msgbufmapped = 0; /* don't record dump msgs in msgbuf */ 403 if (dumpdev == NODEV) 404 return; 405 406 /* 407 * For dumps during autoconfiguration, 408 * if dump device has already configured... 409 */ 410 if (dumpsize == 0) 411 cpu_dumpconf(); 412 if (dumplo < 0) 413 return; 414 printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 415 416 psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 417 printf("dump "); 418 if (psize == -1) { 419 printf("area unavailable\n"); 420 return; 421 } 422 423#if 0 /* XXX this doesn't work. grr. */ 424 /* toss any characters present prior to dump */ 425 while (sget() != NULL); /* syscons and pccons differ */ 426#endif 427 428 bytes = ctob(dumpmem_high) + IOM_END; 429 maddr = 0; 430 blkno = dumplo; 431 dump = bdevsw[major(dumpdev)].d_dump; 432 error = 0; 433 for (i = 0; i < bytes; i += n) { 434 /* 435 * Avoid dumping the ISA memory hole, and areas that 436 * BIOS claims aren't in low memory. 437 */ 438 if (i >= ctob(dumpmem_low) && i < IOM_END) { 439 n = IOM_END - i; 440 maddr += n; 441 blkno += btodb(n); 442 continue; 443 } 444 445 /* Print out how many MBs we to go. */ 446 n = bytes - i; 447 if (n && (n % (1024*1024)) == 0) 448 printf("%d ", n / (1024 * 1024)); 449 450 /* Limit size for next transfer. */ 451 if (n > BYTES_PER_DUMP) 452 n = BYTES_PER_DUMP; 453 454 (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); 455 error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n); 456 if (error) 457 break; 458 maddr += n; 459 blkno += btodb(n); /* XXX? */ 460 461#if 0 /* XXX this doesn't work. grr. */ 462 /* operator aborting dump? */ 463 if (sget() != NULL) { 464 error = EINTR; 465 break; 466 } 467#endif 468 } 469 470 switch (error) { 471 472 case ENXIO: 473 printf("device bad\n"); 474 break; 475 476 case EFAULT: 477 printf("device not ready\n"); 478 break; 479 480 case EINVAL: 481 printf("area improper\n"); 482 break; 483 484 case EIO: 485 printf("i/o error\n"); 486 break; 487 488 case EINTR: 489 printf("aborted from console\n"); 490 break; 491 492 case 0: 493 printf("succeeded\n"); 494 break; 495 496 default: 497 printf("error %d\n", error); 498 break; 499 } 500 printf("\n\n"); 501 delay(5000000); /* 5 seconds */ 502#endif /* TODO */ 503} 504 505/* 506 * Initialize segments and descriptor tables 507 */ 508#define VADDRSTART VM_MIN_KERNEL_ADDRESS 509 510extern int nkpde; 511extern char start[], etext[], edata[], end[]; 512 513void 514initSH3(pc) 515 void *pc; /* XXX return address */ 516{ 517 paddr_t avail; 518 pd_entry_t *pagedir; 519 pt_entry_t *pagetab, pte; 520 u_int sp; 521 int x; 522 char *p; 523 524 avail = sh3_round_page(end); 525 526 /* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */ 527 nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1); 528 529 /* 530 * clear .bss, .common area, page dir area, 531 * process0 stack, page table area 532 */ 533 p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */ 534 memset(edata, 0, p - edata); 535 536#if defined(SH3) && defined(SH4) 537#error "don't define both SH3 and SH4" 538#elif defined(SH3) 539 sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_UNKNOWN); 540#elif defined(SH4) 541 sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_UNKNOWN); 542#else 543#error "define SH3 or SH4" 544#endif 545 546/* 547 * edata end 548 * +-------------+------+-----+----------+-------------+------------+ 549 * | kernel text | data | bss | Page Dir | Proc0 Stack | Page Table | 550 * +-------------+------+-----+----------+-------------+------------+ 551 * NBPG USPACE (1+nkpde)*NBPG 552 * (= 4*NBPG) 553 * Build initial page tables 554 */ 555 pagedir = (void *)avail; 556 pagetab = (void *)(avail + SYSMAP); 557 558 /* 559 * Construct a page table directory 560 * In SH3 H/W does not support PTD, 561 * these structures are used by S/W. 562 */ 563 pte = (pt_entry_t)pagetab; 564 pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N; 565 pagedir[KERNTEXTOFF >> PDSHIFT] = pte; 566 567 /* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000, 568 0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */ 569 pte += NBPG; 570 for (x = 0; x < nkpde; x++) { 571 pagedir[(VADDRSTART >> PDSHIFT) + x] = pte; 572 pte += NBPG; 573 } 574 575 /* Install a PDE recursively mapping page directory as a page table! */ 576 pte = (u_int)pagedir; 577 pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N; 578 pagedir[PDSLOT_PTE] = pte; 579 580 /* set PageDirReg */ 581 SH_MMU_TTB_WRITE((u_int32_t)pagedir); 582 583 /* 584 * Activate MMU 585 */ 586 sh_mmu_start(); 587 588 /* 589 * Now here is virtual address 590 */ 591 592 /* Set proc0paddr */ 593 proc0paddr = (void *)(avail + NBPG); 594 595 /* Set pcb->PageDirReg of proc0 */ 596 proc0paddr->u_pcb.pageDirReg = (int)pagedir; 597 598 /* avail_start is first available physical memory address */ 599 avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde; 600 601 /* atdevbase is first available logical memory address */ 602 atdevbase = VADDRSTART; 603 604 proc0.p_addr = proc0paddr; /* page dir address */ 605 606 /* XXX: PMAP_NEW requires valid curpcb. also init'd in cpu_startup */ 607 curpcb = &proc0.p_addr->u_pcb; 608 609 /* 610 * Initialize the I/O port and I/O mem extent maps. 611 * Note: we don't have to check the return value since 612 * creation of a fixed extent map will never fail (since 613 * descriptor storage has already been allocated). 614 * 615 * N.B. The iomem extent manages _all_ physical addresses 616 * on the machine. When the amount of RAM is found, the two 617 * extents of RAM are allocated from the map (0 -> ISA hole 618 * and end of ISA hole -> end of RAM). 619 */ 620 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 621 (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 622 EX_NOCOALESCE|EX_NOWAIT); 623 624#if 0 625 consinit(); /* XXX SHOULD NOT BE DONE HERE */ 626#endif 627 628 splraise(-1); 629 _cpu_exception_resume(0); 630 631 avail_end = sh3_trunc_page(IOM_RAM_END + 1); 632 633 printf("initSH3\r\n"); 634 635 /* 636 * Calculate check sum 637 */ 638 { 639 u_short *p, sum; 640 int size; 641 642 size = etext - start; 643 p = (u_short *)start; 644 sum = 0; 645 size >>= 1; 646 while (size--) 647 sum += *p++; 648 printf("Check Sum = 0x%x\r\n", sum); 649 } 650 /* 651 * Allocate the physical addresses used by RAM from the iomem 652 * extent map. This is done before the addresses are 653 * page rounded just to make sure we get them all. 654 */ 655 if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN, 656 (IOM_RAM_END-IOM_RAM_BEGIN) + 1, 657 EX_NOWAIT)) { 658 /* XXX What should we do? */ 659 printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n"); 660 } 661 662 /* number of pages of physmem addr space */ 663 physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1); 664#ifdef TODO 665 dumpmem = physmem; 666#endif 667 668 /* 669 * Initialize for pmap_free_pages and pmap_next_page. 670 * These guys should be page-aligned. 671 */ 672 if (physmem < btoc(2 * 1024 * 1024)) { 673 printf("warning: too little memory available; " 674 "have %d bytes, want %d bytes\n" 675 "running in degraded mode\n" 676 "press a key to confirm\n\n", 677 ctob(physmem), 2*1024*1024); 678 cngetc(); 679 } 680 681 /* Call pmap initialization to make new kernel address space */ 682 pmap_bootstrap(atdevbase); 683 684 /* 685 * Initialize error message buffer (at end of core). 686 */ 687 initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE)); 688 689 /* 690 * set boot device information 691 */ 692 setup_bootinfo(); 693 694 /* setup proc0 stack */ 695 sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe); 696 697 /* 698 * XXX We can't return here, because we change stack pointer. 699 * So jump to return address directly. 700 */ 701 __asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp)); 702} 703 704void 705setup_bootinfo(void) 706{ 707 struct btinfo_bootdisk *help; 708 709 *(int *)bootinfo = 1; 710 help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int)); 711 help->biosdev = 0; 712 help->partition = 0; 713 ((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk); 714 ((struct btinfo_common *)help)->type = BTINFO_BOOTDISK; 715} 716 717void * 718lookup_bootinfo(type) 719 int type; 720{ 721 struct btinfo_common *help; 722 int n = *(int*)bootinfo; 723 help = (struct btinfo_common *)(bootinfo + sizeof(int)); 724 while (n--) { 725 if (help->type == type) 726 return (help); 727 help = (struct btinfo_common *)((char*)help + help->len); 728 } 729 return (0); 730} 731 732 733/* 734 * consinit: 735 * initialize the system console. 736 * XXX - shouldn't deal with this initted thing, but then, 737 * it shouldn't be called from init386 either. 738 */ 739void 740consinit() 741{ 742 static int initted; 743 744 if (initted) 745 return; 746 initted = 1; 747 748 cninit(); 749 750#ifdef DDB 751 ddb_init(); 752#endif 753} 754 755void 756cpu_reset() 757{ 758 759 _cpu_exception_suspend(); 760 761 goto *(u_int32_t *)0xa0000000; 762 for (;;) 763 ; 764} 765 766int 767bus_space_map (t, addr, size, flags, bshp) 768 bus_space_tag_t t; 769 bus_addr_t addr; 770 bus_size_t size; 771 int flags; 772 bus_space_handle_t *bshp; 773{ 774 775 *bshp = (bus_space_handle_t)addr; 776 777 return 0; 778} 779 780int 781sh_memio_subregion(t, bsh, offset, size, nbshp) 782 bus_space_tag_t t; 783 bus_space_handle_t bsh; 784 bus_size_t offset, size; 785 bus_space_handle_t *nbshp; 786{ 787 788 *nbshp = bsh + offset; 789 return (0); 790} 791 792int 793sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, 794 bpap, bshp) 795 bus_space_tag_t t; 796 bus_addr_t rstart, rend; 797 bus_size_t size, alignment, boundary; 798 int flags; 799 bus_addr_t *bpap; 800 bus_space_handle_t *bshp; 801{ 802 *bshp = *bpap = rstart; 803 804 return (0); 805} 806 807void 808sh_memio_free(t, bsh, size) 809 bus_space_tag_t t; 810 bus_space_handle_t bsh; 811 bus_size_t size; 812{ 813 814} 815 816void 817sh_memio_unmap(t, bsh, size) 818 bus_space_tag_t t; 819 bus_space_handle_t bsh; 820 bus_size_t size; 821{ 822 return; 823} 824 825#ifdef SH4_PCMCIA 826 827int 828shpcmcia_memio_map(t, bpa, size, flags, bshp) 829 bus_space_tag_t t; 830 bus_addr_t bpa; 831 bus_size_t size; 832 int flags; 833 bus_space_handle_t *bshp; 834{ 835 int error; 836 struct extent *ex; 837 bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT; 838 839 if (pt != SH3_BUS_SPACE_PCMCIA_IO && 840 pt != SH3_BUS_SPACE_PCMCIA_MEM && 841 pt != SH3_BUS_SPACE_PCMCIA_ATT) { 842 *bshp = (bus_space_handle_t)bpa; 843 844 return 0; 845 } 846 847 ex = iomem_ex; 848 849#if 0 850 /* 851 * Before we go any further, let's make sure that this 852 * region is available. 853 */ 854 error = extent_alloc_region(ex, bpa, size, 855 EX_NOWAIT | EX_MALLOCOK ); 856 if (error){ 857 printf("sh3_pcmcia_memio_map:extent_alloc_region error\n"); 858 return (error); 859 } 860#endif 861 862 /* 863 * For memory space, map the bus physical address to 864 * a kernel virtual address. 865 */ 866 error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp ); 867#if 0 868 if (error) { 869 if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) { 870 printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n", 871 bpa, size); 872 printf("sh3_pcmcia_memio_map: can't free region\n"); 873 } 874 } 875#endif 876 877 return (error); 878} 879 880int 881shpcmcia_mem_add_mapping(bpa, size, type, bshp) 882 bus_addr_t bpa; 883 bus_size_t size; 884 int type; 885 bus_space_handle_t *bshp; 886{ 887 u_long pa, endpa; 888 vaddr_t va; 889 pt_entry_t *pte; 890 unsigned int m = 0; 891 int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT; 892 893 pa = sh3_trunc_page(bpa); 894 endpa = sh3_round_page(bpa + size); 895 896#ifdef DIAGNOSTIC 897 if (endpa <= pa) 898 panic("sh3_pcmcia_mem_add_mapping: overflow"); 899#endif 900 901 va = uvm_km_valloc(kernel_map, endpa - pa); 902 if (va == 0){ 903 printf("shpcmcia_add_mapping: nomem \n"); 904 return (ENOMEM); 905 } 906 907 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); 908 909#define MODE(t, s) \ 910 (t) & SH3_BUS_SPACE_PCMCIA_8BIT ? \ 911 _PG_PCMCIA_ ## s ## 8 : \ 912 _PG_PCMCIA_ ## s ## 16 913 switch (io_type) { 914 default: 915 panic("unknown pcmcia space."); 916 /* NOTREACHED */ 917 case SH3_BUS_SPACE_PCMCIA_IO: 918 m = MODE(type, IO); 919 break; 920 case SH3_BUS_SPACE_PCMCIA_MEM: 921 m = MODE(type, MEM); 922 break; 923 case SH3_BUS_SPACE_PCMCIA_ATT: 924 m = MODE(type, ATTR); 925 break; 926 } 927#undef MODE 928 929 for (; pa < endpa; pa += NBPG, va += NBPG) { 930 pmap_enter(pmap_kernel(), va, pa, 931 VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED); 932 933 pte = kvtopte(va); 934 *pte &= ~PG_N; 935 *pte |= m; 936 pmap_update_pg(va); 937 } 938 pmap_update(pmap_kernel()); 939 940 return 0; 941} 942 943void 944shpcmcia_memio_unmap(t, bsh, size) 945 bus_space_tag_t t; 946 bus_space_handle_t bsh; 947 bus_size_t size; 948{ 949 struct extent *ex; 950 u_long va, endva; 951 bus_addr_t bpa; 952 bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT; 953 954 if (pt != SH3_BUS_SPACE_PCMCIA_IO && 955 pt != SH3_BUS_SPACE_PCMCIA_MEM && 956 pt != SH3_BUS_SPACE_PCMCIA_ATT) { 957 return ; 958 } 959 960 ex = iomem_ex; 961 962 va = sh3_trunc_page(bsh); 963 endva = sh3_round_page(bsh + size); 964 965#ifdef DIAGNOSTIC 966 if (endva <= va) 967 panic("sh3_pcmcia_memio_unmap: overflow"); 968#endif 969 970 pmap_extract(pmap_kernel(), va, &bpa); 971 bpa += bsh & PGOFSET; 972 973 /* 974 * Free the kernel virtual mapping. 975 */ 976 uvm_km_free(kernel_map, va, endva - va); 977 978#if 0 979 if (extent_free(ex, bpa, size, 980 EX_NOWAIT | EX_MALLOCOK)) { 981 printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n", 982 "pa", bpa, size); 983 printf("sh3_pcmcia_memio_unmap: can't free region\n"); 984 } 985#endif 986} 987 988void 989shpcmcia_memio_free(t, bsh, size) 990 bus_space_tag_t t; 991 bus_space_handle_t bsh; 992 bus_size_t size; 993{ 994 995 /* sh3_pcmcia_memio_unmap() does all that we need to do. */ 996 shpcmcia_memio_unmap(t, bsh, size); 997} 998 999int 1000shpcmcia_memio_subregion(t, bsh, offset, size, nbshp) 1001 bus_space_tag_t t; 1002 bus_space_handle_t bsh; 1003 bus_size_t offset, size; 1004 bus_space_handle_t *nbshp; 1005{ 1006 1007 *nbshp = bsh + offset; 1008 return (0); 1009} 1010 1011#endif /* SH4_PCMCIA */ 1012 1013#if !defined(DONT_INIT_BSC) 1014/* 1015 * InitializeBsc 1016 * : BSC(Bus State Controler) 1017 */ 1018void InitializeBsc __P((void)); 1019 1020void 1021InitializeBsc() 1022{ 1023 1024 /* 1025 * Drive RAS,CAS in stand by mode and bus release mode 1026 * Area0 = Normal memory, Area5,6=Normal(no burst) 1027 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory 1028 * Area4 = Normal Memory 1029 * Area6 = Normal memory 1030 */ 1031#if defined(SH3) 1032 _reg_write_2(SH3_BCR1, BSC_BCR1_VAL); 1033#elif defined(SH4) 1034 _reg_write_4(SH4_BCR1, BSC_BCR1_VAL); 1035#endif 1036 1037 /* 1038 * Bus Width 1039 * Area4: Bus width = 16bit 1040 * Area6,5 = 16bit 1041 * Area1 = 8bit 1042 * Area2,3: Bus width = 32bit 1043 */ 1044 _reg_write_2(SH_(BCR2), BSC_BCR2_VAL); 1045 1046 /* 1047 * Idle cycle number in transition area and read to write 1048 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 1049 * Area1 = 3, Area0 = 3 1050 */ 1051#if defined(SH3) 1052 _reg_write_2(SH3_WCR1, BSC_WCR1_VAL); 1053#elif defined(SH4) 1054 _reg_write_4(SH4_WCR1, BSC_WCR1_VAL); 1055#endif 1056 1057 /* 1058 * Wait cycle 1059 * Area 6 = 6 1060 * Area 5 = 2 1061 * Area 4 = 10 1062 * Area 3 = 3 1063 * Area 2,1 = 3 1064 * Area 0 = 6 1065 */ 1066#if defined(SH3) 1067 _reg_write_2(SH3_WCR2, BSC_WCR2_VAL); 1068#elif defined(SH4) 1069 _reg_write_4(SH4_WCR2, BSC_WCR2_VAL); 1070#endif 1071 1072#if defined(SH4) && defined(BSC_WCR3_VAL) 1073 _reg_write_4(SH4_WCR3, BSC_WCR3_VAL); 1074#endif 1075 1076 /* 1077 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 1078 * write pre-charge=1cycle 1079 * CAS before RAS refresh RAS assert time = 3 cycle 1080 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON 1081 * CAS before RAS refresh ON, EDO DRAM 1082 */ 1083#if defined(SH3) 1084 _reg_write_2(SH3_MCR, BSC_MCR_VAL); 1085#elif defined(SH4) 1086 _reg_write_4(SH4_MCR, BSC_MCR_VAL); 1087#endif 1088 1089#if defined(BSC_SDMR2_VAL) 1090 _reg_write_1(BSC_SDMR2_VAL, 0); 1091#endif 1092 1093#if defined(BSC_SDMR3_VAL) 1094#if !(defined(COMPUTEXEVB) && defined(SH7709A)) 1095 _reg_write_1(BSC_SDMR3_VAL, 0); 1096#else 1097 _reg_write_2(0x1a000000, 0); /* ADDSET */ 1098 _reg_write_1(BSC_SDMR3_VAL, 0); 1099 _reg_write_2(0x18000000, 0); /* ADDRST */ 1100#endif /* !(COMPUTEXEVB && SH7709A) */ 1101#endif /* BSC_SDMR3_VAL */ 1102 1103 /* 1104 * PCMCIA Control Register 1105 * OE/WE assert delay 3.5 cycle 1106 * OE/WE negate-address delay 3.5 cycle 1107 */ 1108#ifdef BSC_PCR_VAL 1109 _reg_write_2(SH_(PCR), BSC_PCR_VAL); 1110#endif 1111 1112 /* 1113 * Refresh Timer Control/Status Register 1114 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 1115 * Count Limit = 1024 1116 * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 1117 * is the rule of SH3 in writing these register. 1118 */ 1119 _reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL); 1120 1121 /* 1122 * Refresh Timer Counter 1123 * Initialize to 0 1124 */ 1125#ifdef BSC_RTCNT_VAL 1126 _reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL); 1127#endif 1128 1129 /* set Refresh Time Constant Register */ 1130 _reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL); 1131 1132 /* init Refresh Count Register */ 1133#ifdef BSC_RFCR_VAL 1134 _reg_write_2(SH_(RFCR), BSC_RFCR_VAL); 1135#endif 1136 1137 /* 1138 * Clock Pulse Generator 1139 */ 1140 /* Set Clock mode (make internal clock double speed) */ 1141 _reg_write_2(SH_(FRQCR), FRQCR_VAL); 1142 1143 /* 1144 * Cache 1145 */ 1146#ifndef CACHE_DISABLE 1147 /* Cache ON */ 1148 _reg_write_4(SH_(CCR), 0x1); 1149#endif 1150} 1151#endif /* !DONT_INIT_BSC */ 1152 1153 1154 /* XXX This value depends on physical available memory */ 1155#define OSIMAGE_BUF_ADDR (IOM_RAM_BEGIN + 0x00400000) 1156 1157void 1158LoadAndReset(osimage) 1159 char *osimage; 1160{ 1161 void *buf_addr; 1162 u_long size; 1163 u_long *src; 1164 u_long *dest; 1165 u_long csum = 0; 1166 u_long csum2 = 0; 1167 u_long size2; 1168 1169 printf("LoadAndReset: copy start\n"); 1170 buf_addr = (void *)OSIMAGE_BUF_ADDR; 1171 1172 size = *(u_long *)osimage; 1173 src = (u_long *)osimage; 1174 dest = buf_addr; 1175 1176 size = (size + sizeof(u_long) * 2 + 3) >> 2; 1177 size2 = size; 1178 1179 while (size--) { 1180 csum += *src; 1181 *dest++ = *src++; 1182 } 1183 1184 dest = buf_addr; 1185 while (size2--) 1186 csum2 += *dest++; 1187 1188 printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2); 1189 printf("start XLoadAndReset\n"); 1190 1191 /* mask all externel interrupt (XXX) */ 1192 1193 XLoadAndReset(buf_addr); 1194} 1195