# 2.11BSD#431 - /usr/src/sys/pdp/machdep.c

##### Functions

    mapalloc          X
    mapfree           X
    sendsig           X
    setregs           X
    sigreturn         X
    sofub_alloc       X
    sofub_relse       X

##### Variables

    _ubmap            X
    sofub_addr        X
    sofub_base        X
    sofub_off         X
    sofub_size        X
    ub_map            X
    ub_meter          X
    ub_wantmr         X

##### Macros

    BUSY              X
    B_UBUF            X
    E_UBUF            X
    QMEG              X
    SOFUB_DEBUG       X
    UMAPSIZ           X
    WANTED            X
    exad              X

##### struct's

    a                 X
    sigframe          X

       1: /*
       2:  * Copyright (c) 1986 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:  *	@(#)machdep.c	2.4 (2.11BSD) 1999/9/13
       7:  */
       8:
       9: #include "param.h"
      10: #include "../machine/psl.h"
      11: #include "../machine/reg.h"
      12:
      13: #include "signalvar.h"
      14: #include "user.h"
      15: #include "proc.h"
      16: #include "buf.h"
      17: #include "map.h"
      18: #include "uba.h"
      19: #include "syslog.h"
      20:
      21: #ifdef CURRENTLY_EXPANDED_INLINE
      22: /*
      23:  * Clear registers on exec
      24:  */
      25: setregs(entry)
      26:     u_int entry;
      27: {
      28:     u.u_ar0[PC] = entry & ~01;
      29:     u.u_fps.u_fpsr = 0;
      30: }
      31: #endif
      32:
      33: /*
      34:  * Send an interrupt to process.
      35:  *
      36:  * Stack is set up to allow trampoline code stored at u.u_pcb.pcb_sigc (as
      37:  * specified by the user process) to call the user's real signal catch
      38:  * routine, followed by sys sigreturn to the sigreturn routine below (see
      39:  * /usr/src/lib/libc/pdp/sys/sigvec.s).  After sigreturn resets the signal
      40:  * mask, the stack, and the frame pointer, it returns to the user specified
      41:  * pc, ps.
      42:  */
      43: sendsig(p, sig, mask)
      44:     int (*p)(), sig;
      45:     long mask;
      46: {
      47:     struct sigframe {
      48:         int sf_signum;
      49:         int sf_code;
      50:         struct  sigcontext *sf_scp;
      51:         struct  sigcontext sf_sc;
      52:     };
      53:     struct sigframe sf;
      54:     register struct sigframe *sfp = &sf;
      55:     register struct sigcontext *scp = &sf.sf_sc;
      56:     register int *regs;
      57:     int oonstack;
      58:     caddr_t n;
      59:
      60: #ifdef  DIAGNOSTIC
      61:     printf("sendsig %d to %d mask=%O action=%o\n", sig, u.u_procp->p_pid,
      62:         mask, p);
      63: #endif
      64:     regs = u.u_ar0;
      65:     oonstack = u.u_sigstk.ss_flags & SA_ONSTACK;
      66:     /*
      67: 	 * Allocate and validate space for the signal frame.
      68: 	 */
      69:     if  ((u.u_psflags & SAS_ALTSTACK) &&
      70:          !(u.u_sigstk.ss_flags & SA_ONSTACK) &&
      71:          (u.u_sigonstack & sigmask(sig)))
      72:         {
      73:         n = u.u_sigstk.ss_base + u.u_sigstk.ss_size - sizeof (sf);
      74:         u.u_sigstk.ss_flags |= SA_ONSTACK;
      75:         }
      76:     else
      77:         n = (caddr_t)regs[R6] - sizeof (sf);
      78:     if  (!(u.u_sigstk.ss_flags & SA_ONSTACK) &&
      79:          n < (caddr_t)-ctob(u.u_ssize) &&
      80:          !grow(n))
      81:         {
      82:         /*
      83: 		 * Process has trashed its stack; give it an illegal
      84: 		 * instruction violation to halt it in its tracks.
      85: 		 */
      86:         fatalsig(SIGILL);
      87:         return;
      88:         }
      89:     /*
      90: 	 * Build the argument list for the signal handler.
      91: 	 */
      92:     sfp->sf_signum = sig;
      93:     if (sig == SIGILL || sig == SIGFPE) {
      94:         sfp->sf_code = u.u_code;
      95:         u.u_code = 0;
      96:     } else
      97:         sfp->sf_code = 0;
      98:     sfp->sf_scp = (struct sigcontext *)
      99:             (n + (u_int)&((struct sigframe *)0)->sf_sc);
     100:     /*
     101: 	 * Build the signal context to be used by sigreturn.
     102: 	 */
     103:     scp->sc_onstack = oonstack;
     104:     scp->sc_mask = mask;
     105:     scp->sc_sp = regs[R6];
     106:     scp->sc_fp = regs[R5];
     107:     scp->sc_r1 = regs[R1];
     108:     scp->sc_r0 = regs[R0];
     109:     scp->sc_pc = regs[R7];
     110:     scp->sc_ps = regs[RPS];
     111:     scp->sc_ovno = u.u_ovdata.uo_ovbase ? u.u_ovdata.uo_curov : 0;
     112:     copyout((caddr_t)sfp, n, sizeof(*sfp));
     113:     regs[R0] = (int)p;
     114:     regs[R6] = (int)n;
     115:     regs[R7] = (int)u.u_pcb.pcb_sigc;
     116:     regs[RPS] &= ~PSL_T;
     117: }
     118:
     119: /*
     120:  * System call to cleanup state after a signal
     121:  * has been taken.  Reset signal mask and
     122:  * stack state from context left by sendsig (above).
     123:  * Return to previous pc and ps as specified by
     124:  * context left by sendsig. Check carefully to
     125:  * make sure that the user has not modified the
     126:  * ps to gain improper priviledges or to cause
     127:  * a machine fault.
     128:  */
     129: sigreturn()
     130: {
     131:     struct a {
     132:         struct sigcontext *scp;
     133:     };
     134:     struct sigcontext sc;
     135:     register struct sigcontext *scp = &sc;
     136:     register int *regs = u.u_ar0;
     137:
     138:     u.u_error = copyin((caddr_t)((struct a *)u.u_ap)->scp, (caddr_t *)scp, sizeof(*scp));
     139:     if (u.u_error)
     140:         return;
     141:     if ((scp->sc_ps & PSL_USERCLR) != 0 || !USERMODE(scp->sc_ps)) {
     142:         u.u_error = EINVAL;
     143:         return;
     144:     }
     145:     u.u_error = EJUSTRETURN;
     146:     if  (scp->sc_onstack & SA_ONSTACK)
     147:         u.u_sigstk.ss_flags |= SA_ONSTACK;
     148:     else
     149:         u.u_sigstk.ss_flags &= ~SA_ONSTACK;
     150:     u.u_procp->p_sigmask = scp->sc_mask & ~sigcantmask;
     151:     regs[R6] = scp->sc_sp;
     152:     regs[R5] = scp->sc_fp;
     153:     regs[R1] = scp->sc_r1;
     154:     regs[R0] = scp->sc_r0;
     155:     regs[R7] = scp->sc_pc;
     156:     regs[RPS] = scp->sc_ps;
     157: }
     158:
     159: #define UMAPSIZ 10
     160:
     161: struct  mapent _ubmap[UMAPSIZ];
     162: struct  map ub_map[1] = {
     163:     &_ubmap[0], &_ubmap[UMAPSIZ], "ub_map"
     164: };
     165: int ub_wantmr;
     166:
     167: #ifdef UCB_METER
     168: struct ubmeter  ub_meter;
     169: #endif
     170:
     171: /*
     172:  * Routine to allocate the UNIBUS map and initialize for a UNIBUS device.
     173:  * For buffers already mapped by the UNIBUS map, perform the physical to
     174:  * UNIBUS-virtual address translation.
     175:  */
     176: mapalloc(bp)
     177:     register struct buf *bp;
     178: {
     179:     register struct ubmap *ubp;
     180:     register int ub_nregs;
     181:     ubadr_t ubaddr;
     182:     long paddr;
     183:     int s, ub_first;
     184:
     185:     if (!ubmap)
     186:         return;
     187: #ifdef UCB_METER
     188:     ++ub_meter.ub_calls;
     189: #endif
     190:     paddr = ((long)((u_int)bp->b_xmem)) << 16
     191:         | ((long)((u_int)bp->b_un.b_addr));
     192:     if (!(bp->b_flags & B_PHYS)) {
     193:         /*
     194: 		 * Transfer in the buffer cache.
     195: 		 * Change the buffer's physical address
     196: 		 * into a UNIBUS address for the driver.
     197: 		 */
     198: #ifdef UCB_METER
     199:         ++ub_meter.ub_remaps;
     200: #endif
     201:         ubaddr = paddr - (((ubadr_t)bpaddr) << 6) + BUF_UBADDR;
     202:         bp->b_un.b_addr = (caddr_t)loint(ubaddr);
     203:         bp->b_xmem = hiint(ubaddr);
     204:         bp->b_flags |= B_UBAREMAP;
     205:     }
     206:     else {
     207:         /*
     208: 		 * Physical I/O.
     209: 		 * Allocate a section of the UNIBUS map.
     210: 		 */
     211:         ub_nregs = (int)btoub(bp->b_bcount);
     212: #ifdef UCB_METER
     213:         ub_meter.ub_pages += ub_nregs;
     214: #endif
     215:         s = splclock();
     216:         while (!(ub_first = malloc(ub_map,ub_nregs))) {
     217: #ifdef UCB_METER
     218:             ++ub_meter.ub_fails;
     219: #endif
     220:             ub_wantmr = 1;
     221:             sleep(ub_map, PSWP + 1);
     222:         }
     223:         splx(s);
     224:
     225:         ubp = &UBMAP[ub_first];
     226:         bp->b_xmem = ub_first >> 3;
     227:         bp->b_un.b_addr = (caddr_t)((ub_first & 07) << 13);
     228:         bp->b_flags |= B_MAP;
     229:
     230:         while (ub_nregs--) {
     231:             ubp->ub_lo = loint(paddr);
     232:             ubp->ub_hi = hiint(paddr);
     233:             ubp++;
     234:             paddr += (ubadr_t)UBPAGE;
     235:         }
     236:     }
     237: }
     238:
     239: mapfree(bp)
     240:     register struct buf *bp;
     241: {
     242:     register int s;
     243:     ubadr_t ubaddr;
     244:     long paddr;
     245:
     246:     if (bp->b_flags & B_MAP) {
     247:         /*
     248: 		 * Free the UNIBUS map registers
     249: 		 * allocated to this buffer.
     250: 		 */
     251:         s = splclock();
     252:         mfree(ub_map, (size_t)btoub(bp->b_bcount), (bp->b_xmem << 3) |
     253:             (((u_int)bp->b_un.b_addr >> 13) & 07));
     254:         splx(s);
     255:         bp->b_flags &= ~B_MAP;
     256:         if (ub_wantmr)
     257:             wakeup((caddr_t) ub_map);
     258:         ub_wantmr = 0;
     259:     }
     260:     else if (bp->b_flags & B_UBAREMAP) {
     261:         /*
     262: 		 * Translate the UNIBUS virtual address of this buffer
     263: 		 * back to a physical memory address.
     264: 		 */
     265:         ubaddr = ((long)((u_int) bp->b_xmem)) << 16
     266:             | ((long)((u_int)bp->b_un.b_addr));
     267:         paddr = ubaddr - (long)BUF_UBADDR + (((long)bpaddr) << 6);
     268:         bp->b_un.b_addr = (caddr_t)loint(paddr);
     269:         bp->b_xmem = hiint(paddr);
     270:         bp->b_flags &= ~B_UBAREMAP;
     271:     }
     272: }
     273:
     274: #define SOFUB_DEBUG
     275:
     276: #ifdef  SOFUB_MAP
     277: /*
     278:  * Implement soft unibus map for 18 bit controllers present in a
     279:  * 22-bit q-bus systems.  Initially only used by the tape driver
     280:  * (for tar and dump) but when this was integrated into 2.11BSD changes
     281:  * were made to support the RX02 driver as well.
     282:  *
     283:  * Adapted to 2.11BSD and rather heavily revised by:
     284:  *
     285:  *		steven schultz (sms)
     286:  *		GTE Government Systems
     287:  *
     288:  *	from the original by:
     289:  *
     290:  *		matt jacob
     291:  *		University of California at Davis
     292:  *		22-Nov-84
     293: */
     294:
     295: #define QMEG    ((long)(256L*1024L))
     296: #define exad(x,y)   ((long)((long)x<<16|(unsigned)y))
     297: #define B_UBUF      exad(bp->b_xmem,(u_int)bp->b_un.b_addr)
     298: #define E_UBUF      (B_UBUF + (long) bp->b_bcount)
     299:
     300:     size_t  sofub_addr, sofub_off;
     301:     memaddr sofub_base;
     302:     unsigned sofub_size;
     303:
     304: static  int bpxm, bpadd;
     305: static  int sofub_flags;
     306: #define BUSY    1
     307: #define WANTED  2
     308:
     309: /*
     310:  * sofub_alloc - allocate usage of soft unibus map
     311:  *
     312:  *	called from strategy routine of device drivers.
     313:  *
     314:  *	returns 0 if not okay, else returns 1.
     315:  *	expects a buffer pointer as an argument
     316:  *	expects all addresses in bp already validated (by physio)
     317:  *	sets appropriate bits and calls iodone if error
     318: */
     319:
     320: int
     321: sofub_alloc(bp)
     322: register struct buf *bp;
     323:     {
     324:     register int s;
     325:     register int count;
     326:     size_t uaddr;
     327:     memaddr sbase;
     328:
     329:     if  (E_UBUF < QMEG)
     330:         return(1);  /* okay, < 256kb	*/
     331:     else if (bp->b_bcount > sofub_size)
     332:         {
     333:         log(LOG_ERR, "I/O >10kb on %d,%d\n",
     334:             major(bp->b_dev),minor(bp->b_dev));
     335:         bp->b_flags |= B_ERROR;
     336:         bp->b_error = EFAULT;
     337:         iodone(bp);
     338:         return(0);
     339:         }
     340:
     341:     s = splbio();
     342:
     343:     while   (sofub_flags & BUSY)
     344:         {
     345: #ifdef SOFUB_DEBUG
     346:         printf("sofub_alloc sleep\n");
     347: #endif
     348:         sofub_flags |= WANTED;
     349:         sleep((caddr_t) &sofub_flags,PSWP+2);
     350:         }
     351:
     352:     sofub_flags |= BUSY;
     353:     splx(s);
     354:
     355:     /*
     356: 	 * now calculate virtual address of user buffer...
     357: 	 */
     358:
     359:     sofub_off = (size_t)((u_int)bp->b_un.b_addr & 077);
     360:     sofub_addr = (size_t)(((u_int)bp->b_un.b_addr>>6)&01777) | (((int) bp->b_xmem) << 10);
     361:
     362:     bpadd = (u_int)bp->b_un.b_addr;
     363:     bpxm = bp->b_xmem;
     364:
     365:     /*
     366: 	 * if this is a write, we have to fetch data from user buffer first
     367: 	 */
     368:
     369:     if  ((bp->b_flags & B_READ) == 0)
     370:         {
     371:         count = bp->b_bcount;
     372:         uaddr = sofub_addr;
     373:         sbase = sofub_base;
     374:
     375:         /* first, copy all 8kb-1click segments.. */
     376:
     377:         s = spl5();
     378:
     379:         while   (count > (8192-64))
     380:             {
     381:             copyv(uaddr,sofub_off,sbase,0,(8192-64));
     382:             count -= (8192-64);
     383:             uaddr += 0177;  /* add 8192-64 bytes */
     384:             sbase += 0177;
     385:             }
     386:         /* copy last residual segment */
     387:
     388:         copyv(uaddr,sofub_off,sbase,0,count);
     389:         splx(s);
     390:         }
     391:     /* put in new 18 bit address */
     392:
     393:     bp->b_un.b_addr = (caddr_t)ctob((long)sofub_base);
     394:
     395:     /*
     396: 	 * don't turn sofub_base to clicks here
     397: 	 * because half the work is done by
     398: 	 * having it in click form here, i.e.,
     399: 	 * bp->b_xmem would equal
     400: 	 * ctob(x)>>16 (hi six bits of 18)
     401: 	 */
     402:
     403:     bp->b_xmem = (sofub_base >> 10)&3;
     404:     return(1);
     405:     }
     406:
     407: /*
     408:  * sofub_relse	- release sofub_map
     409:  *
     410:  *	passed a buffer pointer and a transfer byte count...
     411:  *	(for use if was a read)
     412:  *
     413:  *	note, we are called from the driver's interrupt service routine.
     414: */
     415:
     416: sofub_relse(bp,count)
     417: register struct buf *bp;
     418: register unsigned count;
     419:     {
     420:     register int s;
     421:     size_t uaddr;
     422:     memaddr sbase;
     423:     long    ebuf = E_UBUF;
     424:     caddr_t newaddr;
     425:     u_int   newxmem;
     426:
     427: /*
     428:  * If the transfer was entirely below or above the 'bounce buffer' then
     429:  * this I/O request was done without the soft map being allocated.
     430: */
     431:     if  (ebuf < ctob((long)sofub_base) ||
     432:          ebuf > ctob((long)sofub_base) + sofub_size)
     433:         return;
     434: #ifdef  SOFUB_DEBUG
     435:     if  (ebuf > QMEG)       /* Can't happen, transfer over 256kb */
     436:         panic("sofub_relse");
     437: #endif
     438:
     439: /*
     440:  * Next make sure that the I/O request is the one which currently has the
     441:  * map allocated to it.
     442: */
     443:     newaddr = (caddr_t)((sofub_addr << 6) | sofub_off);
     444:     newxmem = ((u_int)sofub_addr >> 10) & 077;
     445:
     446:     if  (newaddr != bpadd ||  newxmem != bpxm)
     447:         {
     448: #ifdef  SOFUB_DEBUG
     449:         printf("sofub_relse: new %o:%o, old %o:%o\n",
     450:             newxmem, newaddr, bpxm, bpadd);
     451: #endif
     452:         bp->b_flags |= B_ERROR;
     453:         bp->b_error = EFAULT;
     454:         return;
     455:         }
     456:
     457:     if  (bp->b_flags & B_READ)
     458:         {
     459:         uaddr = sofub_addr;
     460:         sbase = sofub_base;
     461:
     462:         /*
     463: 		 * first, copy all 8kb-1click segments..
     464: 		 */
     465:         s = spl5();
     466:         while   (count > (8192-64))
     467:             {
     468:             copyv(sbase,0,uaddr,sofub_off,(8192-64));
     469:             count -= (8192-64);
     470:             uaddr += 0177;  /* add 8192-64 bytes */
     471:             sbase += 0177;
     472:             }
     473:         /*
     474: 		 * copy last residual segment
     475: 		 */
     476:         copyv(sbase,0,uaddr,sofub_off,count);
     477:         splx(s);
     478:         }
     479:
     480:     bp->b_un.b_addr = newaddr;
     481:     bp->b_xmem = newxmem;
     482:
     483:     sofub_flags &= ~BUSY;
     484:
     485:     if  (sofub_flags & WANTED)
     486:         {
     487: #ifdef  SOFUB_DEBUG
     488:         printf("sofub_relse: wakeup\n");
     489: #endif
     490:         sofub_flags &= ~WANTED;
     491:         wakeup((caddr_t) &sofub_flags);
     492:         }
     493:     }
     494: #endif	/* SOFUB_MAP */

#### Defined functions

mapalloc defined in line 176; used 16 times

- in /usr/src/sys/pdpuba/br.c line 199
- in /usr/src/sys/pdpuba/dr.c line 109
- in /usr/src/sys/pdpuba/hk.c line 348, 418
- in /usr/src/sys/pdpuba/ht.c line 176
- in /usr/src/sys/pdpuba/ra.c line 657
- in /usr/src/sys/pdpuba/rk.c line 100
- in /usr/src/sys/pdpuba/rl.c line 348
- in /usr/src/sys/pdpuba/rx.c line 150
- in /usr/src/sys/pdpuba/si.c line 139
- in /usr/src/sys/pdpuba/tm.c line 275
- in /usr/src/sys/pdpuba/tmscp.c line 1366
- in /usr/src/sys/pdpuba/ts.c line 124, 261
- in /usr/src/sys/pdpuba/xp.c line 408, 492

mapfree defined in line 239; used 1 times

- in /usr/src/sys/sys/ufs_bio.c line 377

sendsig defined in line 43; used 1 times

- in /usr/src/sys/sys/kern_sig.c line 595

setregs defined in line 25; never used
sigreturn defined in line 129; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 32, 213

sofub_alloc defined in line 320; used 4 times

- in /usr/src/sys/pdpuba/rk.c line 95
- in /usr/src/sys/pdpuba/rl.c line 343
- in /usr/src/sys/pdpuba/rx.c line 145
- in /usr/src/sys/pdpuba/tm.c line 267

sofub_relse defined in line 416; used 6 times

- in /usr/src/sys/pdpuba/rk.c line 189
- in /usr/src/sys/pdpuba/rl.c line 478
- in /usr/src/sys/pdpuba/rx.c line 272, 328
- in /usr/src/sys/pdpuba/tm.c line 431, 565

#### Defined variables

_ubmap defined in line 161; used 2 times

- in line 163(2)

bpadd defined in line 304; used 3 times

- in line 362, 446-450(2)

bpxm defined in line 304; used 3 times

- in line 363, 446-450(2)

sofub_addr defined in line 300; used 6 times

- in line 360, 372, 443-444(2), 459
- in /usr/src/sys/pdp/machdep2.c line 178

sofub_base defined in line 301; used 12 times

- in line 373, 393, 403, 431-432(2), 460
- in /usr/src/sys/pdp/machdep2.c line 168-179(6)

sofub_flags defined in line 305; used 8 times

- in line 343-352(4), 483-491(4)

sofub_off defined in line 300; used 7 times

- in line 359, 381, 388, 443, 468, 476
- in /usr/src/sys/pdp/machdep2.c line 179

sofub_size defined in line 302; used 3 times

- in line 331, 432
- in /usr/src/sys/pdp/machdep2.c line 166

ub_map defined in line 162; used 13 times

- in line 216-221(2), 252-257(2)
- in /usr/src/sys/pdp/machdep.c line 216-221(2), 252-257(2)
- in /usr/src/sys/pdp/machdep2.c line 348-350(2), 362
- in /usr/src/sys/pdpif/if_uba.c line 188
- in /usr/src/sys/sys/sys_net.c line 158

ub_meter defined in line 168; used 4 times

- in line 188, 199, 213-218(2)

ub_wantmr defined in line 165; used 6 times

- in line 220, 256-258(2)
- in /usr/src/sys/pdp/machdep.c line 220, 256-258(2)

#### Defined struct's

a defined in line 131; used 2 times

- in line 138(2)

sigframe defined in line 47; used 6 times

- in line 53-54(4), 99(2)

#### Defined macros

BUSY defined in line 306; used 3 times

- in line 343, 352, 483

B_UBUF defined in line 297; used 1 times

- in line 298

E_UBUF defined in line 298; used 2 times

- in line 329, 423

QMEG defined in line 295; used 2 times

- in line 329, 435

SOFUB_DEBUG defined in line 274; used 4 times

- in line 345, 434, 448, 487

UMAPSIZ defined in line 159; used 2 times

- in line 161-163(2)

WANTED defined in line 307; used 3 times

- in line 348, 485-490(2)

exad defined in line 296; used 1 times

- in line 297

Last modified: 1999-09-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1305 |