Annotation of Gnu-Mach/i386/i386at/iopl.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26:  
        !            27: #include <mach/vm_prot.h>
        !            28: #include <mach/machine/vm_types.h>
        !            29: #include <mach/machine/vm_param.h>
        !            30: #include <mach/machine/eflags.h>
        !            31: 
        !            32: #include <ipc/ipc_port.h>
        !            33: 
        !            34: #include <device/io_req.h>
        !            35: 
        !            36: #include <i386/io_port.h>
        !            37: #include <i386/pit.h>
        !            38: 
        !            39: /*
        !            40:  * IOPL device.
        !            41:  */
        !            42: ipc_port_t     iopl_device_port = IP_NULL;
        !            43: mach_device_t  iopl_device = 0;
        !            44: 
        !            45: /*
        !            46:  * Ports that we allow access to.
        !            47:  */
        !            48: io_reg_t iopl_port_list[] = {
        !            49:        /* timer 2 */
        !            50:        0x42,
        !            51:        /* speaker output */
        !            52:        0x61,
        !            53:        /* ATI - savage */
        !            54:        0x1ce, 0x1cf,
        !            55:        /* game port */
        !            56:        0x201,
        !            57:        /* sound board */
        !            58:        0x220, 0x221, 0x222, 0x223, 0x224, 0x225, 0x226, 0x227,
        !            59:        0x228, 0x229, 0x22a, 0x22b, 0x22c, 0x22d, 0x22e, 0x22f,
        !            60:        /* printer */
        !            61:        0x278, 0x279, 0x27a,
        !            62:        0x378, 0x379, 0x37a,
        !            63:        /* ega/vga */
        !            64:        0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7,
        !            65:        0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf,
        !            66:        0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7,
        !            67:        0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, 0x3cd, 0x3ce, 0x3cf,
        !            68:        0x3d0, 0x3d1, 0x3d2, 0x3d3, 0x3d4, 0x3d5, 0x3d6, 0x3d7,
        !            69:        0x3d8, 0x3d9, 0x3da, 0x3db, 0x3dc, 0x3dd, 0x3de, 0x3df,
        !            70:        /* end of list */
        !            71:        IO_REG_NULL,
        !            72:        /* patch space */
        !            73:        0, 0, 0, 0, 0, 0, 0, 0,
        !            74:        0, 0, 0, 0, 0, 0, 0, 0
        !            75: };
        !            76: 
        !            77: int
        !            78: ioplopen(dev, flag, ior)
        !            79:        int     dev;
        !            80:        int     flag;
        !            81:        io_req_t ior;
        !            82: {
        !            83:        iopl_device_port = ior->io_device->port;
        !            84:        iopl_device = ior->io_device;
        !            85: 
        !            86:        io_port_create(iopl_device, iopl_port_list);
        !            87:        return (0);
        !            88: }
        !            89: 
        !            90: 
        !            91: /*ARGSUSED*/
        !            92: ioplclose(dev, flags)
        !            93:        int     dev;
        !            94:        int flags;
        !            95: {
        !            96:        io_port_destroy(iopl_device);
        !            97:        iopl_device_port = IP_NULL;
        !            98:        iopl_device = 0;
        !            99:        return 0;
        !           100: }
        !           101: 
        !           102: /*ARGSUSED*/
        !           103: int iopl_all = 1;
        !           104: ioplmmap(dev, off, prot)
        !           105: int            dev;
        !           106: vm_offset_t    off;
        !           107: vm_prot_t      prot;
        !           108: {
        !           109:     extern vm_offset_t phys_last_addr;
        !           110: 
        !           111:     if (iopl_all) {
        !           112:        if (off == 0)
        !           113:                return 0;
        !           114:        else if (off < 0xa0000)
        !           115:                return -1;
        !           116:        else if (off >= 0x100000 && off <= phys_last_addr)
        !           117:                return -1;
        !           118:        else
        !           119:                return i386_btop(off);
        !           120: 
        !           121:     }
        !           122:        if (off > 0x60000)
        !           123:                return(-1);
        !           124: 
        !           125:        /* Get page frame number for the page to be mapped. */
        !           126: 
        !           127:        return(i386_btop(0xa0000 + off));
        !           128: }
        !           129: 
        !           130: /*
        !           131:  * For DOS compatibility, it's easier to list the ports we don't
        !           132:  * allow access to.
        !           133:  */
        !           134: #define        IOPL_PORTS_USED_MAX     256
        !           135: io_reg_t iopl_ports_used[IOPL_PORTS_USED_MAX] = {
        !           136:        IO_REG_NULL
        !           137: };
        !           138: 
        !           139: boolean_t
        !           140: iopl_port_forbidden(io_port)
        !           141:        int     io_port;
        !           142: {
        !           143:        int     i;
        !           144: 
        !           145: #if 0  /* we only read from these... it should be OK */
        !           146: 
        !           147:        if (io_port <= 0xff)
        !           148:            return TRUE;        /* system ports.  42,61,70,71 allowed above */
        !           149: 
        !           150:        if (io_port >= 0x130 && io_port <= 0x137)
        !           151:            return TRUE;        /* AHA disk */
        !           152: 
        !           153:        if (io_port >= 0x170 && io_port <= 0x177)
        !           154:            return TRUE;        /* HD disk */
        !           155: 
        !           156:        if (io_port >= 0x1f0 && io_port <= 0x1f7)
        !           157:            return TRUE;        /* HD disk */
        !           158: 
        !           159:        if (io_port >= 0x230 && io_port <= 0x237)
        !           160:            return TRUE;        /* AHA disk */
        !           161: 
        !           162:        if (io_port >= 0x280 && io_port <= 0x2df)
        !           163:            return TRUE;        /* 8390 network */
        !           164: 
        !           165:        if (io_port >= 0x300 && io_port <= 0x31f)
        !           166:            return TRUE;        /* 8390 network */
        !           167: 
        !           168:        if (io_port >= 0x330 && io_port <= 0x337)
        !           169:            return TRUE;        /* AHA disk */
        !           170: 
        !           171:        if (io_port >= 0x370 && io_port <= 0x377)
        !           172:            return TRUE;        /* FD disk */
        !           173: 
        !           174:        if (io_port >= 0x3f0 && io_port <= 0x3f7)
        !           175:            return TRUE;        /* FD disk */
        !           176: 
        !           177: #endif
        !           178: 
        !           179:        /*
        !           180:         * Must be OK, as far as we know...
        !           181:         * Record the port in the list, for
        !           182:         * curiosity seekers.
        !           183:         */
        !           184:        for (i = 0; i < IOPL_PORTS_USED_MAX; i++) {
        !           185:            if (iopl_ports_used[i] == io_port)
        !           186:                break;                  /* in list */
        !           187:            if (iopl_ports_used[i] == IO_REG_NULL) {
        !           188:                iopl_ports_used[i] = io_port;
        !           189:                iopl_ports_used[i+1] = IO_REG_NULL;
        !           190:                break;
        !           191:            }
        !           192:        }
        !           193: 
        !           194:        return FALSE;
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * Emulate certain IO instructions for the AT bus.
        !           199:  *
        !           200:  * We emulate writes to the timer control port, 43.
        !           201:  * Only writes to timer 2 are allowed.
        !           202:  *
        !           203:  * Temporarily, we allow reads of any IO port,
        !           204:  * but ONLY if the thread has the IOPL device mapped
        !           205:  * and is not in V86 mode.
        !           206:  *
        !           207:  * This is a HACK and MUST go away when the DOS emulator
        !           208:  * emulates these IO ports, or when we decide that
        !           209:  * the DOS world can get access to all uncommitted IO
        !           210:  * ports.  In that case, config() should remove the IO
        !           211:  * ports for devices it exists from the allowable list.
        !           212:  */
        !           213: boolean_t
        !           214: iopl_emulate(regs, opcode, io_port)
        !           215:        struct i386_saved_state *regs;
        !           216:        int     opcode;
        !           217:        int     io_port;
        !           218: {
        !           219:        iopb_tss_t      iopb;
        !           220: 
        !           221:        iopb = current_thread()->pcb->ims.io_tss;
        !           222:        if (iopb == 0)
        !           223:            return FALSE;               /* no IO mapped */
        !           224: 
        !           225:        /*
        !           226:         * Handle outb to the timer control port,
        !           227:         * for timer 2 only.
        !           228:         */
        !           229:        if (io_port == PITCTL_PORT) {
        !           230: 
        !           231:            int io_byte = regs->eax & 0xff;
        !           232: 
        !           233:            if (((iopb->bitmap[PITCTR2_PORT >> 3] & (1 << (PITCTR2_PORT & 0x7)))
        !           234:                == 0)   /* allowed */
        !           235:             && (opcode == 0xe6 || opcode == 0xee)      /* outb */
        !           236:             && (io_byte & 0xc0) == 0x80)               /* timer 2 */
        !           237:            {
        !           238:                outb(io_port, io_byte);
        !           239:                return TRUE;
        !           240:            }
        !           241:            return FALSE;       /* invalid IO to port 42 */
        !           242:        }
        !           243: 
        !           244:        /*
        !           245:         * If the thread has the IOPL device mapped, and
        !           246:         * the io port is not on the 'forbidden' list, allow
        !           247:         * reads from it.  Reject writes.
        !           248:         *
        !           249:         * Don`t do this for V86 mode threads
        !           250:         * (hack for DOS emulator XXX!)
        !           251:         */
        !           252:        if (!(regs->efl & EFL_VM) &&
        !           253:            iopb_check_mapping(current_thread(), iopl_device) &&
        !           254:            !iopl_port_forbidden(io_port))
        !           255:        {
        !           256:            /*
        !           257:             * handle inb, inw, inl
        !           258:             */
        !           259:            switch (opcode) {
        !           260:                case 0xE4:              /* inb imm */
        !           261:                case 0xEC:              /* inb dx */
        !           262:                    regs->eax = (regs->eax & 0xffffff00)
        !           263:                                | inb(io_port);
        !           264:                    return TRUE;
        !           265: 
        !           266:                case 0x66E5:            /* inw imm */
        !           267:                case 0x66ED:            /* inw dx */
        !           268:                    regs->eax = (regs->eax & 0xffff0000)
        !           269:                                | inw(io_port);
        !           270:                    return TRUE;
        !           271: 
        !           272:                case 0xE5:              /* inl imm */
        !           273:                case 0xED:              /* inl dx */
        !           274:                    regs->eax = inl(io_port);
        !           275:                    return TRUE;
        !           276: 
        !           277:                default:
        !           278:                    return FALSE;       /* OUT not allowed */
        !           279:            }
        !           280:        }
        !           281: 
        !           282:        /*
        !           283:         * Not OK.
        !           284:         */
        !           285:        return FALSE;
        !           286: }
        !           287: 

unix.superglobalmegacorp.com

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