machdep.c revision 1.1
11.1Sitojun/* $NetBSD: machdep.c,v 1.1 1999/09/13 10:30:26 itojun 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_bufcache.h" 791.1Sitojun#include "opt_compat_netbsd.h" 801.1Sitojun#include "opt_ddb.h" 811.1Sitojun#include "opt_memsize.h" 821.1Sitojun#include "opt_initbsc.h" 831.1Sitojun#include "opt_sysv.h" 841.1Sitojun 851.1Sitojun#include <sys/param.h> 861.1Sitojun#include <sys/systm.h> 871.1Sitojun#include <sys/signalvar.h> 881.1Sitojun#include <sys/kernel.h> 891.1Sitojun#include <sys/map.h> 901.1Sitojun#include <sys/proc.h> 911.1Sitojun#include <sys/user.h> 921.1Sitojun#include <sys/exec.h> 931.1Sitojun#include <sys/buf.h> 941.1Sitojun#include <sys/reboot.h> 951.1Sitojun#include <sys/conf.h> 961.1Sitojun#include <sys/file.h> 971.1Sitojun#include <sys/callout.h> 981.1Sitojun#include <sys/malloc.h> 991.1Sitojun#include <sys/mbuf.h> 1001.1Sitojun#include <sys/msgbuf.h> 1011.1Sitojun#include <sys/mount.h> 1021.1Sitojun#include <sys/vnode.h> 1031.1Sitojun#include <sys/device.h> 1041.1Sitojun#include <sys/extent.h> 1051.1Sitojun#include <sys/syscallargs.h> 1061.1Sitojun#ifdef SYSVMSG 1071.1Sitojun#include <sys/msg.h> 1081.1Sitojun#endif 1091.1Sitojun#ifdef SYSVSEM 1101.1Sitojun#include <sys/sem.h> 1111.1Sitojun#endif 1121.1Sitojun#ifdef SYSVSHM 1131.1Sitojun#include <sys/shm.h> 1141.1Sitojun#endif 1151.1Sitojun 1161.1Sitojun#ifdef KGDB 1171.1Sitojun#include <sys/kgdb.h> 1181.1Sitojun#endif 1191.1Sitojun 1201.1Sitojun#include <dev/cons.h> 1211.1Sitojun 1221.1Sitojun#include <vm/vm.h> 1231.1Sitojun#include <vm/vm_kern.h> 1241.1Sitojun#include <vm/vm_page.h> 1251.1Sitojun 1261.1Sitojun#include <uvm/uvm_extern.h> 1271.1Sitojun 1281.1Sitojun#include <sys/sysctl.h> 1291.1Sitojun 1301.1Sitojun#include <machine/cpu.h> 1311.1Sitojun#include <machine/cpufunc.h> 1321.1Sitojun#include <machine/psl.h> 1331.1Sitojun#include <machine/bootinfo.h> 1341.1Sitojun#include <machine/bus.h> 1351.1Sitojun#include <sh3/bscreg.h> 1361.1Sitojun#include <sh3/ccrreg.h> 1371.1Sitojun#include <sh3/cpgreg.h> 1381.1Sitojun#include <sh3/intcreg.h> 1391.1Sitojun#include <sh3/pfcreg.h> 1401.1Sitojun#include <sh3/wdtreg.h> 1411.1Sitojun 1421.1Sitojun#include <sys/termios.h> 1431.1Sitojun#include "sci.h" 1441.1Sitojun 1451.1Sitojun/* the following is used externally (sysctl_hw) */ 1461.1Sitojunchar machine[] = MACHINE; /* cpu "architecture" */ 1471.1Sitojunchar machine_arch[] = MACHINE_ARCH; /* machine_arch = "sh3" */ 1481.1Sitojun 1491.1Sitojun#ifdef sh3_debug 1501.1Sitojunint cpu_debug_mode = 1; 1511.1Sitojun#else 1521.1Sitojunint cpu_debug_mode = 0; 1531.1Sitojun#endif 1541.1Sitojun 1551.1Sitojunchar cpu_model[120]; 1561.1Sitojun 1571.1Sitojunchar bootinfo[BOOTINFO_MAXSIZE]; 1581.1Sitojun 1591.1Sitojun/* 1601.1Sitojun * Declare these as initialized data so we can patch them. 1611.1Sitojun */ 1621.1Sitojunint nswbuf = 0; 1631.1Sitojun#ifdef NBUF 1641.1Sitojunint nbuf = NBUF; 1651.1Sitojun#else 1661.1Sitojunint nbuf = 0; 1671.1Sitojun#endif 1681.1Sitojun#ifdef BUFPAGES 1691.1Sitojunint bufpages = BUFPAGES; 1701.1Sitojun#else 1711.1Sitojunint bufpages = 0; 1721.1Sitojun#endif 1731.1Sitojun#ifdef BUFCACHE 1741.1Sitojunint bufcache = BUFCACHE; /* % of RAM to use for buffer cache */ 1751.1Sitojun#else 1761.1Sitojunint bufcache = 0; /* fallback to old algorithm */ 1771.1Sitojun#endif 1781.1Sitojun 1791.1Sitojunint physmem; 1801.1Sitojunint dumpmem_low; 1811.1Sitojunint dumpmem_high; 1821.1Sitojunextern int boothowto; 1831.1Sitojunint cpu_class; 1841.1Sitojun 1851.1Sitojunpaddr_t msgbuf_paddr; 1861.1Sitojun 1871.1Sitojunvm_map_t exec_map = NULL; 1881.1Sitojunvm_map_t mb_map = NULL; 1891.1Sitojunvm_map_t phys_map = NULL; 1901.1Sitojun 1911.1Sitojunextern paddr_t avail_start, avail_end; 1921.1Sitojunextern u_long atdevbase; 1931.1Sitojunextern int etext,_start; 1941.1Sitojun 1951.1Sitojun#ifdef SYSCALL_DEBUG 1961.1Sitojun#define SCDEBUG_ALL 0x0004 1971.1Sitojunextern int scdebug; 1981.1Sitojun#endif 1991.1Sitojun 2001.1Sitojun#define IOM_RAM_END ((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1) 2011.1Sitojun 2021.1Sitojun/* 2031.1Sitojun * Extent maps to manage I/O and ISA memory hole space. Allocate 2041.1Sitojun * storage for 8 regions in each, initially. Later, ioport_malloc_safe 2051.1Sitojun * will indicate that it's safe to use malloc() to dynamically allocate 2061.1Sitojun * region descriptors. 2071.1Sitojun * 2081.1Sitojun * N.B. At least two regions are _always_ allocated from the iomem 2091.1Sitojun * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 2101.1Sitojun * 2111.1Sitojun * The extent maps are not static! Machine-dependent ISA and EISA 2121.1Sitojun * routines need access to them for bus address space allocation. 2131.1Sitojun */ 2141.1Sitojunstatic long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 2151.1Sitojunstruct extent *ioport_ex; 2161.1Sitojunstruct extent *iomem_ex; 2171.1Sitojunstatic int ioport_malloc_safe; 2181.1Sitojun 2191.1Sitojunvoid setup_bootinfo __P((void)); 2201.1Sitojuncaddr_t allocsys __P((caddr_t)); 2211.1Sitojunvoid dumpsys __P((void)); 2221.1Sitojunvoid identifycpu __P((void)); 2231.1Sitojunvoid initSH3 __P((vaddr_t)); 2241.1Sitojunvoid InitializeSci __P((unsigned char)); 2251.1Sitojunvoid Send16550 __P((int c)); 2261.1Sitojunvoid Init16550 __P((void)); 2271.1Sitojunvoid sh3_cache_on __P((void)); 2281.1Sitojunvoid LoadAndReset __P((char *osimage)); 2291.1Sitojunvoid XLoadAndReset __P((char *osimage)); 2301.1Sitojunvoid Sh3Reset __P((void)); 2311.1Sitojun 2321.1Sitojun#include <dev/ic/comreg.h> 2331.1Sitojun#include <dev/ic/comvar.h> 2341.1Sitojun 2351.1Sitojunvoid consinit __P((void)); 2361.1Sitojun 2371.1Sitojun#ifdef COMPAT_NOMID 2381.1Sitojunstatic int exec_nomid __P((struct proc *, struct exec_package *)); 2391.1Sitojun#endif 2401.1Sitojun 2411.1Sitojun 2421.1Sitojun 2431.1Sitojun/* 2441.1Sitojun * Machine-dependent startup code 2451.1Sitojun * 2461.1Sitojun * This is called from main() in kern/main.c. 2471.1Sitojun */ 2481.1Sitojunvoid 2491.1Sitojuncpu_startup() 2501.1Sitojun{ 2511.1Sitojun unsigned i; 2521.1Sitojun caddr_t v; 2531.1Sitojun int sz; 2541.1Sitojun int base, residual; 2551.1Sitojun vaddr_t minaddr, maxaddr; 2561.1Sitojun vsize_t size; 2571.1Sitojun struct pcb *pcb; 2581.1Sitojun /* int x; */ 2591.1Sitojun 2601.1Sitojun printf(version); 2611.1Sitojun 2621.1Sitojun sprintf(cpu_model, "Hitachi SH3"); 2631.1Sitojun 2641.1Sitojun printf("real mem = %d\n", ctob(physmem)); 2651.1Sitojun 2661.1Sitojun /* 2671.1Sitojun * Find out how much space we need, allocate it, 2681.1Sitojun * and then give everything true virtual addresses. 2691.1Sitojun */ 2701.1Sitojun sz = (int)allocsys((caddr_t)0); 2711.1Sitojun if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0) 2721.1Sitojun panic("startup: no room for tables"); 2731.1Sitojun if (allocsys(v) - v != sz) 2741.1Sitojun panic("startup: table size inconsistency"); 2751.1Sitojun 2761.1Sitojun /* 2771.1Sitojun * Now allocate buffers proper. They are different than the above 2781.1Sitojun * in that they usually occupy more virtual memory than physical. 2791.1Sitojun */ 2801.1Sitojun size = MAXBSIZE * nbuf; 2811.1Sitojun buffers = 0; 2821.1Sitojun if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size), 2831.1Sitojun NULL, UVM_UNKNOWN_OFFSET, 2841.1Sitojun UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 2851.1Sitojun UVM_ADV_NORMAL, 0)) != KERN_SUCCESS) 2861.1Sitojun panic("cpu_startup: cannot allocate VM for buffers"); 2871.1Sitojun minaddr = (vaddr_t)buffers; 2881.1Sitojun 2891.1Sitojun if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { 2901.1Sitojun /* don't want to alloc more physical mem than needed */ 2911.1Sitojun bufpages = btoc(MAXBSIZE) * nbuf; 2921.1Sitojun } 2931.1Sitojun 2941.1Sitojun base = bufpages / nbuf; 2951.1Sitojun residual = bufpages % nbuf; 2961.1Sitojun 2971.1Sitojun for (i = 0; i < nbuf; i++) { 2981.1Sitojun vsize_t curbufsize; 2991.1Sitojun vaddr_t curbuf; 3001.1Sitojun struct vm_page *pg; 3011.1Sitojun 3021.1Sitojun /* 3031.1Sitojun * Each buffer has MAXBSIZE bytes of VM space allocated. Of 3041.1Sitojun * that MAXBSIZE space, we allocate and map (base+1) pages 3051.1Sitojun * for the first "residual" buffers, and then we allocate 3061.1Sitojun * "base" pages for the rest. 3071.1Sitojun */ 3081.1Sitojun curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 3091.1Sitojun curbufsize = CLBYTES * ((i < residual) ? (base+1) : base); 3101.1Sitojun 3111.1Sitojun while (curbufsize) { 3121.1Sitojun /* 3131.1Sitojun * Attempt to allocate buffers from the first 3141.1Sitojun * 16M of RAM to avoid bouncing file system 3151.1Sitojun * transfers. 3161.1Sitojun */ 3171.1Sitojun pg = uvm_pagealloc(NULL, 0, NULL, 0); 3181.1Sitojun if (pg == NULL) 3191.1Sitojun panic("cpu_startup: not enough memory for " 3201.1Sitojun "buffer cache"); 3211.1Sitojun#if defined(PMAP_NEW) 3221.1Sitojun pmap_kenter_pgs(curbuf, &pg, 1); 3231.1Sitojun#else 3241.1Sitojun pmap_enter(kernel_map->pmap, curbuf, 3251.1Sitojun VM_PAGE_TO_PHYS(pg), VM_PROT_ALL, TRUE, 3261.1Sitojun VM_PROT_ALL); 3271.1Sitojun#endif 3281.1Sitojun curbuf += PAGE_SIZE; 3291.1Sitojun curbufsize -= PAGE_SIZE; 3301.1Sitojun } 3311.1Sitojun } 3321.1Sitojun 3331.1Sitojun /* 3341.1Sitojun * Allocate a submap for exec arguments. This map effectively 3351.1Sitojun * limits the number of processes exec'ing at any time. 3361.1Sitojun */ 3371.1Sitojun exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 3381.1Sitojun 16*NCARGS, TRUE, FALSE, NULL); 3391.1Sitojun 3401.1Sitojun /* 3411.1Sitojun * Allocate a submap for physio 3421.1Sitojun */ 3431.1Sitojun phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 3441.1Sitojun VM_PHYS_SIZE, TRUE, FALSE, NULL); 3451.1Sitojun 3461.1Sitojun /* 3471.1Sitojun * Finally, allocate mbuf cluster submap. 3481.1Sitojun */ 3491.1Sitojun mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 3501.1Sitojun VM_MBUF_SIZE, FALSE, FALSE, NULL); 3511.1Sitojun 3521.1Sitojun /* 3531.1Sitojun * Initialize callouts 3541.1Sitojun */ 3551.1Sitojun callfree = callout; 3561.1Sitojun for (i = 1; i < ncallout; i++) 3571.1Sitojun callout[i-1].c_next = &callout[i]; 3581.1Sitojun 3591.1Sitojun printf("avail mem = %ld\n", ptoa(uvmexp.free)); 3601.1Sitojun printf("using %d buffers containing %d bytes of memory\n", 3611.1Sitojun nbuf, bufpages * CLBYTES); 3621.1Sitojun 3631.1Sitojun /* 3641.1Sitojun * Set up buffers, so they can be used to read disk labels. 3651.1Sitojun */ 3661.1Sitojun bufinit(); 3671.1Sitojun 3681.1Sitojun /* Safe for i/o port allocation to use malloc now. */ 3691.1Sitojun ioport_malloc_safe = 1; 3701.1Sitojun 3711.1Sitojun curpcb = pcb = &proc0.p_addr->u_pcb; 3721.1Sitojun pcb->r15 = (int)proc0.p_addr + USPACE - 16; 3731.1Sitojun 3741.1Sitojun proc0.p_md.md_regs = (struct trapframe *)pcb->r15 - 1; 3751.1Sitojun 3761.1Sitojun#ifdef SYSCALL_DEBUG 3771.1Sitojun scdebug |= SCDEBUG_ALL; 3781.1Sitojun#endif 3791.1Sitojun 3801.1Sitojun#if 0 3811.1Sitojun boothowto |= RB_SINGLE; 3821.1Sitojun#endif 3831.1Sitojun} 3841.1Sitojun 3851.1Sitojun/* 3861.1Sitojun * Allocate space for system data structures. We are given 3871.1Sitojun * a starting virtual address and we return a final virtual 3881.1Sitojun * address; along the way we set each data structure pointer. 3891.1Sitojun * 3901.1Sitojun * We call allocsys() with 0 to find out how much space we want, 3911.1Sitojun * allocate that much and fill it with zeroes, and then call 3921.1Sitojun * allocsys() again with the correct base virtual address. 3931.1Sitojun */ 3941.1Sitojuncaddr_t 3951.1Sitojunallocsys(v) 3961.1Sitojun caddr_t v; 3971.1Sitojun{ 3981.1Sitojun 3991.1Sitojun#define valloc(name, type, num) \ 4001.1Sitojun v = (caddr_t)(((name) = (type *)v) + (num)) 4011.1Sitojun#ifdef REAL_CLISTS 4021.1Sitojun valloc(cfree, struct cblock, nclist); 4031.1Sitojun#endif 4041.1Sitojun valloc(callout, struct callout, ncallout); 4051.1Sitojun#ifdef SYSVSHM 4061.1Sitojun valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 4071.1Sitojun#endif 4081.1Sitojun#ifdef SYSVSEM 4091.1Sitojun valloc(sema, struct semid_ds, seminfo.semmni); 4101.1Sitojun valloc(sem, struct sem, seminfo.semmns); 4111.1Sitojun /* This is pretty disgusting! */ 4121.1Sitojun valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 4131.1Sitojun#endif 4141.1Sitojun#ifdef SYSVMSG 4151.1Sitojun valloc(msgpool, char, msginfo.msgmax); 4161.1Sitojun valloc(msgmaps, struct msgmap, msginfo.msgseg); 4171.1Sitojun valloc(msghdrs, struct msg, msginfo.msgtql); 4181.1Sitojun valloc(msqids, struct msqid_ds, msginfo.msgmni); 4191.1Sitojun#endif 4201.1Sitojun 4211.1Sitojun /* 4221.1Sitojun * If necessary, determine the number of pages to use for the 4231.1Sitojun * buffer cache. We allocate 1/2 as many swap buffer headers 4241.1Sitojun * as file I/O buffers. 4251.1Sitojun */ 4261.1Sitojun if (bufpages == 0) { 4271.1Sitojun if (bufcache == 0) { /* use old algorithm */ 4281.1Sitojun /* 4291.1Sitojun * Determine how many buffers to allocate. We use 10% 4301.1Sitojun * of the first 2MB of memory, and 5% of the rest, with 4311.1Sitojun * a minimum of 16 buffers. 4321.1Sitojun */ 4331.1Sitojun if (physmem < btoc(2 * 1024 * 1024)) 4341.1Sitojun bufpages = physmem / (10 * CLSIZE); 4351.1Sitojun else 4361.1Sitojun bufpages = (btoc(2 * 1024 * 1024) + physmem) / 4371.1Sitojun (20 * CLSIZE); 4381.1Sitojun } else { 4391.1Sitojun /* 4401.1Sitojun * Set size of buffer cache to physmem/bufcache * 100 4411.1Sitojun * (i.e., bufcache % of physmem). 4421.1Sitojun */ 4431.1Sitojun if (bufcache < 5 || bufcache > 95) { 4441.1Sitojun printf( 4451.1Sitojun "warning: unable to set bufcache to %d%% of RAM, using 10%%", 4461.1Sitojun bufcache); 4471.1Sitojun bufcache = 10; 4481.1Sitojun } 4491.1Sitojun bufpages= physmem / (CLSIZE * 100) * bufcache; 4501.1Sitojun } 4511.1Sitojun } 4521.1Sitojun if (nbuf == 0) { 4531.1Sitojun nbuf = bufpages; 4541.1Sitojun if (nbuf < 16) 4551.1Sitojun nbuf = 16; 4561.1Sitojun } 4571.1Sitojun 4581.1Sitojun /* 4591.1Sitojun * XXX stopgap measure to prevent wasting too much KVM on 4601.1Sitojun * the sparsely filled buffer cache. 4611.1Sitojun */ 4621.1Sitojun if (nbuf * MAXBSIZE > VM_MAX_KERNEL_BUF) 4631.1Sitojun nbuf = VM_MAX_KERNEL_BUF / MAXBSIZE; 4641.1Sitojun 4651.1Sitojun if (nswbuf == 0) { 4661.1Sitojun nswbuf = (nbuf / 2) &~ 1; /* force even */ 4671.1Sitojun if (nswbuf > 256) 4681.1Sitojun nswbuf = 256; /* sanity */ 4691.1Sitojun } 4701.1Sitojun valloc(buf, struct buf, nbuf); 4711.1Sitojun return v; 4721.1Sitojun} 4731.1Sitojun 4741.1Sitojun/* 4751.1Sitojun * Info for CTL_HW 4761.1Sitojun */ 4771.1Sitojunextern char version[]; 4781.1Sitojun 4791.1Sitojun 4801.1Sitojun#define CPUDEBUG 4811.1Sitojun 4821.1Sitojun 4831.1Sitojun/* 4841.1Sitojun * machine dependent system variables. 4851.1Sitojun */ 4861.1Sitojunint 4871.1Sitojuncpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 4881.1Sitojun int *name; 4891.1Sitojun u_int namelen; 4901.1Sitojun void *oldp; 4911.1Sitojun size_t *oldlenp; 4921.1Sitojun void *newp; 4931.1Sitojun size_t newlen; 4941.1Sitojun struct proc *p; 4951.1Sitojun{ 4961.1Sitojun dev_t consdev; 4971.1Sitojun struct btinfo_bootpath *bibp; 4981.1Sitojun struct trapframe *tf; 4991.1Sitojun char *osimage; 5001.1Sitojun 5011.1Sitojun /* all sysctl names at this level are terminal */ 5021.1Sitojun if (namelen != 1) 5031.1Sitojun return (ENOTDIR); /* overloaded */ 5041.1Sitojun 5051.1Sitojun switch (name[0]) { 5061.1Sitojun case CPU_CONSDEV: 5071.1Sitojun if (cn_tab != NULL) 5081.1Sitojun consdev = cn_tab->cn_dev; 5091.1Sitojun else 5101.1Sitojun consdev = NODEV; 5111.1Sitojun return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 5121.1Sitojun sizeof consdev)); 5131.1Sitojun 5141.1Sitojun case CPU_NKPDE: 5151.1Sitojun return (sysctl_rdint(oldp, oldlenp, newp, nkpde)); 5161.1Sitojun 5171.1Sitojun case CPU_BOOTED_KERNEL: 5181.1Sitojun bibp = lookup_bootinfo(BTINFO_BOOTPATH); 5191.1Sitojun if (!bibp) 5201.1Sitojun return (ENOENT); /* ??? */ 5211.1Sitojun return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath)); 5221.1Sitojun 5231.1Sitojun case CPU_SETPRIVPROC: 5241.1Sitojun if (newp == NULL) 5251.1Sitojun return (0); 5261.1Sitojun 5271.1Sitojun /* set current process to priviledged process */ 5281.1Sitojun tf = p->p_md.md_regs; 5291.1Sitojun tf->tf_ssr |= PSL_MD; 5301.1Sitojun return (0); 5311.1Sitojun 5321.1Sitojun case CPU_DEBUGMODE: 5331.1Sitojun return (sysctl_int(oldp, oldlenp, newp, newlen, 5341.1Sitojun &cpu_debug_mode)); 5351.1Sitojun 5361.1Sitojun case CPU_LOADANDRESET: 5371.1Sitojun if (newp != NULL) { 5381.1Sitojun osimage = (char *)(*(u_long *)newp); 5391.1Sitojun 5401.1Sitojun LoadAndReset(osimage); 5411.1Sitojun /* not reach here */ 5421.1Sitojun } 5431.1Sitojun return (0); 5441.1Sitojun 5451.1Sitojun default: 5461.1Sitojun return (EOPNOTSUPP); 5471.1Sitojun } 5481.1Sitojun /* NOTREACHED */ 5491.1Sitojun} 5501.1Sitojun 5511.1Sitojun/* 5521.1Sitojun * Send an interrupt to process. 5531.1Sitojun * 5541.1Sitojun * Stack is set up to allow sigcode stored 5551.1Sitojun * in u. to call routine, followed by kcall 5561.1Sitojun * to sigreturn routine below. After sigreturn 5571.1Sitojun * resets the signal mask, the stack, and the 5581.1Sitojun * frame pointer, it returns to the user 5591.1Sitojun * specified pc, psl. 5601.1Sitojun */ 5611.1Sitojunvoid 5621.1Sitojunsendsig(catcher, sig, mask, code) 5631.1Sitojun sig_t catcher; 5641.1Sitojun int sig; 5651.1Sitojun sigset_t *mask; 5661.1Sitojun u_long code; 5671.1Sitojun{ 5681.1Sitojun struct proc *p = curproc; 5691.1Sitojun struct trapframe *tf; 5701.1Sitojun struct sigframe *fp, frame; 5711.1Sitojun struct sigacts *psp = p->p_sigacts; 5721.1Sitojun int onstack; 5731.1Sitojun 5741.1Sitojun tf = p->p_md.md_regs; 5751.1Sitojun 5761.1Sitojun /* Do we need to jump onto the signal stack? */ 5771.1Sitojun onstack = 5781.1Sitojun (psp->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 5791.1Sitojun (psp->ps_sigact[sig].sa_flags & SA_ONSTACK) != 0; 5801.1Sitojun 5811.1Sitojun /* Allocate space for the signal handler context. */ 5821.1Sitojun if (onstack) 5831.1Sitojun fp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp + 5841.1Sitojun psp->ps_sigstk.ss_size); 5851.1Sitojun else 5861.1Sitojun fp = (struct sigframe *)tf->tf_r15; 5871.1Sitojun fp--; 5881.1Sitojun 5891.1Sitojun /* Build stack frame for signal trampoline. */ 5901.1Sitojun frame.sf_signum = sig; 5911.1Sitojun frame.sf_code = code; 5921.1Sitojun frame.sf_scp = &fp->sf_sc; 5931.1Sitojun frame.sf_handler = catcher; 5941.1Sitojun 5951.1Sitojun /* Save register context. */ 5961.1Sitojun frame.sf_sc.sc_ssr = tf->tf_ssr; 5971.1Sitojun frame.sf_sc.sc_spc = tf->tf_spc; 5981.1Sitojun frame.sf_sc.sc_pr = tf->tf_pr; 5991.1Sitojun frame.sf_sc.sc_r15 = tf->tf_r15; 6001.1Sitojun frame.sf_sc.sc_r14 = tf->tf_r14; 6011.1Sitojun frame.sf_sc.sc_r13 = tf->tf_r13; 6021.1Sitojun frame.sf_sc.sc_r12 = tf->tf_r12; 6031.1Sitojun frame.sf_sc.sc_r11 = tf->tf_r11; 6041.1Sitojun frame.sf_sc.sc_r10 = tf->tf_r10; 6051.1Sitojun frame.sf_sc.sc_r9 = tf->tf_r9; 6061.1Sitojun frame.sf_sc.sc_r8 = tf->tf_r8; 6071.1Sitojun frame.sf_sc.sc_r7 = tf->tf_r7; 6081.1Sitojun frame.sf_sc.sc_r6 = tf->tf_r6; 6091.1Sitojun frame.sf_sc.sc_r5 = tf->tf_r5; 6101.1Sitojun frame.sf_sc.sc_r4 = tf->tf_r4; 6111.1Sitojun frame.sf_sc.sc_r3 = tf->tf_r3; 6121.1Sitojun frame.sf_sc.sc_r2 = tf->tf_r2; 6131.1Sitojun frame.sf_sc.sc_r1 = tf->tf_r1; 6141.1Sitojun frame.sf_sc.sc_r0 = tf->tf_r0; 6151.1Sitojun frame.sf_sc.sc_trapno = tf->tf_trapno; 6161.1Sitojun#ifdef TODO 6171.1Sitojun frame.sf_sc.sc_err = tf->tf_err; 6181.1Sitojun#endif 6191.1Sitojun 6201.1Sitojun /* Save signal stack. */ 6211.1Sitojun frame.sf_sc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 6221.1Sitojun 6231.1Sitojun /* Save signal mask. */ 6241.1Sitojun frame.sf_sc.sc_mask = *mask; 6251.1Sitojun 6261.1Sitojun#ifdef COMPAT_13 6271.1Sitojun /* 6281.1Sitojun * XXX We always have to save an old style signal mask because 6291.1Sitojun * XXX we might be delivering a signal to a process which will 6301.1Sitojun * XXX escape from the signal in a non-standard way and invoke 6311.1Sitojun * XXX sigreturn() directly. 6321.1Sitojun */ 6331.1Sitojun native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); 6341.1Sitojun#endif 6351.1Sitojun 6361.1Sitojun if (copyout(&frame, fp, sizeof(frame)) != 0) { 6371.1Sitojun /* 6381.1Sitojun * Process has trashed its stack; give it an illegal 6391.1Sitojun * instruction to halt it in its tracks. 6401.1Sitojun */ 6411.1Sitojun sigexit(p, SIGILL); 6421.1Sitojun /* NOTREACHED */ 6431.1Sitojun } 6441.1Sitojun 6451.1Sitojun /* 6461.1Sitojun * Build context to run handler in. 6471.1Sitojun */ 6481.1Sitojun tf->tf_spc = (int)psp->ps_sigcode; 6491.1Sitojun#ifdef TODO 6501.1Sitojun tf->tf_ssr &= ~(PSL_T|PSL_VM|PSL_AC); 6511.1Sitojun#endif 6521.1Sitojun tf->tf_r15 = (int)fp; 6531.1Sitojun 6541.1Sitojun /* Remember that we're now on the signal stack. */ 6551.1Sitojun if (onstack) 6561.1Sitojun psp->ps_sigstk.ss_flags |= SS_ONSTACK; 6571.1Sitojun} 6581.1Sitojun 6591.1Sitojun/* 6601.1Sitojun * System call to cleanup state after a signal 6611.1Sitojun * has been taken. Reset signal mask and 6621.1Sitojun * stack state from context left by sendsig (above). 6631.1Sitojun * Return to previous pc and psl as specified by 6641.1Sitojun * context left by sendsig. Check carefully to 6651.1Sitojun * make sure that the user has not modified the 6661.1Sitojun * psl to gain improper privileges or to cause 6671.1Sitojun * a machine fault. 6681.1Sitojun */ 6691.1Sitojunint 6701.1Sitojunsys___sigreturn14(p, v, retval) 6711.1Sitojun struct proc *p; 6721.1Sitojun void *v; 6731.1Sitojun register_t *retval; 6741.1Sitojun{ 6751.1Sitojun struct sys___sigreturn14_args /* { 6761.1Sitojun syscallarg(struct sigcontext *) sigcntxp; 6771.1Sitojun } */ *uap = v; 6781.1Sitojun struct sigcontext *scp, context; 6791.1Sitojun struct trapframe *tf; 6801.1Sitojun 6811.1Sitojun /* 6821.1Sitojun * The trampoline code hands us the context. 6831.1Sitojun * It is unsafe to keep track of it ourselves, in the event that a 6841.1Sitojun * program jumps out of a signal handler. 6851.1Sitojun */ 6861.1Sitojun scp = SCARG(uap, sigcntxp); 6871.1Sitojun if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0) 6881.1Sitojun return (EFAULT); 6891.1Sitojun 6901.1Sitojun /* Restore signal context. */ 6911.1Sitojun tf = p->p_md.md_regs; 6921.1Sitojun { 6931.1Sitojun /* 6941.1Sitojun * Check for security violations. If we're returning to 6951.1Sitojun * protected mode, the CPU will validate the segment registers 6961.1Sitojun * automatically and generate a trap on violations. We handle 6971.1Sitojun * the trap, rather than doing all of the checking here. 6981.1Sitojun */ 6991.1Sitojun#ifdef TODO 7001.1Sitojun if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) { 7011.1Sitojun return (EINVAL); 7021.1Sitojun } 7031.1Sitojun#endif 7041.1Sitojun 7051.1Sitojun tf->tf_ssr = context.sc_ssr; 7061.1Sitojun } 7071.1Sitojun tf->tf_r0 = context.sc_r0; 7081.1Sitojun tf->tf_r1 = context.sc_r1; 7091.1Sitojun tf->tf_r2 = context.sc_r2; 7101.1Sitojun tf->tf_r3 = context.sc_r3; 7111.1Sitojun tf->tf_r4 = context.sc_r4; 7121.1Sitojun tf->tf_r5 = context.sc_r5; 7131.1Sitojun tf->tf_r6 = context.sc_r6; 7141.1Sitojun tf->tf_r7 = context.sc_r7; 7151.1Sitojun tf->tf_r8 = context.sc_r8; 7161.1Sitojun tf->tf_r9 = context.sc_r9; 7171.1Sitojun tf->tf_r10 = context.sc_r10; 7181.1Sitojun tf->tf_r11 = context.sc_r11; 7191.1Sitojun tf->tf_r12 = context.sc_r12; 7201.1Sitojun tf->tf_r13 = context.sc_r13; 7211.1Sitojun tf->tf_r14 = context.sc_r14; 7221.1Sitojun tf->tf_spc = context.sc_spc; 7231.1Sitojun tf->tf_r15 = context.sc_r15; 7241.1Sitojun tf->tf_pr = context.sc_pr; 7251.1Sitojun 7261.1Sitojun /* Restore signal stack. */ 7271.1Sitojun if (context.sc_onstack & SS_ONSTACK) 7281.1Sitojun p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; 7291.1Sitojun else 7301.1Sitojun p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; 7311.1Sitojun /* Restore signal mask. */ 7321.1Sitojun (void) sigprocmask1(p, SIG_SETMASK, &context.sc_mask, 0); 7331.1Sitojun 7341.1Sitojun return (EJUSTRETURN); 7351.1Sitojun} 7361.1Sitojun 7371.1Sitojunint waittime = -1; 7381.1Sitojunstruct pcb dumppcb; 7391.1Sitojun 7401.1Sitojunvoid 7411.1Sitojuncpu_reboot(howto, bootstr) 7421.1Sitojun int howto; 7431.1Sitojun char *bootstr; 7441.1Sitojun{ 7451.1Sitojun extern int cold; 7461.1Sitojun 7471.1Sitojun if (cold) { 7481.1Sitojun howto |= RB_HALT; 7491.1Sitojun goto haltsys; 7501.1Sitojun } 7511.1Sitojun 7521.1Sitojun boothowto = howto; 7531.1Sitojun if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 7541.1Sitojun waittime = 0; 7551.1Sitojun vfs_shutdown(); 7561.1Sitojun /* 7571.1Sitojun * If we've been adjusting the clock, the todr 7581.1Sitojun * will be out of synch; adjust it now. 7591.1Sitojun */ 7601.1Sitojun /* resettodr(); */ 7611.1Sitojun } 7621.1Sitojun 7631.1Sitojun /* Disable interrupts. */ 7641.1Sitojun splhigh(); 7651.1Sitojun 7661.1Sitojun /* Do a dump if requested. */ 7671.1Sitojun if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 7681.1Sitojun dumpsys(); 7691.1Sitojun 7701.1Sitojunhaltsys: 7711.1Sitojun doshutdownhooks(); 7721.1Sitojun 7731.1Sitojun if (howto & RB_HALT) { 7741.1Sitojun printf("\n"); 7751.1Sitojun printf("The operating system has halted.\n"); 7761.1Sitojun printf("Please press any key to reboot.\n\n"); 7771.1Sitojun cngetc(); 7781.1Sitojun } 7791.1Sitojun 7801.1Sitojun printf("rebooting...\n"); 7811.1Sitojun cpu_reset(); 7821.1Sitojun for(;;) 7831.1Sitojun ; 7841.1Sitojun /*NOTREACHED*/ 7851.1Sitojun} 7861.1Sitojun 7871.1Sitojun/* 7881.1Sitojun * These variables are needed by /sbin/savecore 7891.1Sitojun */ 7901.1Sitojunu_long dumpmag = 0x8fca0101; /* magic number */ 7911.1Sitojunint dumpsize = 0; /* pages */ 7921.1Sitojunlong dumplo = 0; /* blocks */ 7931.1Sitojun 7941.1Sitojun/* 7951.1Sitojun * This is called by main to set dumplo and dumpsize. 7961.1Sitojun * Dumps always skip the first CLBYTES of disk space 7971.1Sitojun * in case there might be a disk label stored there. 7981.1Sitojun * If there is extra space, put dump at the end to 7991.1Sitojun * reduce the chance that swapping trashes it. 8001.1Sitojun */ 8011.1Sitojunvoid 8021.1Sitojuncpu_dumpconf() 8031.1Sitojun{ 8041.1Sitojun#ifdef TODO 8051.1Sitojun int nblks; /* size of dump area */ 8061.1Sitojun int maj; 8071.1Sitojun 8081.1Sitojun if (dumpdev == NODEV) 8091.1Sitojun return; 8101.1Sitojun maj = major(dumpdev); 8111.1Sitojun if (maj < 0 || maj >= nblkdev) 8121.1Sitojun panic("dumpconf: bad dumpdev=0x%x", dumpdev); 8131.1Sitojun if (bdevsw[maj].d_psize == NULL) 8141.1Sitojun return; 8151.1Sitojun nblks = (*bdevsw[maj].d_psize)(dumpdev); 8161.1Sitojun if (nblks <= ctod(1)) 8171.1Sitojun return; 8181.1Sitojun 8191.1Sitojun dumpsize = btoc(IOM_END + ctob(dumpmem_high)); 8201.1Sitojun 8211.1Sitojun /* Always skip the first CLBYTES, in case there is a label there. */ 8221.1Sitojun if (dumplo < ctod(1)) 8231.1Sitojun dumplo = ctod(1); 8241.1Sitojun 8251.1Sitojun /* Put dump at end of partition, and make it fit. */ 8261.1Sitojun if (dumpsize > dtoc(nblks - dumplo)) 8271.1Sitojun dumpsize = dtoc(nblks - dumplo); 8281.1Sitojun if (dumplo < nblks - ctod(dumpsize)) 8291.1Sitojun dumplo = nblks - ctod(dumpsize); 8301.1Sitojun#endif 8311.1Sitojun} 8321.1Sitojun 8331.1Sitojun/* 8341.1Sitojun * Doadump comes here after turning off memory management and 8351.1Sitojun * getting on the dump stack, either when called above, or by 8361.1Sitojun * the auto-restart code. 8371.1Sitojun */ 8381.1Sitojun#define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */ 8391.1Sitojunstatic vaddr_t dumpspace; 8401.1Sitojun 8411.1Sitojunvaddr_t 8421.1Sitojunreserve_dumppages(p) 8431.1Sitojun vaddr_t p; 8441.1Sitojun{ 8451.1Sitojun 8461.1Sitojun dumpspace = p; 8471.1Sitojun return (p + BYTES_PER_DUMP); 8481.1Sitojun} 8491.1Sitojun 8501.1Sitojunvoid 8511.1Sitojundumpsys() 8521.1Sitojun{ 8531.1Sitojun#ifdef TODO 8541.1Sitojun unsigned bytes, i, n; 8551.1Sitojun int maddr, psize; 8561.1Sitojun daddr_t blkno; 8571.1Sitojun int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 8581.1Sitojun int error; 8591.1Sitojun 8601.1Sitojun /* Save registers. */ 8611.1Sitojun savectx(&dumppcb); 8621.1Sitojun 8631.1Sitojun msgbufmapped = 0; /* don't record dump msgs in msgbuf */ 8641.1Sitojun if (dumpdev == NODEV) 8651.1Sitojun return; 8661.1Sitojun 8671.1Sitojun /* 8681.1Sitojun * For dumps during autoconfiguration, 8691.1Sitojun * if dump device has already configured... 8701.1Sitojun */ 8711.1Sitojun if (dumpsize == 0) 8721.1Sitojun cpu_dumpconf(); 8731.1Sitojun if (dumplo < 0) 8741.1Sitojun return; 8751.1Sitojun printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 8761.1Sitojun 8771.1Sitojun psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 8781.1Sitojun printf("dump "); 8791.1Sitojun if (psize == -1) { 8801.1Sitojun printf("area unavailable\n"); 8811.1Sitojun return; 8821.1Sitojun } 8831.1Sitojun 8841.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 8851.1Sitojun /* toss any characters present prior to dump */ 8861.1Sitojun while (sget() != NULL); /*syscons and pccons differ */ 8871.1Sitojun#endif 8881.1Sitojun 8891.1Sitojun bytes = ctob(dumpmem_high) + IOM_END; 8901.1Sitojun maddr = 0; 8911.1Sitojun blkno = dumplo; 8921.1Sitojun dump = bdevsw[major(dumpdev)].d_dump; 8931.1Sitojun error = 0; 8941.1Sitojun for (i = 0; i < bytes; i += n) { 8951.1Sitojun /* 8961.1Sitojun * Avoid dumping the ISA memory hole, and areas that 8971.1Sitojun * BIOS claims aren't in low memory. 8981.1Sitojun */ 8991.1Sitojun if (i >= ctob(dumpmem_low) && i < IOM_END) { 9001.1Sitojun n = IOM_END - i; 9011.1Sitojun maddr += n; 9021.1Sitojun blkno += btodb(n); 9031.1Sitojun continue; 9041.1Sitojun } 9051.1Sitojun 9061.1Sitojun /* Print out how many MBs we to go. */ 9071.1Sitojun n = bytes - i; 9081.1Sitojun if (n && (n % (1024*1024)) == 0) 9091.1Sitojun printf("%d ", n / (1024 * 1024)); 9101.1Sitojun 9111.1Sitojun /* Limit size for next transfer. */ 9121.1Sitojun if (n > BYTES_PER_DUMP) 9131.1Sitojun n = BYTES_PER_DUMP; 9141.1Sitojun 9151.1Sitojun (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); 9161.1Sitojun error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n); 9171.1Sitojun if (error) 9181.1Sitojun break; 9191.1Sitojun maddr += n; 9201.1Sitojun blkno += btodb(n); /* XXX? */ 9211.1Sitojun 9221.1Sitojun#if 0 /* XXX this doesn't work. grr. */ 9231.1Sitojun /* operator aborting dump? */ 9241.1Sitojun if (sget() != NULL) { 9251.1Sitojun error = EINTR; 9261.1Sitojun break; 9271.1Sitojun } 9281.1Sitojun#endif 9291.1Sitojun } 9301.1Sitojun 9311.1Sitojun switch (error) { 9321.1Sitojun 9331.1Sitojun case ENXIO: 9341.1Sitojun printf("device bad\n"); 9351.1Sitojun break; 9361.1Sitojun 9371.1Sitojun case EFAULT: 9381.1Sitojun printf("device not ready\n"); 9391.1Sitojun break; 9401.1Sitojun 9411.1Sitojun case EINVAL: 9421.1Sitojun printf("area improper\n"); 9431.1Sitojun break; 9441.1Sitojun 9451.1Sitojun case EIO: 9461.1Sitojun printf("i/o error\n"); 9471.1Sitojun break; 9481.1Sitojun 9491.1Sitojun case EINTR: 9501.1Sitojun printf("aborted from console\n"); 9511.1Sitojun break; 9521.1Sitojun 9531.1Sitojun case 0: 9541.1Sitojun printf("succeeded\n"); 9551.1Sitojun break; 9561.1Sitojun 9571.1Sitojun default: 9581.1Sitojun printf("error %d\n", error); 9591.1Sitojun break; 9601.1Sitojun } 9611.1Sitojun printf("\n\n"); 9621.1Sitojun delay(5000000); /* 5 seconds */ 9631.1Sitojun#endif /* TODO */ 9641.1Sitojun} 9651.1Sitojun 9661.1Sitojun/* 9671.1Sitojun * Clear registers on exec 9681.1Sitojun */ 9691.1Sitojunvoid 9701.1Sitojunsetregs(p, pack, stack) 9711.1Sitojun struct proc *p; 9721.1Sitojun struct exec_package *pack; 9731.1Sitojun u_long stack; 9741.1Sitojun{ 9751.1Sitojun register struct pcb *pcb = &p->p_addr->u_pcb; 9761.1Sitojun register struct trapframe *tf; 9771.1Sitojun 9781.1Sitojun p->p_md.md_flags &= ~MDP_USEDFPU; 9791.1Sitojun pcb->pcb_flags = 0; 9801.1Sitojun 9811.1Sitojun tf = p->p_md.md_regs; 9821.1Sitojun 9831.1Sitojun tf->tf_r0 = 0; 9841.1Sitojun tf->tf_r1 = 0; 9851.1Sitojun tf->tf_r2 = 0; 9861.1Sitojun tf->tf_r3 = 0; 9871.1Sitojun tf->tf_r4 = *(int *)stack; /* argc */ 9881.1Sitojun tf->tf_r5 = stack+4; /* argv */ 9891.1Sitojun tf->tf_r6 = stack+4*tf->tf_r4 + 8; /* envp */ 9901.1Sitojun tf->tf_r7 = 0; 9911.1Sitojun tf->tf_r8 = 0; 9921.1Sitojun tf->tf_r9 = 0; 9931.1Sitojun tf->tf_r10 = 0; 9941.1Sitojun tf->tf_r11 = 0; 9951.1Sitojun tf->tf_r12 = 0; 9961.1Sitojun tf->tf_r13 = 0; 9971.1Sitojun tf->tf_r14 = 0; 9981.1Sitojun tf->tf_spc = pack->ep_entry; 9991.1Sitojun tf->tf_ssr = PSL_USERSET; 10001.1Sitojun tf->tf_r15 = stack; 10011.1Sitojun#ifdef TODO 10021.1Sitojun tf->tf_ebx = (int)PS_STRINGS; 10031.1Sitojun#endif 10041.1Sitojun} 10051.1Sitojun 10061.1Sitojun/* 10071.1Sitojun * Initialize segments and descriptor tables 10081.1Sitojun */ 10091.1Sitojun 10101.1Sitojunextern struct user *proc0paddr; 10111.1Sitojun 10121.1Sitojunvoid 10131.1SitojuninitSH3(first_avail) 10141.1Sitojun vaddr_t first_avail; 10151.1Sitojun{ 10161.1Sitojun unsigned short *p; 10171.1Sitojun unsigned short sum; 10181.1Sitojun int size; 10191.1Sitojun extern void consinit __P((void)); 10201.1Sitojun 10211.1Sitojun proc0.p_addr = proc0paddr; /* page dir address */ 10221.1Sitojun 10231.1Sitojun /* 10241.1Sitojun * Initialize the I/O port and I/O mem extent maps. 10251.1Sitojun * Note: we don't have to check the return value since 10261.1Sitojun * creation of a fixed extent map will never fail (since 10271.1Sitojun * descriptor storage has already been allocated). 10281.1Sitojun * 10291.1Sitojun * N.B. The iomem extent manages _all_ physical addresses 10301.1Sitojun * on the machine. When the amount of RAM is found, the two 10311.1Sitojun * extents of RAM are allocated from the map (0 -> ISA hole 10321.1Sitojun * and end of ISA hole -> end of RAM). 10331.1Sitojun */ 10341.1Sitojun iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 10351.1Sitojun (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 10361.1Sitojun EX_NOCOALESCE|EX_NOWAIT); 10371.1Sitojun 10381.1Sitojun#if 0 /* XXX (msaitoh) */ 10391.1Sitojun consinit(); /* XXX SHOULD NOT BE DONE HERE */ 10401.1Sitojun#endif 10411.1Sitojun 10421.1Sitojun splraise(-1); 10431.1Sitojun enable_intr(); 10441.1Sitojun 10451.1Sitojun avail_end = sh3_trunc_page(IOM_RAM_END + 1); 10461.1Sitojun 10471.1Sitojun#if 0 /* XXX (msaitoh) */ 10481.1Sitojun printf("initSH3\r\n"); 10491.1Sitojun#endif 10501.1Sitojun 10511.1Sitojun /* 10521.1Sitojun * Calculate check sum 10531.1Sitojun */ 10541.1Sitojun size = (char *)&etext - (char *)&_start; 10551.1Sitojun p = (unsigned short *)&_start; 10561.1Sitojun sum = 0; 10571.1Sitojun size >>= 1; 10581.1Sitojun while (size--) 10591.1Sitojun sum += *p++; 10601.1Sitojun#if 0 10611.1Sitojun printf("Check Sum = 0x%x", sum); 10621.1Sitojun#endif 10631.1Sitojun 10641.1Sitojun /* 10651.1Sitojun * Allocate the physical addresses used by RAM from the iomem 10661.1Sitojun * extent map. This is done before the addresses are 10671.1Sitojun * page rounded just to make sure we get them all. 10681.1Sitojun */ 10691.1Sitojun if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN, 10701.1Sitojun IOM_RAM_SIZE, 10711.1Sitojun EX_NOWAIT)) { 10721.1Sitojun /* XXX What should we do? */ 10731.1Sitojun#if 1 10741.1Sitojun printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n"); 10751.1Sitojun#endif 10761.1Sitojun } 10771.1Sitojun 10781.1Sitojun#if 0 /* avail_start is set in locore.s to first available page rounded 10791.1Sitojun physical mem */ 10801.1Sitojun avail_start = IOM_RAM_BEGIN + NBPG; 10811.1Sitojun#endif 10821.1Sitojun 10831.1Sitojun /* number of pages of physmem addr space */ 10841.1Sitojun physmem = btoc(IOM_RAM_SIZE); 10851.1Sitojun#ifdef TODO 10861.1Sitojun dumpmem = physmem; 10871.1Sitojun#endif 10881.1Sitojun 10891.1Sitojun /* 10901.1Sitojun * Initialize for pmap_free_pages and pmap_next_page. 10911.1Sitojun * These guys should be page-aligned. 10921.1Sitojun */ 10931.1Sitojun if (physmem < btoc(2 * 1024 * 1024)) { 10941.1Sitojun printf("warning: too little memory available; " 10951.1Sitojun "have %d bytes, want %d bytes\n" 10961.1Sitojun "running in degraded mode\n" 10971.1Sitojun "press a key to confirm\n\n", 10981.1Sitojun ctob(physmem), 2*1024*1024); 10991.1Sitojun cngetc(); 11001.1Sitojun } 11011.1Sitojun 11021.1Sitojun /* Call pmap initialization to make new kernel address space */ 11031.1Sitojun pmap_bootstrap((vaddr_t)atdevbase); 11041.1Sitojun 11051.1Sitojun /* 11061.1Sitojun * Initialize error message buffer (at end of core). 11071.1Sitojun */ 11081.1Sitojun initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE)); 11091.1Sitojun 11101.1Sitojun /* 11111.1Sitojun * set boot device information 11121.1Sitojun */ 11131.1Sitojun setup_bootinfo(); 11141.1Sitojun 11151.1Sitojun#if 0 11161.1Sitojun sh3_cache_on(); 11171.1Sitojun#endif 11181.1Sitojun 11191.1Sitojun} 11201.1Sitojun 11211.1Sitojunstruct queue { 11221.1Sitojun struct queue *q_next, *q_prev; 11231.1Sitojun}; 11241.1Sitojun 11251.1Sitojun/* 11261.1Sitojun * insert an element into a queue 11271.1Sitojun */ 11281.1Sitojunvoid 11291.1Sitojun_insque(v1, v2) 11301.1Sitojun void *v1; 11311.1Sitojun void *v2; 11321.1Sitojun{ 11331.1Sitojun struct queue *elem = v1, *head = v2; 11341.1Sitojun struct queue *next; 11351.1Sitojun 11361.1Sitojun next = head->q_next; 11371.1Sitojun elem->q_next = next; 11381.1Sitojun head->q_next = elem; 11391.1Sitojun elem->q_prev = head; 11401.1Sitojun next->q_prev = elem; 11411.1Sitojun} 11421.1Sitojun 11431.1Sitojun/* 11441.1Sitojun * remove an element from a queue 11451.1Sitojun */ 11461.1Sitojunvoid 11471.1Sitojun_remque(v) 11481.1Sitojun void *v; 11491.1Sitojun{ 11501.1Sitojun struct queue *elem = v; 11511.1Sitojun struct queue *next, *prev; 11521.1Sitojun 11531.1Sitojun next = elem->q_next; 11541.1Sitojun prev = elem->q_prev; 11551.1Sitojun next->q_prev = prev; 11561.1Sitojun prev->q_next = next; 11571.1Sitojun elem->q_prev = 0; 11581.1Sitojun} 11591.1Sitojun 11601.1Sitojun#ifdef COMPAT_NOMID 11611.1Sitojunstatic int 11621.1Sitojunexec_nomid(p, epp) 11631.1Sitojun struct proc *p; 11641.1Sitojun struct exec_package *epp; 11651.1Sitojun{ 11661.1Sitojun int error; 11671.1Sitojun u_long midmag, magic; 11681.1Sitojun u_short mid; 11691.1Sitojun struct exec *execp = epp->ep_hdr; 11701.1Sitojun 11711.1Sitojun /* check on validity of epp->ep_hdr performed by exec_out_makecmds */ 11721.1Sitojun 11731.1Sitojun midmag = ntohl(execp->a_midmag); 11741.1Sitojun mid = (midmag >> 16) & 0xffff; 11751.1Sitojun magic = midmag & 0xffff; 11761.1Sitojun 11771.1Sitojun if (magic == 0) { 11781.1Sitojun magic = (execp->a_midmag & 0xffff); 11791.1Sitojun mid = MID_ZERO; 11801.1Sitojun } 11811.1Sitojun 11821.1Sitojun midmag = mid << 16 | magic; 11831.1Sitojun 11841.1Sitojun switch (midmag) { 11851.1Sitojun case (MID_ZERO << 16) | ZMAGIC: 11861.1Sitojun /* 11871.1Sitojun * 386BSD's ZMAGIC format: 11881.1Sitojun */ 11891.1Sitojun error = exec_aout_prep_oldzmagic(p, epp); 11901.1Sitojun break; 11911.1Sitojun 11921.1Sitojun case (MID_ZERO << 16) | QMAGIC: 11931.1Sitojun /* 11941.1Sitojun * BSDI's QMAGIC format: 11951.1Sitojun * same as new ZMAGIC format, but with different magic number 11961.1Sitojun */ 11971.1Sitojun error = exec_aout_prep_zmagic(p, epp); 11981.1Sitojun break; 11991.1Sitojun 12001.1Sitojun case (MID_ZERO << 16) | NMAGIC: 12011.1Sitojun /* 12021.1Sitojun * BSDI's NMAGIC format: 12031.1Sitojun * same as NMAGIC format, but with different magic number 12041.1Sitojun * and with text starting at 0. 12051.1Sitojun */ 12061.1Sitojun error = exec_aout_prep_oldnmagic(p, epp); 12071.1Sitojun break; 12081.1Sitojun 12091.1Sitojun case (MID_ZERO << 16) | OMAGIC: 12101.1Sitojun /* 12111.1Sitojun * BSDI's OMAGIC format: 12121.1Sitojun * same as OMAGIC format, but with different magic number 12131.1Sitojun * and with text starting at 0. 12141.1Sitojun */ 12151.1Sitojun error = exec_aout_prep_oldomagic(p, epp); 12161.1Sitojun break; 12171.1Sitojun 12181.1Sitojun default: 12191.1Sitojun error = ENOEXEC; 12201.1Sitojun } 12211.1Sitojun 12221.1Sitojun return error; 12231.1Sitojun} 12241.1Sitojun#endif 12251.1Sitojun 12261.1Sitojun/* 12271.1Sitojun * cpu_exec_aout_makecmds(): 12281.1Sitojun * cpu-dependent a.out format hook for execve(). 12291.1Sitojun * 12301.1Sitojun * Determine of the given exec package refers to something which we 12311.1Sitojun * understand and, if so, set up the vmcmds for it. 12321.1Sitojun * 12331.1Sitojun * On the i386, old (386bsd) ZMAGIC binaries and BSDI QMAGIC binaries 12341.1Sitojun * if COMPAT_NOMID is given as a kernel option. 12351.1Sitojun */ 12361.1Sitojunint 12371.1Sitojuncpu_exec_aout_makecmds(p, epp) 12381.1Sitojun struct proc *p; 12391.1Sitojun struct exec_package *epp; 12401.1Sitojun{ 12411.1Sitojun int error = ENOEXEC; 12421.1Sitojun 12431.1Sitojun#ifdef COMPAT_NOMID 12441.1Sitojun if ((error = exec_nomid(p, epp)) == 0) 12451.1Sitojun return error; 12461.1Sitojun#endif /* ! COMPAT_NOMID */ 12471.1Sitojun 12481.1Sitojun return error; 12491.1Sitojun} 12501.1Sitojun 12511.1Sitojunvoid 12521.1Sitojunsetup_bootinfo(void) 12531.1Sitojun{ 12541.1Sitojun struct btinfo_bootdisk *help; 12551.1Sitojun 12561.1Sitojun *(int *)bootinfo = 1; 12571.1Sitojun help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int)); 12581.1Sitojun help->biosdev = 0; 12591.1Sitojun help->partition = 0; 12601.1Sitojun ((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk); 12611.1Sitojun ((struct btinfo_common *)help)->type = BTINFO_BOOTDISK; 12621.1Sitojun} 12631.1Sitojun 12641.1Sitojunvoid * 12651.1Sitojunlookup_bootinfo(type) 12661.1Sitojun int type; 12671.1Sitojun{ 12681.1Sitojun struct btinfo_common *help; 12691.1Sitojun int n = *(int*)bootinfo; 12701.1Sitojun help = (struct btinfo_common *)(bootinfo + sizeof(int)); 12711.1Sitojun while (n--) { 12721.1Sitojun if (help->type == type) 12731.1Sitojun return (help); 12741.1Sitojun help = (struct btinfo_common *)((char*)help + help->len); 12751.1Sitojun } 12761.1Sitojun return (0); 12771.1Sitojun} 12781.1Sitojun 12791.1Sitojun 12801.1Sitojun/* 12811.1Sitojun * consinit: 12821.1Sitojun * initialize the system console. 12831.1Sitojun * XXX - shouldn't deal with this initted thing, but then, 12841.1Sitojun * it shouldn't be called from init386 either. 12851.1Sitojun */ 12861.1Sitojunvoid 12871.1Sitojunconsinit() 12881.1Sitojun{ 12891.1Sitojun static int initted; 12901.1Sitojun 12911.1Sitojun if (initted) 12921.1Sitojun return; 12931.1Sitojun initted = 1; 12941.1Sitojun 12951.1Sitojun cninit(); 12961.1Sitojun 12971.1Sitojun#ifdef DDB 12981.1Sitojun ddb_init(); 12991.1Sitojun#endif 13001.1Sitojun} 13011.1Sitojun 13021.1Sitojunvoid 13031.1Sitojuncpu_reset() 13041.1Sitojun{ 13051.1Sitojun 13061.1Sitojun disable_intr(); 13071.1Sitojun 13081.1Sitojun Sh3Reset(); 13091.1Sitojun for (;;) 13101.1Sitojun ; 13111.1Sitojun} 13121.1Sitojun 13131.1Sitojunint 13141.1Sitojunbus_space_map (t, addr, size, flags, bshp) 13151.1Sitojun bus_space_tag_t t; 13161.1Sitojun bus_addr_t addr; 13171.1Sitojun bus_size_t size; 13181.1Sitojun int flags; 13191.1Sitojun bus_space_handle_t *bshp; 13201.1Sitojun{ 13211.1Sitojun 13221.1Sitojun *bshp = (bus_space_handle_t)addr; 13231.1Sitojun 13241.1Sitojun return 0; 13251.1Sitojun} 13261.1Sitojun 13271.1Sitojunint 13281.1Sitojunsh_memio_subregion(t, bsh, offset, size, nbshp) 13291.1Sitojun bus_space_tag_t t; 13301.1Sitojun bus_space_handle_t bsh; 13311.1Sitojun bus_size_t offset, size; 13321.1Sitojun bus_space_handle_t *nbshp; 13331.1Sitojun{ 13341.1Sitojun 13351.1Sitojun *nbshp = bsh + offset; 13361.1Sitojun return (0); 13371.1Sitojun} 13381.1Sitojun 13391.1Sitojunint 13401.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, 13411.1Sitojun bpap, bshp) 13421.1Sitojun bus_space_tag_t t; 13431.1Sitojun bus_addr_t rstart, rend; 13441.1Sitojun bus_size_t size, alignment, boundary; 13451.1Sitojun int flags; 13461.1Sitojun bus_addr_t *bpap; 13471.1Sitojun bus_space_handle_t *bshp; 13481.1Sitojun{ 13491.1Sitojun *bshp = *bpap = rstart; 13501.1Sitojun 13511.1Sitojun return (0); 13521.1Sitojun} 13531.1Sitojun 13541.1Sitojunvoid 13551.1Sitojunsh_memio_free(t, bsh, size) 13561.1Sitojun bus_space_tag_t t; 13571.1Sitojun bus_space_handle_t bsh; 13581.1Sitojun bus_size_t size; 13591.1Sitojun{ 13601.1Sitojun 13611.1Sitojun} 13621.1Sitojun 13631.1Sitojunvoid 13641.1Sitojunsh_memio_unmap(t, bsh, size) 13651.1Sitojun bus_space_tag_t t; 13661.1Sitojun bus_space_handle_t bsh; 13671.1Sitojun bus_size_t size; 13681.1Sitojun{ 13691.1Sitojun return; 13701.1Sitojun} 13711.1Sitojun 13721.1Sitojun/* 13731.1Sitojun * InitializeBsc 13741.1Sitojun * : BSC(Bus State Controler) 13751.1Sitojun */ 13761.1Sitojunvoid InitializeBsc __P((void)); 13771.1Sitojun 13781.1Sitojunvoid 13791.1SitojunInitializeBsc() 13801.1Sitojun{ 13811.1Sitojun 13821.1Sitojun /* 13831.1Sitojun * Drive RAS,CAS in stand by mode and bus release mode 13841.1Sitojun * Area0 = Normal memory, Area5,6=Normal(no burst) 13851.1Sitojun * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory 13861.1Sitojun * Area4 = Normal Memory 13871.1Sitojun * Area6 = Normal memory 13881.1Sitojun */ 13891.1Sitojun SHREG_BSC.BCR1.WORD = BSC_BCR1_VAL; 13901.1Sitojun 13911.1Sitojun /* 13921.1Sitojun * Bus Width 13931.1Sitojun * Area4: Bus width = 16bit 13941.1Sitojun * Area6,5 = 16bit 13951.1Sitojun * Area1 = 8bit 13961.1Sitojun * Area2,3: Bus width = 32bit 13971.1Sitojun */ 13981.1Sitojun SHREG_BSC.BCR2.WORD = BSC_BCR2_VAL; 13991.1Sitojun 14001.1Sitojun /* 14011.1Sitojun * Idle cycle number in transition area and read to write 14021.1Sitojun * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 14031.1Sitojun * Area1 = 3, Area0 = 3 14041.1Sitojun */ 14051.1Sitojun SHREG_BSC.WCR1.WORD = BSC_WCR1_VAL; 14061.1Sitojun 14071.1Sitojun /* 14081.1Sitojun * Wait cycle 14091.1Sitojun * Area 6 = 6 14101.1Sitojun * Area 5 = 2 14111.1Sitojun * Area 4 = 10 14121.1Sitojun * Area 3 = 3 14131.1Sitojun * Area 2,1 = 3 14141.1Sitojun * Area 0 = 6 14151.1Sitojun */ 14161.1Sitojun SHREG_BSC.WCR2.WORD = BSC_WCR2_VAL; 14171.1Sitojun 14181.1Sitojun#ifdef SH4 14191.1Sitojun SHREG_BSC.WCR3.WORD = BSC_WCR3_VAL; 14201.1Sitojun#endif 14211.1Sitojun 14221.1Sitojun /* 14231.1Sitojun * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 14241.1Sitojun * write pre-charge=1cycle 14251.1Sitojun * CAS before RAS refresh RAS assert time = 3 cycle 14261.1Sitojun * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON 14271.1Sitojun * CAS before RAS refresh ON, EDO DRAM 14281.1Sitojun */ 14291.1Sitojun SHREG_BSC.MCR.WORD = BSC_MCR_VAL; 14301.1Sitojun 14311.1Sitojun#ifdef BSC_SDMR_VAL 14321.1Sitojun#if 1 14331.1Sitojun#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 14341.1Sitojun 14351.1Sitojun SDMR = 0; 14361.1Sitojun#else 14371.1Sitojun#define ADDSET (*(volatile unsigned short *)0x1A000000) 14381.1Sitojun#define ADDRST (*(volatile unsigned short *)0x18000000) 14391.1Sitojun#define SDMR (*(volatile unsigned char *)BSC_SDMR_VAL) 14401.1Sitojun 14411.1Sitojun ADDSET = 0; 14421.1Sitojun SDMR = 0; 14431.1Sitojun ADDRST = 0; 14441.1Sitojun#endif 14451.1Sitojun#endif 14461.1Sitojun 14471.1Sitojun /* 14481.1Sitojun * PCMCIA Control Register 14491.1Sitojun * OE/WE assert delay 3.5 cycle 14501.1Sitojun * OE/WE negate-address delay 3.5 cycle 14511.1Sitojun */ 14521.1Sitojun#ifdef BSC_PCR_VAL 14531.1Sitojun SHREG_BSC.PCR.WORD = 0x00ff; 14541.1Sitojun#endif 14551.1Sitojun 14561.1Sitojun /* 14571.1Sitojun * Refresh Timer Control/Status Register 14581.1Sitojun * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 14591.1Sitojun * Count Limit = 1024 14601.1Sitojun * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 14611.1Sitojun * is the rule of SH3 in writing these register. 14621.1Sitojun */ 14631.1Sitojun SHREG_BSC.RTCSR.WORD = BSC_RTCSR_VAL; 14641.1Sitojun 14651.1Sitojun 14661.1Sitojun /* 14671.1Sitojun * Refresh Timer Counter 14681.1Sitojun * Initialize to 0 14691.1Sitojun */ 14701.1Sitojun SHREG_BSC.RTCNT = BSC_RTCNT_VAL; 14711.1Sitojun 14721.1Sitojun /* set Refresh Time Constant Register */ 14731.1Sitojun SHREG_BSC.RTCOR = BSC_RTCOR_VAL; 14741.1Sitojun 14751.1Sitojun /* init Refresh Count Register */ 14761.1Sitojun#ifdef BSC_RFCR_VAL 14771.1Sitojun SHREG_BSC.RFCR = BSC_RFCR_VAL; 14781.1Sitojun#endif 14791.1Sitojun 14801.1Sitojun /* Set Clock mode (make internal clock double speed) */ 14811.1Sitojun 14821.1Sitojun SHREG_FRQCR = FRQCR_VAL; 14831.1Sitojun 14841.1Sitojun#ifndef MMEYE_NO_CACHE 14851.1Sitojun /* Cache ON */ 14861.1Sitojun SHREG_CCR = 0x0001; 14871.1Sitojun#endif 14881.1Sitojun} 14891.1Sitojun 14901.1Sitojunvoid 14911.1Sitojunsh3_cache_on(void) 14921.1Sitojun{ 14931.1Sitojun#ifndef MMEYE_NO_CACHE 14941.1Sitojun /* Cache ON */ 14951.1Sitojun SHREG_CCR = 0x0001; 14961.1Sitojun SHREG_CCR = 0x0009; /* cache clear */ 14971.1Sitojun SHREG_CCR = 0x0001; /* cache on */ 14981.1Sitojun#endif 14991.1Sitojun} 15001.1Sitojun 15011.1Sitojun#include <machine/mmeye.h> 15021.1Sitojunvoid 15031.1SitojunLoadAndReset(char *osimage) 15041.1Sitojun{ 15051.1Sitojun void *buf_addr; 15061.1Sitojun u_long size; 15071.1Sitojun u_long *src; 15081.1Sitojun u_long *dest; 15091.1Sitojun u_long csum = 0; 15101.1Sitojun u_long csum2 = 0; 15111.1Sitojun u_long size2; 15121.1Sitojun#define OSIMAGE_BUF_ADDR 0x8c400000 /* !!!!!! This value depends on physical 15131.1Sitojun available memory */ 15141.1Sitojun 15151.1Sitojun 15161.1Sitojun printf("LoadAndReset:copy start\n"); 15171.1Sitojun buf_addr = (void *)OSIMAGE_BUF_ADDR; 15181.1Sitojun 15191.1Sitojun size = *(u_long *)osimage; 15201.1Sitojun src = (u_long *)osimage; 15211.1Sitojun dest = buf_addr; 15221.1Sitojun 15231.1Sitojun size = (size + sizeof(u_long)*2 + 3) >> 2 ; 15241.1Sitojun size2 = size; 15251.1Sitojun 15261.1Sitojun while (size--){ 15271.1Sitojun csum += *src; 15281.1Sitojun *dest++ = *src++; 15291.1Sitojun } 15301.1Sitojun 15311.1Sitojun dest = buf_addr; 15321.1Sitojun while (size2--) 15331.1Sitojun csum2 += *dest++; 15341.1Sitojun 15351.1Sitojun printf("LoadAndReset:copy end[%lx,%lx]\n", csum, csum2); 15361.1Sitojun printf("start XLoadAndReset\n"); 15371.1Sitojun 15381.1Sitojun /* mask all externel interrupt (XXX) */ 15391.1Sitojun 15401.1Sitojun XLoadAndReset(buf_addr); 15411.1Sitojun} 1542