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