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