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