|
|
1.1 ! root 1: /* ! 2: * these routines are written in C until the 386 compiler/assembler ! 3: * are available ! 4: * ! 5: * Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991 ! 6: */ ! 7: ! 8: #include <sys/debug.h> ! 9: #include <kernel/reg.h> ! 10: ! 11: #include <sys/coherent.h> ! 12: #include <sys/clist.h> ! 13: #include <sys/errno.h> ! 14: #include <sys/inode.h> ! 15: #include <sys/proc.h> ! 16: #include <sys/seg.h> ! 17: #include <signal.h> ! 18: #include <sys/uproc.h> ! 19: #include <sys/buf.h> ! 20: ! 21: #define min(a, b) ((a) < (b) ? (a) : (b)) ! 22: ! 23: /* ! 24: * dmacopy() ! 25: * ! 26: * Copy "npage" 4 kbyte pages from phys addr "from" to phys addr "to". ! 27: */ ! 28: ! 29: dmacopy(npage, from, to) ! 30: long npage; ! 31: cseg_t *from, *to; ! 32: { ! 33: int work = workAlloc (); /* Get a virtual click pair. */ ! 34: ! 35: ASSERT (npage > 0); ! 36: ! 37: for (;;) { ! 38: ptable1_v [work] = * from ++ | SEG_SRW; ! 39: ptable1_v [work + 1] = * to ++ | SEG_SRW; ! 40: memcpy (ctob (work + 1), ctob (work), NBPC); ! 41: ! 42: if (-- npage == 0) ! 43: break; ! 44: ! 45: mmuupd (); /* flush paging TLB */ ! 46: } ! 47: ! 48: workFree(work); ! 49: } ! 50: ! 51: /* ! 52: * dmaclear() ! 53: * ! 54: * Given a byte count, and a system global address, zero-fill the memory. ! 55: */ ! 56: ! 57: void ! 58: dmaclear (nbytes, to) ! 59: long nbytes; ! 60: paddr_t to; ! 61: { ! 62: unsigned off; ! 63: int n; ! 64: cseg_t *base; ! 65: int work = workAlloc (); /* Get a virtual click pair. */ ! 66: ! 67: off = to & (NBPC - 1); ! 68: base = & sysmem.u.pbase [btocrd (to)]; ! 69: n = min (nbytes, NBPC - off); ! 70: ptable1_v [work] = * base ++ | SEG_SRW; ! 71: ! 72: memset (ctob (work) + off, 0, n); ! 73: nbytes -= n; ! 74: ! 75: while (nbytes > 0) { ! 76: n = min (nbytes, NBPC); ! 77: ptable1_v [work] = * base ++ | SEG_SRW; ! 78: mmuupd (); ! 79: ! 80: memset (ctob (work), 0, n); ! 81: nbytes -= n; ! 82: } ! 83: ! 84: workFree(work); ! 85: } ! 86: ! 87: /* ! 88: * dmain() ! 89: * ! 90: * Copy in "nbytes" from system global address "to" to kernel address ! 91: * "vaddr". ! 92: */ ! 93: dmain(nbytes, to, vaddr) ! 94: long nbytes; ! 95: paddr_t to; ! 96: caddr_t vaddr; ! 97: { ! 98: unsigned off; ! 99: unsigned n, n1; ! 100: cseg_t* base; ! 101: int work = workAlloc (); /* Get a virtual click pair. */ ! 102: ! 103: off = to & (NBPC - 1); ! 104: base = & sysmem.u.pbase [btocrd (to)]; ! 105: ! 106: n = min (nbytes, NBPC - off); ! 107: ptable1_v [work] = * base ++ | SEG_SRW; ! 108: ! 109: memcpy (vaddr, ctob (work) + off, n); ! 110: vaddr += n; ! 111: nbytes -= n; ! 112: ! 113: while (nbytes > 0) { ! 114: n = min (nbytes, NBPC); ! 115: ptable1_v [work] = * base ++ | SEG_SRW; ! 116: mmuupd (); ! 117: ! 118: memcpy (vaddr, ctob (work), n); ! 119: vaddr += n; ! 120: nbytes -= n; ! 121: } ! 122: ! 123: workFree (work); ! 124: } ! 125: ! 126: /* ! 127: * dmaout() ! 128: * ! 129: * Copy out "nbytes" from kernel address "vaddr" to system global address ! 130: * "to". ! 131: */ ! 132: dmaout(nbytes, to, vaddr) ! 133: long nbytes; ! 134: paddr_t to; ! 135: caddr_t vaddr; ! 136: { ! 137: unsigned off; ! 138: unsigned n, n1; ! 139: cseg_t *base; ! 140: int work = workAlloc (); /* Get a virtual click pair. */ ! 141: ! 142: off = to & (NBPC - 1); ! 143: base = & sysmem.u.pbase [btocrd (to)]; ! 144: ! 145: n = min (nbytes, NBPC - off); ! 146: ptable1_v [work] = * base ++ | SEG_SRW; ! 147: ! 148: memcpy (ctob (work) + off, vaddr, n); ! 149: vaddr += n; ! 150: nbytes -= n; ! 151: ! 152: while (nbytes > 0) { ! 153: n = min (nbytes, NBPC); ! 154: ptable1_v [work] = * base ++ | SEG_SRW; ! 155: mmuupd (); ! 156: ! 157: memcpy (ctob (work), vaddr, n); ! 158: vaddr += n; ! 159: nbytes -= n; ! 160: } ! 161: ! 162: workFree(work); ! 163: } ! 164: ! 165: /* ! 166: * dmaio2() ! 167: * ! 168: * Copy in "nbytes" from an I/O port "port" to the system global address ! 169: * "to". ! 170: */ ! 171: dmaio2(nbytes, to, port) ! 172: long nbytes, port; ! 173: paddr_t to; ! 174: { ! 175: unsigned off; ! 176: int n; ! 177: cseg_t *base; ! 178: int work = workAlloc (); /* Get a virtual click pair. */ ! 179: ! 180: off = to & (NBPC - 1); ! 181: base = & sysmem.u.pbase [btocrd (to)]; ! 182: ! 183: n = min (nbytes, NBPC - off); ! 184: ptable1_v [work] = * base ++ | SEG_SRW; ! 185: ! 186: io2seg (n, ctob (work) + off, port); ! 187: nbytes -= n; ! 188: ! 189: while (nbytes > 0) { ! 190: n = min (nbytes, NBPC); ! 191: ptable1_v [work] = * base ++ | SEG_SRW; ! 192: mmuupd (); ! 193: io2seg(n, ctob (work), port); ! 194: nbytes -= n; ! 195: } ! 196: ! 197: workFree(work); ! 198: } ! 199: ! 200: /* ! 201: * dma2io() ! 202: * ! 203: * Copy out "nbytes" from the system global address "from" to an I/O port ! 204: * "port". ! 205: */ ! 206: dma2io(nbytes, to, port) ! 207: long nbytes, port; ! 208: paddr_t to; ! 209: { ! 210: unsigned off; ! 211: int n; ! 212: cseg_t *base; ! 213: int work = workAlloc (); /* Get a virtual click pair. */ ! 214: ! 215: off = to & (NBPC - 1); ! 216: base = & sysmem.u.pbase [btocrd (to)]; ! 217: ! 218: n = min (nbytes, NBPC - off); ! 219: ptable1_v [work] = * base ++ | SEG_SRW; ! 220: ! 221: seg2io (n, ctob (work) + off, port); ! 222: nbytes -= n; ! 223: ! 224: while (nbytes > 0) { ! 225: n = min (nbytes, NBPC); ! 226: ptable1_v [work] = * base ++ | SEG_SRW; ! 227: mmuupd (); ! 228: seg2io (n, ctob (work), port); ! 229: nbytes -= n; ! 230: } ! 231: ! 232: workFree(work); ! 233: } ! 234: ! 235: /* ! 236: * pxcopy() ! 237: * ! 238: * copy "n" bytes of data at kernel address "v" from address "uo" in: ! 239: * system global address space (space & SEG_VIRT) ! 240: * physical memory ! (space & SEG_VIRT) ! 241: * Rights are determined by (space & ~ SEG_VIRT): ! 242: * "v" can be anywhere in kernel address space SEG_386_KD ! 243: * "v" must be an address accessible to the user SEG_386_UD ! 244: * Up to one click of data can be copied. No alignment restrictions ! 245: * on "uo" apply. ! 246: */ ! 247: pxcopy(uo, v, n, space) ! 248: unsigned uo; ! 249: char *v; ! 250: register int n; ! 251: { ! 252: cseg_t * base; ! 253: int save; ! 254: int err; ! 255: int work; ! 256: ! 257: if (n > NBPC) ! 258: return 0; ! 259: ! 260: work = workAlloc (); ! 261: ! 262: if (space & SEG_VIRT) { ! 263: space &= ~ SEG_VIRT; ! 264: base = & sysmem.u.pbase [btocrd (uo)]; ! 265: ptable1_v [work] = * base ++ | SEG_SRW; ! 266: ptable1_v [work + 1] = * base ++ | SEG_SRW; ! 267: } else { ! 268: ptable1_v [work] = (uo & ~ (NBPC - 1)) + SEG_SRW; ! 269: ptable1_v [work + 1] = (uo & ~ (NBPC - 1)) + NBPC + SEG_SRW; ! 270: } ! 271: ! 272: save = setspace (space); ! 273: err = kucopy (ctob (work) + (uo & (NBPC - 1)), v, n); ! 274: setspace (save); ! 275: ! 276: workFree (work); ! 277: return err; ! 278: } ! 279: ! 280: ! 281: /* ! 282: * xpcopy() ! 283: * ! 284: * copy "n" bytes of data from kernel address "v" to address "uo" in: ! 285: * system global address space (space&SEG_VIRT) ! 286: * physical memory !(space&SEG_VIRT) ! 287: * Rights are determined by (space&~SEG_VIRT): ! 288: * "v" can be anywhere in kernel address space SEG_386_KD ! 289: * "v" must be an address accessible to the user SEG_386_UD ! 290: * Up to one click of data can be copied. No alignment restrictions on "uo" ! 291: * apply. ! 292: */ ! 293: ! 294: xpcopy(v, uo, n, space) ! 295: char *v; ! 296: unsigned uo; ! 297: register int n; ! 298: { ! 299: cseg_t * base; ! 300: int save; ! 301: int err; ! 302: int work; ! 303: ! 304: if (n > NBPC) ! 305: return 0; ! 306: ! 307: work = workAlloc (); ! 308: ! 309: if (space & SEG_VIRT) { ! 310: space &= ~ SEG_VIRT; ! 311: base = & sysmem.u.pbase [btocrd (uo)]; ! 312: ptable1_v [work] = * base ++ | SEG_SRW; ! 313: ptable1_v [work + 1] = * base ++ | SEG_SRW; ! 314: } else { ! 315: ptable1_v [work] = (uo & ~ (NBPC - 1)) + SEG_SRW; ! 316: ptable1_v [work + 1] = (uo & ~ (NBPC - 1)) + NBPC + SEG_SRW; ! 317: } ! 318: ! 319: save = setspace (space); ! 320: err = ukcopy (v, ctob (work) + (uo & (NBPC - 1)), n); ! 321: setspace (save); ! 322: ! 323: workFree (work); ! 324: return err; ! 325: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.