NetBSD/sys/arch/vax/vax/intvec.s

468 lines
12 KiB
ArmAsm

/* $NetBSD: intvec.s,v 1.20 1996/07/20 18:20:44 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed at Ludd, University of Lule}.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* All bugs are subject to removal without further notice */
#include <machine/mtpr.h>
#include <machine/pte.h>
#include <machine/trap.h>
#define ENTRY(name) \
.text ; \
.align 2 ; \
.globl name ; \
name /**/:
#define TRAPCALL(namn, typ) \
ENTRY(namn) ; \
pushl $0 ; \
pushl $typ ; \
jbr trap
#define TRAPARGC(namn, typ) \
ENTRY(namn) ; \
pushl $typ ; \
jbr trap
#define FASTINTR(namn, rutin) \
ENTRY(namn) ; \
pushr $0x3f ; \
calls $0,_/**/rutin ; \
popr $0x3f ; \
rei
#define STRAY(scbnr, vecnr) \
ENTRY(stray/**/vecnr) ; \
pushr $0x3f ; \
pushl $/**/0x/**/vecnr ; \
pushl $scbnr ; \
calls $2,_stray ; \
popr $0x3f ; \
rei
#define KSTACK 0
#define ISTACK 1
#define INTVEC(label,stack) \
.long label+stack;
.text
.globl _kernbase, _rpb
_kernbase:
_rpb:
/*
* First page in memory we have rpb; so that we know where
* (must be on a 64k page boundary, easiest here). We use it
* to store SCB vectors generated when compiling the kernel,
* and move the SCB later to somewhere else.
*/
INTVEC(stray00, ISTACK) # Unused., 0
INTVEC(mcheck, ISTACK) # Machine Check., 4
INTVEC(invkstk, ISTACK) # Kernel Stack Invalid., 8
INTVEC(stray0C, ISTACK) # Power Failed., C
INTVEC(privinflt, KSTACK) # Privileged/Reserved Instruction.
INTVEC(stray14, ISTACK) # Customer Reserved Instruction, 14
INTVEC(resopflt, KSTACK) # Reserved Operand/Boot Vector(?), 18
INTVEC(resadflt, KSTACK) # # Reserved Address Mode., 1C
INTVEC(access_v, KSTACK) # Access Control Violation, 20
INTVEC(transl_v, KSTACK) # Translation Invalid, 24
INTVEC(tracep, KSTACK) # Trace Pending, 28
INTVEC(breakp, KSTACK) # Breakpoint Instruction, 2C
INTVEC(stray30, ISTACK) # Compatibility Exception, 30
INTVEC(arithflt, KSTACK) # Arithmetic Fault, 34
INTVEC(stray38, ISTACK) # Unused, 38
INTVEC(stray3C, ISTACK) # Unused, 3C
INTVEC(syscall, KSTACK) # main syscall trap, chmk, 40
INTVEC(resopflt, KSTACK) # chme, 44
INTVEC(resopflt, KSTACK) # chms, 48
INTVEC(resopflt, KSTACK) # chmu, 4C
INTVEC(sbiexc, ISTACK) # System Backplane Exception/BIerror, 50
INTVEC(cmrerr, ISTACK) # Corrected Memory Read, 54
INTVEC(rxcs, ISTACK) # System Backplane Alert/RXCD, 58
INTVEC(sbiflt, ISTACK) # System Backplane Fault, 5C
INTVEC(stray60, ISTACK) # Memory Write Timeout, 60
INTVEC(stray64, ISTACK) # Unused, 64
INTVEC(stray68, ISTACK) # Unused, 68
INTVEC(stray6C, ISTACK) # Unused, 6C
INTVEC(stray70, ISTACK) # Unused, 70
INTVEC(stray74, ISTACK) # Unused, 74
INTVEC(stray78, ISTACK) # Unused, 78
INTVEC(stray7C, ISTACK) # Unused, 7C
INTVEC(stray80, ISTACK) # Unused, 80
INTVEC(stray84, ISTACK) # Unused, 84
INTVEC(astintr, KSTACK) # Asynchronous Sustem Trap, AST
INTVEC(stray8C, ISTACK) # Unused, 8C
INTVEC(stray90, ISTACK) # Unused, 90
INTVEC(stray94, ISTACK) # Unused, 94
INTVEC(stray98, ISTACK) # Unused, 98
INTVEC(stray9C, ISTACK) # Unused, 9C
INTVEC(softclock,ISTACK) # Software clock interrupt
INTVEC(strayA4, ISTACK) # Unused, A4
INTVEC(strayA8, ISTACK) # Unused, A8
INTVEC(strayAC, ISTACK) # Unused, AC
INTVEC(netint, ISTACK) # Network interrupt
INTVEC(strayB4, ISTACK) # Unused, B4
INTVEC(strayB8, ISTACK) # Unused, B8
INTVEC(ddbtrap, ISTACK) # Kernel debugger trap, BC
INTVEC(hardclock,ISTACK) # Interval Timer
INTVEC(strayC4, ISTACK) # Unused, C4
INTVEC(emulate, KSTACK) # Subset instruction emulation
INTVEC(strayCC, ISTACK) # Unused, CC
INTVEC(strayD0, ISTACK) # Unused, D0
INTVEC(strayD4, ISTACK) # Unused, D4
INTVEC(strayD8, ISTACK) # Unused, D8
INTVEC(strayDC, ISTACK) # Unused, DC
INTVEC(strayE0, ISTACK) # Unused, E0
INTVEC(strayE4, ISTACK) # Unused, E4
INTVEC(strayE8, ISTACK) # Unused, E8
INTVEC(strayEC, ISTACK) # Unused, EC
INTVEC(strayF0, ISTACK)
INTVEC(strayF4, ISTACK)
INTVEC(consrint, ISTACK) # Console Terminal Recieve Interrupt
INTVEC(constint, ISTACK) # Console Terminal Transmit Interrupt
/* space for adapter vectors */
.space 0x100
STRAY(0,00)
.align 2
#
# mcheck is the badaddress trap, also called when referencing
# a invalid address (busserror)
# _memtest (memtest in C) holds the address to continue execution
# at when returning from a intentional test.
#
mcheck: .globl mcheck
tstl _cold # Ar we still in coldstart?
bneq L4 # Yes.
pushr $0x3f
pushab 24(sp)
calls $1, _machinecheck
popr $0x3f
addl2 (sp)+,sp
rei
L4: addl2 (sp)+,sp # remove info pushed on stack
cmpl _vax_cputype,$1 # Is it a 11/780?
bneq 1f # No...
mtpr $0, $PR_SBIFS # Clear SBI fault register
brb 2f
1: cmpl _vax_cputype,$4 # Is it a 8600?
bneq 3f
mtpr $0, $PR_EHSR # Clear Error status register
brb 2f
3: mtpr $0xF,$PR_MCESR # clear the bus error bit
2: movl _memtest,(sp) # REI to new adress
rei
TRAPCALL(invkstk, T_KSPNOTVAL)
STRAY(0,0C)
TRAPCALL(privinflt, T_PRIVINFLT)
STRAY(0,14)
TRAPCALL(resopflt, T_RESOPFLT)
TRAPCALL(resadflt, T_RESADFLT)
.align 2
transl_v: .globl transl_v # Translation violation, 20
pushl $T_TRANSFLT
L3: bbc $1,4(sp),L1
bisl2 $T_PTEFETCH, (sp)
L1: bbc $2,4(sp),L2
bisl2 $T_WRITE, (sp)
L2: movl (sp), 4(sp)
addl2 $4, sp
jbr trap
.align 2
access_v:.globl access_v # Access cntrl viol fault, 24
blbs (sp), ptelen
pushl $T_ACCFLT
jbr L3
ptelen: movl $T_PTELEN, (sp) # PTE must expand (or send segv)
jbr trap;
TRAPCALL(tracep, T_TRCTRAP)
TRAPCALL(breakp, T_BPTFLT)
STRAY(0,30)
TRAPARGC(arithflt, T_ARITHFLT)
STRAY(0,38)
STRAY(0,3C)
.align 2 # Main system call
.globl syscall
syscall:
pushl $T_SYSCALL
pushr $0xfff
mfpr $PR_USP, -(sp)
pushl ap
pushl fp
pushl sp # pointer to syscall frame; defined in trap.h
calls $1, _syscall
movl (sp)+, fp
movl (sp)+, ap
mtpr (sp)+, $PR_USP
popr $0xfff
addl2 $8, sp
mtpr $0x1f, $PR_IPL # Be sure we can REI
rei
STRAY(0,44)
STRAY(0,48)
STRAY(0,4C)
ENTRY(sbiexc)
tstl _cold /* Is it ok to get errs during boot??? */
bneq 1f
pushr $0x3f
pushl $0x50
pushl $0
calls $2,_stray
popr $0x3f
1: rei
FASTINTR(cmrerr,cmrerr)
ENTRY(rxcs); /* console interrupt from some other processor */
pushr $0x3f
#if VAX8200
cmpl $5,_vax_cputype
bneq 1f
calls $0,_rxcdintr
brb 2f
#endif
1: pushl $0x58
pushl $0
calls $2,_stray
2: popr $0x3f
rei
ENTRY(sbiflt);
moval sbifltmsg, -(sp)
calls $1, _panic
STRAY(0,60)
STRAY(0,64)
STRAY(0,68)
STRAY(0,6C)
STRAY(0,70)
STRAY(0,74)
STRAY(0,78)
STRAY(0,7C)
STRAY(0,80)
STRAY(0,84)
TRAPCALL(astintr, T_ASTFLT)
STRAY(0,8C)
STRAY(0,90)
STRAY(0,94)
STRAY(0,98)
STRAY(0,9C)
FASTINTR(softclock,softclock)
STRAY(0,A4)
STRAY(0,A8)
STRAY(0,AC)
FASTINTR(netint,netintr) #network packet interrupt
STRAY(0,B4)
STRAY(0,B8)
TRAPCALL(ddbtrap, T_KDBTRAP)
.align 2
.globl hardclock
hardclock: mtpr $0xc1,$PR_ICCS # Reset interrupt flag
pushr $0x3f
pushl sp
addl2 $24,(sp)
calls $1,_hardclock
popr $0x3f
rei
STRAY(0,C4)
STRAY(0,CC)
STRAY(0,D0)
STRAY(0,D4)
STRAY(0,D8)
STRAY(0,DC)
STRAY(0,E0)
STRAY(0,E4)
STRAY(0,E8)
STRAY(0,EC)
STRAY(0,F0)
STRAY(0,F4)
FASTINTR(consrint,gencnrint)
FASTINTR(constint,gencntint)
/*
* Main routine for traps; all go through this.
* Note that we put USP on the frame here, which sometimes should
* be KSP to be correct, but because we only alters it when we are
* called from user space it doesn't care.
* _sret is used in cpu_set_kpc to jump out to user space first time.
*/
.globl _sret
trap: pushr $0xfff
mfpr $PR_USP, -(sp)
pushl ap
pushl fp
pushl sp
calls $1, _arithflt
_sret: movl (sp)+, fp
movl (sp)+, ap
mtpr (sp)+, $PR_USP
popr $0xfff
addl2 $8, sp
mtpr $0x1f, $PR_IPL # Be sure we can REI
rei
sbifltmsg:
.asciz "SBI fault",0
#if VAX630 || VAX650
/*
* Table of emulated Microvax instructions supported by emulate.s.
* Use noemulate to convert unimplemented ones to reserved instruction faults.
*/
.globl _emtable
_emtable:
/* f8 */ .long _EMashp; .long _EMcvtlp; .long noemulate; .long noemulate
/* fc */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 00 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 04 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 08 */ .long _EMcvtps; .long _EMcvtsp; .long noemulate; .long _EMcrc
/* 0c */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 10 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 14 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 18 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 1c */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 20 */ .long _EMaddp4; .long _EMaddp6; .long _EMsubp4; .long _EMsubp6
/* 24 */ .long _EMcvtpt; .long _EMmulp; .long _EMcvttp; .long _EMdivp
/* 28 */ .long noemulate; .long _EMcmpc3; .long _EMscanc; .long _EMspanc
/* 2c */ .long noemulate; .long _EMcmpc5; .long _EMmovtc; .long _EMmovtuc
/* 30 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
/* 34 */ .long _EMmovp; .long _EMcmpp3; .long _EMcvtpl; .long _EMcmpp4
/* 38 */ .long _EMeditpc; .long _EMmatchc; .long _EMlocc; .long _EMskpc
#endif
/*
* The following is called with the stack set up as follows:
*
* (sp): Opcode
* 4(sp): Instruction PC
* 8(sp): Operand 1
* 12(sp): Operand 2
* 16(sp): Operand 3
* 20(sp): Operand 4
* 24(sp): Operand 5
* 28(sp): Operand 6
* 32(sp): Operand 7 (unused)
* 36(sp): Operand 8 (unused)
* 40(sp): Return PC
* 44(sp): Return PSL
* 48(sp): TOS before instruction
*
* Each individual routine is called with the stack set up as follows:
*
* (sp): Return address of trap handler
* 4(sp): Opcode (will get return PSL)
* 8(sp): Instruction PC
* 12(sp): Operand 1
* 16(sp): Operand 2
* 20(sp): Operand 3
* 24(sp): Operand 4
* 28(sp): Operand 5
* 32(sp): Operand 6
* 36(sp): saved register 11
* 40(sp): saved register 10
* 44(sp): Return PC
* 48(sp): Return PSL
* 52(sp): TOS before instruction
* See the VAX Architecture Reference Manual, Section B-5 for more
* information.
*/
.align 2
.globl emulate
emulate:
#if VAX630 || VAX650
movl r11,32(sp) # save register r11 in unused operand
movl r10,36(sp) # save register r10 in unused operand
cvtbl (sp),r10 # get opcode
addl2 $8,r10 # shift negative opcodes
subl3 r10,$0x43,r11 # forget it if opcode is out of range
bcs noemulate
movl _emtable[r10],r10 # call appropriate emulation routine
jsb (r10) # routines put return values into regs 0-5
movl 32(sp),r11 # restore register r11
movl 36(sp),r10 # restore register r10
insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot
addl2 $40,sp # adjust stack for return
rei
noemulate:
addl2 $48,sp # adjust stack for
#endif
.word 0xffff # "reserved instruction fault"
.globl _intrnames, _eintrnames, _intrcnt, _eintrcnt
_intrnames:
.long 0
_eintrnames:
_intrcnt:
.long 0
_eintrcnt:
.data
_scb: .long 0
.globl _scb