# 2.11BSD#431 - /usr/src/sys/pdp/mch_trap.s

##### Functions

    call              X
    emt               X
    iothndlr          X
    powrdown          X
    syscall           X
    trap              X

##### Macros

    PVECT             X

       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

- in line 247

catchfault defined in line 255; used 1 times

- in line 235

emt defined in line 201; used 1 times

- in /usr/src/sys/pdp/scb.s line 89

iothndlr defined in line 160; used 1 times

- in /usr/src/sys/pdp/scb.s line 84

powrdown defined in line 267; used 1 times

- in /usr/src/sys/pdp/scb.s line 88

syscall defined in line 177; used 1 times

- in /usr/src/sys/pdp/mch_start.s line 24

trap defined in line 231; used 9 times

- in /usr/src/sys/pdp/scb.s line 76-86(5), 119, 158-160(3)

trap1 defined in line 233; used 2 times

- in line 163-165(2)

trap2 defined in line 246; used 4 times

- in line 180, 204-208(3)

#### Defined variables

powrup defined in line 279; used 1 times

- in line 268

saveps defined in line 14; used 5 times

- in line 53, 161, 178, 202, 232

#### Defined macros

PVECT defined in line 265; used 1 times

- in line 268

Last modified: 1994-01-09 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 907 |