Annotation of coherent/b/STREAMS/i386/md.c, revision 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.