|
|
1.1 ! root 1: /* (lgl- ! 2: * md.c ! 3: * ! 4: * The information contained herein is a trade secret of Mark Williams ! 5: * Company, and is confidential information. It is provided under a ! 6: * license agreement, and may be copied or disclosed only under the ! 7: * terms of that agreement. Any reproduction or disclosure of this ! 8: * material without the express written authorization of Mark Williams ! 9: * Company or persuant to the license agreement is unlawful. ! 10: * ! 11: * COHERENT Version 2.3.37 ! 12: * Copyright (c) 1982, 1983, 1984. ! 13: * An unpublished work by Mark Williams Company, Chicago. ! 14: * All rights reserved. ! 15: -lgl) */ ! 16: /* ! 17: * Coherent 386 ! 18: * IBM PC ! 19: * Machine dependent stuff. ! 20: * ! 21: */ ! 22: #include <sys/coherent.h> ! 23: #include <sys/reg.h> ! 24: #include <sys/clist.h> ! 25: #include <errno.h> ! 26: #include <sys/inode.h> ! 27: #include <sys/proc.h> ! 28: #include <sys/seg.h> ! 29: #include <signal.h> ! 30: #include <sys/uproc.h> ! 31: #include <sys/buf.h> ! 32: ! 33: /* ! 34: * Set up a new process. ! 35: */ ! 36: msetusr(ip, sp) ! 37: caddr_t sp; ! 38: caddr_t ip; ! 39: { ! 40: u.u_regl[EIP] = ip; ! 41: u.u_regl[UESP] = sp; ! 42: } ! 43: ! 44: /* ! 45: * Given an irq level (1..15) and an irq function pointer, try to hook the ! 46: * function into the desired interrupt. Do not allow resetting of the ! 47: * clock interrupt, irq 0. ! 48: * ! 49: * On success, return 1. ! 50: * If the level number is invalid or the interrupt is already in use, ! 51: * do nothing but return 0. ! 52: * ! 53: * Make an entry in the "vecs" table, for use by the assist. ! 54: * Make sure that the channel on the 8259 is armed. ! 55: * Interrupt vectors 2 and 9 are mapped into channel 9. ! 56: */ ! 57: int ! 58: setivec(level, fun) ! 59: unsigned int level; ! 60: int (*fun)(); ! 61: { ! 62: register int picm; ! 63: extern int (*vecs[])(); ! 64: extern int vret(); ! 65: ! 66: if (level >= NUM_IRQ_LEVELS) ! 67: return 0; ! 68: if (level == 2) ! 69: level = 9; ! 70: if (level==0 || vecs[level]!=&vret) ! 71: return 0; ! 72: ! 73: vecs[level] = fun; ! 74: ! 75: /* ! 76: * NIGEL: The original code here (and matching code below in clrivec ()) ! 77: * takes pains to correctly manipulate the slave PIC chain mask bit in ! 78: * the master PIC. This is redundant, and unnecessarily complex, so I ! 79: * have removed it to aid the process of adding a more rational system ! 80: * of interrupt handling for the DDI/DKI. ! 81: * ! 82: * Now the slave PIC chain mask bit is enabled (via a modification to ! 83: * code in "i386/as.s") at startup, and it should never be disabled. ! 84: * ! 85: * The rational interrupt scheme requires that the implementations of ! 86: * the DDI/DKI functions know the base-level mask value so that they ! 87: * can correctly (and quickly) manipulate masks to raise and lower ! 88: * priority levels even when deeply nested inside interrupts (see the ! 89: * implementations of those functions for a deeper discussion of the ! 90: * issues involved). This function cooperates with the new system via ! 91: * the DDI_BASE_..._MASK () macro, which either manipulates the mask ! 92: * register as the old code did or passes responsibility over to the ! 93: * new DDI/DKI scheme if it has been enabled. ! 94: * ! 95: * The new macro-calls are defined in <sys/reg.h> ! 96: */ ! 97: ! 98: if ( level >= LOWEST_SLAVE_IRQ ) { ! 99: picm = inb(SPICM); ! 100: picm &= ~(0x01 << (level-LOWEST_SLAVE_IRQ)); ! 101: DDI_BASE_SLAVE_MASK (picm); ! 102: } else { ! 103: picm = inb(PICM); ! 104: picm &= ~(0x01 << level); ! 105: DDI_BASE_MASTER_MASK (picm); ! 106: } ! 107: return 1; ! 108: } ! 109: ! 110: /* ! 111: * Clear an interrupt vector. ! 112: */ ! 113: clrivec(level) ! 114: register int level; ! 115: { ! 116: register int picm; ! 117: extern int (*vecs[])(); ! 118: extern int vret(); ! 119: ! 120: if ((level &= 0x0F) == 2) ! 121: level = 9; ! 122: if (level == 0) ! 123: printf("clrivec: level=%d", level); ! 124: vecs[level] = &vret; ! 125: ! 126: /* ! 127: * NIGEL: This code has been modified to match the changes made to the ! 128: * setivec () routine above. See the comment there for details. ! 129: */ ! 130: ! 131: if (level >= LOWEST_SLAVE_IRQ) { ! 132: picm = inb(SPICM); ! 133: picm |= (0x01 << (level-LOWEST_SLAVE_IRQ)); ! 134: DDI_BASE_SLAVE_MASK (picm); ! 135: } else { ! 136: picm = inb(PICM); ! 137: picm |= (0x01 << level); ! 138: DDI_BASE_SLAVE_MASK (picm); ! 139: } ! 140: } ! 141: ! 142: ! 143: /* ! 144: * Convert an array of filesystem 3 byte ! 145: * numbers to longs. This routine, unlike the old one, ! 146: * is independent of the order of bytes in a long. ! 147: * Bytes have 8 bits, though. ! 148: */ ! 149: l3tol(lp, cp, nl) ! 150: register long *lp; ! 151: register unsigned char *cp; ! 152: register unsigned nl; ! 153: { ! 154: register long l; ! 155: ! 156: if (nl != 0) { ! 157: do { ! 158: l = (long)cp[0] << 16; ! 159: l |= (long)cp[1]; ! 160: l |= (long)cp[2] << 8; ! 161: cp += 3; ! 162: *lp++ = l; ! 163: } while (--nl); ! 164: } ! 165: } ! 166: /* ! 167: * Convert an array of longs into an array ! 168: * of filesystem 3 byte numbers. This routine, unlike ! 169: * the old one, is independent of the order of bytes in ! 170: * a long. Bytes have 8 bits. ! 171: */ ! 172: ltol3(cp, lp, nl) ! 173: register char *cp; ! 174: register long *lp; ! 175: register unsigned nl; ! 176: { ! 177: register long l; ! 178: ! 179: if (nl != 0) { ! 180: do { ! 181: l = *lp++; ! 182: cp[0] = l >> 16; ! 183: cp[1] = l; ! 184: cp[2] = l >> 8; ! 185: cp += 3; ! 186: } while (--nl); ! 187: } ! 188: } ! 189: ! 190: ! 191: /* ! 192: * Given a port number and a bit value, write the bit value into ! 193: * the tss iomap. ! 194: * ! 195: * Bit value of 0 enables user I/O for that port. ! 196: * Bit value of 1 disables user I/O for that port. ! 197: * ! 198: * Return 1 if port number is valid for the bitmap, else 0. ! 199: */ ! 200: int ! 201: kiopriv(port, bit) ! 202: unsigned int port, bit; ! 203: { ! 204: extern int tssIoMap; ! 205: extern int tssIoEnd; ! 206: int ret = 0; ! 207: int * ip; ! 208: unsigned int offset = port >> 5; ! 209: int shift = port & 0x1f; ! 210: int mask = 1 << shift; ! 211: int val = (bit & 1) << shift; ! 212: ! 213: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) { ! 214: ip = (& tssIoMap) + offset; ! 215: *ip &= ~mask; /* clear old bit value */ ! 216: *ip |= val; /* or in desired new bit value */ ! 217: ret = 1; ! 218: } ! 219: return ret; ! 220: } ! 221: ! 222: /* ! 223: * Given a 32 bit mask and a word offset into the tss io map, ! 224: * bitwise or the mask into the map. ! 225: * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc. ! 226: * Current valid range for offset is 0..63, covering ports 0..7ff. ! 227: * ! 228: * Return the new map word. ! 229: */ ! 230: int ! 231: iomapOr(val, offset) ! 232: int val, offset; ! 233: { ! 234: extern int tssIoMap; ! 235: extern int tssIoEnd; ! 236: int ret; ! 237: int * ip; ! 238: ! 239: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) { ! 240: ip = (& tssIoMap) + offset; ! 241: ret = *ip |= val; ! 242: } ! 243: return ret; ! 244: } ! 245: ! 246: /* ! 247: * Given a 32 bit mask and a word offset into the tss io map, ! 248: * bitwise and the mask into the map. ! 249: * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc. ! 250: * Current valid range for offset is 0..63, covering ports 0..7ff. ! 251: * ! 252: * Return the new map word. ! 253: */ ! 254: int ! 255: iomapAnd(val, offset) ! 256: int val, offset; ! 257: { ! 258: extern int tssIoMap; ! 259: extern int tssIoEnd; ! 260: int ret; ! 261: int * ip; ! 262: ! 263: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) { ! 264: ip = (& tssIoMap) + offset; ! 265: ret = *ip &= val; ! 266: } ! 267: return ret; ! 268: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.