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