V10/sys/io/mem.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Memory special file
 *	minor device 0 is physical memory
 *	minor device 1 is kernel memory 
 *	minor device 2 is EOF/RATHOLE
 *	minor device 3 is unibus memory (addressed by shorts)
 *	minor device 4 is obsolete
 *	minor device 5 is processor registers
 */

#include "sys/param.h"
#include "sys/user.h"
#include "sys/buf.h"
#include "sys/conf.h"
#include "sys/pte.h"
#include "sys/mtpr.h"
#include "sys/vm.h"

int mmread(), mmwrite();
struct cdevsw mmcdev = cdinit(nulldev, nulldev, mmread, mmwrite, nodev);

char *vmmap;
struct pte *mmap;

mmread(dev)
{
	register int o; long lbuf;
	register unsigned c, v;

	switch (minor(dev)) {

	case 0:
		while (u.u_count != 0 && u.u_error == 0) {
			if (fubyte(u.u_base) == -1)
				goto fault;
			v = btop(Ltol(u.u_offset));
			*(int *)mmap = v | (PG_V | PG_KR);
			mtpr(TBIS, vmmap);
			o = Ltol(u.u_offset) & PGOFSET;
			c = min((unsigned)(NBPG - o), u.u_count);
			c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
			if (copyout((caddr_t)&vmmap[o], u.u_base, c))
				goto fault;
			u.u_count -= c;
			u.u_base += c;
			u.u_offset = Lladd(u.u_offset, c);
		}
		return;

	case 1:
		iomove((caddr_t)Ltol(u.u_offset), u.u_count, B_READ);
		return;

	case 2:
		return;

	case 3:
		if (!useracc(u.u_base, u.u_count, B_WRITE))
			goto fault;
		if (UNIcpy((caddr_t)Ltol(u.u_offset), u.u_base, u.u_count, B_READ))
			goto fault;
		c = u.u_count;
		u.u_count = 0;
		u.u_base += c;
		u.u_offset = Lladd(u.u_offset, c);
		return;

	case 5:
		c = min(u.u_count, sizeof(long));
		lbuf = umfpr(Ltol(u.u_offset)/sizeof(long));
		if (copyout((caddr_t)&lbuf, u.u_base, c))
			goto fault;
		u.u_count -= c;
		u.u_base += c;
		u.u_offset = Lladd(u.u_offset, c);
		return;
	}
fault:
	u.u_error = EFAULT;
	return;
}

mmwrite(dev)
{
	register int o; long lbuf;
	register unsigned c, v;

	switch (minor(dev)) {

	case 0:
		while (u.u_count != 0 && u.u_error == 0) {
			if (fubyte(u.u_base) == -1)
				goto fault;
			v = btop(Ltol(u.u_offset));
			*(int *)mmap = v | (PG_V | PG_KW);
			mtpr(TBIS, vmmap);
			o = Ltol(u.u_offset) & PGOFSET;
			c = min((unsigned)(NBPG - o), u.u_count);
			c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
			if (copyin(u.u_base, (caddr_t)&vmmap[o], c))
				goto fault;
			u.u_count -= c;
			u.u_base += c;
			u.u_offset = Lladd(u.u_offset, c);
		}
		return;

	case 1:
		iomove((caddr_t)Ltol(u.u_offset), u.u_count, B_WRITE);
		return;

	case 2:
		u.u_offset = Lladd(u.u_offset, u.u_count);
		u.u_count = 0;
		return;

	case 3:
		if (!useracc(u.u_base, u.u_count, B_READ))
			goto fault;
		if (UNIcpy((caddr_t)Ltol(u.u_offset), u.u_base, u.u_count, B_WRITE))
			goto fault;
		u.u_base += u.u_count;
		u.u_offset = Lladd(u.u_offset, u.u_count);
		u.u_count = 0;
		return;

	case 5:
		if (u.u_count < sizeof(long))
			goto fault;
		if (copyin(u.u_base, (caddr_t)&lbuf, sizeof(long)))
			goto fault;
		if (umtpr(Ltol(u.u_offset) / sizeof(long), lbuf) == 0)
			goto fault;
		u.u_count -= sizeof(long);
		u.u_base += sizeof(long);
		u.u_offset = Lladd(u.u_offset, sizeof(long));
		return;
	}
fault:
	u.u_error = EFAULT;
	return;
}