xref: /netbsd/sys/arch/vax/vax/intvec.S (revision 6550d01e)
1/*	$NetBSD: intvec.S,v 1.19 2010/12/20 00:25:45 matt Exp $   */
2
3/*
4 * Copyright (c) 1994, 1997 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
33
34#include "assym.h"
35#include <sys/cdefs.h>
36#include <net/netisr.h>
37
38#include "opt_ddb.h"
39#include "opt_cputype.h"
40#include "opt_emulate.h"
41#include "opt_multiprocessor.h"
42#include "opt_lockdebug.h"
43#include "leds.h"
44
45#define SCBENTRY(name) \
46	.text			; \
47	.align 2		; \
48	.globl __CONCAT(X,name)	; \
49__CONCAT(X,name):
50
51#define TRAPCALL(namn, typ) \
52SCBENTRY(namn)			; \
53	pushl $0		; \
54	pushl $typ		; \
55	jbr Xtrap
56
57#define TRAPARGC(namn, typ) \
58SCBENTRY(namn)			; \
59	pushl $typ		; \
60	jbr Xtrap
61
62#define FASTINTR(namn, rutin) \
63SCBENTRY(namn)			; \
64	pushr $0x3f		; \
65	calls $0,_C_LABEL(rutin)	; \
66	popr $0x3f		; \
67	rei
68
69#define	PUSHR	pushr	$0x3f
70#define	POPR	popr	$0x3f
71
72#define KSTACK 0
73#define ISTACK 1
74#define	NOVEC	.long 0
75#define INTVEC(label,stack)	\
76	.long	__CONCAT(X,label)+stack;
77
78	.text
79
80	.globl	_C_LABEL(kernbase), _C_LABEL(rpb), _C_LABEL(kernel_text)
81	.set	_C_LABEL(kernel_text),KERNBASE
82_C_LABEL(kernbase):
83_C_LABEL(rpb):
84/*
85 * First page in memory we have rpb; so that we know where
86 * (must be on a 64k page boundary, easiest here). We use it
87 * to store SCB vectors generated when compiling the kernel,
88 * and move the SCB later to somewhere else.
89 */
90
91	NOVEC;				# Unused, 0
92	INTVEC(mcheck, ISTACK)		# Machine Check., 4
93	INTVEC(invkstk, ISTACK) 	# Kernel Stack Invalid., 8
94	NOVEC;			 	# Power Failed., C
95	INTVEC(privinflt, KSTACK)	# Privileged/Reserved Instruction.
96	INTVEC(xfcflt, KSTACK)		# Customer Reserved Instruction, 14
97	INTVEC(resopflt, KSTACK)	# Reserved Operand/Boot Vector(?), 18
98	INTVEC(resadflt, KSTACK)	# Reserved Address Mode., 1C
99	INTVEC(access_v, KSTACK)	# Access Control Violation, 20
100	INTVEC(transl_v, KSTACK)	# Translation Invalid, 24
101	INTVEC(tracep, KSTACK)		# Trace Pending, 28
102	INTVEC(breakp, KSTACK)		# Breakpoint Instruction, 2C
103	NOVEC;			 	# Compatibility Exception, 30
104	INTVEC(arithflt, KSTACK)	# Arithmetic Fault, 34
105	NOVEC;			 	# Unused, 38
106	NOVEC;			 	# Unused, 3C
107	INTVEC(syscall, KSTACK)		# main syscall trap, chmk, 40
108	INTVEC(resopflt, KSTACK)	# chme, 44
109	INTVEC(resopflt, KSTACK)	# chms, 48
110	INTVEC(resopflt, KSTACK)	# chmu, 4C
111	NOVEC;				# System Backplane Exception/BIerror, 50
112	INTVEC(cmrerr, ISTACK)		# Corrected Memory Read, 54
113	NOVEC;				# System Backplane Alert/RXCD, 58
114	INTVEC(sbiflt, ISTACK)		# System Backplane Fault, 5C
115	NOVEC;				# Memory Write Timeout, 60
116	NOVEC;				# Unused, 64
117	NOVEC;				# Unused, 68
118	NOVEC;				# Unused, 6C
119	NOVEC;				# Unused, 70
120	NOVEC;				# Unused, 74
121	NOVEC;				# Unused, 78
122	NOVEC;				# Unused, 7C
123	NOVEC;				# Unused, 80
124	NOVEC;				# Unused, 84
125	INTVEC(astintr,	KSTACK)		# Asynchronous Sustem Trap, AST (IPL 02)
126	NOVEC;				# Unused, 8C
127	NOVEC;				# Unused, 90
128	NOVEC;				# Unused, 94
129	NOVEC;				# Unused, 98
130	NOVEC;				# Unused, 9C
131	INTVEC(softclock, KSTACK);	# Software clock interrupt, A0 (IPL 08)
132	NOVEC;				# Unused, A4 (IPL 09)
133	NOVEC;				# Unused, A8 (IPL 10)
134	INTVEC(softbio, KSTACK);	# Software bio interrupt, AC (IPL 11)
135	INTVEC(softnet, KSTACK);	# Software net interrupt, B0 (IPL 12)
136	INTVEC(softserial, KSTACK);	# Software serial interrupt, B4 (IPL 13)
137	NOVEC;				# Unused, B8 (IPL 14)
138	INTVEC(ddbtrap, ISTACK) 	# Kernel debugger trap, BC (IPL 15)
139	INTVEC(hardclock,ISTACK)	# Interval Timer
140	NOVEC;				# Unused, C4
141	INTVEC(emulate, KSTACK)		# Subset instruction emulation, C8
142	NOVEC;				# Unused, CC
143	NOVEC;				# Unused, D0
144	NOVEC;				# Unused, D4
145	NOVEC;				# Unused, D8
146	NOVEC;				# Unused, DC
147	NOVEC;				# Unused, E0
148	NOVEC;				# Unused, E4
149	NOVEC;				# Unused, E8
150	NOVEC;				# Unused, EC
151	NOVEC;
152	NOVEC;
153	NOVEC;
154	NOVEC;
155
156	/* space for adapter vectors */
157	.space 0x100
158
159		.align 2
160#
161# mcheck is the badaddress trap, also called when referencing
162# a invalid address (busserror)
163# _memtest (memtest in C) holds the address to continue execution
164# at when returning from a intentional test.
165#
166SCBENTRY(mcheck)
167	tstl	_C_LABEL(cold)		# Ar we still in coldstart?
168	bneq	L4		# Yes.
169
170	pushr	$0x7f
171	pushab	24(%sp)
172	movl	_C_LABEL(dep_call),%r6	# CPU dependent mchk handling
173	calls	$1,*MCHK(%r6)
174	tstl	%r0		# If not machine check, try memory error
175	beql	1f
176	calls	$0,*MEMERR(%r6)
177	pushab	2f
178	calls	$1,_C_LABEL(panic)
1792:	.asciz	"mchk"
1801:	popr	$0x7f
181	addl2	(%sp)+,%sp
182
183	rei
184
185L4:	addl2	(%sp)+,%sp	# remove info pushed on stack
186	pushr	$0x3f		# save regs for clobbering
187	movl	_C_LABEL(dep_call),%r0	# get CPU-specific mchk handler
188	tstl	BADADDR(%r0)	# any handler available?
189	bneq	4f		# yep, call it
190	popr	$0x3f		# nope, restore regs
191	brb	0f		# continue
1924:	calls	$0,*BADADDR(%r0)	# call machine-specific handler
193	popr	$0x3f		# restore regs
194	brb	2f
195
1960:	cmpl	_C_LABEL(vax_cputype),$1 # Is it a 11/780?
197	bneq	1f		# No...
198
199	mtpr	$0, $PR_SBIFS	# Clear SBI fault register
200	brb	2f
201
2021:	cmpl	_C_LABEL(vax_cputype),$4 # Is it a 8600?
203	bneq	3f
204
205	mtpr	$0, $PR_EHSR	# Clear Error status register
206	brb	2f
207
2083:	mtpr	$0xF,$PR_MCESR	# clear the bus error bit
2092:	movl	_C_LABEL(memtest),(%sp)	# REI to new address
210	rei
211
212	TRAPCALL(invkstk, T_KSPNOTVAL)
213
214SCBENTRY(privinflt)	# Privileged/unimplemented instruction
215#ifndef NO_INSN_EMULATE
216	jsb	_C_LABEL(unimemu)	# do not return if insn emulated
217#endif
218	pushl	$0
219	pushl	$T_PRIVINFLT
220	jbr	Xtrap
221
222	TRAPCALL(xfcflt, T_XFCFLT);
223	TRAPCALL(resopflt, T_RESOPFLT)
224	TRAPCALL(resadflt, T_RESADFLT)
225
226/*
227 * Translation fault, used only when simulating page reference bit.
228 * Therefore it is done a fast revalidation of the page if it is
229 * referenced. Trouble here is the hardware bug on KA650 CPUs that
230 * put in a need for an extra check when the fault is gotten during
231 * PTE reference. Handled in pmap.c.
232 */
233SCBENTRY(transl_v)		# 20: Translation violation
234	pushr	$0x3f
235	pushl	28(%sp)
236	pushl	28(%sp)
237	calls	$2,_C_LABEL(pmap_simulref)
238	tstl	%r0
239	bneq	1f
240	popr	$0x3f
241	addl2	$8,%sp
242	rei
2431:	popr	$0x3f
244	brw	Xaccess_v
245
246SCBENTRY(access_v)			# 24: Access cntrl viol fault
247	blbs	(%sp), ptelen
248	pushl	$T_ACCFLT
249	bbc	$1,4(%sp),1f
250	bisl2	$T_PTEFETCH,(%sp)
2511:	bbc	$2,4(%sp),2f
252	bisl2	$T_WRITE,(%sp)
2532:	movl	(%sp), 4(%sp)
254	addl2	$4, %sp
255	jbr	Xtrap
256
257ptelen: movl	$T_PTELEN, (%sp)		# PTE must expand (or send segv)
258	jbr	Xtrap;
259
260TRAPCALL(tracep, T_TRCTRAP)
261TRAPCALL(breakp, T_BPTFLT)
262
263TRAPARGC(arithflt, T_ARITHFLT)
264
265SCBENTRY(syscall)			# Main system call
266	pushl	$T_SYSCALL
267	pushr	$0xfff
268	mfpr	$PR_USP, -(%sp)
269	mfpr    $PR_SSP, %r0		/* SSP contains curlwp */
270	movl	L_PROC(%r0), %r0
271	pushl	%ap
272	pushl	%fp
273	pushl	%sp		# pointer to syscall frame; defined in trap.h
274	calls	$1, *P_MD_SYSCALL(%r0)
275	movl	(%sp)+, %fp
276	movl	(%sp)+, %ap
277	mtpr	(%sp)+, $PR_USP
278	popr	$0xfff
279	addl2	$8, %sp
280	mtpr	$IPL_HIGH, $PR_IPL	# Be sure we can REI
281	rei
282
283
284SCBENTRY(cmrerr)
285	PUSHR
286	movl	_C_LABEL(dep_call),%r0
287	calls	$0,*MEMERR(%r0)
288	POPR
289	rei
290
291SCBENTRY(sbiflt);
292	pushab	sbifltmsg
293	calls	$1, _C_LABEL(panic)
294
295TRAPCALL(astintr, T_ASTFLT)
296
297TRAPCALL(ddbtrap, T_KDBTRAP)
298
299SCBENTRY(hardclock)
300#ifdef DDB
301	tstl	0x80000100		# rpb wait element
302	beql	1f			# set, jmp to debugger
303	pushl	$0
304	pushl	$T_KDBTRAP
305	jbr	Xtrap
306#endif
3071:	pushr	$0x3f
308	mfpr    $PR_ICCS,%r0
309	tstl    %r0
310	bgeq    2f
311	incl    _C_LABEL(clock_misscnt)+EV_COUNT
312	adwc    $0,_C_LABEL(clock_misscnt)+EV_COUNT+4
3132:      mtpr	$0x800000c1,$PR_ICCS		# Reset interrupt flag
314	incl	_C_LABEL(clock_intrcnt)+EV_COUNT	# count the number of clock interrupts
315	adwc	$0,_C_LABEL(clock_intrcnt)+EV_COUNT+4
316
317	mfpr    $PR_SSP, %r0		/* SSP contains curlwp */
318	movl	L_CPU(%r0), %r0		/* get current CPU */
319	incl    CI_NINTR(%r0)
320	adwc    $0,(CI_NINTR+4)(%r0)
321
322#if VAX46 || VAXANY
323	cmpl	_C_LABEL(vax_boardtype),$VAX_BTYP_46
324	bneq	1f
325	movl	_C_LABEL(ka46_cpu),%r0
326	clrl	VC_DIAGTIMM(%r0)
327#endif
3281:	pushl	%sp
329	addl2	$24,(%sp)
330	calls	$1,_C_LABEL(hardclock)
331#if NLEDS
332	calls	$0,_C_LABEL(leds_intr)
333#endif
334	popr	$0x3f
335	rei
336
337/*
338 * Main routine for traps; all go through this.
339 * Note that we put USP on the frame here, which sometimes should
340 * be KSP to be correct, but because we only alters it when we are
341 * called from user space it doesn't care.
342 * _sret is used in cpu_set_kpc to jump out to user space first time.
343 */
344	.globl	_C_LABEL(sret)
345Xtrap:	pushr	$0xfff
346	mfpr	$PR_USP, -(%sp)
347	pushl	%ap
348	pushl	%fp
349	pushl	%sp
350	calls	$1, _C_LABEL(trap)
351_C_LABEL(sret):
352	movl	(%sp)+, %fp
353	movl	(%sp)+, %ap
354	mtpr	(%sp)+, $PR_USP
355	popr	$0xfff
356	addl2	$8, %sp
357	mtpr	$IPL_HIGH, $PR_IPL	# Be sure we can REI
358	rei
359
360sbifltmsg:
361	.asciz	"SBI fault"
362
363#ifndef NO_INSN_EMULATE
364/*
365 * Table of emulated Microvax instructions supported by emulate.s.
366 * Use noemulate to convert unimplemented ones to reserved instruction faults.
367 */
368	.globl	_C_LABEL(emtable)
369_C_LABEL(emtable):
370/* f8 */ .long _C_LABEL(EMashp);	.long _C_LABEL(EMcvtlp)
371/* fa */ .long noemulate;		.long noemulate
372/* fc */ .long noemulate;		.long noemulate
373/* fe */ .long noemulate;		.long noemulate
374/* 00 */ .long noemulate;		.long noemulate
375/* 02 */ .long noemulate;		.long noemulate
376/* 04 */ .long noemulate;		.long noemulate
377/* 05 */ .long noemulate;		.long noemulate
378/* 08 */ .long _C_LABEL(EMcvtps);	.long _C_LABEL(EMcvtsp)
379/* 0a */ .long noemulate;		.long _C_LABEL(EMcrc)
380/* 0c */ .long noemulate;		.long noemulate
381/* 0e */ .long noemulate;		.long noemulate
382/* 10 */ .long noemulate;		.long noemulate
383/* 12 */ .long noemulate;		.long noemulate
384/* 14 */ .long noemulate;		.long noemulate
385/* 16 */ .long noemulate;		.long noemulate
386/* 18 */ .long noemulate;		.long noemulate
387/* 1a */ .long noemulate;		.long noemulate
388/* 1c */ .long noemulate;		.long noemulate
389/* 1e */ .long noemulate;		.long noemulate
390/* 20 */ .long _C_LABEL(EMaddp4);	.long _C_LABEL(EMaddp6)
391/* 22 */ .long _C_LABEL(EMsubp4);	.long _C_LABEL(EMsubp6)
392/* 24 */ .long _C_LABEL(EMcvtpt);	.long _C_LABEL(EMmulp)
393/* 26 */ .long _C_LABEL(EMcvttp);	.long _C_LABEL(EMdivp)
394/* 28 */ .long noemulate;		.long _C_LABEL(EMcmpc3)
395/* 2a */ .long _C_LABEL(EMscanc);	.long _C_LABEL(EMspanc)
396/* 2c */ .long noemulate;		.long _C_LABEL(EMcmpc5)
397/* 2e */ .long _C_LABEL(EMmovtc);	.long _C_LABEL(EMmovtuc)
398/* 30 */ .long noemulate;		.long noemulate
399/* 32 */ .long noemulate;		.long noemulate
400/* 34 */ .long _C_LABEL(EMmovp);	.long _C_LABEL(EMcmpp3)
401/* 36 */ .long _C_LABEL(EMcvtpl);	.long _C_LABEL(EMcmpp4)
402/* 38 */ .long _C_LABEL(EMeditpc);	.long _C_LABEL(EMmatchc)
403/* 3a */ .long _C_LABEL(EMlocc);	.long _C_LABEL(EMskpc)
404#endif
405/*
406 * The following is called with the stack set up as follows:
407 *
408 *	  (%sp): Opcode
409 *	 4(%sp): Instruction PC
410 *	 8(%sp): Operand 1
411 *	12(%sp): Operand 2
412 *	16(%sp): Operand 3
413 *	20(%sp): Operand 4
414 *	24(%sp): Operand 5
415 *	28(%sp): Operand 6
416 *	32(%sp): Operand 7 (unused)
417 *	36(%sp): Operand 8 (unused)
418 *	40(%sp): Return PC
419 *	44(%sp): Return PSL
420 *	48(%sp): TOS before instruction
421 *
422 * Each individual routine is called with the stack set up as follows:
423 *
424 *	  (%sp): Return address of trap handler
425 *	 4(%sp): Opcode (will get return PSL)
426 *	 8(%sp): Instruction PC
427 *	12(%sp): Operand 1
428 *	16(%sp): Operand 2
429 *	20(%sp): Operand 3
430 *	24(%sp): Operand 4
431 *	28(%sp): Operand 5
432 *	32(%sp): Operand 6
433 *	36(%sp): saved register 11
434 *	40(%sp): saved register 10
435 *	44(%sp): Return PC
436 *	48(%sp): Return PSL
437 *	52(%sp): TOS before instruction
438 *	See the VAX Architecture Reference Manual, Section B-5 for more
439 *	information.
440 */
441
442SCBENTRY(emulate)
443#ifndef NO_INSN_EMULATE
444	movl	%r11,32(%sp)		# save register %r11 in unused operand
445	movl	%r10,36(%sp)		# save register %r10 in unused operand
446	cvtbl	(%sp),%r10		# get opcode
447	addl2	$8,%r10			# shift negative opcodes
448	subl3	%r10,$0x43,%r11		# forget it if opcode is out of range
449	bcs	noemulate
450	movl	_C_LABEL(emtable)[%r10],%r10
451				# call appropriate emulation routine
452	jsb	(%r10)		# routines put return values into regs 0-5
453	movl	32(%sp),%r11		# restore register %r11
454	movl	36(%sp),%r10		# restore register %r10
455	insv	(%sp),$0,$4,44(%sp)	# and condition codes in Opcode spot
456	addl2	$40,%sp			# adjust stack for return
457	rei
458noemulate:
459	addl2	$48,%sp			# adjust stack for
460#endif
461	.word	0xffff			# "reserved instruction fault"
462