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