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