Annotation of coherent/b/STREAMS/i386/md.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.