xref: /netbsd-src/sys/arch/vax/vax/trap.c (revision 6ea46cb5e46c49111a6ecf3bcbe3c7e2730fe9f6)
1 #define SCHEDDEBUG
2 #undef FAULTDEBUG
3 /*
4  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *     This product includes software developed at Ludd, University of Lule}.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *	$Id: trap.c,v 1.2 1994/08/16 23:47:37 ragge Exp $
33  */
34 
35  /* All bugs are subject to removal without further notice */
36 
37 
38 
39 #include "sys/types.h"
40 #include "sys/param.h"
41 #include "sys/proc.h"
42 #include "sys/syscall.h"
43 #include "sys/systm.h"
44 #include "vax/include/mtpr.h"
45 #include "vax/include/pte.h"
46 #include "vm/vm.h"
47 #include "vm/vm_kern.h"
48 #include "vm/vm_page.h"
49 #include "kern/syscalls.c"
50 
51 
52 extern 	int want_resched,whichqs,startpmapdebug;
53 
54 /*
55  * astint() forces rescheduling of processes. Called by the fancy
56  * hardware supported Asynchronous System Trap on VAXen :)
57  */
58 astint(psl){
59 	mtpr(AST_NO,PR_ASTLVL); /* Turn off AST's */
60 	splclock(); /* We want no interrupts now */
61 /*	printf("Passerar astint() %x\n",whichqs); */
62 	if(whichqs&&want_resched){
63 		setrunqueue(curproc);
64 #ifdef SCHEDDEBUG
65 /*		printf("Swtch() fr}n AST\n"); */
66 #endif
67 		swtch();
68 	}
69 }
70 
71 #define PxTOP0(x) ((x&0x40000000) ?                          \
72                    (x+MAXTSIZ+MAXDSIZ+MAXSSIZ-0x80000000):   \
73                    (x&0x7fffffff))
74 
75 access_v(info,vaddr,pc,psl)
76         unsigned psl,pc,vaddr,info;
77 {
78         int rv,i;
79         vm_map_t map;
80         vm_prot_t ftype;
81         unsigned addr,pteaddr;
82         extern vm_map_t kernel_map,pte_map;
83 
84 printf("access_v: vaddr %x, pc %x, info %d\n",vaddr,pc,info);
85         addr=(vaddr& ~PAGE_MASK); /* Must give beginning of page */
86         if(pc>(unsigned)0x80000000&&vaddr>(unsigned)0x80000000){
87                 map=kernel_map;
88         } else {
89                 map= &curproc->p_vmspace->vm_map;
90         }
91         if(info&4) ftype=VM_PROT_WRITE|VM_PROT_READ;
92         else ftype = VM_PROT_READ;
93 
94 /*
95  * If it was an pte fault we first fault pte.
96  */
97         if(info&2){
98 printf("Warning: access_v caused pte fault.\n");
99                 pteaddr=(PxTOP0(vaddr)>>PGSHIFT)+
100                         curproc->p_vmspace->vm_pmap.pm_ptab;
101                 pteaddr=(pteaddr &= ~PAGE_MASK);
102                 rv = vm_fault(pte_map, pteaddr, ftype, FALSE);
103                 if (rv != KERN_SUCCESS) {
104                         printf("ptefault - ]t skogen... :(  %d\n",rv);
105                         asm("halt");
106                 }
107                 for(i=0;i<PAGE_SIZE;i+=4) *(int *)(pteaddr+i)=0x20000000;
108         }
109 
110         rv = vm_fault(map, addr, ftype, FALSE);
111         if (rv != KERN_SUCCESS) {
112                 printf("pagefault - ]t helvete... :(  %d\n",rv);
113                 printf("pc: 0x %x, vaddr 0x %x\n",pc,vaddr);
114                 asm("halt");
115         }
116 }
117 
118 
119 ingen_v(info,vaddr,pc,psl)
120 	unsigned psl,pc,vaddr,info;
121 {
122 	int rv,i;
123 	vm_map_t map;
124 	vm_prot_t ftype;
125 	unsigned addr,pteaddr;
126 	extern vm_map_t kernel_map,pte_map;
127 
128 	addr=(vaddr& ~PAGE_MASK); /* Must give beginning of page */
129 #ifdef FAULTDEBUG
130 	printf("Page fault ------------------------------\n");
131 printf("Inv_pte: psl %x, pc %x, vaddr %x, addr %x, info %x\n",
132 	psl,pc,vaddr,addr,info);
133 #endif
134 	if(pc>(unsigned)0x80000000&&vaddr>(unsigned)0x80000000){
135 if(startpmapdebug)		printf("Kernel map\n");
136 		map=kernel_map;
137 	} else {
138 if(startpmapdebug)		printf("User map\n");
139 		map= &curproc->p_vmspace->vm_map;
140 	}
141 	if(info&4) ftype=VM_PROT_WRITE;
142 	else ftype = VM_PROT_READ;
143 
144 /*
145  * If it was an pte fault we first fault pte.
146  */
147 	if(info&2){
148 #ifdef FAULTDEBUG
149 printf("Warning: pte fault: addr %x\n",vaddr);
150 #endif
151 printf("pte_v: vaddr %x, pc %x, info %d\n",vaddr,pc,info);
152 		pteaddr=(PxTOP0(vaddr)>>PGSHIFT)+
153 			curproc->p_vmspace->vm_pmap.pm_ptab;
154 		pteaddr=(pteaddr &= ~PAGE_MASK);
155 #ifdef FAULTDEBUG
156 printf("F{rdig pteaddr %x\n",pteaddr);
157 #endif
158 		rv = vm_fault(pte_map, pteaddr, ftype, FALSE);
159 		if (rv != KERN_SUCCESS) {
160 			printf("ptefault - ]t skogen... :(  %d\n",rv);
161 			asm("halt");
162 		}
163 		for(i=0;i<PAGE_SIZE;i+=4) *(int *)(pteaddr+i)=0x20000000;
164 	}
165 
166 printf("sidfel: vaddr %x, pc %x, info %d\n",vaddr,pc,info);
167 /* if(vaddr==0x8015c000)asm("halt"); */
168 	rv = vm_fault(map, addr, ftype, FALSE);
169 	if (rv != KERN_SUCCESS) {
170 		printf("pagefault - ]t helvete... :(  %d\n",rv);
171 		printf("pc: 0x %x, vaddr 0x %x\n",pc,vaddr);
172 		asm("halt");
173 	}
174 /* {extern int startpmapdebug;if(startpmapdebug) asm("halt");} */
175 #ifdef FAULTDEBUG
176 	printf("Slut page fault ------------------------------\n");
177 #endif
178 }
179 
180 struct	sysc_frame {
181 	int	ap;	/* Argument pointer on user stack */
182 	int	r1;	/* General registers r0 & r1 */
183 	int	r0;
184 	int	type;	/* System call number */
185 	int	pc;	/* User pc */
186 	int	psl;	/* User psl */
187 };
188 
189 static	struct  sysc_frame *execptr; /* Used to alter sp & pc during exec */
190 
191 setregs(p,pack,stack,retval)
192         struct proc *p;
193         int pack,stack,retval[2]; /* Not all are ints... */
194 {
195 	execptr->pc=pack+2;
196 	mtpr(stack,PR_USP);
197 #ifdef DEBUG
198         printf("Setregs: p %x, pack %x, stack %x, retval %x\n",
199                 p,pack,stack,retval);
200 #endif
201 }
202 
203 syscall(frame)
204 	struct	sysc_frame *frame;
205 {
206 	struct sysent *callp;
207 	int err,rval[2],args[8],narg;
208 
209 	execptr=frame;
210 	if(frame->type<0||frame->type>=nsysent)
211 		callp= &sysent[0];
212 	else
213 		callp= &sysent[frame->type];
214 
215 	rval[0]=0;
216 	rval[1]=frame->r1;
217 	narg=callp->sy_narg * sizeof(int);
218 	if((narg=callp->sy_narg*4)!=0)
219 		copyin(frame->ap+4, args, narg);
220 printf("%s: pid %d, args %x, callp->sy_call %x\n",syscallnames[frame->type],
221 		curproc->p_pid, args, callp->sy_call);
222 if(!strcmp("fork",syscallnames[frame->type])){
223 	printf("frame %x, narg %d\n",frame,narg); asm("halt");}
224 	err=(*callp->sy_call)(curproc,args,rval);
225 printf("return pid %d, call %s, err %d rval %d, %d\n",curproc->p_pid,
226 		syscallnames[frame->type],err,rval[0],rval[1]);
227 if(!strcmp("fork",syscallnames[frame->type])){
228 	printf("frame %x, narg %d\n",frame,narg); asm("halt");}
229 	switch(err){
230 	case 0:
231 		frame->r1=rval[1];
232 		frame->r0=rval[0];
233 		frame->psl &= ~PSL_C;
234 		break;
235 	case EJUSTRETURN:
236 		return;
237 	case ERESTART:
238 		frame->pc=frame->pc-2;
239 		break;
240 	default:
241 		frame->r0=err;
242 		frame->psl |= PSL_C;
243 		break;
244 	}
245         if(want_resched){
246                 setrunqueue(curproc);
247 #ifdef SCHEDDEBUG
248 /*                 printf("Swtch() fr}n syscall\n"); */
249 #endif
250                 swtch();
251         }
252 }
253