1: /*
   2:  * Copyright (c) 1987 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)mch_trap.s	2.2 (2.11BSD GTE) 1/9/94
   7:  */
   8: #include "DEFS.h"
   9: #include "../machine/mch_iopage.h"
  10: #include "../machine/koverlay.h"
  11: #include "../machine/trap.h"
  12: 
  13: 
  14: SPACE(LOCAL, saveps, 2)
  15: 
  16: /*
  17:  *	jsr	r0,call
  18:  *	jmp	trap_handler
  19:  *
  20:  *	mov	PS,saveps
  21:  *	jsr	r0,call1
  22:  *	jmp	trap_handler
  23:  *
  24:  * Interrupt interface code to C.  Creates an interrupt stack frame, calls
  25:  * the indicated trap_handler.  Call forces the previous mode to be user so
  26:  * that copy in/out and friends use user space if called from interrupt
  27:  * level.  Call1 is simply an alternate entry to call that assumes that the
  28:  * PS has already been changed and the original PS can be found in saveps.
  29:  * Call1 also doesn't increment cnt.v_intr since it's only called from
  30:  * synchronous software traps.
  31:  *
  32:  * The interrupt stack frame - note that values in <pdp/reg.h> must agree:
  33:  *
  34:  *				  reg.h
  35:  *		| ps		|   2	/ ps and pc saved by interrupt
  36:  *		| pc		|   1
  37:  *	u.u_ar0	| r0		|   0
  38:  *		| nps		|	/ from interrupt vector
  39:  *		| ovno		|
  40:  *		| r1		|  -3
  41:  *		| sp		|  -4
  42:  *		| code		|	/ nps & 037
  43:  *	--------------------------------/ above belongs to call, below to csv
  44:  *		| ret		|	/ return address to call
  45:  *	r5	| old r5	|  -7
  46:  *		| ovno		|
  47:  *		| r4		|  -9
  48:  *		| r3		| -10
  49:  *		| r2		| -11
  50:  *	sp	| *empty*	|
  51:  */
  52: call1:
  53:         mov     saveps,-(sp)            / stuff saved nps into interrupt frame
  54:         SPLLOW                          / ensure low priority (why?)
  55:         br      1f                      / branch around count of interrupts
  56: 
  57: ASENTRY(call)
  58:         /*
  59: 	 * Interrupt entry code.  Save various registers, etc., and call
  60: 	 * interrupt service routine.
  61: 	 */
  62:         mov     PS,-(sp)                / stuff nps into interrupt frame
  63: #ifdef UCB_METER
  64:         inc     _cnt+V_INTR             / cnt.v_intr++
  65: #endif
  66: 1:
  67:         mov     __ovno,-(sp)            / save overlay number,
  68:         mov     r1,-(sp)                /   r1,
  69:         mfpd    sp                      /   sp
  70:         mov     6(sp),-(sp)             / grab nps and calculate
  71:         bic     $!37,(sp)               /   code = nps & 037
  72:         bis     $30000,PS               / force previous mode = user
  73:         jsr     pc,(r0)                 / call trap_handler
  74: #ifdef INET
  75:         /*
  76: 	 * Check for scheduled network service requests.  The network sets
  77: 	 * _knetisr to schedule network activity at a later time when the
  78: 	 * system IPL is low and things are ``less hectic'' ...
  79: 	 */
  80:         mov     PS,-(sp)                / set SPL7 so _knetisr doesn't get
  81:         SPL7                            /   changed while we're looking at it
  82:         tst     _knetisr                / if (_knetisr != 0
  83:         beq     2f
  84:         bit     $340,20(sp)             /  && interrupted IPL == 0
  85:         bne     2f                      /  [shouldn't we check against SPLNET?]
  86:         cmp     sp,$_u                  /  && sp > _u (not on interrupt stack))
  87:         blos    2f
  88: #ifdef UCB_METER
  89:         inc     _cnt+V_SOFT             /   increment soft interrupt counter,
  90: #endif
  91:         clr     _knetisr                /   reset the flag,
  92:         SPLNET                          /   set network IPL,
  93:         clr     -(sp)                   /   and KScall(netintr, 0)
  94:         mov     $_netintr,-(sp)
  95:         jsr     pc,_KScall
  96:         cmp     (sp)+,(sp)+
  97: 2:
  98:         mov     (sp)+,PS                / restore PS
  99: #endif
 100:         /*
 101: 	 * Clean up from interrupt.  If previous mode was user and _runrun
 102: 	 * is set, generate an artificial SWITCHTRAP so we can schedule in a
 103: 	 * new process.
 104: 	 */
 105:         bit     $20000,10(sp)           / previous mode = user??
 106:         beq     4f
 107:         tstb    _runrun                 / yep, is the user's time up?
 108:         beq     3f
 109:         mov     $T_SWITCHTRAP,(sp)      / yep, set code to T_SWITCHTRAP
 110:         jsr     pc,_trap                /   and give up cpu
 111: 3:
 112:         /*
 113: 	 * Trap from user space: toss code and reset user's stack pointer.
 114: 	 */
 115:         tst     (sp)+                   / toss code, reset user's sp
 116:         mtpd    sp                      /   and enter common cleanup code
 117:         br      5f
 118: 4:
 119:         /*
 120: 	 * Trap from kernel or supervisor space: toss code and stack pointer
 121: 	 * (only user stack pointers need to be set or reset).
 122: 	 */
 123:         cmp     (sp)+,(sp)+             / trap from kernel or supervisor:
 124: 5:                                      /   toss code and sp
 125:         /*
 126: 	 * Finish final clean up, restore registers, etc. make sure we
 127: 	 * leave the same overlay mapped that we came in on, and return
 128: 	 * from the interrupt.
 129: 	 */
 130:         mov     (sp)+,r1                / restore r1
 131: 
 132:         mov     (sp)+,r0                / current overlay different from
 133:         cmp     r0,__ovno               /   interrupted overlay?
 134:         beq     6f
 135:         SPL7                            / yes, go non-interruptable (rtt
 136:                                         /   below restores PS)
 137:         mov     r0,__ovno               / reset ovno and mapping for
 138:         asl     r0                      /   interrupted overlay
 139:         mov     ova(r0),OVLY_PAR
 140:         mov     ovd(r0),OVLY_PDR
 141: 6:
 142:         tst     (sp)+                   / toss nps
 143:         mov     (sp)+,r0                / restore r0
 144:         rtt                             / and return from the trap ...
 145: 
 146: 
 147: #ifdef INET
 148: /*
 149:  * iothndlr is used to allow the network in supervisor mode to make calls
 150:  * to the kernel.
 151:  *
 152:  * the network pushes a <pc,ps> pair on the kernel stack before doing the
 153:  * 'iot'.  when we process the iot here we throw the saved <pc,ps> pair
 154:  * resulting from the 'iot' away and use instead the pair pushed by the
 155:  * network as the target for our 'rtt'.
 156:  *
 157:  * there was a warning that this hasn't been tested with overlays in the
 158:  * kernel.  can't see why it wouldn't work.
 159:  */
 160: ASENTRY(iothndlr)
 161:         mov     PS,saveps               / save PS in case we have to trap
 162:         bit     $20000,PS               / previous mode = supervisor?
 163:         bne     trap1                   /   (no, let trap handle it)
 164:         bit     $10000,PS
 165:         beq     trap1                   /   (no, let trap handle it)
 166:         cmp     (sp)+,(sp)+             / yes, toss iot frame and execute rtt
 167:         rtt                             /   on behalf of networking kernel
 168: #endif
 169: 
 170: 
 171: /*
 172:  * System call interface to C code.  Creates a fake interrupt stack frame and
 173:  * then vectors on to the real syscall handler.  It's not necessary to
 174:  * create a real interrupt stack frame with everything in the world saved
 175:  * since this is a synchronous trap.
 176:  */
 177: ASENTRY(syscall)
 178:         mov     PS,saveps               / save PS just in case we need to trap
 179:         bit     $20000,PS               / trap from user space?
 180:         beq     trap2                   / no, die
 181:         mov     r0,-(sp)
 182:         cmp     -(sp),-(sp)             / fake __ovno and nps - not needed
 183:         mov     r1,-(sp)
 184:         mfpd    sp                      / grab user's sp for argument addresses
 185:         tst     -(sp)                   / fake code - not needed
 186:         jsr     pc,_syscall             / call syscall and start cleaning up
 187:         tst     (sp)+
 188:         mtpd    sp                      / reload user sp, r1 and r0
 189:         mov     (sp)+,r1                /   (cret already reloaded the other
 190:         cmp     (sp)+,(sp)+             /   registers)
 191:         mov     (sp)+,r0
 192:         rtt                             / and return from the trap
 193: 
 194: 
 195: /*
 196:  * Emt takes emulator traps, which are requests to change the overlay for the
 197:  * current process.  If an invalid emt is received, _trap is called.  Note
 198:  * that choverlay is not called with a trap frame - only r0 and r1 are saved;
 199:  * it's not necessary to save __ovno as this is a synchronous trap.
 200:  */
 201: ASENTRY(emt)
 202:         mov     PS,saveps               / save PS just in case we need to trap
 203:         bit     $20000,PS               / if the emt isn't from user mode,
 204:         beq     trap2                   /   or, the process isn't overlaid,
 205:         tst     _u+U_OVBASE             /   or the requested overlay number
 206:         beq     trap2                   /   isn't valid, enter _trap
 207:         cmp     r0,$NOVL
 208:         bhi     trap2
 209:         mov     r0,-(sp)                / everything's cool, save r0 and r1
 210:         mov     r1,-(sp)                /   so they don't get trashed
 211:         mov     r0,_u+U_CUROV           / u.u_curov = r0
 212:         mov     $RO,-(sp)               / map the overlay in read only
 213: #ifdef UCB_METER
 214:         inc     _cnt+V_OVLY             / cnt.v_ovly++
 215: #endif
 216:         add     $1,_u+U_RU+RU_OVLY+2    / u.u_ru.ru_ovly++
 217:         adc     _u+U_RU+RU_OVLY
 218:         jsr     pc,_choverlay           / and get choverlay to bring the overlay in
 219:         tst     (sp)+                   / toss choverlay's paramter,
 220:         mov     (sp)+,r1                /   restore r0 and r1,
 221:         mov     (sp)+,r0
 222:         rtt                             /   and return from the trap
 223: 
 224: 
 225: /*
 226:  * Traps without specialized catchers get vectored here.  We re-enable memory
 227:  * management because the fault that caused this trap may have been a memory
 228:  * management fault which sometimes causes the contents of the memory managment
 229:  * registers to be frozen so error recovery can be attempted.
 230:  */
 231: ASENTRY(trap)
 232:         mov     PS,saveps               / save PS for call1
 233: trap1:
 234:         tst     nofault                 / if someone's already got this trap
 235:         bne     catchfault              /   scoped out, give it to them
 236:         /*
 237: 	 * save current values of memory management registers in case we
 238: 	 * want to back up the instruction that failed
 239: 	 */
 240:         mov     SSR0,ssr
 241: #ifndef KERN_NONSEP
 242:         mov     SSR1,ssr+2
 243: #endif
 244:         mov     SSR2,ssr+4
 245:         mov     $1,SSR0                 / re-enable relocation
 246: trap2:
 247:         jsr     r0,call1; jmp _trap     / and let call take us in to _trap ...
 248:         /*NOTREACHED*/
 249: 
 250: 
 251: /*
 252:  * We branch here when we take a trap and find that the variable nofault is
 253:  * set indicating that someone else is interested in taking the trap.
 254:  */
 255: catchfault:
 256:         mov     $1,SSR0                 / re-enable memory management
 257:         mov     nofault,(sp)            /   relocation, fiddle with the
 258:         rtt                             /   machine trap frame and boogie
 259: 
 260: 
 261: /*
 262:  * Power fail handling.  On power down, we just set up for the next trap.
 263:  * On power up we attempt an autoboot ...
 264:  */
 265: #define PVECT   24                      / power fail vector
 266: 
 267: ASENTRY(powrdown)
 268:         mov     $powrup,PVECT           / on power up, trap to powrup,
 269:         SPL7                            / and loop at high priority
 270:         br      .
 271: 
 272: #ifndef KERN_NONSEP
 273:         .data
 274: #endif
 275:         /*
 276: 	 * Power back on... wait a bit, then attempt a reboot.  Can't do much
 277: 	 * since memory management is off (hence we are in "data" space).
 278: 	 */
 279: powrup:
 280:         /*
 281: 	 * Not sure why these are necessary except that on a 44 it appears
 282: 	 * that the first instruction or two of a power up trap do not
 283: 	 * execute properly.
 284: 	 */
 285:         nop;nop;nop
 286:         /*
 287: 	 * The nested loop below gives 38 seconds of delay on a 11/44 (30 sec
 288: 	 * on a 11/93) for controllers to complete selftest after power comes
 289: 	 * back up.
 290: 	*/
 291:         mov     $400.,r0
 292: 2:
 293:         clr     r1
 294: 3:      nop
 295:         sob     r1,3b
 296:         sob     r0,2b
 297: 
 298:         mov     $RB_POWRFAIL,r4         / and try to reboot ...
 299:         mov     _bootdev,r3
 300: /*
 301:  * 'jsr' can not be used because there is no stack at the moment (battery
 302:  * backup preserves memory but not registers).  'hardboot' sets up a stack
 303:  * if it needs one, so it is not necessary to do that here.
 304: */
 305:         jmp     *$hardboot
 306:         /*NOTREACHED*/
 307:         .text

Defined functions

call defined in line 57; never used
call1 defined in line 52; used 1 times
catchfault defined in line 255; used 1 times
emt defined in line 201; used 1 times
iothndlr defined in line 160; used 1 times
powrdown defined in line 267; used 1 times
syscall defined in line 177; used 1 times
trap defined in line 231; used 9 times
trap1 defined in line 233; used 2 times
trap2 defined in line 246; used 4 times

Defined variables

powrup defined in line 279; used 1 times
saveps defined in line 14; used 5 times

Defined macros

PVECT defined in line 265; used 1 times
Last modified: 1994-01-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3636
Valid CSS Valid XHTML 1.0 Strict