1 /* $NetBSD: powerpc_machdep.c,v 1.11 2002/03/18 04:50:32 briggs Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/conf.h> 36 #include <sys/disklabel.h> 37 #include <sys/exec.h> 38 #include <sys/sysctl.h> 39 #include <sys/user.h> 40 41 int cpu_timebase; 42 int cpu_printfataltraps; 43 44 /* 45 * Set set up registers on exec. 46 */ 47 void 48 setregs(p, pack, stack) 49 struct proc *p; 50 struct exec_package *pack; 51 u_long stack; 52 { 53 struct trapframe *tf = trapframe(p); 54 struct ps_strings arginfo; 55 56 memset(tf, 0, sizeof *tf); 57 tf->fixreg[1] = -roundup(-stack + 8, 16); 58 59 /* 60 * XXX Machine-independent code has already copied arguments and 61 * XXX environment to userland. Get them back here. 62 */ 63 (void)copyin((char *)p->p_psstr, &arginfo, sizeof (arginfo)); 64 65 /* 66 * Set up arguments for _start(): 67 * _start(argc, argv, envp, obj, cleanup, ps_strings); 68 * 69 * Notes: 70 * - obj and cleanup are the auxiliary and termination 71 * vectors. They are fixed up by ld.elf_so. 72 * - ps_strings is a NetBSD extension, and will be 73 * ignored by executables which are strictly 74 * compliant with the SVR4 ABI. 75 * 76 * XXX We have to set both regs and retval here due to different 77 * XXX calling convention in trap.c and init_main.c. 78 */ 79 tf->fixreg[3] = arginfo.ps_nargvstr; 80 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 81 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 82 tf->fixreg[6] = 0; /* auxillary vector */ 83 tf->fixreg[7] = 0; /* termination vector */ 84 tf->fixreg[8] = (register_t)p->p_psstr; /* NetBSD extension */ 85 86 tf->srr0 = pack->ep_entry; 87 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 88 p->p_addr->u_pcb.pcb_flags = 0; 89 } 90 91 /* 92 * Machine dependent system variables. 93 */ 94 int 95 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 96 int *name; 97 u_int namelen; 98 void *oldp; 99 size_t *oldlenp; 100 void *newp; 101 size_t newlen; 102 struct proc *p; 103 { 104 /* all sysctl names at this level are terminal */ 105 if (namelen != 1) 106 return ENOTDIR; 107 108 switch (name[0]) { 109 case CPU_CACHELINE: 110 /* Deprecated */ 111 return sysctl_rdint(oldp, oldlenp, newp, CACHELINESIZE); 112 case CPU_TIMEBASE: 113 if (cpu_timebase) 114 return sysctl_rdint(oldp, oldlenp, newp, cpu_timebase); 115 break; 116 case CPU_PRINTFATALTRAPS: 117 return sysctl_int(oldp, oldlenp, newp, newlen, 118 &cpu_printfataltraps); 119 case CPU_CACHEINFO: 120 /* Use this instead of CPU_CACHELINE */ 121 return sysctl_rdstruct(oldp, oldlenp, newp, 122 &curcpu()->ci_ci, 123 sizeof(curcpu()->ci_ci)); 124 default: 125 break; 126 } 127 return EOPNOTSUPP; 128 } 129 130 /* 131 * Crash dump handling. 132 */ 133 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 134 int dumpsize = 0; /* size of dump in pages */ 135 long dumplo = -1; /* blocks */ 136 137 /* 138 * This is called by main to set dumplo and dumpsize. 139 */ 140 void 141 cpu_dumpconf() 142 { 143 int nblks; /* size of dump device */ 144 int skip; 145 int maj; 146 147 if (dumpdev == NODEV) 148 return; 149 maj = major(dumpdev); 150 if (maj < 0 || maj >= nblkdev) 151 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 152 if (bdevsw[maj].d_psize == NULL) 153 return; 154 nblks = (*bdevsw[maj].d_psize)(dumpdev); 155 if (nblks <= ctod(1)) 156 return; 157 158 dumpsize = physmem; 159 160 /* Skip enough blocks at start of disk to preserve an eventual disklabel. */ 161 skip = LABELSECTOR + 1; 162 skip += ctod(1) - 1; 163 skip = ctod(dtoc(skip)); 164 if (dumplo < skip) 165 dumplo = skip; 166 167 /* Put dump at end of partition */ 168 if (dumpsize > dtoc(nblks - dumplo)) 169 dumpsize = dtoc(nblks - dumplo); 170 if (dumplo < nblks - ctod(dumpsize)) 171 dumplo = nblks - ctod(dumpsize); 172 } 173