Annotation of Gnu-Mach/i386/i386at/iopl.c, revision 1.1.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.