machdep.c revision 1.9
1/* $NetBSD: machdep.c,v 1.9 2000/02/24 23:32:32 msaitoh 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_memsize.h" 80#include "opt_initbsc.h" 81 82#include <sys/param.h> 83#include <sys/systm.h> 84#include <sys/signalvar.h> 85#include <sys/kernel.h> 86#include <sys/map.h> 87#include <sys/proc.h> 88#include <sys/user.h> 89#include <sys/exec.h> 90#include <sys/buf.h> 91#include <sys/reboot.h> 92#include <sys/conf.h> 93#include <sys/file.h> 94#include <sys/malloc.h> 95#include <sys/mbuf.h> 96#include <sys/msgbuf.h> 97#include <sys/mount.h> 98#include <sys/vnode.h> 99#include <sys/device.h> 100#include <sys/extent.h> 101#include <sys/syscallargs.h> 102 103#ifdef KGDB 104#include <sys/kgdb.h> 105#endif 106 107#include <dev/cons.h> 108 109#include <vm/vm.h> 110#include <vm/vm_kern.h> 111#include <vm/vm_page.h> 112 113#include <uvm/uvm_extern.h> 114 115#include <sys/sysctl.h> 116 117#include <machine/cpu.h> 118#include <machine/cpufunc.h> 119#include <machine/psl.h> 120#include <machine/bootinfo.h> 121#include <machine/bus.h> 122#include <sh3/bscreg.h> 123#include <sh3/ccrreg.h> 124#include <sh3/cpgreg.h> 125#include <sh3/intcreg.h> 126#include <sh3/pfcreg.h> 127#include <sh3/wdtreg.h> 128 129#include <sys/termios.h> 130#include "sci.h" 131 132/* the following is used externally (sysctl_hw) */ 133char machine[] = MACHINE; /* cpu "architecture" */ 134char machine_arch[] = MACHINE_ARCH; /* machine_arch = "sh3" */ 135 136#ifdef sh3_debug 137int cpu_debug_mode = 1; 138#else 139int cpu_debug_mode = 0; 140#endif 141 142char bootinfo[BOOTINFO_MAXSIZE]; 143 144int physmem; 145int dumpmem_low; 146int dumpmem_high; 147vaddr_t atdevbase; /* location of start of iomem in virtual */ 148paddr_t msgbuf_paddr; 149struct user *proc0paddr; 150 151extern int boothowto; 152extern paddr_t avail_start, avail_end; 153 154#ifdef SYSCALL_DEBUG 155#define SCDEBUG_ALL 0x0004 156extern int scdebug; 157#endif 158 159#define IOM_RAM_END ((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1) 160 161/* 162 * Extent maps to manage I/O and ISA memory hole space. Allocate 163 * storage for 8 regions in each, initially. Later, ioport_malloc_safe 164 * will indicate that it's safe to use malloc() to dynamically allocate 165 * region descriptors. 166 * 167 * N.B. At least two regions are _always_ allocated from the iomem 168 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 169 * 170 * The extent maps are not static! Machine-dependent ISA and EISA 171 * routines need access to them for bus address space allocation. 172 */ 173static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 174struct extent *ioport_ex; 175struct extent *iomem_ex; 176static int ioport_malloc_safe; 177 178void setup_bootinfo __P((void)); 179void dumpsys __P((void)); 180void identifycpu __P((void)); 181void initSH3 __P((void *)); 182void InitializeSci __P((unsigned char)); 183void sh3_cache_on __P((void)); 184void LoadAndReset __P((char *)); 185void XLoadAndReset __P((char *)); 186void Sh3Reset __P((void)); 187#ifdef SH4 188void sh4_cache_flush __P((vaddr_t)); 189#endif 190 191#include <dev/ic/comreg.h> 192#include <dev/ic/comvar.h> 193 194void consinit __P((void)); 195 196/* 197 * Machine-dependent startup code 198 * 199 * This is called from main() in kern/main.c. 200 */ 201void 202cpu_startup() 203{ 204 205 sh3_startup(); 206 207 /* Safe for i/o port allocation to use malloc now. */ 208 ioport_malloc_safe = 1; 209 210#ifdef SYSCALL_DEBUG 211 scdebug |= SCDEBUG_ALL; 212#endif 213 214#ifdef FORCE_RB_SINGLE 215 boothowto |= RB_SINGLE; 216#endif 217} 218 219/* 220 * Info for CTL_HW 221 */ 222extern char version[]; 223 224#define CPUDEBUG 225 226/* 227 * machine dependent system variables. 228 */ 229int 230cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 231 int *name; 232 u_int namelen; 233 void *oldp; 234 size_t *oldlenp; 235 void *newp; 236 size_t newlen; 237 struct proc *p; 238{ 239 dev_t consdev; 240 struct btinfo_bootpath *bibp; 241 struct trapframe *tf; 242 char *osimage; 243 244 /* all sysctl names at this level are terminal */ 245 if (namelen != 1) 246 return (ENOTDIR); /* overloaded */ 247 248 switch (name[0]) { 249 case CPU_CONSDEV: 250 if (cn_tab != NULL) 251 consdev = cn_tab->cn_dev; 252 else 253 consdev = NODEV; 254 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 255 sizeof consdev)); 256 257 case CPU_NKPDE: 258 return (sysctl_rdint(oldp, oldlenp, newp, nkpde)); 259 260 case CPU_BOOTED_KERNEL: 261 bibp = lookup_bootinfo(BTINFO_BOOTPATH); 262 if (!bibp) 263 return (ENOENT); /* ??? */ 264 return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath)); 265 266 case CPU_SETPRIVPROC: 267 if (newp == NULL) 268 return (0); 269 270 /* set current process to priviledged process */ 271 tf = p->p_md.md_regs; 272 tf->tf_ssr |= PSL_MD; 273 return (0); 274 275 case CPU_DEBUGMODE: 276 return (sysctl_int(oldp, oldlenp, newp, newlen, 277 &cpu_debug_mode)); 278 279 case CPU_LOADANDRESET: 280 if (newp != NULL) { 281 osimage = (char *)(*(u_long *)newp); 282 283 LoadAndReset(osimage); 284 /* not reach here */ 285 } 286 return (0); 287 288 default: 289 return (EOPNOTSUPP); 290 } 291 /* NOTREACHED */ 292} 293 294int waittime = -1; 295struct pcb dumppcb; 296 297void 298cpu_reboot(howto, bootstr) 299 int howto; 300 char *bootstr; 301{ 302 303 if (cold) { 304 howto |= RB_HALT; 305 goto haltsys; 306 } 307 308 boothowto = howto; 309 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 310 waittime = 0; 311 vfs_shutdown(); 312 /* 313 * If we've been adjusting the clock, the todr 314 * will be out of synch; adjust it now. 315 */ 316 /* resettodr(); */ 317 } 318 319 /* Disable interrupts. */ 320 splhigh(); 321 322 /* Do a dump if requested. */ 323 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 324 dumpsys(); 325 326haltsys: 327 doshutdownhooks(); 328 329 if (howto & RB_HALT) { 330 printf("\n"); 331 printf("The operating system has halted.\n"); 332 printf("Please press any key to reboot.\n\n"); 333 cngetc(); 334 } 335 336 printf("rebooting...\n"); 337 cpu_reset(); 338 for(;;) 339 ; 340 /*NOTREACHED*/ 341} 342 343/* 344 * These variables are needed by /sbin/savecore 345 */ 346u_long dumpmag = 0x8fca0101; /* magic number */ 347int dumpsize = 0; /* pages */ 348long dumplo = 0; /* blocks */ 349 350/* 351 * This is called by main to set dumplo and dumpsize. 352 * Dumps always skip the first CLBYTES of disk space 353 * in case there might be a disk label stored there. 354 * If there is extra space, put dump at the end to 355 * reduce the chance that swapping trashes it. 356 */ 357void 358cpu_dumpconf() 359{ 360#ifdef TODO 361 int nblks; /* size of dump area */ 362 int maj; 363 364 if (dumpdev == NODEV) 365 return; 366 maj = major(dumpdev); 367 if (maj < 0 || maj >= nblkdev) 368 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 369 if (bdevsw[maj].d_psize == NULL) 370 return; 371 nblks = (*bdevsw[maj].d_psize)(dumpdev); 372 if (nblks <= ctod(1)) 373 return; 374 375 dumpsize = btoc(IOM_END + ctob(dumpmem_high)); 376 377 /* Always skip the first CLBYTES, in case there is a label there. */ 378 if (dumplo < ctod(1)) 379 dumplo = ctod(1); 380 381 /* Put dump at end of partition, and make it fit. */ 382 if (dumpsize > dtoc(nblks - dumplo)) 383 dumpsize = dtoc(nblks - dumplo); 384 if (dumplo < nblks - ctod(dumpsize)) 385 dumplo = nblks - ctod(dumpsize); 386#endif 387} 388 389/* 390 * Doadump comes here after turning off memory management and 391 * getting on the dump stack, either when called above, or by 392 * the auto-restart code. 393 */ 394#define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */ 395static vaddr_t dumpspace; 396 397vaddr_t 398reserve_dumppages(p) 399 vaddr_t p; 400{ 401 402 dumpspace = p; 403 return (p + BYTES_PER_DUMP); 404} 405 406void 407dumpsys() 408{ 409#ifdef TODO 410 unsigned bytes, i, n; 411 int maddr, psize; 412 daddr_t blkno; 413 int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 414 int error; 415 416 /* Save registers. */ 417 savectx(&dumppcb); 418 419 msgbufmapped = 0; /* don't record dump msgs in msgbuf */ 420 if (dumpdev == NODEV) 421 return; 422 423 /* 424 * For dumps during autoconfiguration, 425 * if dump device has already configured... 426 */ 427 if (dumpsize == 0) 428 cpu_dumpconf(); 429 if (dumplo < 0) 430 return; 431 printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 432 433 psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 434 printf("dump "); 435 if (psize == -1) { 436 printf("area unavailable\n"); 437 return; 438 } 439 440#if 0 /* XXX this doesn't work. grr. */ 441 /* toss any characters present prior to dump */ 442 while (sget() != NULL); /*syscons and pccons differ */ 443#endif 444 445 bytes = ctob(dumpmem_high) + IOM_END; 446 maddr = 0; 447 blkno = dumplo; 448 dump = bdevsw[major(dumpdev)].d_dump; 449 error = 0; 450 for (i = 0; i < bytes; i += n) { 451 /* 452 * Avoid dumping the ISA memory hole, and areas that 453 * BIOS claims aren't in low memory. 454 */ 455 if (i >= ctob(dumpmem_low) && i < IOM_END) { 456 n = IOM_END - i; 457 maddr += n; 458 blkno += btodb(n); 459 continue; 460 } 461 462 /* Print out how many MBs we to go. */ 463 n = bytes - i; 464 if (n && (n % (1024*1024)) == 0) 465 printf("%d ", n / (1024 * 1024)); 466 467 /* Limit size for next transfer. */ 468 if (n > BYTES_PER_DUMP) 469 n = BYTES_PER_DUMP; 470 471 (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); 472 error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n); 473 if (error) 474 break; 475 maddr += n; 476 blkno += btodb(n); /* XXX? */ 477 478#if 0 /* XXX this doesn't work. grr. */ 479 /* operator aborting dump? */ 480 if (sget() != NULL) { 481 error = EINTR; 482 break; 483 } 484#endif 485 } 486 487 switch (error) { 488 489 case ENXIO: 490 printf("device bad\n"); 491 break; 492 493 case EFAULT: 494 printf("device not ready\n"); 495 break; 496 497 case EINVAL: 498 printf("area improper\n"); 499 break; 500 501 case EIO: 502 printf("i/o error\n"); 503 break; 504 505 case EINTR: 506 printf("aborted from console\n"); 507 break; 508 509 case 0: 510 printf("succeeded\n"); 511 break; 512 513 default: 514 printf("error %d\n", error); 515 break; 516 } 517 printf("\n\n"); 518 delay(5000000); /* 5 seconds */ 519#endif /* TODO */ 520} 521 522/* 523 * Initialize segments and descriptor tables 524 */ 525#define VBRINIT ((char *)IOM_RAM_BEGIN) 526#define Trap100Vec (VBRINIT + 0x100) 527#define Trap600Vec (VBRINIT + 0x600) 528#define TLBVECTOR (VBRINIT + 0x400) 529#define VADDRSTART VM_MIN_KERNEL_ADDRESS 530 531extern int nkpde; 532extern char MonTrap100[], MonTrap100_end[]; 533extern char MonTrap600[], MonTrap600_end[]; 534extern char _start[], etext[], edata[], end[]; 535extern char tlbmisshandler_stub[], tlbmisshandler_stub_end[]; 536 537void 538initSH3(pc) 539 void *pc; /* XXX return address */ 540{ 541 paddr_t avail; 542 pd_entry_t *pagedir; 543 pt_entry_t *pagetab, pte; 544 u_int sp; 545 int x; 546 char *p; 547 548 avail = sh3_round_page(end); 549 550 /* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */ 551 nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1); 552 553 /* 554 * clear .bss, .common area, page dir area, 555 * process0 stack, page table area 556 */ 557 p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */ 558 bzero(edata, p - edata); 559 560 /* 561 * install trap handler 562 */ 563 bcopy(MonTrap100, Trap100Vec, MonTrap100_end - MonTrap100); 564 bcopy(MonTrap600, Trap600Vec, MonTrap600_end - MonTrap600); 565 __asm ("ldc %0, vbr" :: "r"(VBRINIT)); 566 567/* 568 * edata end 569 * +-------------+------+-----+----------+-------------+------------+ 570 * | kernel text | data | bss | Page Dir | Proc0 Stack | Page Table | 571 * +-------------+------+-----+----------+-------------+------------+ 572 * NBPG USPACE (1+nkpde)*NBPG 573 * (= 4*NBPG) 574 * Build initial page tables 575 */ 576 pagedir = (void *)avail; 577 pagetab = (void *)(avail + SYSMAP); 578 579 /* 580 * Construct a page table directory 581 * In SH3 H/W does not support PTD, 582 * these structures are used by S/W. 583 */ 584 pte = (pt_entry_t)pagetab; 585 pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N; 586 pagedir[KERNTEXTOFF >> PDSHIFT] = pte; 587 588 /* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000, 589 0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */ 590 pte += NBPG; 591 for (x = 0; x < nkpde; x++) { 592 pagedir[(VADDRSTART >> PDSHIFT) + x] = pte; 593 pte += NBPG; 594 } 595 596 /* Install a PDE recursively mapping page directory as a page table! */ 597 pte = (u_int)pagedir; 598 pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N; 599 pagedir[PDSLOT_PTE] = pte; 600 601 /* set PageDirReg */ 602 SHREG_TTB = (u_int)pagedir; 603 604 /* Set TLB miss handler */ 605 p = tlbmisshandler_stub; 606 x = tlbmisshandler_stub_end - p; 607 bcopy(p, TLBVECTOR, x); 608 609 /* 610 * Activate MMU 611 */ 612 613#define MMUCR_AT 0x0001 /* address traslation enable */ 614#define MMUCR_IX 0x0002 /* index mode */ 615#define MMUCR_TF 0x0004 /* TLB flush */ 616#define MMUCR_SV 0x0100 /* single virtual space mode */ 617 618 SHREG_MMUCR = MMUCR_AT | MMUCR_TF | MMUCR_SV; 619 620 /* 621 * Now here is virtual address 622 */ 623 624 /* Set proc0paddr */ 625 proc0paddr = (void *)(avail + NBPG); 626 627 /* Set pcb->PageDirReg of proc0 */ 628 proc0paddr->u_pcb.pageDirReg = (int)pagedir; 629 630 /* avail_start is first available physical memory address */ 631 avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde; 632 633 /* atdevbase is first available logical memory address */ 634 atdevbase = VADDRSTART; 635 636 proc0.p_addr = proc0paddr; /* page dir address */ 637 638 /* XXX: PMAP_NEW requires valid curpcb. also init'd in cpu_startup */ 639 curpcb = &proc0.p_addr->u_pcb; 640 641 /* 642 * Initialize the I/O port and I/O mem extent maps. 643 * Note: we don't have to check the return value since 644 * creation of a fixed extent map will never fail (since 645 * descriptor storage has already been allocated). 646 * 647 * N.B. The iomem extent manages _all_ physical addresses 648 * on the machine. When the amount of RAM is found, the two 649 * extents of RAM are allocated from the map (0 -> ISA hole 650 * and end of ISA hole -> end of RAM). 651 */ 652 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 653 (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 654 EX_NOCOALESCE|EX_NOWAIT); 655 656#if 0 657 consinit(); /* XXX SHOULD NOT BE DONE HERE */ 658#endif 659 660 splraise(-1); 661 enable_intr(); 662 663 avail_end = sh3_trunc_page(IOM_RAM_END + 1); 664 665 printf("initSH3\r\n"); 666 667 /* 668 * Calculate check sum 669 */ 670 { 671 u_short *p, sum; 672 int size; 673 674 size = etext - _start; 675 p = (u_short *)_start; 676 sum = 0; 677 size >>= 1; 678 while (size--) 679 sum += *p++; 680 printf("Check Sum = 0x%x\r\n", sum); 681 } 682 /* 683 * Allocate the physical addresses used by RAM from the iomem 684 * extent map. This is done before the addresses are 685 * page rounded just to make sure we get them all. 686 */ 687 if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN, 688 (IOM_RAM_END-IOM_RAM_BEGIN) + 1, 689 EX_NOWAIT)) { 690 /* XXX What should we do? */ 691 printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n"); 692 } 693 694 /* number of pages of physmem addr space */ 695 physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1); 696#ifdef TODO 697 dumpmem = physmem; 698#endif 699 700 /* 701 * Initialize for pmap_free_pages and pmap_next_page. 702 * These guys should be page-aligned. 703 */ 704 if (physmem < btoc(2 * 1024 * 1024)) { 705 printf("warning: too little memory available; " 706 "have %d bytes, want %d bytes\n" 707 "running in degraded mode\n" 708 "press a key to confirm\n\n", 709 ctob(physmem), 2*1024*1024); 710 cngetc(); 711 } 712 713 /* Call pmap initialization to make new kernel address space */ 714 pmap_bootstrap(atdevbase); 715 716 /* 717 * Initialize error message buffer (at end of core). 718 */ 719 initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE)); 720 721 /* 722 * set boot device information 723 */ 724 setup_bootinfo(); 725 726#if 0 727 sh3_cache_on(); 728#endif 729 730 /* setup proc0 stack */ 731 sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe); 732 733 /* 734 * XXX We can't return here, because we change stack pointer. 735 * So jump to return address directly. 736 */ 737 __asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp)); 738} 739 740void 741setup_bootinfo(void) 742{ 743 struct btinfo_bootdisk *help; 744 745 *(int *)bootinfo = 1; 746 help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int)); 747 help->biosdev = 0; 748 help->partition = 0; 749 ((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk); 750 ((struct btinfo_common *)help)->type = BTINFO_BOOTDISK; 751} 752 753void * 754lookup_bootinfo(type) 755 int type; 756{ 757 struct btinfo_common *help; 758 int n = *(int*)bootinfo; 759 help = (struct btinfo_common *)(bootinfo + sizeof(int)); 760 while (n--) { 761 if (help->type == type) 762 return (help); 763 help = (struct btinfo_common *)((char*)help + help->len); 764 } 765 return (0); 766} 767 768 769/* 770 * consinit: 771 * initialize the system console. 772 * XXX - shouldn't deal with this initted thing, but then, 773 * it shouldn't be called from init386 either. 774 */ 775void 776consinit() 777{ 778 static int initted; 779 780 if (initted) 781 return; 782 initted = 1; 783 784 cninit(); 785 786#ifdef DDB 787 ddb_init(); 788#endif 789} 790 791void 792cpu_reset() 793{ 794 795 disable_intr(); 796 797 Sh3Reset(); 798 for (;;) 799 ; 800} 801 802int 803bus_space_map (t, addr, size, flags, bshp) 804 bus_space_tag_t t; 805 bus_addr_t addr; 806 bus_size_t size; 807 int flags; 808 bus_space_handle_t *bshp; 809{ 810 811 *bshp = (bus_space_handle_t)addr; 812 813 return 0; 814} 815 816int 817sh_memio_subregion(t, bsh, offset, size, nbshp) 818 bus_space_tag_t t; 819 bus_space_handle_t bsh; 820 bus_size_t offset, size; 821 bus_space_handle_t *nbshp; 822{ 823 824 *nbshp = bsh + offset; 825 return (0); 826} 827 828int 829sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, 830 bpap, bshp) 831 bus_space_tag_t t; 832 bus_addr_t rstart, rend; 833 bus_size_t size, alignment, boundary; 834 int flags; 835 bus_addr_t *bpap; 836 bus_space_handle_t *bshp; 837{ 838 *bshp = *bpap = rstart; 839 840 return (0); 841} 842 843void 844sh_memio_free(t, bsh, size) 845 bus_space_tag_t t; 846 bus_space_handle_t bsh; 847 bus_size_t size; 848{ 849 850} 851 852void 853sh_memio_unmap(t, bsh, size) 854 bus_space_tag_t t; 855 bus_space_handle_t bsh; 856 bus_size_t size; 857{ 858 return; 859} 860 861/* 862 * InitializeBsc 863 * : BSC(Bus State Controler) 864 */ 865void InitializeBsc __P((void)); 866 867void 868InitializeBsc() 869{ 870 871 /* 872 * Drive RAS,CAS in stand by mode and bus release mode 873 * Area0 = Normal memory, Area5,6=Normal(no burst) 874 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory 875 * Area4 = Normal Memory 876 * Area6 = Normal memory 877 */ 878 SHREG_BCR1 = BSC_BCR1_VAL; 879 880 /* 881 * Bus Width 882 * Area4: Bus width = 16bit 883 * Area6,5 = 16bit 884 * Area1 = 8bit 885 * Area2,3: Bus width = 32bit 886 */ 887 SHREG_BCR2 = BSC_BCR2_VAL; 888 889 /* 890 * Idle cycle number in transition area and read to write 891 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 892 * Area1 = 3, Area0 = 3 893 */ 894 SHREG_WCR1 = BSC_WCR1_VAL; 895 896 /* 897 * Wait cycle 898 * Area 6 = 6 899 * Area 5 = 2 900 * Area 4 = 10 901 * Area 3 = 3 902 * Area 2,1 = 3 903 * Area 0 = 6 904 */ 905 SHREG_WCR2 = BSC_WCR2_VAL; 906 907#ifdef SH4 908 SHREG_WCR3 = BSC_WCR3_VAL; 909#endif 910 911 /* 912 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 913 * write pre-charge=1cycle 914 * CAS before RAS refresh RAS assert time = 3 cycle 915 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON 916 * CAS before RAS refresh ON, EDO DRAM 917 */ 918 SHREG_MCR = BSC_MCR_VAL; 919 920#ifdef BSC_SDMR_VAL 921#if 1 922#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 923 924 SDMR = 0; 925#else 926#define ADDSET (*(volatile unsigned short *)0x1A000000) 927#define ADDRST (*(volatile unsigned short *)0x18000000) 928#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 929 930 ADDSET = 0; 931 SDMR = 0; 932 ADDRST = 0; 933#endif 934#endif 935 936 /* 937 * PCMCIA Control Register 938 * OE/WE assert delay 3.5 cycle 939 * OE/WE negate-address delay 3.5 cycle 940 */ 941#ifdef BSC_PCR_VAL 942 SHREG_PCR = 0x00ff; 943#endif 944 945 /* 946 * Refresh Timer Control/Status Register 947 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 948 * Count Limit = 1024 949 * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 950 * is the rule of SH3 in writing these register. 951 */ 952 SHREG_RTCSR = BSC_RTCSR_VAL; 953 954 955 /* 956 * Refresh Timer Counter 957 * Initialize to 0 958 */ 959#ifdef BSC_RTCNT_VAL 960 SHREG_RTCNT = BSC_RTCNT_VAL; 961#endif 962 963 /* set Refresh Time Constant Register */ 964 SHREG_RTCOR = BSC_RTCOR_VAL; 965 966 /* init Refresh Count Register */ 967#ifdef BSC_RFCR_VAL 968 SHREG_RFCR = BSC_RFCR_VAL; 969#endif 970 971 /* Set Clock mode (make internal clock double speed) */ 972 973 SHREG_FRQCR = FRQCR_VAL; 974 975#ifndef MMEYE_NO_CACHE 976 /* Cache ON */ 977 SHREG_CCR = CCR_CE; 978#endif 979} 980 981void 982sh3_cache_on(void) 983{ 984#ifndef MMEYE_NO_CACHE 985 /* Cache ON */ 986 SHREG_CCR = CCR_CE; 987 SHREG_CCR = CCR_CF | CCR_CE; /* cache clear */ 988 SHREG_CCR = CCR_CE; /* cache on */ 989#endif 990} 991 992#ifdef SH4 993void 994sh4_cache_flush(addr) 995 vaddr_t addr; 996{ 997#if 1 998#define SH_ADDR_ARRAY_BASE_ADDR 0xf4000000 999#define WRITE_ADDR_ARRAY( entry ) \ 1000 (*(volatile u_int32_t *)(SH_ADDR_ARRAY_BASE_ADDR|(entry)|0x00)) 1001 1002 int entry; 1003 1004 entry = ((u_int32_t)addr) & 0x3fe0; 1005 1006 WRITE_ADDR_ARRAY(entry) = 0; 1007#else 1008 volatile int *p = (int *)IOM_RAM_BEGIN; 1009 int i; 1010 /* volatile */int d; 1011 1012 for(i = 0; i < 512; i++){ 1013 d = *p; 1014 p += 8; 1015 } 1016#endif 1017} 1018#endif 1019 1020#include <machine/mmeye.h> 1021 1022 /* XXX This value depends on physical available memory */ 1023#define OSIMAGE_BUF_ADDR (IOM_RAM_BEGIN + 0x00400000) 1024 1025void 1026LoadAndReset(osimage) 1027 char *osimage; 1028{ 1029 void *buf_addr; 1030 u_long size; 1031 u_long *src; 1032 u_long *dest; 1033 u_long csum = 0; 1034 u_long csum2 = 0; 1035 u_long size2; 1036 1037 printf("LoadAndReset: copy start\n"); 1038 buf_addr = (void *)OSIMAGE_BUF_ADDR; 1039 1040 size = *(u_long *)osimage; 1041 src = (u_long *)osimage; 1042 dest = buf_addr; 1043 1044 size = (size + sizeof(u_long) * 2 + 3) >> 2; 1045 size2 = size; 1046 1047 while (size--) { 1048 csum += *src; 1049 *dest++ = *src++; 1050 } 1051 1052 dest = buf_addr; 1053 while (size2--) 1054 csum2 += *dest++; 1055 1056 printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2); 1057 printf("start XLoadAndReset\n"); 1058 1059 /* mask all externel interrupt (XXX) */ 1060 1061 XLoadAndReset(buf_addr); 1062} 1063