2.11BSD/sys/pdp/mem.c
/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)mem.c 1.3 (2.11BSD GTE) 1996/5/15
*/
#include "param.h"
#include "../machine/seg.h"
#include "user.h"
#include "conf.h"
#include "uio.h"
/*
* This routine is callable only from the high
* kernel as it assumes normal mapping and doesn't
* bother to save 'seg5'.
*/
mmrw(dev, uio, flag)
dev_t dev;
register struct uio *uio;
int flag;
{
register struct iovec *iov;
int error = 0;
register u_int c;
u_int on;
char zero[1024];
if (minor(dev) == 3)
bzero(zero, sizeof (zero));
while (uio->uio_resid && error == 0) {
iov = uio->uio_iov;
if (iov->iov_len == 0) {
uio->uio_iov++;
uio->uio_iovcnt--;
if (uio->uio_iovcnt < 0)
panic("mmrw");
continue;
}
switch (minor(dev)) {
/* minor device 0 is physical memory (/dev/mem) */
case 0:
mapseg5((memaddr)(uio->uio_offset>>6),
((btoc(8192)-1)<<8)|RW);
on = uio->uio_offset & 077L;
c = MIN(iov->iov_len, 8192 - on);
error = uiomove(SEG5+on, c, uio);
normalseg5();
break;
/* minor device 1 is kernel memory (/dev/kmem) */
case 1:
error = uiomove((caddr_t)uio->uio_offset, iov->iov_len, uio);
break;
/* minor device 2 is EOF/RATHOLE (/dev/null) */
case 2:
if (uio->uio_rw == UIO_READ)
return(0);
c = iov->iov_len;
iov->iov_base += c;
iov->iov_len -= c;
uio->uio_offset += c;
uio->uio_resid -= c;
break;
/* minor device 3 is ZERO (/dev/zero) */
case 3:
if (uio->uio_rw == UIO_WRITE)
return(EIO);
c = MIN(iov->iov_len, sizeof (zero));
error = uiomove(zero, c, uio);
break;
default:
return(EINVAL);
} /* switch */
} /* while */
return(error);
}
/*
* Internal versions of mmread(), mmwrite()
* used by disk driver ecc routines.
*/
getmemc(addr)
long addr;
{
register int a, c, d;
/*
* bn = addr >> 6
* on = addr & 077
*/
a = UISA[0];
d = UISD[0];
UISA[0] = addr >> 6;
UISD[0] = RO; /* one click, read only */
c = fuibyte((caddr_t)(addr & 077));
UISA[0] = a;
UISD[0] = d;
return(c);
}
putmemc(addr,contents)
long addr;
int contents;
{
register int a, d;
/*
* bn = addr >> 6
* on = addr & 077
*/
a = UISA[0];
d = UISD[0];
UISA[0] = addr >> 6;
UISD[0] = RW; /* one click, read/write */
suibyte((caddr_t)(addr & 077), contents);
UISA[0] = a;
UISD[0] = d;
}