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