version 1.47.4.10, 2002/11/11 21:59:09 |
version 1.48, 2001/04/24 04:30:58 |
|
|
* @(#)mem.c 8.3 (Berkeley) 1/12/94 |
* @(#)mem.c 8.3 (Berkeley) 1/12/94 |
*/ |
*/ |
|
|
|
#include "opt_compat_netbsd.h" |
|
|
/* |
/* |
* Memory special file |
* Memory special file |
*/ |
*/ |
|
|
#include <sys/cdefs.h> |
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
|
#include "opt_compat_netbsd.h" |
|
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/buf.h> |
#include <sys/buf.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
Line 56 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 53 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
#include <sys/fcntl.h> |
#include <sys/fcntl.h> |
#include <sys/conf.h> |
|
|
|
#include <machine/cpu.h> |
#include <machine/cpu.h> |
|
#include <machine/conf.h> |
|
|
#include <uvm/uvm_extern.h> |
#include <uvm/uvm_extern.h> |
|
|
#define DEV_IO 14 /* iopl for compat_10 */ |
|
|
|
extern char *vmmap; /* poor name! */ |
extern char *vmmap; /* poor name! */ |
caddr_t zeropage; |
caddr_t zeropage; |
|
|
dev_type_open(mmopen); |
|
dev_type_read(mmrw); |
|
dev_type_ioctl(mmioctl); |
|
dev_type_mmap(mmmmap); |
|
|
|
const struct cdevsw mem_cdevsw = { |
|
mmopen, nullclose, mmrw, mmrw, mmioctl, |
|
nostop, notty, nopoll, mmmmap, nokqfilter, |
|
}; |
|
|
|
|
|
/*ARGSUSED*/ |
/*ARGSUSED*/ |
int |
int |
mmopen(dev, flag, mode, p) |
mmopen(dev, flag, mode, p) |
Line 89 mmopen(dev, flag, mode, p) |
|
Line 73 mmopen(dev, flag, mode, p) |
|
switch (minor(dev)) { |
switch (minor(dev)) { |
#ifdef COMPAT_10 |
#ifdef COMPAT_10 |
/* This is done by i386_iopl(3) now. */ |
/* This is done by i386_iopl(3) now. */ |
case DEV_IO: |
case 14: |
if (flag & FWRITE) { |
if (flag & FWRITE) { |
struct trapframe *fp; |
struct trapframe *fp; |
fp = curlwp->l_md.md_regs; |
fp = curproc->p_md.md_regs; |
fp->tf_eflags |= PSL_IOPL; |
fp->tf_eflags |= PSL_IOPL; |
} |
} |
break; |
break; |
Line 106 mmopen(dev, flag, mode, p) |
|
Line 90 mmopen(dev, flag, mode, p) |
|
|
|
/*ARGSUSED*/ |
/*ARGSUSED*/ |
int |
int |
|
mmclose(dev, flag, mode, p) |
|
dev_t dev; |
|
int flag, mode; |
|
struct proc *p; |
|
{ |
|
|
|
return (0); |
|
} |
|
|
|
/*ARGSUSED*/ |
|
int |
mmrw(dev, uio, flags) |
mmrw(dev, uio, flags) |
dev_t dev; |
dev_t dev; |
struct uio *uio; |
struct uio *uio; |
Line 118 mmrw(dev, uio, flags) |
|
Line 113 mmrw(dev, uio, flags) |
|
static int physlock; |
static int physlock; |
vm_prot_t prot; |
vm_prot_t prot; |
|
|
if (minor(dev) == DEV_MEM) { |
if (minor(dev) == 0) { |
/* lock against other uses of shared vmmap */ |
/* lock against other uses of shared vmmap */ |
while (physlock > 0) { |
while (physlock > 0) { |
physlock++; |
physlock++; |
Line 139 mmrw(dev, uio, flags) |
|
Line 134 mmrw(dev, uio, flags) |
|
continue; |
continue; |
} |
} |
switch (minor(dev)) { |
switch (minor(dev)) { |
case DEV_MEM: |
|
|
/* minor device 0 is physical memory */ |
|
case 0: |
v = uio->uio_offset; |
v = uio->uio_offset; |
prot = uio->uio_rw == UIO_READ ? VM_PROT_READ : |
prot = uio->uio_rw == UIO_READ ? VM_PROT_READ : |
VM_PROT_WRITE; |
VM_PROT_WRITE; |
pmap_enter(pmap_kernel(), (vaddr_t)vmmap, |
pmap_enter(pmap_kernel(), (vaddr_t)vmmap, |
trunc_page(v), prot, PMAP_WIRED|prot); |
trunc_page(v), prot, PMAP_WIRED|prot); |
pmap_update(pmap_kernel()); |
pmap_update(); |
o = uio->uio_offset & PGOFSET; |
o = uio->uio_offset & PGOFSET; |
c = min(uio->uio_resid, (int)(PAGE_SIZE - o)); |
c = min(uio->uio_resid, (int)(PAGE_SIZE - o)); |
error = uiomove((caddr_t)vmmap + o, c, uio); |
error = uiomove((caddr_t)vmmap + o, c, uio); |
pmap_remove(pmap_kernel(), (vaddr_t)vmmap, |
pmap_remove(pmap_kernel(), (vaddr_t)vmmap, |
(vaddr_t)vmmap + PAGE_SIZE); |
(vaddr_t)vmmap + PAGE_SIZE); |
pmap_update(pmap_kernel()); |
pmap_update(); |
break; |
break; |
|
|
case DEV_KMEM: |
/* minor device 1 is kernel memory */ |
|
case 1: |
v = uio->uio_offset; |
v = uio->uio_offset; |
c = min(iov->iov_len, MAXPHYS); |
c = min(iov->iov_len, MAXPHYS); |
if (!uvm_kernacc((caddr_t)v, c, |
if (!uvm_kernacc((caddr_t)v, c, |
Line 163 mmrw(dev, uio, flags) |
|
Line 161 mmrw(dev, uio, flags) |
|
error = uiomove((caddr_t)v, c, uio); |
error = uiomove((caddr_t)v, c, uio); |
break; |
break; |
|
|
case DEV_NULL: |
/* minor device 2 is EOF/rathole */ |
|
case 2: |
if (uio->uio_rw == UIO_WRITE) |
if (uio->uio_rw == UIO_WRITE) |
uio->uio_resid = 0; |
uio->uio_resid = 0; |
return (0); |
return (0); |
|
|
case DEV_ZERO: |
/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */ |
|
case 12: |
if (uio->uio_rw == UIO_WRITE) { |
if (uio->uio_rw == UIO_WRITE) { |
uio->uio_resid = 0; |
uio->uio_resid = 0; |
return (0); |
return (0); |
Line 186 mmrw(dev, uio, flags) |
|
Line 186 mmrw(dev, uio, flags) |
|
return (ENXIO); |
return (ENXIO); |
} |
} |
} |
} |
if (minor(dev) == DEV_MEM) { |
if (minor(dev) == 0) { |
if (physlock > 1) |
if (physlock > 1) |
wakeup((caddr_t)&physlock); |
wakeup((caddr_t)&physlock); |
physlock = 0; |
physlock = 0; |
Line 210 mmmmap(dev, off, prot) |
|
Line 210 mmmmap(dev, off, prot) |
|
* and /dev/zero is a hack that is handled via the default |
* and /dev/zero is a hack that is handled via the default |
* pager in mmap(). |
* pager in mmap(). |
*/ |
*/ |
if (minor(dev) != DEV_MEM) |
if (minor(dev) != 0) |
return (-1); |
return (-1); |
|
|
if ((u_int)off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0) |
if ((u_int)off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0) |