1: /*
2: * ISR 'ramdisk' driver.
3: * This driver implements a 'ram disk' in main memory.
4: *
5: * For the block device, the driver works by remapping buffer header
6: * addresses and simply returning. This way the buffer copy is done only
7: * once. It is faster than any mass storage device in access time and
8: * transfer time (both are immediate) and consumes less cpu time in the
9: * driver than most.
10: *
11: * Gregory Travis, Institute for Social Research, September 1984
12: * Mucked about, KB, March 1987.
13: * Remucked and stomped, Casey Leedom, August 1987.
14: */
15:
16: #include "ram.h"
17: #if NRAM > 0
18: #include "param.h"
19: #include "../machine/seg.h"
20:
21: #include "buf.h"
22: #include "user.h"
23: #include "conf.h"
24: #include "map.h"
25: #include "systm.h"
26: #include "dk.h"
27:
28: #ifdef UCB_METER
29: static int ram_dkn = -1; /* number for iostat */
30: #endif
31:
32: u_int ram_size = NRAM; /* (patchable) ram disk size */
33: memaddr ram_base; /* base of ram disk area */
34:
35: /*
36: * Allocate core for ramdisk(s)
37: */
38: size_t
39: raminit()
40: {
41: if (ram_size) {
42: if (ram_base = malloc(coremap, ram_size*btoc(NBPG))) {
43: #ifdef UCB_METER
44: dk_alloc(&ram_dkn, 1, "ram", 0L);
45: #endif
46: return(ram_size*btoc(NBPG));
47: }
48: printf("ram: nospace\n");
49: }
50: return(0);
51: }
52:
53: ramopen(dev)
54: dev_t dev;
55: {
56: if (minor(dev) || !ram_base)
57: return (ENXIO);
58: return (0);
59: }
60:
61: ramstrategy(bp)
62: register struct buf *bp;
63: {
64: register memaddr ramaddr;
65:
66: if (!ram_base) {
67: printf("ram: not allocated\n");
68: bp->b_error = ENXIO;
69: bp->b_flags |= B_ERROR;
70: goto done;
71: }
72: if(bp->b_blkno < 0 ||
73: ((bp->b_blkno + ((bp->b_bcount+(NBPG-1)) >> PGSHIFT)) > ram_size)) {
74: bp->b_error = EINVAL;
75: bp->b_flags |= B_ERROR;
76: goto done;
77: }
78: #ifdef UCB_METER
79: if (ram_dkn >= 0) {
80: dk_xfer[ram_dkn]++;
81: dk_wds[ram_dkn] += bp->b_bcount>>6;
82: }
83: #endif
84: ramaddr = ram_base + bp->b_blkno * btoc(NBPG);
85: if (bp->b_flags & B_PHYS)
86: ramstart(ramaddr, bp);
87: else if (bp->b_flags & B_READ) {
88: #ifdef DIAGNOSTIC
89: if(bp->b_flags & B_RAMREMAP)
90: panic("ram: remap!");
91: #endif
92: bp->b_flags |= B_RAMREMAP; /* block read (sic) */
93: bp->b_un.b_addr = (caddr_t)(ramaddr << 6);
94: bp->b_xmem = (ramaddr >> 10) & 077;
95: } else
96: if ((bp->b_flags & B_RAMREMAP) == 0)
97: ramstart(ramaddr, bp); /* virgin write */
98: done:
99: iodone(bp);
100: }
101:
102: /*
103: * Start transfer between ram disk (ramaddr) and buffer. Actually completes
104: * synchronously of course, but what the heck.
105: */
106: ramstart(ramaddr, bp)
107: memaddr ramaddr;
108: register struct buf *bp;
109: {
110: register u_int n, c;
111: memaddr bufaddr;
112: caddr_t seg6addr;
113: int error;
114:
115: if (!(n = bp->b_bcount))
116: return;
117: #ifdef UCB_METER
118: if (ram_dkn >= 0)
119: dk_busy |= 1 << ram_dkn;
120: #endif
121: bufaddr = bftopaddr(bp); /* click address of buffer */
122: seg6addr = SEG6 + ((u_int)bp->b_un.b_addr & 077);
123: c = MIN(n, (SEG6+8192)-seg6addr);
124: for (;;) {
125: if (bp->b_flags & B_READ) {
126: mapseg5(ramaddr, ((btoc(8192)-1)<<8)|RO);
127: if (error = fmove(bufaddr, ((btoc(8192)-1)<<8)|RW,
128: SEG5, seg6addr, c))
129: break;
130: } else {
131: mapseg5(ramaddr, ((btoc(8192)-1)<<8)|RW);
132: if (error = fmove(bufaddr, ((btoc(8192)-1)<<8)|RO,
133: seg6addr, SEG5, c))
134: break;
135: }
136: if (!(n -= c))
137: break;
138: ramaddr += btoc(8192);
139: bufaddr += btoc(8192);
140: seg6addr = SEG6;
141: c = MIN(n, 8192);
142: }
143: normalseg5();
144: #ifdef UCB_METER
145: if (ram_dkn >= 0)
146: dk_busy &= ~(1 << ram_dkn);
147: #endif
148: if (error) {
149: bp->b_error = error;
150: bp->b_flags |= B_ERROR;
151: }
152: }
153: #endif NRAM
Defined functions
Defined variables