/* * Memory special file * minor device 0 is physical memory * minor device 1 is kernel memory * minor device 2 is EOF/BITBUCKET * * Block device stuff added */ /*** Rewritten for Interdata 7-8/32 *** Code is made simpler (and less portable!) by the assumption *** that all physical memory is contiguous and directly addressable. ***/ #include "../h/local.h" #ifdef SCCS_ID static char SCCS_ID [] = "@(#)mem.c 5.1 13:40:24 - 82/05/21 "; #endif SCCS_ID #include "../h/param.h" #include "../h/systm.h" #include "../h/dir.h" #include "../h/user.h" #include "../h/buf.h" #include "../h/conf.h" #include "../h/seg.h" /* * If you think some of these expressions look weird, remember * that memtop contains the last valid address. Thus, * addresses <= memtop are valid (as opposed to < memtop) */ mmread(dev) dev_t dev; { caddr_t addr = u.u_offset; register c = u.u_count; if(minor(dev) == 0 || minor(dev) == 1) { if(addr <= memtop) { if(&addr[c] > memtop) c = memtop - addr + 1; iomove (addr, c, B_READ); } else u.u_error = ENODEV; } else if(minor(dev) == 2) { ; } else u.u_error = ENODEV; } mmwrite(dev) dev_t dev; { caddr_t addr = u.u_offset; register c = u.u_count; if(minor(dev) == 0 || minor(dev) == 1) { if(addr <= memtop) { if(&addr[c] > memtop) c = memtop - addr + 1; iomove(addr, c, B_WRITE); } else u.u_error = ENODEV; } else if(minor(dev) == 2) { u.u_count = 0; u.u_base += c; u.u_offset += c; return; } else u.u_error = ENODEV; } #ifdef GWW_BD struct buf mmtab; /* Imagine, 'block memory' */ extern struct { int mm_start; int mm_blocks; } mmmap[]; extern int mmndev; mmstrategy(bp) struct buf *bp; { int dev; dev = minor(bp->b_dev); if(bp->b_blkno < mmmap[dev].mm_blocks) { bp->b_un.b_addr = (caddr_t) ((bp->b_blkno + mmmap[dev].mm_start) * PGSIZE); bp->b_resid = 0; iodone(bp); } else { bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; iodone(bp); } } mmopen(dev) { } mmclose(dev) { } #endif GWW_BD