machdep.c revision 1.30
11.30Such/* $NetBSD: machdep.c,v 1.30 2002/02/17 20:57:12 uch Exp $ */ 21.1Sitojun 31.1Sitojun/*- 41.1Sitojun * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 51.1Sitojun * All rights reserved. 61.1Sitojun * 71.1Sitojun * This code is derived from software contributed to The NetBSD Foundation 81.1Sitojun * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 91.1Sitojun * Simulation Facility, NASA Ames Research Center. 101.1Sitojun * 111.1Sitojun * Redistribution and use in source and binary forms, with or without 121.1Sitojun * modification, are permitted provided that the following conditions 131.1Sitojun * are met: 141.1Sitojun * 1. Redistributions of source code must retain the above copyright 151.1Sitojun * notice, this list of conditions and the following disclaimer. 161.1Sitojun * 2. Redistributions in binary form must reproduce the above copyright 171.1Sitojun * notice, this list of conditions and the following disclaimer in the 181.1Sitojun * documentation and/or other materials provided with the distribution. 191.1Sitojun * 3. All advertising materials mentioning features or use of this software 201.1Sitojun * must display the following acknowledgement: 211.1Sitojun * This product includes software developed by the NetBSD 221.1Sitojun * Foundation, Inc. and its contributors. 231.1Sitojun * 4. Neither the name of The NetBSD Foundation nor the names of its 241.1Sitojun * contributors may be used to endorse or promote products derived 251.1Sitojun * from this software without specific prior written permission. 261.1Sitojun * 271.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 281.1Sitojun * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 291.1Sitojun * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 301.1Sitojun * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 311.1Sitojun * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 321.1Sitojun * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 331.1Sitojun * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 341.1Sitojun * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 351.1Sitojun * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 361.1Sitojun * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 371.1Sitojun * POSSIBILITY OF SUCH DAMAGE. 381.1Sitojun */ 391.1Sitojun 401.1Sitojun/*- 411.1Sitojun * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 421.1Sitojun * All rights reserved. 431.1Sitojun * 441.1Sitojun * This code is derived from software contributed to Berkeley by 451.1Sitojun * William Jolitz. 461.1Sitojun * 471.1Sitojun * Redistribution and use in source and binary forms, with or without 481.1Sitojun * modification, are permitted provided that the following conditions 491.1Sitojun * are met: 501.1Sitojun * 1. Redistributions of source code must retain the above copyright 511.1Sitojun * notice, this list of conditions and the following disclaimer. 521.1Sitojun * 2. Redistributions in binary form must reproduce the above copyright 531.1Sitojun * notice, this list of conditions and the following disclaimer in the 541.1Sitojun * documentation and/or other materials provided with the distribution. 551.1Sitojun * 3. All advertising materials mentioning features or use of this software 561.1Sitojun * must display the following acknowledgement: 571.1Sitojun * This product includes software developed by the University of 581.1Sitojun * California, Berkeley and its contributors. 591.1Sitojun * 4. Neither the name of the University nor the names of its contributors 601.1Sitojun * may be used to endorse or promote products derived from this software 611.1Sitojun * without specific prior written permission. 621.1Sitojun * 631.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 641.1Sitojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 651.1Sitojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 661.1Sitojun * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 671.1Sitojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 681.1Sitojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 691.1Sitojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 701.1Sitojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 711.1Sitojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 721.1Sitojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 731.1Sitojun * SUCH DAMAGE. 741.1Sitojun * 751.1Sitojun * @(#)machdep.c 7.4 (Berkeley) 6/3/91 761.1Sitojun */ 771.1Sitojun 781.1Sitojun#include "opt_ddb.h" 791.26Slukem#include "opt_kgdb.h" 801.15Ssoren#include "opt_syscall_debug.h" 811.1Sitojun#include "opt_memsize.h" 821.1Sitojun#include "opt_initbsc.h" 831.1Sitojun 841.1Sitojun#include <sys/param.h> 851.1Sitojun#include <sys/systm.h> 861.1Sitojun#include <sys/signalvar.h> 871.1Sitojun#include <sys/kernel.h> 881.1Sitojun#include <sys/map.h> 891.1Sitojun#include <sys/proc.h> 901.1Sitojun#include <sys/user.h> 911.1Sitojun#include <sys/exec.h> 921.1Sitojun#include <sys/buf.h> 931.1Sitojun#include <sys/reboot.h> 941.1Sitojun#include <sys/conf.h> 951.1Sitojun#include <sys/file.h> 961.1Sitojun#include <sys/malloc.h> 971.1Sitojun#include <sys/mbuf.h> 981.1Sitojun#include <sys/msgbuf.h> 991.1Sitojun#include <sys/mount.h> 1001.1Sitojun#include <sys/vnode.h> 1011.1Sitojun#include <sys/device.h> 1021.1Sitojun#include <sys/extent.h> 1031.1Sitojun#include <sys/syscallargs.h> 1041.1Sitojun 1051.1Sitojun#ifdef KGDB 1061.1Sitojun#include <sys/kgdb.h> 1071.1Sitojun#endif 1081.1Sitojun 1091.1Sitojun#include <dev/cons.h> 1101.1Sitojun 1111.1Sitojun#include <uvm/uvm_extern.h> 1121.1Sitojun 1131.1Sitojun#include <sys/sysctl.h> 1141.1Sitojun 1151.1Sitojun#include <machine/cpu.h> 1161.1Sitojun#include <machine/cpufunc.h> 1171.1Sitojun#include <machine/psl.h> 1181.1Sitojun#include <machine/bootinfo.h> 1191.1Sitojun#include <machine/bus.h> 1201.1Sitojun#include <sh3/bscreg.h> 1211.1Sitojun#include <sh3/ccrreg.h> 1221.1Sitojun#include <sh3/cpgreg.h> 1231.1Sitojun#include <sh3/intcreg.h> 1241.1Sitojun#include <sh3/pfcreg.h> 1251.1Sitojun#include <sh3/wdtreg.h> 1261.30Such#include <sh3/mmu.h> 1271.1Sitojun 1281.1Sitojun#include <sys/termios.h> 1291.1Sitojun#include "sci.h" 1301.1Sitojun 1311.1Sitojun/* the following is used externally (sysctl_hw) */ 1321.1Sitojunchar machine[] = MACHINE; /* cpu "architecture" */ 1331.1Sitojunchar machine_arch[] = MACHINE_ARCH; /* machine_arch = "sh3" */ 1341.1Sitojun 1351.1Sitojun#ifdef sh3_debug 1361.1Sitojunint cpu_debug_mode = 1; 1371.1Sitojun#else 1381.1Sitojunint cpu_debug_mode = 0; 1391.1Sitojun#endif 1401.1Sitojun 1411.1Sitojunchar bootinfo[BOOTINFO_MAXSIZE]; 1421.1Sitojun 1431.3Smsaitohint physmem; 1441.3Smsaitohint dumpmem_low; 1451.3Smsaitohint dumpmem_high; 1461.3Smsaitohvaddr_t atdevbase; /* location of start of iomem in virtual */ 1471.1Sitojunpaddr_t msgbuf_paddr; 1481.3Smsaitohstruct user *proc0paddr; 1491.1Sitojun 1501.3Smsaitohextern int boothowto; 1511.1Sitojunextern paddr_t avail_start, avail_end; 1521.1Sitojun 1531.1Sitojun#ifdef SYSCALL_DEBUG 1541.1Sitojun#define SCDEBUG_ALL 0x0004 1551.1Sitojunextern int scdebug; 1561.1Sitojun#endif 1571.1Sitojun 1581.1Sitojun#define IOM_RAM_END ((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1) 1591.1Sitojun 1601.1Sitojun/* 1611.1Sitojun * Extent maps to manage I/O and ISA memory hole space. Allocate 1621.1Sitojun * storage for 8 regions in each, initially. Later, ioport_malloc_safe 1631.1Sitojun * will indicate that it's safe to use malloc() to dynamically allocate 1641.1Sitojun * region descriptors. 1651.1Sitojun * 1661.1Sitojun * N.B. At least two regions are _always_ allocated from the iomem 1671.1Sitojun * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 1681.1Sitojun * 1691.1Sitojun * The extent maps are not static! Machine-dependent ISA and EISA 1701.1Sitojun * routines need access to them for bus address space allocation. 1711.1Sitojun */ 1721.1Sitojunstatic long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 1731.1Sitojunstruct extent *ioport_ex; 1741.1Sitojunstruct extent *iomem_ex; 1751.1Sitojunstatic int ioport_malloc_safe; 1761.1Sitojun 1771.3Smsaitohvoid setup_bootinfo __P((void)); 1781.3Smsaitohvoid dumpsys __P((void)); 1791.3Smsaitohvoid identifycpu __P((void)); 1801.3Smsaitohvoid initSH3 __P((void *)); 1811.3Smsaitohvoid InitializeSci __P((unsigned char)); 1821.3Smsaitohvoid sh3_cache_on __P((void)); 1831.3Smsaitohvoid LoadAndReset __P((char *)); 1841.3Smsaitohvoid XLoadAndReset __P((char *)); 1851.3Smsaitohvoid Sh3Reset __P((void)); 1861.9Smsaitoh#ifdef SH4 1871.9Smsaitohvoid sh4_cache_flush __P((vaddr_t)); 1881.9Smsaitoh#endif 1891.1Sitojun 1901.1Sitojun#include <dev/ic/comreg.h> 1911.1Sitojun#include <dev/ic/comvar.h> 1921.1Sitojun 1931.1Sitojunvoid consinit __P((void)); 1941.1Sitojun 1951.1Sitojun/* 1961.1Sitojun * Machine-dependent startup code 1971.1Sitojun * 1981.1Sitojun * This is called from main() in kern/main.c. 1991.1Sitojun */ 2001.1Sitojunvoid 2011.1Sitojuncpu_startup() 2021.1Sitojun{ 2031.1Sitojun 2041.5Stsubai sh3_startup(); 2051.1Sitojun 2061.1Sitojun /* Safe for i/o port allocation to use malloc now. */ 2071.1Sitojun ioport_malloc_safe = 1; 2081.1Sitojun 2091.1Sitojun#ifdef SYSCALL_DEBUG 2101.1Sitojun scdebug |= SCDEBUG_ALL; 2111.1Sitojun#endif 2121.1Sitojun 2131.3Smsaitoh#ifdef FORCE_RB_SINGLE 2141.1Sitojun boothowto |= RB_SINGLE; 2151.1Sitojun#endif 2161.1Sitojun} 2171.1Sitojun 2181.1Sitojun#define CPUDEBUG 2191.1Sitojun 2201.1Sitojun/* 2211.1Sitojun * machine dependent system variables. 2221.1Sitojun */ 2231.1Sitojunint 2241.1Sitojuncpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 2251.1Sitojun int *name; 2261.1Sitojun u_int namelen; 2271.1Sitojun void *oldp; 2281.1Sitojun size_t *oldlenp; 2291.1Sitojun void *newp; 2301.1Sitojun size_t newlen; 2311.1Sitojun struct proc *p; 2321.1Sitojun{ 2331.1Sitojun dev_t consdev; 2341.1Sitojun struct btinfo_bootpath *bibp; 2351.1Sitojun struct trapframe *tf; 2361.1Sitojun char *osimage; 2371.1Sitojun 2381.1Sitojun /* all sysctl names at this level are terminal */ 2391.1Sitojun if (namelen != 1) 2401.1Sitojun return (ENOTDIR); /* overloaded */ 2411.1Sitojun 2421.1Sitojun switch (name[0]) { 2431.1Sitojun case CPU_CONSDEV: 2441.1Sitojun if (cn_tab != NULL) 2451.1Sitojun consdev = cn_tab->cn_dev; 2461.1Sitojun else 2471.1Sitojun consdev = NODEV; 2481.1Sitojun return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 2491.1Sitojun sizeof consdev)); 2501.1Sitojun 2511.1Sitojun case CPU_NKPDE: 2521.1Sitojun return (sysctl_rdint(oldp, oldlenp, newp, nkpde)); 2531.1Sitojun 2541.1Sitojun case CPU_BOOTED_KERNEL: 2551.1Sitojun bibp = lookup_bootinfo(BTINFO_BOOTPATH); 2561.1Sitojun if (!bibp) 2571.1Sitojun return (ENOENT); /* ??? */ 2581.1Sitojun return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath)); 2591.1Sitojun 2601.1Sitojun case CPU_SETPRIVPROC: 2611.1Sitojun if (newp == NULL) 2621.1Sitojun return (0); 2631.1Sitojun 2641.1Sitojun /* set current process to priviledged process */ 2651.1Sitojun tf = p->p_md.md_regs; 2661.1Sitojun tf->tf_ssr |= PSL_MD; 2671.1Sitojun return (0); 2681.1Sitojun 2691.1Sitojun case CPU_DEBUGMODE: 2701.1Sitojun return (sysctl_int(oldp, oldlenp, newp, newlen, 2711.1Sitojun &cpu_debug_mode)); 2721.1Sitojun 2731.1Sitojun case CPU_LOADANDRESET: 2741.1Sitojun if (newp != NULL) { 2751.1Sitojun osimage = (char *)(*(u_long *)newp); 2761.1Sitojun 2771.1Sitojun LoadAndReset(osimage); 2781.1Sitojun /* not reach here */ 2791.1Sitojun } 2801.1Sitojun return (0); 2811.1Sitojun 2821.1Sitojun default: 2831.1Sitojun return (EOPNOTSUPP); 2841.1Sitojun } 2851.1Sitojun /* NOTREACHED */ 2861.1Sitojun} 2871.1Sitojun 2881.3Smsaitohint waittime = -1; 2891.1Sitojunstruct pcb dumppcb; 2901.1Sitojun 2911.1Sitojunvoid 2921.1Sitojuncpu_reboot(howto, bootstr) 2931.1Sitojun int howto; 2941.1Sitojun char *bootstr; 2951.1Sitojun{ 2961.1Sitojun 2971.1Sitojun if (cold) { 2981.1Sitojun howto |= RB_HALT; 2991.1Sitojun goto haltsys; 3001.1Sitojun } 3011.1Sitojun 3021.1Sitojun boothowto = howto; 3031.1Sitojun if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 3041.1Sitojun waittime = 0; 3051.1Sitojun vfs_shutdown(); 3061.1Sitojun /* 3071.1Sitojun * If we've been adjusting the clock, the todr 3081.1Sitojun * will be out of synch; adjust it now. 3091.1Sitojun */ 3101.1Sitojun /* resettodr(); */ 3111.1Sitojun } 3121.1Sitojun 3131.1Sitojun /* Disable interrupts. */ 3141.1Sitojun splhigh(); 3151.1Sitojun 3161.1Sitojun /* Do a dump if requested. */ 3171.1Sitojun if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 3181.1Sitojun dumpsys(); 3191.1Sitojun 3201.1Sitojunhaltsys: 3211.1Sitojun doshutdownhooks(); 3221.1Sitojun 3231.1Sitojun if (howto & RB_HALT) { 3241.1Sitojun printf("\n"); 3251.1Sitojun printf("The operating system has halted.\n"); 3261.1Sitojun printf("Please press any key to reboot.\n\n"); 3271.1Sitojun cngetc(); 3281.1Sitojun } 3291.1Sitojun 3301.1Sitojun printf("rebooting...\n"); 3311.1Sitojun cpu_reset(); 3321.1Sitojun for(;;) 3331.1Sitojun ; 3341.1Sitojun /*NOTREACHED*/ 3351.1Sitojun} 3361.1Sitojun 3371.1Sitojun/* 3381.1Sitojun * These variables are needed by /sbin/savecore 3391.1Sitojun */ 3401.1Sitojunu_long dumpmag = 0x8fca0101; /* magic number */ 3411.1Sitojunint dumpsize = 0; /* pages */ 3421.1Sitojunlong dumplo = 0; /* blocks */ 3431.1Sitojun 3441.1Sitojun/* 3451.1Sitojun * This is called by main to set dumplo and dumpsize. 3461.1Sitojun * Dumps always skip the first CLBYTES of disk space 3471.1Sitojun * in case there might be a disk label stored there. 3481.1Sitojun * If there is extra space, put dump at the end to 3491.1Sitojun * reduce the chance that swapping trashes it. 3501.1Sitojun */ 3511.1Sitojunvoid 3521.1Sitojuncpu_dumpconf() 3531.1Sitojun{ 3541.1Sitojun#ifdef TODO 3551.1Sitojun int nblks; /* size of dump area */ 3561.1Sitojun int maj; 3571.1Sitojun 3581.1Sitojun if (dumpdev == NODEV) 3591.1Sitojun return; 3601.1Sitojun maj = major(dumpdev); 3611.1Sitojun if (maj < 0 || maj >= nblkdev) 3621.1Sitojun panic("dumpconf: bad dumpdev=0x%x", dumpdev); 3631.1Sitojun if (bdevsw[maj].d_psize == NULL) 3641.1Sitojun return; 3651.1Sitojun nblks = (*bdevsw[maj].d_psize)(dumpdev); 3661.1Sitojun if (nblks <= ctod(1)) 3671.1Sitojun return; 3681.1Sitojun 3691.1Sitojun dumpsize = btoc(IOM_END + ctob(dumpmem_high)); 3701.1Sitojun 3711.1Sitojun /* Always skip the first CLBYTES, in case there is a label there. */ 3721.1Sitojun if (dumplo < ctod(1)) 3731.1Sitojun dumplo = ctod(1); 3741.1Sitojun 3751.1Sitojun /* Put dump at end of partition, and make it fit. */ 3761.1Sitojun if (dumpsize > dtoc(nblks - dumplo)) 3771.1Sitojun dumpsize = dtoc(nblks - dumplo); 3781.1Sitojun if (dumplo < nblks - ctod(dumpsize)) 3791.1Sitojun dumplo = nblks - ctod(dumpsize); 3801.1Sitojun#endif 3811.1Sitojun} 3821.1Sitojun 3831.1Sitojun/* 3841.1Sitojun * Doadump comes here after turning off memory management and 3851.1Sitojun * getting on the dump stack, either when called above, or by 3861.1Sitojun * the auto-restart code. 3871.1Sitojun */ 3881.1Sitojun#define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */ 3891.1Sitojunstatic vaddr_t dumpspace; 3901.1Sitojun 3911.1Sitojunvaddr_t 3921.1Sitojunreserve_dumppages(p) 3931.1Sitojun vaddr_t p; 3941.1Sitojun{ 3951.1Sitojun 3961.1Sitojun dumpspace = p; 3971.1Sitojun return (p + BYTES_PER_DUMP); 3981.1Sitojun} 3991.1Sitojun 4001.1Sitojunvoid 4011.1Sitojundumpsys() 4021.1Sitojun{ 4031.1Sitojun#ifdef TODO 4041.1Sitojun unsigned bytes, i, n; 4051.1Sitojun int maddr, psize; 4061.1Sitojun daddr_t blkno; 4071.1Sitojun int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 4081.1Sitojun int error; 4091.1Sitojun 4101.1Sitojun /* Save registers. */ 4111.1Sitojun savectx(&dumppcb); 4121.1Sitojun 4131.1Sitojun msgbufmapped = 0; /* don't record dump msgs in msgbuf */ 4141.1Sitojun if (dumpdev == NODEV) 4151.1Sitojun return; 4161.1Sitojun 4171.1Sitojun /* 4181.1Sitojun * For dumps during autoconfiguration, 4191.1Sitojun * if dump device has already configured... 4201.1Sitojun */ 4211.1Sitojun if (dumpsize == 0) 4221.1Sitojun cpu_dumpconf(); 4231.1Sitojun if (dumplo < 0) 4241.1Sitojun return; 4251.1Sitojun printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 4261.1Sitojun 4271.1Sitojun psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 4281.1Sitojun printf("dump "); 4291.1Sitojun if (psize == -1) { 4301.1Sitojun printf("area unavailable\n"); 4311.1Sitojun return; 4321.1Sitojun } 4331.1Sitojun 4341.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 4351.1Sitojun /* toss any characters present prior to dump */ 4361.13Smsaitoh while (sget() != NULL); /* syscons and pccons differ */ 4371.1Sitojun#endif 4381.1Sitojun 4391.1Sitojun bytes = ctob(dumpmem_high) + IOM_END; 4401.1Sitojun maddr = 0; 4411.1Sitojun blkno = dumplo; 4421.1Sitojun dump = bdevsw[major(dumpdev)].d_dump; 4431.1Sitojun error = 0; 4441.1Sitojun for (i = 0; i < bytes; i += n) { 4451.1Sitojun /* 4461.1Sitojun * Avoid dumping the ISA memory hole, and areas that 4471.1Sitojun * BIOS claims aren't in low memory. 4481.1Sitojun */ 4491.1Sitojun if (i >= ctob(dumpmem_low) && i < IOM_END) { 4501.1Sitojun n = IOM_END - i; 4511.1Sitojun maddr += n; 4521.1Sitojun blkno += btodb(n); 4531.1Sitojun continue; 4541.1Sitojun } 4551.1Sitojun 4561.1Sitojun /* Print out how many MBs we to go. */ 4571.1Sitojun n = bytes - i; 4581.1Sitojun if (n && (n % (1024*1024)) == 0) 4591.1Sitojun printf("%d ", n / (1024 * 1024)); 4601.1Sitojun 4611.1Sitojun /* Limit size for next transfer. */ 4621.1Sitojun if (n > BYTES_PER_DUMP) 4631.1Sitojun n = BYTES_PER_DUMP; 4641.1Sitojun 4651.1Sitojun (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); 4661.1Sitojun error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n); 4671.1Sitojun if (error) 4681.1Sitojun break; 4691.1Sitojun maddr += n; 4701.1Sitojun blkno += btodb(n); /* XXX? */ 4711.1Sitojun 4721.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 4731.1Sitojun /* operator aborting dump? */ 4741.1Sitojun if (sget() != NULL) { 4751.1Sitojun error = EINTR; 4761.1Sitojun break; 4771.1Sitojun } 4781.1Sitojun#endif 4791.1Sitojun } 4801.1Sitojun 4811.1Sitojun switch (error) { 4821.1Sitojun 4831.1Sitojun case ENXIO: 4841.1Sitojun printf("device bad\n"); 4851.1Sitojun break; 4861.1Sitojun 4871.1Sitojun case EFAULT: 4881.1Sitojun printf("device not ready\n"); 4891.1Sitojun break; 4901.1Sitojun 4911.1Sitojun case EINVAL: 4921.1Sitojun printf("area improper\n"); 4931.1Sitojun break; 4941.1Sitojun 4951.1Sitojun case EIO: 4961.1Sitojun printf("i/o error\n"); 4971.1Sitojun break; 4981.1Sitojun 4991.1Sitojun case EINTR: 5001.1Sitojun printf("aborted from console\n"); 5011.1Sitojun break; 5021.1Sitojun 5031.1Sitojun case 0: 5041.1Sitojun printf("succeeded\n"); 5051.1Sitojun break; 5061.1Sitojun 5071.1Sitojun default: 5081.1Sitojun printf("error %d\n", error); 5091.1Sitojun break; 5101.1Sitojun } 5111.1Sitojun printf("\n\n"); 5121.1Sitojun delay(5000000); /* 5 seconds */ 5131.1Sitojun#endif /* TODO */ 5141.1Sitojun} 5151.1Sitojun 5161.1Sitojun/* 5171.1Sitojun * Initialize segments and descriptor tables 5181.1Sitojun */ 5191.8Smsaitoh#define VBRINIT ((char *)IOM_RAM_BEGIN) 5201.3Smsaitoh#define Trap100Vec (VBRINIT + 0x100) 5211.3Smsaitoh#define Trap600Vec (VBRINIT + 0x600) 5221.3Smsaitoh#define TLBVECTOR (VBRINIT + 0x400) 5231.3Smsaitoh#define VADDRSTART VM_MIN_KERNEL_ADDRESS 5241.3Smsaitoh 5251.3Smsaitohextern int nkpde; 5261.3Smsaitohextern char MonTrap100[], MonTrap100_end[]; 5271.3Smsaitohextern char MonTrap600[], MonTrap600_end[]; 5281.3Smsaitohextern char _start[], etext[], edata[], end[]; 5291.3Smsaitohextern char tlbmisshandler_stub[], tlbmisshandler_stub_end[]; 5301.1Sitojun 5311.1Sitojunvoid 5321.3SmsaitohinitSH3(pc) 5331.3Smsaitoh void *pc; /* XXX return address */ 5341.1Sitojun{ 5351.3Smsaitoh paddr_t avail; 5361.3Smsaitoh pd_entry_t *pagedir; 5371.3Smsaitoh pt_entry_t *pagetab, pte; 5381.3Smsaitoh u_int sp; 5391.3Smsaitoh int x; 5401.3Smsaitoh char *p; 5411.3Smsaitoh 5421.3Smsaitoh avail = sh3_round_page(end); 5431.3Smsaitoh 5441.4Smsaitoh /* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */ 5451.4Smsaitoh nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1); 5461.4Smsaitoh 5471.3Smsaitoh /* 5481.3Smsaitoh * clear .bss, .common area, page dir area, 5491.3Smsaitoh * process0 stack, page table area 5501.3Smsaitoh */ 5511.4Smsaitoh p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */ 5521.27Sichiro memset(edata, 0, p - edata); 5531.3Smsaitoh 5541.30Such#if defined(SH3) && defined(SH4) 5551.30Such#error "don't define both SH3 and SH4" 5561.30Such#elif defined(SH3) 5571.30Such sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_UNKNOWN); 5581.30Such#elif defined(SH4) 5591.30Such sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_UNKNOWN); 5601.30Such#else 5611.30Such#error "define SH3 or SH4" 5621.30Such#endif 5631.3Smsaitoh /* 5641.3Smsaitoh * install trap handler 5651.3Smsaitoh */ 5661.27Sichiro memcpy(Trap100Vec, MonTrap100, MonTrap100_end - MonTrap100); 5671.27Sichiro memcpy(Trap600Vec, MonTrap600, MonTrap600_end - MonTrap600); 5681.3Smsaitoh __asm ("ldc %0, vbr" :: "r"(VBRINIT)); 5691.3Smsaitoh 5701.3Smsaitoh/* 5711.3Smsaitoh * edata end 5721.3Smsaitoh * +-------------+------+-----+----------+-------------+------------+ 5731.3Smsaitoh * | kernel text | data | bss | Page Dir | Proc0 Stack | Page Table | 5741.3Smsaitoh * +-------------+------+-----+----------+-------------+------------+ 5751.4Smsaitoh * NBPG USPACE (1+nkpde)*NBPG 5761.3Smsaitoh * (= 4*NBPG) 5771.3Smsaitoh * Build initial page tables 5781.3Smsaitoh */ 5791.3Smsaitoh pagedir = (void *)avail; 5801.3Smsaitoh pagetab = (void *)(avail + SYSMAP); 5811.3Smsaitoh 5821.3Smsaitoh /* 5831.13Smsaitoh * Construct a page table directory 5841.13Smsaitoh * In SH3 H/W does not support PTD, 5851.13Smsaitoh * these structures are used by S/W. 5861.3Smsaitoh */ 5871.3Smsaitoh pte = (pt_entry_t)pagetab; 5881.3Smsaitoh pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N; 5891.3Smsaitoh pagedir[KERNTEXTOFF >> PDSHIFT] = pte; 5901.3Smsaitoh 5911.3Smsaitoh /* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000, 5921.3Smsaitoh 0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */ 5931.3Smsaitoh pte += NBPG; 5941.3Smsaitoh for (x = 0; x < nkpde; x++) { 5951.3Smsaitoh pagedir[(VADDRSTART >> PDSHIFT) + x] = pte; 5961.3Smsaitoh pte += NBPG; 5971.3Smsaitoh } 5981.3Smsaitoh 5991.3Smsaitoh /* Install a PDE recursively mapping page directory as a page table! */ 6001.3Smsaitoh pte = (u_int)pagedir; 6011.3Smsaitoh pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N; 6021.3Smsaitoh pagedir[PDSLOT_PTE] = pte; 6031.3Smsaitoh 6041.3Smsaitoh /* set PageDirReg */ 6051.30Such SH_MMU_TTB_WRITE((u_int32_t)pagedir); 6061.3Smsaitoh 6071.3Smsaitoh /* Set TLB miss handler */ 6081.3Smsaitoh p = tlbmisshandler_stub; 6091.3Smsaitoh x = tlbmisshandler_stub_end - p; 6101.27Sichiro memcpy(TLBVECTOR, p, x); 6111.3Smsaitoh 6121.3Smsaitoh /* 6131.3Smsaitoh * Activate MMU 6141.3Smsaitoh */ 6151.30Such sh_mmu_start(); 6161.3Smsaitoh 6171.3Smsaitoh /* 6181.3Smsaitoh * Now here is virtual address 6191.3Smsaitoh */ 6201.3Smsaitoh 6211.3Smsaitoh /* Set proc0paddr */ 6221.3Smsaitoh proc0paddr = (void *)(avail + NBPG); 6231.3Smsaitoh 6241.3Smsaitoh /* Set pcb->PageDirReg of proc0 */ 6251.3Smsaitoh proc0paddr->u_pcb.pageDirReg = (int)pagedir; 6261.3Smsaitoh 6271.3Smsaitoh /* avail_start is first available physical memory address */ 6281.3Smsaitoh avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde; 6291.3Smsaitoh 6301.3Smsaitoh /* atdevbase is first available logical memory address */ 6311.3Smsaitoh atdevbase = VADDRSTART; 6321.1Sitojun 6331.1Sitojun proc0.p_addr = proc0paddr; /* page dir address */ 6341.1Sitojun 6351.3Smsaitoh /* XXX: PMAP_NEW requires valid curpcb. also init'd in cpu_startup */ 6361.3Smsaitoh curpcb = &proc0.p_addr->u_pcb; 6371.3Smsaitoh 6381.1Sitojun /* 6391.1Sitojun * Initialize the I/O port and I/O mem extent maps. 6401.1Sitojun * Note: we don't have to check the return value since 6411.1Sitojun * creation of a fixed extent map will never fail (since 6421.1Sitojun * descriptor storage has already been allocated). 6431.1Sitojun * 6441.1Sitojun * N.B. The iomem extent manages _all_ physical addresses 6451.1Sitojun * on the machine. When the amount of RAM is found, the two 6461.1Sitojun * extents of RAM are allocated from the map (0 -> ISA hole 6471.1Sitojun * and end of ISA hole -> end of RAM). 6481.1Sitojun */ 6491.1Sitojun iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 6501.1Sitojun (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 6511.1Sitojun EX_NOCOALESCE|EX_NOWAIT); 6521.1Sitojun 6531.3Smsaitoh#if 0 6541.1Sitojun consinit(); /* XXX SHOULD NOT BE DONE HERE */ 6551.1Sitojun#endif 6561.1Sitojun 6571.1Sitojun splraise(-1); 6581.1Sitojun enable_intr(); 6591.1Sitojun 6601.1Sitojun avail_end = sh3_trunc_page(IOM_RAM_END + 1); 6611.1Sitojun 6621.1Sitojun printf("initSH3\r\n"); 6631.1Sitojun 6641.1Sitojun /* 6651.1Sitojun * Calculate check sum 6661.1Sitojun */ 6671.3Smsaitoh { 6681.3Smsaitoh u_short *p, sum; 6691.3Smsaitoh int size; 6701.3Smsaitoh 6711.3Smsaitoh size = etext - _start; 6721.3Smsaitoh p = (u_short *)_start; 6731.1Sitojun sum = 0; 6741.1Sitojun size >>= 1; 6751.1Sitojun while (size--) 6761.1Sitojun sum += *p++; 6771.3Smsaitoh printf("Check Sum = 0x%x\r\n", sum); 6781.3Smsaitoh } 6791.1Sitojun /* 6801.1Sitojun * Allocate the physical addresses used by RAM from the iomem 6811.1Sitojun * extent map. This is done before the addresses are 6821.1Sitojun * page rounded just to make sure we get them all. 6831.1Sitojun */ 6841.1Sitojun if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN, 6851.3Smsaitoh (IOM_RAM_END-IOM_RAM_BEGIN) + 1, 6861.1Sitojun EX_NOWAIT)) { 6871.1Sitojun /* XXX What should we do? */ 6881.1Sitojun printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n"); 6891.1Sitojun } 6901.1Sitojun 6911.1Sitojun /* number of pages of physmem addr space */ 6921.3Smsaitoh physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1); 6931.1Sitojun#ifdef TODO 6941.1Sitojun dumpmem = physmem; 6951.1Sitojun#endif 6961.1Sitojun 6971.1Sitojun /* 6981.1Sitojun * Initialize for pmap_free_pages and pmap_next_page. 6991.1Sitojun * These guys should be page-aligned. 7001.1Sitojun */ 7011.1Sitojun if (physmem < btoc(2 * 1024 * 1024)) { 7021.1Sitojun printf("warning: too little memory available; " 7031.1Sitojun "have %d bytes, want %d bytes\n" 7041.1Sitojun "running in degraded mode\n" 7051.1Sitojun "press a key to confirm\n\n", 7061.1Sitojun ctob(physmem), 2*1024*1024); 7071.1Sitojun cngetc(); 7081.1Sitojun } 7091.1Sitojun 7101.1Sitojun /* Call pmap initialization to make new kernel address space */ 7111.3Smsaitoh pmap_bootstrap(atdevbase); 7121.1Sitojun 7131.1Sitojun /* 7141.1Sitojun * Initialize error message buffer (at end of core). 7151.1Sitojun */ 7161.1Sitojun initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE)); 7171.1Sitojun 7181.1Sitojun /* 7191.1Sitojun * set boot device information 7201.1Sitojun */ 7211.1Sitojun setup_bootinfo(); 7221.1Sitojun 7231.1Sitojun#if 0 7241.1Sitojun sh3_cache_on(); 7251.1Sitojun#endif 7261.1Sitojun 7271.3Smsaitoh /* setup proc0 stack */ 7281.3Smsaitoh sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe); 7291.3Smsaitoh 7301.3Smsaitoh /* 7311.3Smsaitoh * XXX We can't return here, because we change stack pointer. 7321.3Smsaitoh * So jump to return address directly. 7331.3Smsaitoh */ 7341.3Smsaitoh __asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp)); 7351.1Sitojun} 7361.1Sitojun 7371.1Sitojunvoid 7381.1Sitojunsetup_bootinfo(void) 7391.1Sitojun{ 7401.1Sitojun struct btinfo_bootdisk *help; 7411.1Sitojun 7421.1Sitojun *(int *)bootinfo = 1; 7431.1Sitojun help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int)); 7441.1Sitojun help->biosdev = 0; 7451.1Sitojun help->partition = 0; 7461.1Sitojun ((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk); 7471.1Sitojun ((struct btinfo_common *)help)->type = BTINFO_BOOTDISK; 7481.1Sitojun} 7491.1Sitojun 7501.1Sitojunvoid * 7511.1Sitojunlookup_bootinfo(type) 7521.1Sitojun int type; 7531.1Sitojun{ 7541.1Sitojun struct btinfo_common *help; 7551.1Sitojun int n = *(int*)bootinfo; 7561.1Sitojun help = (struct btinfo_common *)(bootinfo + sizeof(int)); 7571.1Sitojun while (n--) { 7581.1Sitojun if (help->type == type) 7591.1Sitojun return (help); 7601.1Sitojun help = (struct btinfo_common *)((char*)help + help->len); 7611.1Sitojun } 7621.1Sitojun return (0); 7631.1Sitojun} 7641.1Sitojun 7651.1Sitojun 7661.1Sitojun/* 7671.1Sitojun * consinit: 7681.1Sitojun * initialize the system console. 7691.1Sitojun * XXX - shouldn't deal with this initted thing, but then, 7701.1Sitojun * it shouldn't be called from init386 either. 7711.1Sitojun */ 7721.1Sitojunvoid 7731.1Sitojunconsinit() 7741.1Sitojun{ 7751.1Sitojun static int initted; 7761.1Sitojun 7771.1Sitojun if (initted) 7781.1Sitojun return; 7791.1Sitojun initted = 1; 7801.1Sitojun 7811.1Sitojun cninit(); 7821.1Sitojun 7831.1Sitojun#ifdef DDB 7841.1Sitojun ddb_init(); 7851.1Sitojun#endif 7861.1Sitojun} 7871.1Sitojun 7881.1Sitojunvoid 7891.1Sitojuncpu_reset() 7901.1Sitojun{ 7911.1Sitojun 7921.1Sitojun disable_intr(); 7931.1Sitojun 7941.1Sitojun Sh3Reset(); 7951.1Sitojun for (;;) 7961.1Sitojun ; 7971.1Sitojun} 7981.1Sitojun 7991.1Sitojunint 8001.1Sitojunbus_space_map (t, addr, size, flags, bshp) 8011.1Sitojun bus_space_tag_t t; 8021.1Sitojun bus_addr_t addr; 8031.1Sitojun bus_size_t size; 8041.1Sitojun int flags; 8051.1Sitojun bus_space_handle_t *bshp; 8061.1Sitojun{ 8071.1Sitojun 8081.1Sitojun *bshp = (bus_space_handle_t)addr; 8091.1Sitojun 8101.1Sitojun return 0; 8111.1Sitojun} 8121.1Sitojun 8131.1Sitojunint 8141.1Sitojunsh_memio_subregion(t, bsh, offset, size, nbshp) 8151.1Sitojun bus_space_tag_t t; 8161.1Sitojun bus_space_handle_t bsh; 8171.1Sitojun bus_size_t offset, size; 8181.1Sitojun bus_space_handle_t *nbshp; 8191.1Sitojun{ 8201.1Sitojun 8211.1Sitojun *nbshp = bsh + offset; 8221.1Sitojun return (0); 8231.1Sitojun} 8241.1Sitojun 8251.1Sitojunint 8261.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, 8271.1Sitojun bpap, bshp) 8281.1Sitojun bus_space_tag_t t; 8291.1Sitojun bus_addr_t rstart, rend; 8301.1Sitojun bus_size_t size, alignment, boundary; 8311.1Sitojun int flags; 8321.1Sitojun bus_addr_t *bpap; 8331.1Sitojun bus_space_handle_t *bshp; 8341.1Sitojun{ 8351.1Sitojun *bshp = *bpap = rstart; 8361.1Sitojun 8371.1Sitojun return (0); 8381.1Sitojun} 8391.1Sitojun 8401.1Sitojunvoid 8411.1Sitojunsh_memio_free(t, bsh, size) 8421.1Sitojun bus_space_tag_t t; 8431.1Sitojun bus_space_handle_t bsh; 8441.1Sitojun bus_size_t size; 8451.1Sitojun{ 8461.1Sitojun 8471.1Sitojun} 8481.1Sitojun 8491.1Sitojunvoid 8501.1Sitojunsh_memio_unmap(t, bsh, size) 8511.1Sitojun bus_space_tag_t t; 8521.1Sitojun bus_space_handle_t bsh; 8531.1Sitojun bus_size_t size; 8541.1Sitojun{ 8551.1Sitojun return; 8561.1Sitojun} 8571.20Smsaitoh 8581.20Smsaitoh#ifdef SH4_PCMCIA 8591.20Smsaitoh 8601.20Smsaitohint 8611.20Smsaitohshpcmcia_memio_map(t, bpa, size, flags, bshp) 8621.20Smsaitoh bus_space_tag_t t; 8631.20Smsaitoh bus_addr_t bpa; 8641.20Smsaitoh bus_size_t size; 8651.20Smsaitoh int flags; 8661.20Smsaitoh bus_space_handle_t *bshp; 8671.20Smsaitoh{ 8681.20Smsaitoh int error; 8691.20Smsaitoh struct extent *ex; 8701.20Smsaitoh bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT; 8711.20Smsaitoh 8721.20Smsaitoh if (pt != SH3_BUS_SPACE_PCMCIA_IO && 8731.20Smsaitoh pt != SH3_BUS_SPACE_PCMCIA_MEM && 8741.20Smsaitoh pt != SH3_BUS_SPACE_PCMCIA_ATT) { 8751.20Smsaitoh *bshp = (bus_space_handle_t)bpa; 8761.20Smsaitoh 8771.20Smsaitoh return 0; 8781.20Smsaitoh } 8791.20Smsaitoh 8801.20Smsaitoh ex = iomem_ex; 8811.20Smsaitoh 8821.20Smsaitoh#if 0 8831.20Smsaitoh /* 8841.20Smsaitoh * Before we go any further, let's make sure that this 8851.20Smsaitoh * region is available. 8861.20Smsaitoh */ 8871.20Smsaitoh error = extent_alloc_region(ex, bpa, size, 8881.20Smsaitoh EX_NOWAIT | EX_MALLOCOK ); 8891.20Smsaitoh if (error){ 8901.20Smsaitoh printf("sh3_pcmcia_memio_map:extent_alloc_region error\n"); 8911.20Smsaitoh return (error); 8921.20Smsaitoh } 8931.20Smsaitoh#endif 8941.20Smsaitoh 8951.20Smsaitoh /* 8961.20Smsaitoh * For memory space, map the bus physical address to 8971.20Smsaitoh * a kernel virtual address. 8981.20Smsaitoh */ 8991.20Smsaitoh error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp ); 9001.20Smsaitoh#if 0 9011.20Smsaitoh if (error) { 9021.20Smsaitoh if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) { 9031.20Smsaitoh printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n", 9041.20Smsaitoh bpa, size); 9051.20Smsaitoh printf("sh3_pcmcia_memio_map: can't free region\n"); 9061.20Smsaitoh } 9071.20Smsaitoh } 9081.20Smsaitoh#endif 9091.20Smsaitoh 9101.20Smsaitoh return (error); 9111.20Smsaitoh} 9121.20Smsaitoh 9131.20Smsaitohint 9141.20Smsaitohshpcmcia_mem_add_mapping(bpa, size, type, bshp) 9151.20Smsaitoh bus_addr_t bpa; 9161.20Smsaitoh bus_size_t size; 9171.20Smsaitoh int type; 9181.20Smsaitoh bus_space_handle_t *bshp; 9191.20Smsaitoh{ 9201.20Smsaitoh u_long pa, endpa; 9211.20Smsaitoh vaddr_t va; 9221.20Smsaitoh pt_entry_t *pte; 9231.20Smsaitoh unsigned int m = 0; 9241.20Smsaitoh int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT; 9251.20Smsaitoh 9261.20Smsaitoh pa = sh3_trunc_page(bpa); 9271.20Smsaitoh endpa = sh3_round_page(bpa + size); 9281.20Smsaitoh 9291.20Smsaitoh#ifdef DIAGNOSTIC 9301.20Smsaitoh if (endpa <= pa) 9311.20Smsaitoh panic("sh3_pcmcia_mem_add_mapping: overflow"); 9321.20Smsaitoh#endif 9331.20Smsaitoh 9341.20Smsaitoh va = uvm_km_valloc(kernel_map, endpa - pa); 9351.20Smsaitoh if (va == 0){ 9361.20Smsaitoh printf("shpcmcia_add_mapping: nomem \n"); 9371.20Smsaitoh return (ENOMEM); 9381.20Smsaitoh } 9391.20Smsaitoh 9401.20Smsaitoh *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); 9411.20Smsaitoh 9421.29Such#define MODE(t, s) \ 9431.29Such (t) & SH3_BUS_SPACE_PCMCIA_8BIT ? \ 9441.29Such _PG_PCMCIA_ ## s ## 8 : \ 9451.29Such _PG_PCMCIA_ ## s ## 16 9461.29Such switch (io_type) { 9471.29Such default: 9481.29Such panic("unknown pcmcia space."); 9491.29Such /* NOTREACHED */ 9501.29Such case SH3_BUS_SPACE_PCMCIA_IO: 9511.29Such m = MODE(type, IO); 9521.29Such break; 9531.29Such case SH3_BUS_SPACE_PCMCIA_MEM: 9541.29Such m = MODE(type, MEM); 9551.29Such break; 9561.29Such case SH3_BUS_SPACE_PCMCIA_ATT: 9571.29Such m = MODE(type, ATTR); 9581.29Such break; 9591.20Smsaitoh } 9601.29Such#undef MODE 9611.20Smsaitoh 9621.20Smsaitoh for (; pa < endpa; pa += NBPG, va += NBPG) { 9631.20Smsaitoh pmap_enter(pmap_kernel(), va, pa, 9641.22Smsaitoh VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED); 9651.20Smsaitoh 9661.20Smsaitoh pte = kvtopte(va); 9671.20Smsaitoh *pte &= ~PG_N; 9681.20Smsaitoh *pte |= m; 9691.20Smsaitoh pmap_update_pg(va); 9701.20Smsaitoh } 9711.28Schris pmap_update(pmap_kernel()); 9721.20Smsaitoh 9731.20Smsaitoh return 0; 9741.20Smsaitoh} 9751.20Smsaitoh 9761.20Smsaitohvoid 9771.20Smsaitohshpcmcia_memio_unmap(t, bsh, size) 9781.20Smsaitoh bus_space_tag_t t; 9791.20Smsaitoh bus_space_handle_t bsh; 9801.20Smsaitoh bus_size_t size; 9811.20Smsaitoh{ 9821.20Smsaitoh struct extent *ex; 9831.20Smsaitoh u_long va, endva; 9841.20Smsaitoh bus_addr_t bpa; 9851.20Smsaitoh bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT; 9861.20Smsaitoh 9871.20Smsaitoh if (pt != SH3_BUS_SPACE_PCMCIA_IO && 9881.20Smsaitoh pt != SH3_BUS_SPACE_PCMCIA_MEM && 9891.20Smsaitoh pt != SH3_BUS_SPACE_PCMCIA_ATT) { 9901.20Smsaitoh return ; 9911.20Smsaitoh } 9921.20Smsaitoh 9931.20Smsaitoh ex = iomem_ex; 9941.20Smsaitoh 9951.20Smsaitoh va = sh3_trunc_page(bsh); 9961.20Smsaitoh endva = sh3_round_page(bsh + size); 9971.20Smsaitoh 9981.20Smsaitoh#ifdef DIAGNOSTIC 9991.20Smsaitoh if (endva <= va) 10001.20Smsaitoh panic("sh3_pcmcia_memio_unmap: overflow"); 10011.20Smsaitoh#endif 10021.20Smsaitoh 10031.22Smsaitoh pmap_extract(pmap_kernel(), va, &bpa); 10041.24Sichiro bpa += bsh & PGOFSET; 10051.20Smsaitoh 10061.20Smsaitoh /* 10071.20Smsaitoh * Free the kernel virtual mapping. 10081.20Smsaitoh */ 10091.20Smsaitoh uvm_km_free(kernel_map, va, endva - va); 10101.20Smsaitoh 10111.20Smsaitoh#if 0 10121.20Smsaitoh if (extent_free(ex, bpa, size, 10131.20Smsaitoh EX_NOWAIT | EX_MALLOCOK)) { 10141.20Smsaitoh printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n", 10151.20Smsaitoh "pa", bpa, size); 10161.20Smsaitoh printf("sh3_pcmcia_memio_unmap: can't free region\n"); 10171.20Smsaitoh } 10181.20Smsaitoh#endif 10191.20Smsaitoh} 10201.20Smsaitoh 10211.20Smsaitohvoid 10221.20Smsaitohshpcmcia_memio_free(t, bsh, size) 10231.20Smsaitoh bus_space_tag_t t; 10241.20Smsaitoh bus_space_handle_t bsh; 10251.20Smsaitoh bus_size_t size; 10261.20Smsaitoh{ 10271.20Smsaitoh 10281.20Smsaitoh /* sh3_pcmcia_memio_unmap() does all that we need to do. */ 10291.20Smsaitoh shpcmcia_memio_unmap(t, bsh, size); 10301.20Smsaitoh} 10311.20Smsaitoh 10321.20Smsaitohint 10331.20Smsaitohshpcmcia_memio_subregion(t, bsh, offset, size, nbshp) 10341.20Smsaitoh bus_space_tag_t t; 10351.20Smsaitoh bus_space_handle_t bsh; 10361.20Smsaitoh bus_size_t offset, size; 10371.20Smsaitoh bus_space_handle_t *nbshp; 10381.20Smsaitoh{ 10391.20Smsaitoh 10401.20Smsaitoh *nbshp = bsh + offset; 10411.20Smsaitoh return (0); 10421.20Smsaitoh} 10431.20Smsaitoh 10441.20Smsaitoh#endif /* SH4_PCMCIA */ 10451.1Sitojun 10461.18Smsaitoh#if !defined(DONT_INIT_BSC) 10471.1Sitojun/* 10481.1Sitojun * InitializeBsc 10491.1Sitojun * : BSC(Bus State Controler) 10501.1Sitojun */ 10511.1Sitojunvoid InitializeBsc __P((void)); 10521.1Sitojun 10531.1Sitojunvoid 10541.1SitojunInitializeBsc() 10551.1Sitojun{ 10561.1Sitojun 10571.1Sitojun /* 10581.1Sitojun * Drive RAS,CAS in stand by mode and bus release mode 10591.1Sitojun * Area0 = Normal memory, Area5,6=Normal(no burst) 10601.1Sitojun * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory 10611.1Sitojun * Area4 = Normal Memory 10621.1Sitojun * Area6 = Normal memory 10631.1Sitojun */ 10641.3Smsaitoh SHREG_BCR1 = BSC_BCR1_VAL; 10651.1Sitojun 10661.1Sitojun /* 10671.1Sitojun * Bus Width 10681.1Sitojun * Area4: Bus width = 16bit 10691.1Sitojun * Area6,5 = 16bit 10701.1Sitojun * Area1 = 8bit 10711.1Sitojun * Area2,3: Bus width = 32bit 10721.1Sitojun */ 10731.13Smsaitoh SHREG_BCR2 = BSC_BCR2_VAL; 10741.1Sitojun 10751.1Sitojun /* 10761.1Sitojun * Idle cycle number in transition area and read to write 10771.1Sitojun * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 10781.1Sitojun * Area1 = 3, Area0 = 3 10791.1Sitojun */ 10801.3Smsaitoh SHREG_WCR1 = BSC_WCR1_VAL; 10811.1Sitojun 10821.1Sitojun /* 10831.1Sitojun * Wait cycle 10841.1Sitojun * Area 6 = 6 10851.1Sitojun * Area 5 = 2 10861.1Sitojun * Area 4 = 10 10871.1Sitojun * Area 3 = 3 10881.1Sitojun * Area 2,1 = 3 10891.1Sitojun * Area 0 = 6 10901.1Sitojun */ 10911.3Smsaitoh SHREG_WCR2 = BSC_WCR2_VAL; 10921.1Sitojun 10931.13Smsaitoh#if defined(SH4) && defined(BSC_WCR3_VAL) 10941.3Smsaitoh SHREG_WCR3 = BSC_WCR3_VAL; 10951.1Sitojun#endif 10961.1Sitojun 10971.1Sitojun /* 10981.1Sitojun * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 10991.1Sitojun * write pre-charge=1cycle 11001.1Sitojun * CAS before RAS refresh RAS assert time = 3 cycle 11011.1Sitojun * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON 11021.1Sitojun * CAS before RAS refresh ON, EDO DRAM 11031.1Sitojun */ 11041.3Smsaitoh SHREG_MCR = BSC_MCR_VAL; 11051.1Sitojun 11061.11Smsaitoh#if defined(BSC_SDMR2_VAL) 11071.11Smsaitoh#define SDMR2 (*(volatile unsigned char *)BSC_SDMR2_VAL) 11081.1Sitojun 11091.11Smsaitoh SDMR2 = 0; 11101.11Smsaitoh#endif 11111.11Smsaitoh 11121.11Smsaitoh#if defined(BSC_SDMR3_VAL) 11131.19Smsaitoh#if !(defined(COMPUTEXEVB) && defined(SH7709A)) 11141.11Smsaitoh#define SDMR3 (*(volatile unsigned char *)BSC_SDMR3_VAL) 11151.11Smsaitoh 11161.11Smsaitoh SDMR3 = 0; 11171.1Sitojun#else 11181.1Sitojun#define ADDSET (*(volatile unsigned short *)0x1A000000) 11191.1Sitojun#define ADDRST (*(volatile unsigned short *)0x18000000) 11201.11Smsaitoh#define SDMR3 (*(volatile unsigned char *)BSC_SDMR3_VAL) 11211.1Sitojun 11221.1Sitojun ADDSET = 0; 11231.11Smsaitoh SDMR3 = 0; 11241.1Sitojun ADDRST = 0; 11251.1Sitojun#endif 11261.1Sitojun#endif 11271.1Sitojun 11281.1Sitojun /* 11291.1Sitojun * PCMCIA Control Register 11301.1Sitojun * OE/WE assert delay 3.5 cycle 11311.1Sitojun * OE/WE negate-address delay 3.5 cycle 11321.1Sitojun */ 11331.1Sitojun#ifdef BSC_PCR_VAL 11341.12Smsaitoh SHREG_PCR = BSC_PCR_VAL; 11351.1Sitojun#endif 11361.1Sitojun 11371.1Sitojun /* 11381.1Sitojun * Refresh Timer Control/Status Register 11391.1Sitojun * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 11401.1Sitojun * Count Limit = 1024 11411.1Sitojun * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 11421.1Sitojun * is the rule of SH3 in writing these register. 11431.1Sitojun */ 11441.3Smsaitoh SHREG_RTCSR = BSC_RTCSR_VAL; 11451.1Sitojun 11461.1Sitojun 11471.1Sitojun /* 11481.1Sitojun * Refresh Timer Counter 11491.1Sitojun * Initialize to 0 11501.1Sitojun */ 11511.9Smsaitoh#ifdef BSC_RTCNT_VAL 11521.3Smsaitoh SHREG_RTCNT = BSC_RTCNT_VAL; 11531.9Smsaitoh#endif 11541.1Sitojun 11551.1Sitojun /* set Refresh Time Constant Register */ 11561.3Smsaitoh SHREG_RTCOR = BSC_RTCOR_VAL; 11571.1Sitojun 11581.1Sitojun /* init Refresh Count Register */ 11591.1Sitojun#ifdef BSC_RFCR_VAL 11601.3Smsaitoh SHREG_RFCR = BSC_RFCR_VAL; 11611.1Sitojun#endif 11621.1Sitojun 11631.1Sitojun /* Set Clock mode (make internal clock double speed) */ 11641.1Sitojun 11651.1Sitojun SHREG_FRQCR = FRQCR_VAL; 11661.1Sitojun 11671.1Sitojun#ifndef MMEYE_NO_CACHE 11681.1Sitojun /* Cache ON */ 11691.6Smsaitoh SHREG_CCR = CCR_CE; 11701.1Sitojun#endif 11711.1Sitojun} 11721.18Smsaitoh#endif 11731.1Sitojun 11741.1Sitojunvoid 11751.1Sitojunsh3_cache_on(void) 11761.1Sitojun{ 11771.1Sitojun#ifndef MMEYE_NO_CACHE 11781.1Sitojun /* Cache ON */ 11791.6Smsaitoh SHREG_CCR = CCR_CE; 11801.6Smsaitoh SHREG_CCR = CCR_CF | CCR_CE; /* cache clear */ 11811.6Smsaitoh SHREG_CCR = CCR_CE; /* cache on */ 11821.1Sitojun#endif 11831.1Sitojun} 11841.9Smsaitoh 11851.9Smsaitoh#ifdef SH4 11861.9Smsaitohvoid 11871.9Smsaitohsh4_cache_flush(addr) 11881.9Smsaitoh vaddr_t addr; 11891.9Smsaitoh{ 11901.9Smsaitoh#if 1 11911.9Smsaitoh#define SH_ADDR_ARRAY_BASE_ADDR 0xf4000000 11921.9Smsaitoh#define WRITE_ADDR_ARRAY( entry ) \ 11931.9Smsaitoh (*(volatile u_int32_t *)(SH_ADDR_ARRAY_BASE_ADDR|(entry)|0x00)) 11941.9Smsaitoh 11951.9Smsaitoh int entry; 11961.9Smsaitoh 11971.9Smsaitoh entry = ((u_int32_t)addr) & 0x3fe0; 11981.9Smsaitoh 11991.9Smsaitoh WRITE_ADDR_ARRAY(entry) = 0; 12001.9Smsaitoh#else 12011.9Smsaitoh volatile int *p = (int *)IOM_RAM_BEGIN; 12021.9Smsaitoh int i; 12031.9Smsaitoh /* volatile */int d; 12041.9Smsaitoh 12051.9Smsaitoh for(i = 0; i < 512; i++){ 12061.9Smsaitoh d = *p; 12071.9Smsaitoh p += 8; 12081.9Smsaitoh } 12091.9Smsaitoh#endif 12101.9Smsaitoh} 12111.9Smsaitoh#endif 12121.8Smsaitoh 12131.8Smsaitoh /* XXX This value depends on physical available memory */ 12141.8Smsaitoh#define OSIMAGE_BUF_ADDR (IOM_RAM_BEGIN + 0x00400000) 12151.8Smsaitoh 12161.1Sitojunvoid 12171.3SmsaitohLoadAndReset(osimage) 12181.3Smsaitoh char *osimage; 12191.1Sitojun{ 12201.1Sitojun void *buf_addr; 12211.1Sitojun u_long size; 12221.1Sitojun u_long *src; 12231.1Sitojun u_long *dest; 12241.1Sitojun u_long csum = 0; 12251.1Sitojun u_long csum2 = 0; 12261.1Sitojun u_long size2; 12271.1Sitojun 12281.3Smsaitoh printf("LoadAndReset: copy start\n"); 12291.1Sitojun buf_addr = (void *)OSIMAGE_BUF_ADDR; 12301.1Sitojun 12311.1Sitojun size = *(u_long *)osimage; 12321.1Sitojun src = (u_long *)osimage; 12331.1Sitojun dest = buf_addr; 12341.1Sitojun 12351.3Smsaitoh size = (size + sizeof(u_long) * 2 + 3) >> 2; 12361.1Sitojun size2 = size; 12371.1Sitojun 12381.3Smsaitoh while (size--) { 12391.1Sitojun csum += *src; 12401.1Sitojun *dest++ = *src++; 12411.1Sitojun } 12421.1Sitojun 12431.1Sitojun dest = buf_addr; 12441.1Sitojun while (size2--) 12451.1Sitojun csum2 += *dest++; 12461.1Sitojun 12471.3Smsaitoh printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2); 12481.1Sitojun printf("start XLoadAndReset\n"); 12491.1Sitojun 12501.1Sitojun /* mask all externel interrupt (XXX) */ 12511.1Sitojun 12521.1Sitojun XLoadAndReset(buf_addr); 12531.1Sitojun} 1254