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

##### Functions

    cret              X
    csv               X

##### Variables

    __ovno            X

##### Macros

    ovh               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:
       7: #if defined(LIBC_SCCS) && !defined(KERNEL) && !defined(SUPERVISOR)
       8:         <@(#)csv.s	2.4 (2.11BSD GTE) 12/24/92\0>
       9:         .even
      10: #endif
      11:
      12: /*
      13:  * C register save and restore routines.  When a C routine is called its stack
      14:  * frame (after csv or ovhandlr have set things up) looks like this:
      15:  *
      16:  *	_________________________________
      17:  *	| return address to caller 	|
      18:  *	|-------------------------------|
      19:  * r5->	| old r5 ("frame pointer")	|
      20:  *	|-------------------------------|
      21:  *	| previous __ovno		|
      22:  *	|-------------------------------|
      23:  *	| old r4			|
      24:  *	|-------------------------------|
      25:  *	| old r3			|
      26:  *	|-------------------------------|
      27:  *	| old r2			|
      28:  *	|-------------------------------|
      29:  * sp->	| empty parameter slot		|
      30:  *	|_______________________________|
      31:  *
      32:  * The "empty parameter slot" is a simple optimization the compiler uses to
      33:  * avoid overhead in its generated parameter cleanup code after a function
      34:  * has been called.  Rather than (for example) generating:
      35:  *
      36:  *	mov	foo,-(sp)	/ push parameter
      37:  *	jsr	pc,bar		/ call function
      38:  *	tst	(sp)+		/ throw away parameter
      39:  *
      40:  * The compiler always keeps one empty slot on the stack and generates:
      41:  *
      42:  *	mov	foo,(sp)	/ pass parameter
      43:  *	jsr	pc,bar		/ call function
      44:  *
      45:  * The savings are not quite so dramatic when more than one parameter is
      46:  * passed, but still worth the effort.  If the function has any local stack
      47:  * variables, space for them will have be be allocated by the function thereby
      48:  * "moving" the empty parameter slot down.
      49:  */
      50:
      51: /*
      52:  * KERNEP and SUPERVISOR (network code) notes:
      53:  *
      54:  * Stack checking can be enabled for the KERNEL (and SUPERVISOR network)
      55:  * by defining CHECKSTACK in the config file.  Looks to see if the
      56:  * kernel and supervisor (network) stacks have collided, etc.
      57:  *
      58:  * Networking kernel doesn't currently need overlays (and probably never
      59:  * will).  If it's ever necessary to overlay the networking code, it would
      60:  * be done in exactly the same manner as that used by the kernel.  This would
      61:  * actually end up simplifying things ...
      62:  *
      63:  * It's debatable whether or not the standard library, KERNEL, and
      64:  * SUPERVISOR copies of csv/cret should be integrated this way, because
      65:  * the ifdef's sometimes make it hard to keep track of things.  But the
      66:  * code and comments here are complicated enough that it's worth the effort
      67:  * to keep all three versions in general sync.
      68:  */
      69: #include "DEFS.h"
      70:
      71: #ifndef SUPERVISOR              /* networking kernel doesn't use overlays */
      72: #ifdef KERNEL
      73: #include "../machine/mch_iopage.h"
      74: #include "../machine/koverlay.h"
      75: #endif
      76:
      77: .data
      78: #ifdef KERNEL
      79: .globl  ova, ovd                / overlay descriptor tables
      80: #endif
      81: .globl  __ovno                  / currently mapped overlay
      82: __ovno: 0
      83: .text
      84:
      85: .globl  _etext                  / used by cret to determine returns to overlay
      86:                                 / area (any return address higher than _etext)
      87:                                 / the loader defines only if referenced
      88:
      89: /*
      90:  * The loader (/bin/ld) generates `thunks' for functions loaded in overlays.
      91:  * A thunk resides in the base segment and takes the name _foo which is the
      92:  * function's interface to the outside world (this allows pointers to functions
      93:  * to work even if functions are located in overlays).  The function itself is
      94:  * renamed to ~foo.
      95:  *
      96:  * ovhndlr(1-9,a-f) are called from the thunks via a jsr r5 after r1 is set to
      97:  * the location of the first instruction in the subroutine after the call to
      98:  * csv (~foo+4).
      99:  *
     100:  *	_foo:	mov	$~foo+4,r1
     101:  *		jsr	r5,ovhndlr`n'
     102:  *
     103:  * The ovhndlr`n' in turn move the requested overlay number into r0 and
     104:  * branch to ovhndlr which sets the overlay, simulates a csv and transfers to
     105:  * (r1) (~foo+4).  Thus, the function's call to csv is bypassed.
     106:  */
     107: #define ovh(x, n)       .globl  ovhndlr/**/x; \
     108:                 ovhndlr/**/x: \
     109:                         mov     $n,r0; \
     110:                         br      ovhndlr;
     111:
     112: ovh(1,001);     ovh(2,002);     ovh(3,003);     ovh(4,004)
     113: ovh(5,005);     ovh(6,006);     ovh(7,007);     ovh(8,010)
     114: ovh(9,011);     ovh(a,012);     ovh(b,013);     ovh(c,014)
     115: ovh(d,015);     ovh(e,016);     ovh(f,017)
     116:
     117: #ifndef KERNEL
     118: emt     = 0104000               / overlays switched by emulator trap
     119:                                 / overlay number is placed in r0
     120: #endif KERNEL
     121:
     122: /*
     123:  * ovhndlr(ov::r0, ~foo+4::r1, _foo+8::r5)
     124:  *
     125:  * Ovhandler builds the new stack frame as fast as possible to avoid problems
     126:  * with getting interrupted halfway through.  if we get interrupted between the
     127:  * "jsr r5,ovhndlr`x'" and the "mov sp,r5" below and a longjmp is attempted,
     128:  * rollback will fail utterly.  If we get interrupted before we finish saving
     129:  * registers reserved for register variables and an attempt is made to longjmp
     130:  * to the caller of our service routine rollback will incorrectly pull `saved'
     131:  * register values from the incomplete stack frame leading to
     132:  * non-deterministic behavior.
     133:  *
     134:  * There's very little that can be done about this asside from changing the
     135:  * entire stack frame sequence which involves changes to the compiler, loader,
     136:  * this file and any other routine (like rollback) which `knows' how the C
     137:  * stack frame is put together ...
     138:  */
     139: ovhndlr:
     140: #if defined(KERNEL) && defined(CHECKSTACK)
     141:         cmp     sp, $_u         / before the u. area?
     142:         blo     9f              /   yes, assume it's remapped, so OK
     143:         cmp     sp, $KERN_SBASE / falling off the bottom?
     144:         bhi     9f              /   no, also OK
     145:         spl     7               / lock out interrupts
     146:         halt                    / can't 'panic', that uses the stack!
     147:         br      .               / in case continue is done
     148: 9:
     149: #endif
     150:         mov     sp,r5           / simulate a csv ...
     151:         mov     __ovno,-(sp)
     152:         cmp     r0,(sp)         / is the requested overlay already mapped?
     153:         beq     1f
     154: #ifdef KERNEL
     155:         mov     PS,-(sp)        / save PS
     156:         SPL7
     157:         mov     r0,__ovno       / set new overlay number
     158:         asl     r0              / compute descriptor index and map
     159:         mov     ova(r0), OVLY_PAR / the new overlay in
     160:         mov     ovd(r0), OVLY_PDR
     161:         mov     (sp)+,PS        / restore PS, unmask interrupts
     162: #else
     163:         emt                     /   no, ask the kernel for it ...
     164:         mov     r0,__ovno       /     and indicate the new overlay
     165:         /*
     166: 	 * SPECIAL NOTE: the pair of instructions "emt" and "mov r0,__ovno"
     167: 	 * form a race condition.  A signal can interrupt the sequence
     168: 	 * causing all sorts of nastiness if the signal routine calls a
     169: 	 * routine in the old overlay or is itself in the old overlay ...
     170: 	 * There is no solution that doesn't involve changing the way
     171: 	 * an overlay switch from the kernal.  Most [potential] solutions
     172: 	 * significantly increase the overhead of an overlay switch.
     173: 	 * A tenable solution has yet to be found ...
     174: 	 */
     175: #endif
     176: 1:
     177:         mov     r4,-(sp)
     178:         mov     r3,-(sp)
     179:         mov     r2,-(sp)
     180:         jsr     pc,(r1)         / jsr leaves empty parameter slot on stack
     181: #endif /* !SUPERVISOR */
     182:
     183:
     184: /*
     185:  * Csv for routines called directly (in base or intra-overlay calls).
     186:  * no overlays have been changed, so we just save the previous overlay
     187:  * number on the stack.  Note that r0 isn't set to the current overlay
     188:  * because we weren't called through a thunk.
     189:  */
     190: .globl  csv
     191: csv:
     192: #if (defined(KERNEL) || defined(SUPERVISOR)) && defined(CHECKSTACK)
     193: #ifdef SUPERVISOR
     194:         cmp     sp,$NET_STOP    / out of the top of the stack?
     195:         bhi     8f              /   yes, die
     196:         cmp     sp,$NET_SBASE   / falling off the bottom?
     197:         bhi     9f              /   no, so OK
     198: 8:
     199:         spl     7               / lock out interrupts
     200:         halt                    / can't 'panic', that uses the stack!
     201:         br      .               / in case continue is done
     202: 9:
     203: #else
     204:         cmp     sp,$_u          / before the u. area?
     205:         blo     9f              / assume it was remapped, so OK
     206:         cmp     sp,$KERN_SBASE  / falling off the bottom?
     207:         bhi     9f              / no, so OK
     208:         spl     7               / lock out interrupts
     209:         halt                    / can't 'panic', that uses the stack!
     210:         br      .               / in case continue is done
     211: 9:
     212: #endif
     213: #endif
     214:         mov     r5,r1           / save transfer address,
     215:         mov     sp,r5
     216: #ifdef SUPERVISOR
     217:         clr     -(sp)
     218: #else
     219:         mov     __ovno,-(sp)
     220: #endif
     221:         mov     r4,-(sp)
     222:         mov     r3,-(sp)
     223:         mov     r2,-(sp)
     224:         jsr     pc,(r1)
     225:
     226: /*
     227:  * Cret is used by everyone so it has to check if we're returning to an
     228:  * overlay different from the one that may be currently mapped.
     229:  */
     230: .globl  cret
     231: cret:
     232: #if (defined(KERNEL) || defined(SUPERVISOR)) && defined(CHECKSTACK)
     233: #ifdef SUPERVISOR
     234:         cmp     sp,$NET_STOP    / out of the top of the stack?
     235:         bhi     8f              /   yes, die
     236:         cmp     sp,$NET_SBASE   / falling off the bottom?
     237:         bhi     9f              /   no, so OK
     238: 8:
     239:         spl     7               / lock out interrupts
     240:         halt                    / can't 'panic', that uses the stack!
     241:         br      .               / in case continue is done
     242: 9:
     243: #else
     244:         cmp     sp,$_u          / before the u. area?
     245:         blo     9f              / assume it was remapped, so OK
     246:         cmp     sp,$KERN_SBASE  / falling off the bottom?
     247:         bhi     9f              / no, so OK
     248:         spl     7               / lock out interrupts
     249:         halt                    / can't 'panic', that uses the stack!
     250:         br      .               / in case continue is done
     251: 9:
     252: #endif
     253: #endif
     254:         mov     r5,r2
     255: #ifdef SUPERVISOR
     256:         tst     -(r2)           / skip over overlay slot
     257: #else
     258:         mov     -(r2),r4        / r4 = old __ovno - if non-zero we've started
     259:         bne     2f              /   using overlays so we'll have to make
     260:                                 /   sure the old overlay is mapped if we're
     261:                                 /   returning to the overlay area
     262: 1:
     263: #endif
     264:         mov     -(r2),r4        / restore registers, reset stack, pop frame
     265:         mov     -(r2),r3        /   pointer and return
     266:         mov     -(r2),r2
     267:         mov     r5,sp           / (more interrupt problems here *sigh* ...)
     268:         mov     (sp)+,r5
     269:         rts     pc
     270: #ifndef SUPERVISOR
     271: 2:
     272:         /*
     273: 	 * Not returning to base segment, so check that the right
     274: 	 * overlay is mapped in, and if not change the mapping.
     275: 	 */
     276:         cmp     r4,__ovno       / current overlay same as old overlay?
     277:         beq     1b              /   lucked out!
     278: #if     defined(KERNEL) && defined(INET)
     279:         cmp     2(r5),$Kretu    / must always restore overlays if returning
     280:         beq     3f              /   from SKcall
     281: #endif
     282:         cmp     2(r5),$_etext   / returning to base segment?
     283:         blos    1b              /   sometimes things *do* work out ...
     284: #ifdef KERNEL
     285: 3:
     286:         mov     PS,-(sp)        / (sigh) returning to a different overlay
     287:         SPL7
     288:         mov     r4,__ovno       / set new overlay number
     289:         asl     r4              / and map the new overlay in
     290:         mov     ova(r4), OVLY_PAR
     291:         mov     ovd(r4), OVLY_PDR
     292:         mov     (sp)+,PS        / restore PS, unmask interrupts
     293:         br      1b
     294: #else
     295:         mov     r0,r3           / (sigh) returning to a different overlay -
     296:         mov     r4,r0           /   have to save r0 because we can't trash
     297:         emt                     /   a function result and ask UNIX to switch
     298:         mov     r4,__ovno       /   the old overlay in
     299:         mov     r3,r0           / note that as with ovhndlr the pair "emt"
     300:         br      1b              /   "mov r4,__ovno" can be interrupted
     301: #endif
     302: #endif /* !SUPERVISOR */

#### Defined functions

cret declared in line 230; defined in line 231; used 1 times

- in line 230

csv declared in line 190; defined in line 191; used 1 times

- in line 190

emt defined in line 118; used 2 times

- in line 163, 297

ovhndlr defined in line 139; never used

#### Defined variables

__ovno declared in line 81; defined in line 82; used 8 times

- in line 81, 151, 157, 164, 219, 276, 288, 298

#### Defined macros

ovh defined in line 107; used 15 times

- in line 112-115(15)

Last modified: 1992-12-25 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 617 |