machdep.c revision 1.4
11.4Smsaitoh/* $NetBSD: machdep.c,v 1.4 1999/09/16 22:52:11 msaitoh 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_compat_netbsd.h" 791.1Sitojun#include "opt_ddb.h" 801.1Sitojun#include "opt_memsize.h" 811.1Sitojun#include "opt_initbsc.h" 821.1Sitojun#include "opt_sysv.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/callout.h> 971.1Sitojun#include <sys/malloc.h> 981.1Sitojun#include <sys/mbuf.h> 991.1Sitojun#include <sys/msgbuf.h> 1001.1Sitojun#include <sys/mount.h> 1011.1Sitojun#include <sys/vnode.h> 1021.1Sitojun#include <sys/device.h> 1031.1Sitojun#include <sys/extent.h> 1041.1Sitojun#include <sys/syscallargs.h> 1051.1Sitojun 1061.1Sitojun#ifdef KGDB 1071.1Sitojun#include <sys/kgdb.h> 1081.1Sitojun#endif 1091.1Sitojun 1101.1Sitojun#include <dev/cons.h> 1111.1Sitojun 1121.1Sitojun#include <vm/vm.h> 1131.1Sitojun#include <vm/vm_kern.h> 1141.1Sitojun#include <vm/vm_page.h> 1151.1Sitojun 1161.1Sitojun#include <uvm/uvm_extern.h> 1171.1Sitojun 1181.1Sitojun#include <sys/sysctl.h> 1191.1Sitojun 1201.1Sitojun#include <machine/cpu.h> 1211.1Sitojun#include <machine/cpufunc.h> 1221.1Sitojun#include <machine/psl.h> 1231.1Sitojun#include <machine/bootinfo.h> 1241.1Sitojun#include <machine/bus.h> 1251.1Sitojun#include <sh3/bscreg.h> 1261.1Sitojun#include <sh3/ccrreg.h> 1271.1Sitojun#include <sh3/cpgreg.h> 1281.1Sitojun#include <sh3/intcreg.h> 1291.1Sitojun#include <sh3/pfcreg.h> 1301.1Sitojun#include <sh3/wdtreg.h> 1311.1Sitojun 1321.1Sitojun#include <sys/termios.h> 1331.1Sitojun#include "sci.h" 1341.1Sitojun 1351.1Sitojun/* the following is used externally (sysctl_hw) */ 1361.1Sitojunchar machine[] = MACHINE; /* cpu "architecture" */ 1371.1Sitojunchar machine_arch[] = MACHINE_ARCH; /* machine_arch = "sh3" */ 1381.1Sitojun 1391.1Sitojun#ifdef sh3_debug 1401.1Sitojunint cpu_debug_mode = 1; 1411.1Sitojun#else 1421.1Sitojunint cpu_debug_mode = 0; 1431.1Sitojun#endif 1441.1Sitojun 1451.1Sitojunchar cpu_model[120]; 1461.1Sitojun 1471.1Sitojunchar bootinfo[BOOTINFO_MAXSIZE]; 1481.1Sitojun 1491.3Smsaitohint physmem; 1501.3Smsaitohint dumpmem_low; 1511.3Smsaitohint dumpmem_high; 1521.3Smsaitohvaddr_t atdevbase; /* location of start of iomem in virtual */ 1531.1Sitojunpaddr_t msgbuf_paddr; 1541.3Smsaitohstruct user *proc0paddr; 1551.1Sitojun 1561.1Sitojunvm_map_t exec_map = NULL; 1571.1Sitojunvm_map_t mb_map = NULL; 1581.1Sitojunvm_map_t phys_map = NULL; 1591.1Sitojun 1601.3Smsaitohextern int boothowto; 1611.1Sitojunextern paddr_t avail_start, avail_end; 1621.1Sitojun 1631.1Sitojun#ifdef SYSCALL_DEBUG 1641.1Sitojun#define SCDEBUG_ALL 0x0004 1651.1Sitojunextern int scdebug; 1661.1Sitojun#endif 1671.1Sitojun 1681.1Sitojun#define IOM_RAM_END ((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1) 1691.1Sitojun 1701.1Sitojun/* 1711.1Sitojun * Extent maps to manage I/O and ISA memory hole space. Allocate 1721.1Sitojun * storage for 8 regions in each, initially. Later, ioport_malloc_safe 1731.1Sitojun * will indicate that it's safe to use malloc() to dynamically allocate 1741.1Sitojun * region descriptors. 1751.1Sitojun * 1761.1Sitojun * N.B. At least two regions are _always_ allocated from the iomem 1771.1Sitojun * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 1781.1Sitojun * 1791.1Sitojun * The extent maps are not static! Machine-dependent ISA and EISA 1801.1Sitojun * routines need access to them for bus address space allocation. 1811.1Sitojun */ 1821.1Sitojunstatic long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 1831.1Sitojunstruct extent *ioport_ex; 1841.1Sitojunstruct extent *iomem_ex; 1851.1Sitojunstatic int ioport_malloc_safe; 1861.1Sitojun 1871.3Smsaitohvoid setup_bootinfo __P((void)); 1881.3Smsaitohvoid dumpsys __P((void)); 1891.3Smsaitohvoid identifycpu __P((void)); 1901.3Smsaitohvoid initSH3 __P((void *)); 1911.3Smsaitohvoid InitializeSci __P((unsigned char)); 1921.3Smsaitohvoid sh3_cache_on __P((void)); 1931.3Smsaitohvoid LoadAndReset __P((char *)); 1941.3Smsaitohvoid XLoadAndReset __P((char *)); 1951.3Smsaitohvoid Sh3Reset __P((void)); 1961.1Sitojun 1971.1Sitojun#include <dev/ic/comreg.h> 1981.1Sitojun#include <dev/ic/comvar.h> 1991.1Sitojun 2001.1Sitojunvoid consinit __P((void)); 2011.1Sitojun 2021.1Sitojun#ifdef COMPAT_NOMID 2031.1Sitojunstatic int exec_nomid __P((struct proc *, struct exec_package *)); 2041.1Sitojun#endif 2051.1Sitojun 2061.1Sitojun/* 2071.1Sitojun * Machine-dependent startup code 2081.1Sitojun * 2091.1Sitojun * This is called from main() in kern/main.c. 2101.1Sitojun */ 2111.1Sitojunvoid 2121.1Sitojuncpu_startup() 2131.1Sitojun{ 2141.1Sitojun unsigned i; 2151.1Sitojun caddr_t v; 2161.1Sitojun int sz; 2171.1Sitojun int base, residual; 2181.1Sitojun vaddr_t minaddr, maxaddr; 2191.1Sitojun vsize_t size; 2201.1Sitojun struct pcb *pcb; 2211.2Stsubai char pbuf[9]; 2221.1Sitojun 2231.1Sitojun printf(version); 2241.1Sitojun 2251.1Sitojun sprintf(cpu_model, "Hitachi SH3"); 2261.1Sitojun 2271.2Stsubai format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 2281.2Stsubai printf("total memory = %s\n", pbuf); 2291.1Sitojun 2301.1Sitojun /* 2311.1Sitojun * Find out how much space we need, allocate it, 2321.1Sitojun * and then give everything true virtual addresses. 2331.1Sitojun */ 2341.2Stsubai sz = (int)allocsys(NULL, NULL); 2351.1Sitojun if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0) 2361.1Sitojun panic("startup: no room for tables"); 2371.2Stsubai if (allocsys(v, NULL) - v != sz) 2381.1Sitojun panic("startup: table size inconsistency"); 2391.1Sitojun 2401.1Sitojun /* 2411.1Sitojun * Now allocate buffers proper. They are different than the above 2421.1Sitojun * in that they usually occupy more virtual memory than physical. 2431.1Sitojun */ 2441.1Sitojun size = MAXBSIZE * nbuf; 2451.1Sitojun buffers = 0; 2461.1Sitojun if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size), 2471.1Sitojun NULL, UVM_UNKNOWN_OFFSET, 2481.1Sitojun UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 2491.1Sitojun UVM_ADV_NORMAL, 0)) != KERN_SUCCESS) 2501.1Sitojun panic("cpu_startup: cannot allocate VM for buffers"); 2511.1Sitojun minaddr = (vaddr_t)buffers; 2521.1Sitojun if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { 2531.1Sitojun /* don't want to alloc more physical mem than needed */ 2541.1Sitojun bufpages = btoc(MAXBSIZE) * nbuf; 2551.1Sitojun } 2561.1Sitojun 2571.1Sitojun base = bufpages / nbuf; 2581.1Sitojun residual = bufpages % nbuf; 2591.1Sitojun for (i = 0; i < nbuf; i++) { 2601.1Sitojun vsize_t curbufsize; 2611.1Sitojun vaddr_t curbuf; 2621.1Sitojun struct vm_page *pg; 2631.1Sitojun 2641.1Sitojun /* 2651.1Sitojun * Each buffer has MAXBSIZE bytes of VM space allocated. Of 2661.1Sitojun * that MAXBSIZE space, we allocate and map (base+1) pages 2671.1Sitojun * for the first "residual" buffers, and then we allocate 2681.1Sitojun * "base" pages for the rest. 2691.1Sitojun */ 2701.1Sitojun curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 2711.1Sitojun curbufsize = CLBYTES * ((i < residual) ? (base+1) : base); 2721.1Sitojun 2731.1Sitojun while (curbufsize) { 2741.1Sitojun pg = uvm_pagealloc(NULL, 0, NULL, 0); 2751.1Sitojun if (pg == NULL) 2761.1Sitojun panic("cpu_startup: not enough memory for " 2771.1Sitojun "buffer cache"); 2781.2Stsubai pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 2791.2Stsubai VM_PROT_READ|VM_PROT_WRITE); 2801.1Sitojun curbuf += PAGE_SIZE; 2811.1Sitojun curbufsize -= PAGE_SIZE; 2821.1Sitojun } 2831.1Sitojun } 2841.1Sitojun 2851.1Sitojun /* 2861.1Sitojun * Allocate a submap for exec arguments. This map effectively 2871.1Sitojun * limits the number of processes exec'ing at any time. 2881.1Sitojun */ 2891.1Sitojun exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 2901.1Sitojun 16*NCARGS, TRUE, FALSE, NULL); 2911.1Sitojun 2921.1Sitojun /* 2931.1Sitojun * Allocate a submap for physio 2941.1Sitojun */ 2951.1Sitojun phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 2961.1Sitojun VM_PHYS_SIZE, TRUE, FALSE, NULL); 2971.1Sitojun 2981.1Sitojun /* 2991.1Sitojun * Finally, allocate mbuf cluster submap. 3001.1Sitojun */ 3011.1Sitojun mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 3021.1Sitojun VM_MBUF_SIZE, FALSE, FALSE, NULL); 3031.1Sitojun 3041.1Sitojun /* 3051.1Sitojun * Initialize callouts 3061.1Sitojun */ 3071.1Sitojun callfree = callout; 3081.1Sitojun for (i = 1; i < ncallout; i++) 3091.1Sitojun callout[i-1].c_next = &callout[i]; 3101.1Sitojun 3111.2Stsubai format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 3121.2Stsubai printf("avail memory = %s\n", pbuf); 3131.2Stsubai format_bytes(pbuf, sizeof(pbuf), bufpages * CLBYTES); 3141.2Stsubai printf("using %d buffers containing %s of memory\n", nbuf, pbuf); 3151.1Sitojun 3161.1Sitojun /* 3171.1Sitojun * Set up buffers, so they can be used to read disk labels. 3181.1Sitojun */ 3191.1Sitojun bufinit(); 3201.1Sitojun 3211.1Sitojun /* Safe for i/o port allocation to use malloc now. */ 3221.1Sitojun ioport_malloc_safe = 1; 3231.1Sitojun 3241.1Sitojun curpcb = pcb = &proc0.p_addr->u_pcb; 3251.1Sitojun pcb->r15 = (int)proc0.p_addr + USPACE - 16; 3261.1Sitojun 3271.1Sitojun proc0.p_md.md_regs = (struct trapframe *)pcb->r15 - 1; 3281.1Sitojun 3291.1Sitojun#ifdef SYSCALL_DEBUG 3301.1Sitojun scdebug |= SCDEBUG_ALL; 3311.1Sitojun#endif 3321.1Sitojun 3331.3Smsaitoh#ifdef FORCE_RB_SINGLE 3341.1Sitojun boothowto |= RB_SINGLE; 3351.1Sitojun#endif 3361.1Sitojun} 3371.1Sitojun 3381.1Sitojun/* 3391.1Sitojun * Info for CTL_HW 3401.1Sitojun */ 3411.1Sitojunextern char version[]; 3421.1Sitojun 3431.1Sitojun#define CPUDEBUG 3441.1Sitojun 3451.1Sitojun/* 3461.1Sitojun * machine dependent system variables. 3471.1Sitojun */ 3481.1Sitojunint 3491.1Sitojuncpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 3501.1Sitojun int *name; 3511.1Sitojun u_int namelen; 3521.1Sitojun void *oldp; 3531.1Sitojun size_t *oldlenp; 3541.1Sitojun void *newp; 3551.1Sitojun size_t newlen; 3561.1Sitojun struct proc *p; 3571.1Sitojun{ 3581.1Sitojun dev_t consdev; 3591.1Sitojun struct btinfo_bootpath *bibp; 3601.1Sitojun struct trapframe *tf; 3611.1Sitojun char *osimage; 3621.1Sitojun 3631.1Sitojun /* all sysctl names at this level are terminal */ 3641.1Sitojun if (namelen != 1) 3651.1Sitojun return (ENOTDIR); /* overloaded */ 3661.1Sitojun 3671.1Sitojun switch (name[0]) { 3681.1Sitojun case CPU_CONSDEV: 3691.1Sitojun if (cn_tab != NULL) 3701.1Sitojun consdev = cn_tab->cn_dev; 3711.1Sitojun else 3721.1Sitojun consdev = NODEV; 3731.1Sitojun return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 3741.1Sitojun sizeof consdev)); 3751.1Sitojun 3761.1Sitojun case CPU_NKPDE: 3771.1Sitojun return (sysctl_rdint(oldp, oldlenp, newp, nkpde)); 3781.1Sitojun 3791.1Sitojun case CPU_BOOTED_KERNEL: 3801.1Sitojun bibp = lookup_bootinfo(BTINFO_BOOTPATH); 3811.1Sitojun if (!bibp) 3821.1Sitojun return (ENOENT); /* ??? */ 3831.1Sitojun return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath)); 3841.1Sitojun 3851.1Sitojun case CPU_SETPRIVPROC: 3861.1Sitojun if (newp == NULL) 3871.1Sitojun return (0); 3881.1Sitojun 3891.1Sitojun /* set current process to priviledged process */ 3901.1Sitojun tf = p->p_md.md_regs; 3911.1Sitojun tf->tf_ssr |= PSL_MD; 3921.1Sitojun return (0); 3931.1Sitojun 3941.1Sitojun case CPU_DEBUGMODE: 3951.1Sitojun return (sysctl_int(oldp, oldlenp, newp, newlen, 3961.1Sitojun &cpu_debug_mode)); 3971.1Sitojun 3981.1Sitojun case CPU_LOADANDRESET: 3991.1Sitojun if (newp != NULL) { 4001.1Sitojun osimage = (char *)(*(u_long *)newp); 4011.1Sitojun 4021.1Sitojun LoadAndReset(osimage); 4031.1Sitojun /* not reach here */ 4041.1Sitojun } 4051.1Sitojun return (0); 4061.1Sitojun 4071.1Sitojun default: 4081.1Sitojun return (EOPNOTSUPP); 4091.1Sitojun } 4101.1Sitojun /* NOTREACHED */ 4111.1Sitojun} 4121.1Sitojun 4131.1Sitojun/* 4141.1Sitojun * Send an interrupt to process. 4151.1Sitojun * 4161.1Sitojun * Stack is set up to allow sigcode stored 4171.1Sitojun * in u. to call routine, followed by kcall 4181.1Sitojun * to sigreturn routine below. After sigreturn 4191.1Sitojun * resets the signal mask, the stack, and the 4201.1Sitojun * frame pointer, it returns to the user 4211.1Sitojun * specified pc, psl. 4221.1Sitojun */ 4231.1Sitojunvoid 4241.1Sitojunsendsig(catcher, sig, mask, code) 4251.1Sitojun sig_t catcher; 4261.1Sitojun int sig; 4271.1Sitojun sigset_t *mask; 4281.1Sitojun u_long code; 4291.1Sitojun{ 4301.1Sitojun struct proc *p = curproc; 4311.1Sitojun struct trapframe *tf; 4321.1Sitojun struct sigframe *fp, frame; 4331.1Sitojun struct sigacts *psp = p->p_sigacts; 4341.1Sitojun int onstack; 4351.1Sitojun 4361.1Sitojun tf = p->p_md.md_regs; 4371.1Sitojun 4381.1Sitojun /* Do we need to jump onto the signal stack? */ 4391.1Sitojun onstack = 4401.1Sitojun (psp->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 4411.1Sitojun (psp->ps_sigact[sig].sa_flags & SA_ONSTACK) != 0; 4421.1Sitojun 4431.1Sitojun /* Allocate space for the signal handler context. */ 4441.1Sitojun if (onstack) 4451.1Sitojun fp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp + 4461.1Sitojun psp->ps_sigstk.ss_size); 4471.1Sitojun else 4481.1Sitojun fp = (struct sigframe *)tf->tf_r15; 4491.1Sitojun fp--; 4501.1Sitojun 4511.1Sitojun /* Build stack frame for signal trampoline. */ 4521.1Sitojun frame.sf_signum = sig; 4531.1Sitojun frame.sf_code = code; 4541.1Sitojun frame.sf_scp = &fp->sf_sc; 4551.1Sitojun frame.sf_handler = catcher; 4561.1Sitojun 4571.1Sitojun /* Save register context. */ 4581.1Sitojun frame.sf_sc.sc_ssr = tf->tf_ssr; 4591.1Sitojun frame.sf_sc.sc_spc = tf->tf_spc; 4601.1Sitojun frame.sf_sc.sc_pr = tf->tf_pr; 4611.1Sitojun frame.sf_sc.sc_r15 = tf->tf_r15; 4621.1Sitojun frame.sf_sc.sc_r14 = tf->tf_r14; 4631.1Sitojun frame.sf_sc.sc_r13 = tf->tf_r13; 4641.1Sitojun frame.sf_sc.sc_r12 = tf->tf_r12; 4651.1Sitojun frame.sf_sc.sc_r11 = tf->tf_r11; 4661.1Sitojun frame.sf_sc.sc_r10 = tf->tf_r10; 4671.1Sitojun frame.sf_sc.sc_r9 = tf->tf_r9; 4681.1Sitojun frame.sf_sc.sc_r8 = tf->tf_r8; 4691.1Sitojun frame.sf_sc.sc_r7 = tf->tf_r7; 4701.1Sitojun frame.sf_sc.sc_r6 = tf->tf_r6; 4711.1Sitojun frame.sf_sc.sc_r5 = tf->tf_r5; 4721.1Sitojun frame.sf_sc.sc_r4 = tf->tf_r4; 4731.1Sitojun frame.sf_sc.sc_r3 = tf->tf_r3; 4741.1Sitojun frame.sf_sc.sc_r2 = tf->tf_r2; 4751.1Sitojun frame.sf_sc.sc_r1 = tf->tf_r1; 4761.1Sitojun frame.sf_sc.sc_r0 = tf->tf_r0; 4771.1Sitojun frame.sf_sc.sc_trapno = tf->tf_trapno; 4781.1Sitojun#ifdef TODO 4791.1Sitojun frame.sf_sc.sc_err = tf->tf_err; 4801.1Sitojun#endif 4811.1Sitojun 4821.1Sitojun /* Save signal stack. */ 4831.1Sitojun frame.sf_sc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 4841.1Sitojun 4851.1Sitojun /* Save signal mask. */ 4861.1Sitojun frame.sf_sc.sc_mask = *mask; 4871.1Sitojun 4881.1Sitojun#ifdef COMPAT_13 4891.1Sitojun /* 4901.1Sitojun * XXX We always have to save an old style signal mask because 4911.1Sitojun * XXX we might be delivering a signal to a process which will 4921.1Sitojun * XXX escape from the signal in a non-standard way and invoke 4931.1Sitojun * XXX sigreturn() directly. 4941.1Sitojun */ 4951.1Sitojun native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); 4961.1Sitojun#endif 4971.1Sitojun 4981.1Sitojun if (copyout(&frame, fp, sizeof(frame)) != 0) { 4991.1Sitojun /* 5001.1Sitojun * Process has trashed its stack; give it an illegal 5011.1Sitojun * instruction to halt it in its tracks. 5021.1Sitojun */ 5031.1Sitojun sigexit(p, SIGILL); 5041.1Sitojun /* NOTREACHED */ 5051.1Sitojun } 5061.1Sitojun 5071.1Sitojun /* 5081.1Sitojun * Build context to run handler in. 5091.1Sitojun */ 5101.1Sitojun tf->tf_spc = (int)psp->ps_sigcode; 5111.1Sitojun#ifdef TODO 5121.1Sitojun tf->tf_ssr &= ~(PSL_T|PSL_VM|PSL_AC); 5131.1Sitojun#endif 5141.1Sitojun tf->tf_r15 = (int)fp; 5151.1Sitojun 5161.1Sitojun /* Remember that we're now on the signal stack. */ 5171.1Sitojun if (onstack) 5181.1Sitojun psp->ps_sigstk.ss_flags |= SS_ONSTACK; 5191.1Sitojun} 5201.1Sitojun 5211.1Sitojun/* 5221.1Sitojun * System call to cleanup state after a signal 5231.1Sitojun * has been taken. Reset signal mask and 5241.1Sitojun * stack state from context left by sendsig (above). 5251.1Sitojun * Return to previous pc and psl as specified by 5261.1Sitojun * context left by sendsig. Check carefully to 5271.1Sitojun * make sure that the user has not modified the 5281.1Sitojun * psl to gain improper privileges or to cause 5291.1Sitojun * a machine fault. 5301.1Sitojun */ 5311.1Sitojunint 5321.1Sitojunsys___sigreturn14(p, v, retval) 5331.1Sitojun struct proc *p; 5341.1Sitojun void *v; 5351.1Sitojun register_t *retval; 5361.1Sitojun{ 5371.1Sitojun struct sys___sigreturn14_args /* { 5381.1Sitojun syscallarg(struct sigcontext *) sigcntxp; 5391.1Sitojun } */ *uap = v; 5401.1Sitojun struct sigcontext *scp, context; 5411.1Sitojun struct trapframe *tf; 5421.1Sitojun 5431.1Sitojun /* 5441.1Sitojun * The trampoline code hands us the context. 5451.1Sitojun * It is unsafe to keep track of it ourselves, in the event that a 5461.1Sitojun * program jumps out of a signal handler. 5471.1Sitojun */ 5481.1Sitojun scp = SCARG(uap, sigcntxp); 5491.1Sitojun if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0) 5501.1Sitojun return (EFAULT); 5511.1Sitojun 5521.1Sitojun /* Restore signal context. */ 5531.1Sitojun tf = p->p_md.md_regs; 5541.1Sitojun { 5551.1Sitojun /* 5561.1Sitojun * Check for security violations. If we're returning to 5571.1Sitojun * protected mode, the CPU will validate the segment registers 5581.1Sitojun * automatically and generate a trap on violations. We handle 5591.1Sitojun * the trap, rather than doing all of the checking here. 5601.1Sitojun */ 5611.1Sitojun#ifdef TODO 5621.1Sitojun if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) { 5631.1Sitojun return (EINVAL); 5641.1Sitojun } 5651.1Sitojun#endif 5661.1Sitojun 5671.1Sitojun tf->tf_ssr = context.sc_ssr; 5681.1Sitojun } 5691.1Sitojun tf->tf_r0 = context.sc_r0; 5701.1Sitojun tf->tf_r1 = context.sc_r1; 5711.1Sitojun tf->tf_r2 = context.sc_r2; 5721.1Sitojun tf->tf_r3 = context.sc_r3; 5731.1Sitojun tf->tf_r4 = context.sc_r4; 5741.1Sitojun tf->tf_r5 = context.sc_r5; 5751.1Sitojun tf->tf_r6 = context.sc_r6; 5761.1Sitojun tf->tf_r7 = context.sc_r7; 5771.1Sitojun tf->tf_r8 = context.sc_r8; 5781.1Sitojun tf->tf_r9 = context.sc_r9; 5791.1Sitojun tf->tf_r10 = context.sc_r10; 5801.1Sitojun tf->tf_r11 = context.sc_r11; 5811.1Sitojun tf->tf_r12 = context.sc_r12; 5821.1Sitojun tf->tf_r13 = context.sc_r13; 5831.1Sitojun tf->tf_r14 = context.sc_r14; 5841.1Sitojun tf->tf_spc = context.sc_spc; 5851.1Sitojun tf->tf_r15 = context.sc_r15; 5861.1Sitojun tf->tf_pr = context.sc_pr; 5871.1Sitojun 5881.1Sitojun /* Restore signal stack. */ 5891.1Sitojun if (context.sc_onstack & SS_ONSTACK) 5901.1Sitojun p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; 5911.1Sitojun else 5921.1Sitojun p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; 5931.1Sitojun /* Restore signal mask. */ 5941.1Sitojun (void) sigprocmask1(p, SIG_SETMASK, &context.sc_mask, 0); 5951.1Sitojun 5961.1Sitojun return (EJUSTRETURN); 5971.1Sitojun} 5981.1Sitojun 5991.3Smsaitohint waittime = -1; 6001.3Smsaitohint cold = 1; 6011.1Sitojunstruct pcb dumppcb; 6021.1Sitojun 6031.1Sitojunvoid 6041.1Sitojuncpu_reboot(howto, bootstr) 6051.1Sitojun int howto; 6061.1Sitojun char *bootstr; 6071.1Sitojun{ 6081.1Sitojun 6091.1Sitojun if (cold) { 6101.1Sitojun howto |= RB_HALT; 6111.1Sitojun goto haltsys; 6121.1Sitojun } 6131.1Sitojun 6141.1Sitojun boothowto = howto; 6151.1Sitojun if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 6161.1Sitojun waittime = 0; 6171.1Sitojun vfs_shutdown(); 6181.1Sitojun /* 6191.1Sitojun * If we've been adjusting the clock, the todr 6201.1Sitojun * will be out of synch; adjust it now. 6211.1Sitojun */ 6221.1Sitojun /* resettodr(); */ 6231.1Sitojun } 6241.1Sitojun 6251.1Sitojun /* Disable interrupts. */ 6261.1Sitojun splhigh(); 6271.1Sitojun 6281.1Sitojun /* Do a dump if requested. */ 6291.1Sitojun if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 6301.1Sitojun dumpsys(); 6311.1Sitojun 6321.1Sitojunhaltsys: 6331.1Sitojun doshutdownhooks(); 6341.1Sitojun 6351.1Sitojun if (howto & RB_HALT) { 6361.1Sitojun printf("\n"); 6371.1Sitojun printf("The operating system has halted.\n"); 6381.1Sitojun printf("Please press any key to reboot.\n\n"); 6391.1Sitojun cngetc(); 6401.1Sitojun } 6411.1Sitojun 6421.1Sitojun printf("rebooting...\n"); 6431.1Sitojun cpu_reset(); 6441.1Sitojun for(;;) 6451.1Sitojun ; 6461.1Sitojun /*NOTREACHED*/ 6471.1Sitojun} 6481.1Sitojun 6491.1Sitojun/* 6501.1Sitojun * These variables are needed by /sbin/savecore 6511.1Sitojun */ 6521.1Sitojunu_long dumpmag = 0x8fca0101; /* magic number */ 6531.1Sitojunint dumpsize = 0; /* pages */ 6541.1Sitojunlong dumplo = 0; /* blocks */ 6551.1Sitojun 6561.1Sitojun/* 6571.1Sitojun * This is called by main to set dumplo and dumpsize. 6581.1Sitojun * Dumps always skip the first CLBYTES of disk space 6591.1Sitojun * in case there might be a disk label stored there. 6601.1Sitojun * If there is extra space, put dump at the end to 6611.1Sitojun * reduce the chance that swapping trashes it. 6621.1Sitojun */ 6631.1Sitojunvoid 6641.1Sitojuncpu_dumpconf() 6651.1Sitojun{ 6661.1Sitojun#ifdef TODO 6671.1Sitojun int nblks; /* size of dump area */ 6681.1Sitojun int maj; 6691.1Sitojun 6701.1Sitojun if (dumpdev == NODEV) 6711.1Sitojun return; 6721.1Sitojun maj = major(dumpdev); 6731.1Sitojun if (maj < 0 || maj >= nblkdev) 6741.1Sitojun panic("dumpconf: bad dumpdev=0x%x", dumpdev); 6751.1Sitojun if (bdevsw[maj].d_psize == NULL) 6761.1Sitojun return; 6771.1Sitojun nblks = (*bdevsw[maj].d_psize)(dumpdev); 6781.1Sitojun if (nblks <= ctod(1)) 6791.1Sitojun return; 6801.1Sitojun 6811.1Sitojun dumpsize = btoc(IOM_END + ctob(dumpmem_high)); 6821.1Sitojun 6831.1Sitojun /* Always skip the first CLBYTES, in case there is a label there. */ 6841.1Sitojun if (dumplo < ctod(1)) 6851.1Sitojun dumplo = ctod(1); 6861.1Sitojun 6871.1Sitojun /* Put dump at end of partition, and make it fit. */ 6881.1Sitojun if (dumpsize > dtoc(nblks - dumplo)) 6891.1Sitojun dumpsize = dtoc(nblks - dumplo); 6901.1Sitojun if (dumplo < nblks - ctod(dumpsize)) 6911.1Sitojun dumplo = nblks - ctod(dumpsize); 6921.1Sitojun#endif 6931.1Sitojun} 6941.1Sitojun 6951.1Sitojun/* 6961.1Sitojun * Doadump comes here after turning off memory management and 6971.1Sitojun * getting on the dump stack, either when called above, or by 6981.1Sitojun * the auto-restart code. 6991.1Sitojun */ 7001.1Sitojun#define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */ 7011.1Sitojunstatic vaddr_t dumpspace; 7021.1Sitojun 7031.1Sitojunvaddr_t 7041.1Sitojunreserve_dumppages(p) 7051.1Sitojun vaddr_t p; 7061.1Sitojun{ 7071.1Sitojun 7081.1Sitojun dumpspace = p; 7091.1Sitojun return (p + BYTES_PER_DUMP); 7101.1Sitojun} 7111.1Sitojun 7121.1Sitojunvoid 7131.1Sitojundumpsys() 7141.1Sitojun{ 7151.1Sitojun#ifdef TODO 7161.1Sitojun unsigned bytes, i, n; 7171.1Sitojun int maddr, psize; 7181.1Sitojun daddr_t blkno; 7191.1Sitojun int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 7201.1Sitojun int error; 7211.1Sitojun 7221.1Sitojun /* Save registers. */ 7231.1Sitojun savectx(&dumppcb); 7241.1Sitojun 7251.1Sitojun msgbufmapped = 0; /* don't record dump msgs in msgbuf */ 7261.1Sitojun if (dumpdev == NODEV) 7271.1Sitojun return; 7281.1Sitojun 7291.1Sitojun /* 7301.1Sitojun * For dumps during autoconfiguration, 7311.1Sitojun * if dump device has already configured... 7321.1Sitojun */ 7331.1Sitojun if (dumpsize == 0) 7341.1Sitojun cpu_dumpconf(); 7351.1Sitojun if (dumplo < 0) 7361.1Sitojun return; 7371.1Sitojun printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 7381.1Sitojun 7391.1Sitojun psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 7401.1Sitojun printf("dump "); 7411.1Sitojun if (psize == -1) { 7421.1Sitojun printf("area unavailable\n"); 7431.1Sitojun return; 7441.1Sitojun } 7451.1Sitojun 7461.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 7471.1Sitojun /* toss any characters present prior to dump */ 7481.1Sitojun while (sget() != NULL); /*syscons and pccons differ */ 7491.1Sitojun#endif 7501.1Sitojun 7511.1Sitojun bytes = ctob(dumpmem_high) + IOM_END; 7521.1Sitojun maddr = 0; 7531.1Sitojun blkno = dumplo; 7541.1Sitojun dump = bdevsw[major(dumpdev)].d_dump; 7551.1Sitojun error = 0; 7561.1Sitojun for (i = 0; i < bytes; i += n) { 7571.1Sitojun /* 7581.1Sitojun * Avoid dumping the ISA memory hole, and areas that 7591.1Sitojun * BIOS claims aren't in low memory. 7601.1Sitojun */ 7611.1Sitojun if (i >= ctob(dumpmem_low) && i < IOM_END) { 7621.1Sitojun n = IOM_END - i; 7631.1Sitojun maddr += n; 7641.1Sitojun blkno += btodb(n); 7651.1Sitojun continue; 7661.1Sitojun } 7671.1Sitojun 7681.1Sitojun /* Print out how many MBs we to go. */ 7691.1Sitojun n = bytes - i; 7701.1Sitojun if (n && (n % (1024*1024)) == 0) 7711.1Sitojun printf("%d ", n / (1024 * 1024)); 7721.1Sitojun 7731.1Sitojun /* Limit size for next transfer. */ 7741.1Sitojun if (n > BYTES_PER_DUMP) 7751.1Sitojun n = BYTES_PER_DUMP; 7761.1Sitojun 7771.1Sitojun (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); 7781.1Sitojun error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n); 7791.1Sitojun if (error) 7801.1Sitojun break; 7811.1Sitojun maddr += n; 7821.1Sitojun blkno += btodb(n); /* XXX? */ 7831.1Sitojun 7841.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 7851.1Sitojun /* operator aborting dump? */ 7861.1Sitojun if (sget() != NULL) { 7871.1Sitojun error = EINTR; 7881.1Sitojun break; 7891.1Sitojun } 7901.1Sitojun#endif 7911.1Sitojun } 7921.1Sitojun 7931.1Sitojun switch (error) { 7941.1Sitojun 7951.1Sitojun case ENXIO: 7961.1Sitojun printf("device bad\n"); 7971.1Sitojun break; 7981.1Sitojun 7991.1Sitojun case EFAULT: 8001.1Sitojun printf("device not ready\n"); 8011.1Sitojun break; 8021.1Sitojun 8031.1Sitojun case EINVAL: 8041.1Sitojun printf("area improper\n"); 8051.1Sitojun break; 8061.1Sitojun 8071.1Sitojun case EIO: 8081.1Sitojun printf("i/o error\n"); 8091.1Sitojun break; 8101.1Sitojun 8111.1Sitojun case EINTR: 8121.1Sitojun printf("aborted from console\n"); 8131.1Sitojun break; 8141.1Sitojun 8151.1Sitojun case 0: 8161.1Sitojun printf("succeeded\n"); 8171.1Sitojun break; 8181.1Sitojun 8191.1Sitojun default: 8201.1Sitojun printf("error %d\n", error); 8211.1Sitojun break; 8221.1Sitojun } 8231.1Sitojun printf("\n\n"); 8241.1Sitojun delay(5000000); /* 5 seconds */ 8251.1Sitojun#endif /* TODO */ 8261.1Sitojun} 8271.1Sitojun 8281.1Sitojun/* 8291.1Sitojun * Clear registers on exec 8301.1Sitojun */ 8311.1Sitojunvoid 8321.1Sitojunsetregs(p, pack, stack) 8331.1Sitojun struct proc *p; 8341.1Sitojun struct exec_package *pack; 8351.1Sitojun u_long stack; 8361.1Sitojun{ 8371.1Sitojun register struct pcb *pcb = &p->p_addr->u_pcb; 8381.1Sitojun register struct trapframe *tf; 8391.1Sitojun 8401.1Sitojun p->p_md.md_flags &= ~MDP_USEDFPU; 8411.1Sitojun pcb->pcb_flags = 0; 8421.1Sitojun 8431.1Sitojun tf = p->p_md.md_regs; 8441.1Sitojun 8451.1Sitojun tf->tf_r0 = 0; 8461.1Sitojun tf->tf_r1 = 0; 8471.1Sitojun tf->tf_r2 = 0; 8481.1Sitojun tf->tf_r3 = 0; 8491.1Sitojun tf->tf_r4 = *(int *)stack; /* argc */ 8501.1Sitojun tf->tf_r5 = stack+4; /* argv */ 8511.1Sitojun tf->tf_r6 = stack+4*tf->tf_r4 + 8; /* envp */ 8521.1Sitojun tf->tf_r7 = 0; 8531.1Sitojun tf->tf_r8 = 0; 8541.1Sitojun tf->tf_r9 = 0; 8551.1Sitojun tf->tf_r10 = 0; 8561.1Sitojun tf->tf_r11 = 0; 8571.1Sitojun tf->tf_r12 = 0; 8581.1Sitojun tf->tf_r13 = 0; 8591.1Sitojun tf->tf_r14 = 0; 8601.1Sitojun tf->tf_spc = pack->ep_entry; 8611.1Sitojun tf->tf_ssr = PSL_USERSET; 8621.1Sitojun tf->tf_r15 = stack; 8631.1Sitojun#ifdef TODO 8641.3Smsaitoh tf->tf_r9 = (int)PS_STRINGS; 8651.1Sitojun#endif 8661.1Sitojun} 8671.1Sitojun 8681.1Sitojun/* 8691.1Sitojun * Initialize segments and descriptor tables 8701.1Sitojun */ 8711.3Smsaitoh#define VBRINIT ((char *)0x8c000000) 8721.3Smsaitoh#define Trap100Vec (VBRINIT + 0x100) 8731.3Smsaitoh#define Trap600Vec (VBRINIT + 0x600) 8741.3Smsaitoh#define TLBVECTOR (VBRINIT + 0x400) 8751.3Smsaitoh#define VADDRSTART VM_MIN_KERNEL_ADDRESS 8761.3Smsaitoh 8771.3Smsaitohextern int nkpde; 8781.3Smsaitohextern char MonTrap100[], MonTrap100_end[]; 8791.3Smsaitohextern char MonTrap600[], MonTrap600_end[]; 8801.3Smsaitohextern char _start[], etext[], edata[], end[]; 8811.3Smsaitohextern char tlbmisshandler_stub[], tlbmisshandler_stub_end[]; 8821.1Sitojun 8831.1Sitojunvoid 8841.3SmsaitohinitSH3(pc) 8851.3Smsaitoh void *pc; /* XXX return address */ 8861.1Sitojun{ 8871.3Smsaitoh paddr_t avail; 8881.3Smsaitoh pd_entry_t *pagedir; 8891.3Smsaitoh pt_entry_t *pagetab, pte; 8901.3Smsaitoh u_int sp; 8911.3Smsaitoh int x; 8921.3Smsaitoh char *p; 8931.3Smsaitoh 8941.3Smsaitoh avail = sh3_round_page(end); 8951.3Smsaitoh 8961.4Smsaitoh /* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */ 8971.4Smsaitoh nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1); 8981.4Smsaitoh 8991.3Smsaitoh /* 9001.3Smsaitoh * clear .bss, .common area, page dir area, 9011.3Smsaitoh * process0 stack, page table area 9021.3Smsaitoh */ 9031.4Smsaitoh p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */ 9041.3Smsaitoh bzero(edata, p - edata); 9051.3Smsaitoh 9061.3Smsaitoh /* 9071.3Smsaitoh * install trap handler 9081.3Smsaitoh */ 9091.3Smsaitoh bcopy(MonTrap100, Trap100Vec, MonTrap100_end - MonTrap100); 9101.3Smsaitoh bcopy(MonTrap600, Trap600Vec, MonTrap600_end - MonTrap600); 9111.3Smsaitoh __asm ("ldc %0, vbr" :: "r"(VBRINIT)); 9121.3Smsaitoh 9131.3Smsaitoh/* 9141.3Smsaitoh * edata end 9151.3Smsaitoh * +-------------+------+-----+----------+-------------+------------+ 9161.3Smsaitoh * | kernel text | data | bss | Page Dir | Proc0 Stack | Page Table | 9171.3Smsaitoh * +-------------+------+-----+----------+-------------+------------+ 9181.4Smsaitoh * NBPG USPACE (1+nkpde)*NBPG 9191.3Smsaitoh * (= 4*NBPG) 9201.3Smsaitoh * Build initial page tables 9211.3Smsaitoh */ 9221.3Smsaitoh pagedir = (void *)avail; 9231.3Smsaitoh pagetab = (void *)(avail + SYSMAP); 9241.3Smsaitoh 9251.3Smsaitoh /* 9261.3Smsaitoh * Construct a page table directory 9271.3Smsaitoh * In SH3 H/W does not support PTD, 9281.3Smsaitoh * these structures are used by S/W. 9291.3Smsaitoh */ 9301.3Smsaitoh pte = (pt_entry_t)pagetab; 9311.3Smsaitoh pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N; 9321.3Smsaitoh pagedir[KERNTEXTOFF >> PDSHIFT] = pte; 9331.3Smsaitoh 9341.3Smsaitoh /* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000, 9351.3Smsaitoh 0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */ 9361.3Smsaitoh pte += NBPG; 9371.3Smsaitoh for (x = 0; x < nkpde; x++) { 9381.3Smsaitoh pagedir[(VADDRSTART >> PDSHIFT) + x] = pte; 9391.3Smsaitoh pte += NBPG; 9401.3Smsaitoh } 9411.3Smsaitoh 9421.3Smsaitoh /* Install a PDE recursively mapping page directory as a page table! */ 9431.3Smsaitoh pte = (u_int)pagedir; 9441.3Smsaitoh pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N; 9451.3Smsaitoh pagedir[PDSLOT_PTE] = pte; 9461.3Smsaitoh 9471.3Smsaitoh /* set PageDirReg */ 9481.3Smsaitoh SHREG_TTB = (u_int)pagedir; 9491.3Smsaitoh 9501.3Smsaitoh /* Set TLB miss handler */ 9511.3Smsaitoh p = tlbmisshandler_stub; 9521.3Smsaitoh x = tlbmisshandler_stub_end - p; 9531.3Smsaitoh bcopy(p, TLBVECTOR, x); 9541.3Smsaitoh 9551.3Smsaitoh /* 9561.3Smsaitoh * Activate MMU 9571.3Smsaitoh */ 9581.3Smsaitoh 9591.3Smsaitoh#define MMUCR_AT 0x0001 /* address traslation enable */ 9601.3Smsaitoh#define MMUCR_IX 0x0002 /* index mode */ 9611.3Smsaitoh#define MMUCR_TF 0x0004 /* TLB flush */ 9621.3Smsaitoh#define MMUCR_SV 0x0100 /* single virtual space mode */ 9631.3Smsaitoh 9641.3Smsaitoh SHREG_MMUCR = MMUCR_AT | MMUCR_TF | MMUCR_SV; 9651.3Smsaitoh 9661.3Smsaitoh /* 9671.3Smsaitoh * Now here is virtual address 9681.3Smsaitoh */ 9691.3Smsaitoh 9701.3Smsaitoh /* Set proc0paddr */ 9711.3Smsaitoh proc0paddr = (void *)(avail + NBPG); 9721.3Smsaitoh 9731.3Smsaitoh /* Set pcb->PageDirReg of proc0 */ 9741.3Smsaitoh proc0paddr->u_pcb.pageDirReg = (int)pagedir; 9751.3Smsaitoh 9761.3Smsaitoh /* avail_start is first available physical memory address */ 9771.3Smsaitoh avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde; 9781.3Smsaitoh 9791.3Smsaitoh /* atdevbase is first available logical memory address */ 9801.3Smsaitoh atdevbase = VADDRSTART; 9811.1Sitojun 9821.1Sitojun proc0.p_addr = proc0paddr; /* page dir address */ 9831.1Sitojun 9841.3Smsaitoh /* XXX: PMAP_NEW requires valid curpcb. also init'd in cpu_startup */ 9851.3Smsaitoh curpcb = &proc0.p_addr->u_pcb; 9861.3Smsaitoh 9871.1Sitojun /* 9881.1Sitojun * Initialize the I/O port and I/O mem extent maps. 9891.1Sitojun * Note: we don't have to check the return value since 9901.1Sitojun * creation of a fixed extent map will never fail (since 9911.1Sitojun * descriptor storage has already been allocated). 9921.1Sitojun * 9931.1Sitojun * N.B. The iomem extent manages _all_ physical addresses 9941.1Sitojun * on the machine. When the amount of RAM is found, the two 9951.1Sitojun * extents of RAM are allocated from the map (0 -> ISA hole 9961.1Sitojun * and end of ISA hole -> end of RAM). 9971.1Sitojun */ 9981.1Sitojun iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 9991.1Sitojun (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 10001.1Sitojun EX_NOCOALESCE|EX_NOWAIT); 10011.1Sitojun 10021.3Smsaitoh#if 0 10031.1Sitojun consinit(); /* XXX SHOULD NOT BE DONE HERE */ 10041.1Sitojun#endif 10051.1Sitojun 10061.1Sitojun splraise(-1); 10071.1Sitojun enable_intr(); 10081.1Sitojun 10091.1Sitojun avail_end = sh3_trunc_page(IOM_RAM_END + 1); 10101.1Sitojun 10111.1Sitojun printf("initSH3\r\n"); 10121.1Sitojun 10131.1Sitojun /* 10141.1Sitojun * Calculate check sum 10151.1Sitojun */ 10161.3Smsaitoh { 10171.3Smsaitoh u_short *p, sum; 10181.3Smsaitoh int size; 10191.3Smsaitoh 10201.3Smsaitoh size = etext - _start; 10211.3Smsaitoh p = (u_short *)_start; 10221.1Sitojun sum = 0; 10231.1Sitojun size >>= 1; 10241.1Sitojun while (size--) 10251.1Sitojun sum += *p++; 10261.3Smsaitoh printf("Check Sum = 0x%x\r\n", sum); 10271.3Smsaitoh } 10281.1Sitojun /* 10291.1Sitojun * Allocate the physical addresses used by RAM from the iomem 10301.1Sitojun * extent map. This is done before the addresses are 10311.1Sitojun * page rounded just to make sure we get them all. 10321.1Sitojun */ 10331.1Sitojun if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN, 10341.3Smsaitoh (IOM_RAM_END-IOM_RAM_BEGIN) + 1, 10351.1Sitojun EX_NOWAIT)) { 10361.1Sitojun /* XXX What should we do? */ 10371.1Sitojun printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n"); 10381.1Sitojun } 10391.1Sitojun 10401.1Sitojun /* number of pages of physmem addr space */ 10411.3Smsaitoh physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1); 10421.1Sitojun#ifdef TODO 10431.1Sitojun dumpmem = physmem; 10441.1Sitojun#endif 10451.1Sitojun 10461.1Sitojun /* 10471.1Sitojun * Initialize for pmap_free_pages and pmap_next_page. 10481.1Sitojun * These guys should be page-aligned. 10491.1Sitojun */ 10501.1Sitojun if (physmem < btoc(2 * 1024 * 1024)) { 10511.1Sitojun printf("warning: too little memory available; " 10521.1Sitojun "have %d bytes, want %d bytes\n" 10531.1Sitojun "running in degraded mode\n" 10541.1Sitojun "press a key to confirm\n\n", 10551.1Sitojun ctob(physmem), 2*1024*1024); 10561.1Sitojun cngetc(); 10571.1Sitojun } 10581.1Sitojun 10591.1Sitojun /* Call pmap initialization to make new kernel address space */ 10601.3Smsaitoh pmap_bootstrap(atdevbase); 10611.1Sitojun 10621.1Sitojun /* 10631.1Sitojun * Initialize error message buffer (at end of core). 10641.1Sitojun */ 10651.1Sitojun initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE)); 10661.1Sitojun 10671.1Sitojun /* 10681.1Sitojun * set boot device information 10691.1Sitojun */ 10701.1Sitojun setup_bootinfo(); 10711.1Sitojun 10721.1Sitojun#if 0 10731.1Sitojun sh3_cache_on(); 10741.1Sitojun#endif 10751.1Sitojun 10761.3Smsaitoh /* setup proc0 stack */ 10771.3Smsaitoh sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe); 10781.3Smsaitoh 10791.3Smsaitoh /* 10801.3Smsaitoh * XXX We can't return here, because we change stack pointer. 10811.3Smsaitoh * So jump to return address directly. 10821.3Smsaitoh */ 10831.3Smsaitoh __asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp)); 10841.1Sitojun} 10851.1Sitojun 10861.1Sitojunstruct queue { 10871.1Sitojun struct queue *q_next, *q_prev; 10881.1Sitojun}; 10891.1Sitojun 10901.1Sitojun/* 10911.1Sitojun * insert an element into a queue 10921.1Sitojun */ 10931.1Sitojunvoid 10941.1Sitojun_insque(v1, v2) 10951.1Sitojun void *v1; 10961.1Sitojun void *v2; 10971.1Sitojun{ 10981.1Sitojun struct queue *elem = v1, *head = v2; 10991.1Sitojun struct queue *next; 11001.1Sitojun 11011.1Sitojun next = head->q_next; 11021.1Sitojun elem->q_next = next; 11031.1Sitojun head->q_next = elem; 11041.1Sitojun elem->q_prev = head; 11051.1Sitojun next->q_prev = elem; 11061.1Sitojun} 11071.1Sitojun 11081.1Sitojun/* 11091.1Sitojun * remove an element from a queue 11101.1Sitojun */ 11111.1Sitojunvoid 11121.1Sitojun_remque(v) 11131.1Sitojun void *v; 11141.1Sitojun{ 11151.1Sitojun struct queue *elem = v; 11161.1Sitojun struct queue *next, *prev; 11171.1Sitojun 11181.1Sitojun next = elem->q_next; 11191.1Sitojun prev = elem->q_prev; 11201.1Sitojun next->q_prev = prev; 11211.1Sitojun prev->q_next = next; 11221.1Sitojun elem->q_prev = 0; 11231.1Sitojun} 11241.1Sitojun 11251.1Sitojun#ifdef COMPAT_NOMID 11261.1Sitojunstatic int 11271.1Sitojunexec_nomid(p, epp) 11281.1Sitojun struct proc *p; 11291.1Sitojun struct exec_package *epp; 11301.1Sitojun{ 11311.1Sitojun int error; 11321.1Sitojun u_long midmag, magic; 11331.1Sitojun u_short mid; 11341.1Sitojun struct exec *execp = epp->ep_hdr; 11351.1Sitojun 11361.1Sitojun /* check on validity of epp->ep_hdr performed by exec_out_makecmds */ 11371.1Sitojun 11381.1Sitojun midmag = ntohl(execp->a_midmag); 11391.1Sitojun mid = (midmag >> 16) & 0xffff; 11401.1Sitojun magic = midmag & 0xffff; 11411.1Sitojun 11421.1Sitojun if (magic == 0) { 11431.1Sitojun magic = (execp->a_midmag & 0xffff); 11441.1Sitojun mid = MID_ZERO; 11451.1Sitojun } 11461.1Sitojun 11471.1Sitojun midmag = mid << 16 | magic; 11481.1Sitojun 11491.1Sitojun switch (midmag) { 11501.1Sitojun case (MID_ZERO << 16) | ZMAGIC: 11511.1Sitojun /* 11521.1Sitojun * 386BSD's ZMAGIC format: 11531.1Sitojun */ 11541.1Sitojun error = exec_aout_prep_oldzmagic(p, epp); 11551.1Sitojun break; 11561.1Sitojun 11571.1Sitojun case (MID_ZERO << 16) | QMAGIC: 11581.1Sitojun /* 11591.1Sitojun * BSDI's QMAGIC format: 11601.1Sitojun * same as new ZMAGIC format, but with different magic number 11611.1Sitojun */ 11621.1Sitojun error = exec_aout_prep_zmagic(p, epp); 11631.1Sitojun break; 11641.1Sitojun 11651.1Sitojun case (MID_ZERO << 16) | NMAGIC: 11661.1Sitojun /* 11671.1Sitojun * BSDI's NMAGIC format: 11681.1Sitojun * same as NMAGIC format, but with different magic number 11691.1Sitojun * and with text starting at 0. 11701.1Sitojun */ 11711.1Sitojun error = exec_aout_prep_oldnmagic(p, epp); 11721.1Sitojun break; 11731.1Sitojun 11741.1Sitojun case (MID_ZERO << 16) | OMAGIC: 11751.1Sitojun /* 11761.1Sitojun * BSDI's OMAGIC format: 11771.1Sitojun * same as OMAGIC format, but with different magic number 11781.1Sitojun * and with text starting at 0. 11791.1Sitojun */ 11801.1Sitojun error = exec_aout_prep_oldomagic(p, epp); 11811.1Sitojun break; 11821.1Sitojun 11831.1Sitojun default: 11841.1Sitojun error = ENOEXEC; 11851.1Sitojun } 11861.1Sitojun 11871.1Sitojun return error; 11881.1Sitojun} 11891.1Sitojun#endif 11901.1Sitojun 11911.1Sitojun/* 11921.1Sitojun * cpu_exec_aout_makecmds(): 11931.1Sitojun * cpu-dependent a.out format hook for execve(). 11941.1Sitojun * 11951.1Sitojun * Determine of the given exec package refers to something which we 11961.1Sitojun * understand and, if so, set up the vmcmds for it. 11971.1Sitojun * 11981.1Sitojun * On the i386, old (386bsd) ZMAGIC binaries and BSDI QMAGIC binaries 11991.1Sitojun * if COMPAT_NOMID is given as a kernel option. 12001.1Sitojun */ 12011.1Sitojunint 12021.1Sitojuncpu_exec_aout_makecmds(p, epp) 12031.1Sitojun struct proc *p; 12041.1Sitojun struct exec_package *epp; 12051.1Sitojun{ 12061.1Sitojun int error = ENOEXEC; 12071.1Sitojun 12081.1Sitojun#ifdef COMPAT_NOMID 12091.1Sitojun if ((error = exec_nomid(p, epp)) == 0) 12101.1Sitojun return error; 12111.1Sitojun#endif /* ! COMPAT_NOMID */ 12121.1Sitojun 12131.1Sitojun return error; 12141.1Sitojun} 12151.1Sitojun 12161.1Sitojunvoid 12171.1Sitojunsetup_bootinfo(void) 12181.1Sitojun{ 12191.1Sitojun struct btinfo_bootdisk *help; 12201.1Sitojun 12211.1Sitojun *(int *)bootinfo = 1; 12221.1Sitojun help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int)); 12231.1Sitojun help->biosdev = 0; 12241.1Sitojun help->partition = 0; 12251.1Sitojun ((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk); 12261.1Sitojun ((struct btinfo_common *)help)->type = BTINFO_BOOTDISK; 12271.1Sitojun} 12281.1Sitojun 12291.1Sitojunvoid * 12301.1Sitojunlookup_bootinfo(type) 12311.1Sitojun int type; 12321.1Sitojun{ 12331.1Sitojun struct btinfo_common *help; 12341.1Sitojun int n = *(int*)bootinfo; 12351.1Sitojun help = (struct btinfo_common *)(bootinfo + sizeof(int)); 12361.1Sitojun while (n--) { 12371.1Sitojun if (help->type == type) 12381.1Sitojun return (help); 12391.1Sitojun help = (struct btinfo_common *)((char*)help + help->len); 12401.1Sitojun } 12411.1Sitojun return (0); 12421.1Sitojun} 12431.1Sitojun 12441.1Sitojun 12451.1Sitojun/* 12461.1Sitojun * consinit: 12471.1Sitojun * initialize the system console. 12481.1Sitojun * XXX - shouldn't deal with this initted thing, but then, 12491.1Sitojun * it shouldn't be called from init386 either. 12501.1Sitojun */ 12511.1Sitojunvoid 12521.1Sitojunconsinit() 12531.1Sitojun{ 12541.1Sitojun static int initted; 12551.1Sitojun 12561.1Sitojun if (initted) 12571.1Sitojun return; 12581.1Sitojun initted = 1; 12591.1Sitojun 12601.1Sitojun cninit(); 12611.1Sitojun 12621.1Sitojun#ifdef DDB 12631.1Sitojun ddb_init(); 12641.1Sitojun#endif 12651.1Sitojun} 12661.1Sitojun 12671.1Sitojunvoid 12681.1Sitojuncpu_reset() 12691.1Sitojun{ 12701.1Sitojun 12711.1Sitojun disable_intr(); 12721.1Sitojun 12731.1Sitojun Sh3Reset(); 12741.1Sitojun for (;;) 12751.1Sitojun ; 12761.1Sitojun} 12771.1Sitojun 12781.1Sitojunint 12791.1Sitojunbus_space_map (t, addr, size, flags, bshp) 12801.1Sitojun bus_space_tag_t t; 12811.1Sitojun bus_addr_t addr; 12821.1Sitojun bus_size_t size; 12831.1Sitojun int flags; 12841.1Sitojun bus_space_handle_t *bshp; 12851.1Sitojun{ 12861.1Sitojun 12871.1Sitojun *bshp = (bus_space_handle_t)addr; 12881.1Sitojun 12891.1Sitojun return 0; 12901.1Sitojun} 12911.1Sitojun 12921.1Sitojunint 12931.1Sitojunsh_memio_subregion(t, bsh, offset, size, nbshp) 12941.1Sitojun bus_space_tag_t t; 12951.1Sitojun bus_space_handle_t bsh; 12961.1Sitojun bus_size_t offset, size; 12971.1Sitojun bus_space_handle_t *nbshp; 12981.1Sitojun{ 12991.1Sitojun 13001.1Sitojun *nbshp = bsh + offset; 13011.1Sitojun return (0); 13021.1Sitojun} 13031.1Sitojun 13041.1Sitojunint 13051.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, 13061.1Sitojun bpap, bshp) 13071.1Sitojun bus_space_tag_t t; 13081.1Sitojun bus_addr_t rstart, rend; 13091.1Sitojun bus_size_t size, alignment, boundary; 13101.1Sitojun int flags; 13111.1Sitojun bus_addr_t *bpap; 13121.1Sitojun bus_space_handle_t *bshp; 13131.1Sitojun{ 13141.1Sitojun *bshp = *bpap = rstart; 13151.1Sitojun 13161.1Sitojun return (0); 13171.1Sitojun} 13181.1Sitojun 13191.1Sitojunvoid 13201.1Sitojunsh_memio_free(t, bsh, size) 13211.1Sitojun bus_space_tag_t t; 13221.1Sitojun bus_space_handle_t bsh; 13231.1Sitojun bus_size_t size; 13241.1Sitojun{ 13251.1Sitojun 13261.1Sitojun} 13271.1Sitojun 13281.1Sitojunvoid 13291.1Sitojunsh_memio_unmap(t, bsh, size) 13301.1Sitojun bus_space_tag_t t; 13311.1Sitojun bus_space_handle_t bsh; 13321.1Sitojun bus_size_t size; 13331.1Sitojun{ 13341.1Sitojun return; 13351.1Sitojun} 13361.1Sitojun 13371.1Sitojun/* 13381.1Sitojun * InitializeBsc 13391.1Sitojun * : BSC(Bus State Controler) 13401.1Sitojun */ 13411.1Sitojunvoid InitializeBsc __P((void)); 13421.1Sitojun 13431.1Sitojunvoid 13441.1SitojunInitializeBsc() 13451.1Sitojun{ 13461.1Sitojun 13471.1Sitojun /* 13481.1Sitojun * Drive RAS,CAS in stand by mode and bus release mode 13491.1Sitojun * Area0 = Normal memory, Area5,6=Normal(no burst) 13501.1Sitojun * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory 13511.1Sitojun * Area4 = Normal Memory 13521.1Sitojun * Area6 = Normal memory 13531.1Sitojun */ 13541.3Smsaitoh SHREG_BCR1 = BSC_BCR1_VAL; 13551.1Sitojun 13561.1Sitojun /* 13571.1Sitojun * Bus Width 13581.1Sitojun * Area4: Bus width = 16bit 13591.1Sitojun * Area6,5 = 16bit 13601.1Sitojun * Area1 = 8bit 13611.1Sitojun * Area2,3: Bus width = 32bit 13621.1Sitojun */ 13631.3Smsaitoh SHREG_BCR2 = BSC_BCR2_VAL; 13641.1Sitojun 13651.1Sitojun /* 13661.1Sitojun * Idle cycle number in transition area and read to write 13671.1Sitojun * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 13681.1Sitojun * Area1 = 3, Area0 = 3 13691.1Sitojun */ 13701.3Smsaitoh SHREG_WCR1 = BSC_WCR1_VAL; 13711.1Sitojun 13721.1Sitojun /* 13731.1Sitojun * Wait cycle 13741.1Sitojun * Area 6 = 6 13751.1Sitojun * Area 5 = 2 13761.1Sitojun * Area 4 = 10 13771.1Sitojun * Area 3 = 3 13781.1Sitojun * Area 2,1 = 3 13791.1Sitojun * Area 0 = 6 13801.1Sitojun */ 13811.3Smsaitoh SHREG_WCR2 = BSC_WCR2_VAL; 13821.1Sitojun 13831.1Sitojun#ifdef SH4 13841.3Smsaitoh SHREG_WCR3 = BSC_WCR3_VAL; 13851.1Sitojun#endif 13861.1Sitojun 13871.1Sitojun /* 13881.1Sitojun * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 13891.1Sitojun * write pre-charge=1cycle 13901.1Sitojun * CAS before RAS refresh RAS assert time = 3 cycle 13911.1Sitojun * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON 13921.1Sitojun * CAS before RAS refresh ON, EDO DRAM 13931.1Sitojun */ 13941.3Smsaitoh SHREG_MCR = BSC_MCR_VAL; 13951.1Sitojun 13961.1Sitojun#ifdef BSC_SDMR_VAL 13971.1Sitojun#if 1 13981.1Sitojun#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 13991.1Sitojun 14001.1Sitojun SDMR = 0; 14011.1Sitojun#else 14021.1Sitojun#define ADDSET (*(volatile unsigned short *)0x1A000000) 14031.1Sitojun#define ADDRST (*(volatile unsigned short *)0x18000000) 14041.1Sitojun#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 14051.1Sitojun 14061.1Sitojun ADDSET = 0; 14071.1Sitojun SDMR = 0; 14081.1Sitojun ADDRST = 0; 14091.1Sitojun#endif 14101.1Sitojun#endif 14111.1Sitojun 14121.1Sitojun /* 14131.1Sitojun * PCMCIA Control Register 14141.1Sitojun * OE/WE assert delay 3.5 cycle 14151.1Sitojun * OE/WE negate-address delay 3.5 cycle 14161.1Sitojun */ 14171.1Sitojun#ifdef BSC_PCR_VAL 14181.3Smsaitoh SHREG_PCR = 0x00ff; 14191.1Sitojun#endif 14201.1Sitojun 14211.1Sitojun /* 14221.1Sitojun * Refresh Timer Control/Status Register 14231.1Sitojun * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 14241.1Sitojun * Count Limit = 1024 14251.1Sitojun * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 14261.1Sitojun * is the rule of SH3 in writing these register. 14271.1Sitojun */ 14281.3Smsaitoh SHREG_RTCSR = BSC_RTCSR_VAL; 14291.1Sitojun 14301.1Sitojun 14311.1Sitojun /* 14321.1Sitojun * Refresh Timer Counter 14331.1Sitojun * Initialize to 0 14341.1Sitojun */ 14351.3Smsaitoh SHREG_RTCNT = BSC_RTCNT_VAL; 14361.1Sitojun 14371.1Sitojun /* set Refresh Time Constant Register */ 14381.3Smsaitoh SHREG_RTCOR = BSC_RTCOR_VAL; 14391.1Sitojun 14401.1Sitojun /* init Refresh Count Register */ 14411.1Sitojun#ifdef BSC_RFCR_VAL 14421.3Smsaitoh SHREG_RFCR = BSC_RFCR_VAL; 14431.1Sitojun#endif 14441.1Sitojun 14451.1Sitojun /* Set Clock mode (make internal clock double speed) */ 14461.1Sitojun 14471.1Sitojun SHREG_FRQCR = FRQCR_VAL; 14481.1Sitojun 14491.1Sitojun#ifndef MMEYE_NO_CACHE 14501.1Sitojun /* Cache ON */ 14511.1Sitojun SHREG_CCR = 0x0001; 14521.1Sitojun#endif 14531.1Sitojun} 14541.1Sitojun 14551.1Sitojunvoid 14561.1Sitojunsh3_cache_on(void) 14571.1Sitojun{ 14581.1Sitojun#ifndef MMEYE_NO_CACHE 14591.1Sitojun /* Cache ON */ 14601.1Sitojun SHREG_CCR = 0x0001; 14611.1Sitojun SHREG_CCR = 0x0009; /* cache clear */ 14621.1Sitojun SHREG_CCR = 0x0001; /* cache on */ 14631.1Sitojun#endif 14641.1Sitojun} 14651.1Sitojun 14661.1Sitojun#include <machine/mmeye.h> 14671.1Sitojunvoid 14681.3SmsaitohLoadAndReset(osimage) 14691.3Smsaitoh char *osimage; 14701.1Sitojun{ 14711.1Sitojun void *buf_addr; 14721.1Sitojun u_long size; 14731.1Sitojun u_long *src; 14741.1Sitojun u_long *dest; 14751.1Sitojun u_long csum = 0; 14761.1Sitojun u_long csum2 = 0; 14771.1Sitojun u_long size2; 14781.1Sitojun#define OSIMAGE_BUF_ADDR 0x8c400000 /* !!!!!! This value depends on physical 14791.1Sitojun available memory */ 14801.1Sitojun 14811.1Sitojun 14821.3Smsaitoh printf("LoadAndReset: copy start\n"); 14831.1Sitojun buf_addr = (void *)OSIMAGE_BUF_ADDR; 14841.1Sitojun 14851.1Sitojun size = *(u_long *)osimage; 14861.1Sitojun src = (u_long *)osimage; 14871.1Sitojun dest = buf_addr; 14881.1Sitojun 14891.3Smsaitoh size = (size + sizeof(u_long) * 2 + 3) >> 2; 14901.1Sitojun size2 = size; 14911.1Sitojun 14921.3Smsaitoh while (size--) { 14931.1Sitojun csum += *src; 14941.1Sitojun *dest++ = *src++; 14951.1Sitojun } 14961.1Sitojun 14971.1Sitojun dest = buf_addr; 14981.1Sitojun while (size2--) 14991.1Sitojun csum2 += *dest++; 15001.1Sitojun 15011.3Smsaitoh printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2); 15021.1Sitojun printf("start XLoadAndReset\n"); 15031.1Sitojun 15041.1Sitojun /* mask all externel interrupt (XXX) */ 15051.1Sitojun 15061.1Sitojun XLoadAndReset(buf_addr); 15071.1Sitojun} 1508