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