#include "assym.h"
#include <sys/cdefs.h>
#include "opt_ddb.h"
#include "opt_cputype.h"
#include "opt_emulate.h"
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
#include "leds.h"
#define SCBENTRY(name) \
.text ; \
.align 2 ; \
.globl __CONCAT(X,name) ; \
__CONCAT(X,name):
#define TRAPCALL(namn, typ) \
SCBENTRY(namn) ; \
pushl $0 ; \
pushl $typ ; \
jbr Xtrap
#define TRAPARGC(namn, typ) \
SCBENTRY(namn) ; \
pushl $typ ; \
jbr Xtrap
#define FASTINTR(namn, rutin) \
SCBENTRY(namn) ; \
pushr $0x3f ; \
calls $0,_C_LABEL(rutin) ; \
popr $0x3f ; \
rei
#define PUSHR pushr $0x3f
#define POPR popr $0x3f
#define KSTACK 0
#define ISTACK 1
#define NOVEC .long 0
#define INTVEC(label,stack) \
.long __CONCAT(X,label)+stack;
.text
.globl _C_LABEL(kernbase), _C_LABEL(rpb), _C_LABEL(kernel_text)
.set _C_LABEL(kernel_text),KERNBASE
_C_LABEL(kernbase):
_C_LABEL(rpb):
NOVEC; # Unused, 0
INTVEC(mcheck, ISTACK) # Machine Check., 4
INTVEC(invkstk, ISTACK) # Kernel Stack Invalid., 8
NOVEC; # Power Failed., C
INTVEC(privinflt, KSTACK) # Privileged/Reserved Instruction.
INTVEC(xfcflt, KSTACK) # 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
NOVEC; # Compatibility Exception, 30
INTVEC(arithflt, KSTACK) # Arithmetic Fault, 34
NOVEC; # Unused, 38
NOVEC; # Unused, 3C
INTVEC(syscall, KSTACK) # main syscall trap, chmk, 40
INTVEC(chmx, KSTACK) # chme, 44
INTVEC(chmx, KSTACK) # chms, 48
INTVEC(chmx, KSTACK) # chmu, 4C
NOVEC; # System Backplane Exception/BIerror, 50
INTVEC(cmrerr, ISTACK) # Corrected Memory Read, 54
NOVEC; # System Backplane Alert/RXCD, 58
INTVEC(sbiflt, ISTACK) # System Backplane Fault, 5C
NOVEC; # Memory Write Timeout, 60
NOVEC; # Unused, 64
NOVEC; # Unused, 68
NOVEC; # Unused, 6C
NOVEC; # Unused, 70
NOVEC; # Unused, 74
NOVEC; # Unused, 78
NOVEC; # Unused, 7C
NOVEC; # Unused, 80
NOVEC; # Unused, 84
INTVEC(astintr, KSTACK) # Asynchronous Sustem Trap, AST (IPL 02)
NOVEC; # Unused, 8C
NOVEC; # Unused, 90
NOVEC; # Unused, 94
NOVEC; # Unused, 98
NOVEC; # Unused, 9C
INTVEC(softclock, KSTACK); # Software clock interrupt, A0 (IPL 08)
NOVEC; # Unused, A4 (IPL 09)
NOVEC; # Unused, A8 (IPL 10)
INTVEC(softbio, KSTACK); # Software bio interrupt, AC (IPL 11)
INTVEC(softnet, KSTACK); # Software net interrupt, B0 (IPL 12)
INTVEC(softserial, KSTACK); # Software serial interrupt, B4 (IPL 13)
NOVEC; # Unused, B8 (IPL 14)
INTVEC(ddbtrap, ISTACK) # Kernel debugger trap, BC (IPL 15)
INTVEC(hardclock,ISTACK) # Interval Timer
NOVEC; # Unused, C4
INTVEC(emulate, KSTACK) # Subset instruction emulation, C8
NOVEC; # Unused, CC
NOVEC; # Unused, D0
NOVEC; # Unused, D4
NOVEC; # Unused, D8
NOVEC; # Unused, DC
NOVEC; # Unused, E0
NOVEC; # Unused, E4
NOVEC; # Unused, E8
NOVEC; # Unused, EC
NOVEC;
NOVEC;
NOVEC;
NOVEC;
.space 0x100
.align 2
#
#
SCBENTRY(mcheck)
tstl _C_LABEL(cold) # Ar we still in coldstart?
bneq L4 # Yes.
pushr $0x7f
pushab 24(%sp)
movl _C_LABEL(dep_call),%r6 # CPU dependent mchk handling
calls $1,*MCHK(%r6)
tstl %r0 # If not machine check, try memory error
beql 1f
calls $0,*MEMERR(%r6)
pushab 2f
calls $1,_C_LABEL(panic)
2: .asciz "mchk"
1: popr $0x7f
addl2 (%sp)+,%sp
rei
L4: addl2 (%sp)+,%sp # remove info pushed on stack
pushr $0x3f # save regs for clobbering
movl _C_LABEL(dep_call),%r0 # get CPU-specific mchk handler
tstl BADADDR(%r0) # any handler available?
bneq 4f # yep, call it
popr $0x3f # nope, restore regs
brb 0f # continue
4: calls $0,*BADADDR(%r0) # call machine-specific handler
popr $0x3f # restore regs
brb 2f
0: cmpl _C_LABEL(vax_cputype),$1 # Is it a 11/780?
bneq 1f # No...
mtpr $0, $PR_SBIFS # Clear SBI fault register
brb 2f
1: cmpl _C_LABEL(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 _C_LABEL(memtest),(%sp) # REI to new address
rei
TRAPCALL(invkstk, T_KSPNOTVAL)
SCBENTRY(privinflt) # Privileged/unimplemented instruction
#ifndef NO_INSN_EMULATE
jsb _C_LABEL(unimemu) # do not return if insn emulated
#endif
pushl $0
pushl $T_PRIVINFLT
jbr Xtrap
TRAPCALL(xfcflt, T_XFCFLT);
TRAPCALL(resopflt, T_RESOPFLT)
TRAPCALL(resadflt, T_RESADFLT)
SCBENTRY(chmx)
clrl (%sp) # CHM code already on stack
pushl $T_RESOPFLT
jbr Xtrap
SCBENTRY(transl_v) # 20: Translation violation
pushr $0x3f
pushl 28(%sp)
pushl 28(%sp)
calls $2,_C_LABEL(pmap_simulref)
tstl %r0
bneq 1f
popr $0x3f
addl2 $8,%sp
rei
1: popr $0x3f
brw Xaccess_v
SCBENTRY(access_v) # 24: Access cntrl viol fault
blbs (%sp), ptelen
pushl $T_ACCFLT
bbc $1,4(%sp),1f
bisl2 $T_PTEFETCH,(%sp)
1: bbc $2,4(%sp),2f
bisl2 $T_WRITE,(%sp)
2: movl (%sp), 4(%sp)
addl2 $4, %sp
jbr Xtrap
ptelen: movl $T_PTELEN, (%sp) # PTE must expand (or send segv)
jbr Xtrap;
TRAPCALL(tracep, T_TRCTRAP)
TRAPCALL(breakp, T_BPTFLT)
TRAPARGC(arithflt, T_ARITHFLT)
SCBENTRY(syscall) # Main system call
#if 1
cmpl (%sp), $SYS__lwp_getprivate
bneq 1f
mfpr $PR_SSP, %r0 # get curlwp
movl L_PRIVATE(%r0), %r0 # get l_private
addl2 $4, %sp # eat the code
rei
1:
#endif
pushl $T_SYSCALL
pushr $0xfff
mfpr $PR_USP, -(%sp)
mfpr $PR_SSP, %r0
movl L_PROC(%r0), %r0
pushl %ap
pushl %fp
pushl %sp # pointer to syscall frame; defined in trap.h
calls $1, *P_MD_SYSCALL(%r0)
movl (%sp)+, %fp
movl (%sp)+, %ap
mtpr (%sp)+, $PR_USP
popr $0xfff
addl2 $8, %sp
mtpr $IPL_HIGH, $PR_IPL # Be sure we can REI
rei
SCBENTRY(cmrerr)
PUSHR
movl _C_LABEL(dep_call),%r0
calls $0,*MEMERR(%r0)
POPR
rei
SCBENTRY(sbiflt);
pushab sbifltmsg
calls $1, _C_LABEL(panic)
TRAPCALL(astintr, T_ASTFLT)
TRAPCALL(ddbtrap, T_KDBTRAP)
SCBENTRY(hardclock)
#ifdef DDB
tstl 0x80000100 # rpb wait element
beql 1f # set, jmp to debugger
pushl $0
pushl $T_KDBTRAP
jbr Xtrap
#endif
1: pushr $0x3f
mfpr $PR_ICCS,%r0
tstl %r0
bgeq 2f
incl _C_LABEL(clock_misscnt)+EV_COUNT
adwc $0,_C_LABEL(clock_misscnt)+EV_COUNT+4
2: mtpr $0x800000c1,$PR_ICCS # Reset interrupt flag
incl _C_LABEL(clock_intrcnt)+EV_COUNT # count the number of clock interrupts
adwc $0,_C_LABEL(clock_intrcnt)+EV_COUNT+4
mfpr $PR_SSP, %r0
movl L_CPU(%r0), %r0
incl CI_NINTR(%r0)
adwc $0,(CI_NINTR+4)(%r0)
#if VAX46 || VAXANY
cmpl _C_LABEL(vax_boardtype),$VAX_BTYP_46
bneq 1f
movl _C_LABEL(ka46_cpu),%r0
clrl VC_DIAGTIMM(%r0)
#endif
1: pushl %sp
addl2 $24,(%sp)
calls $1,_C_LABEL(hardclock)
#if NLEDS
calls $0,_C_LABEL(leds_intr)
#endif
popr $0x3f
rei
.globl _C_LABEL(sret)
Xtrap: pushr $0xfff
mfpr $PR_USP, -(%sp)
pushl %ap
pushl %fp
pushl %sp
calls $1, _C_LABEL(trap)
_C_LABEL(sret):
movl (%sp)+, %fp
movl (%sp)+, %ap
mtpr (%sp)+, $PR_USP
popr $0xfff
addl2 $8, %sp
mtpr $IPL_HIGH, $PR_IPL # Be sure we can REI
rei
sbifltmsg:
.asciz "SBI fault"
#ifndef NO_INSN_EMULATE
.globl _C_LABEL(emtable)
_C_LABEL(emtable):
.long _C_LABEL(EMashp); .long _C_LABEL(EMcvtlp)
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long _C_LABEL(EMcvtps); .long _C_LABEL(EMcvtsp)
.long noemulate; .long _C_LABEL(EMcrc)
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long _C_LABEL(EMaddp4); .long _C_LABEL(EMaddp6)
.long _C_LABEL(EMsubp4); .long _C_LABEL(EMsubp6)
.long _C_LABEL(EMcvtpt); .long _C_LABEL(EMmulp)
.long _C_LABEL(EMcvttp); .long _C_LABEL(EMdivp)
.long noemulate; .long _C_LABEL(EMcmpc3)
.long _C_LABEL(EMscanc); .long _C_LABEL(EMspanc)
.long noemulate; .long _C_LABEL(EMcmpc5)
.long _C_LABEL(EMmovtc); .long _C_LABEL(EMmovtuc)
.long noemulate; .long noemulate
.long noemulate; .long noemulate
.long _C_LABEL(EMmovp); .long _C_LABEL(EMcmpp3)
.long _C_LABEL(EMcvtpl); .long _C_LABEL(EMcmpp4)
.long _C_LABEL(EMeditpc); .long _C_LABEL(EMmatchc)
.long _C_LABEL(EMlocc); .long _C_LABEL(EMskpc)
#endif
SCBENTRY(emulate)
#ifndef NO_INSN_EMULATE
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 _C_LABEL(emtable)[%r10],%r10
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"