diff options
author | Thomas Schwinge <tschwinge@gnu.org> | 2007-04-01 22:10:40 +0000 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gnu.org> | 2009-06-18 00:27:07 +0200 |
commit | 123d406152b033dc321d57cd86e45d058746547c (patch) | |
tree | e6b3c96e63ed7d973760e0f7290e573e24777d18 /i386 | |
parent | 861203044a89a8e0cb9b6e0200aad791ee9e5804 (diff) |
2007-04-02 Thomas Schwinge <tschwinge@gnu.org>
* i386/i386/io_emulate.c: Remove file.
* i386/i386/io_emulate.h: Likewise.
* i386/i386at/iopl.c: Likewise.
* i386/Makefrag.am (libkernel_a_SOURCES): Remove the aforementioned
files.
* i386/i386/trap.c: Don't include <i386/io_emulate.h>.
(v86_assist, check_io_fault): Remove functions.
(user_trap): Remove the code referencing the above functions.
* i386/i386at/conf.c (dev_name_list): Remove the `iopl' device.
* DEVELOPMENT: Document this.
Diffstat (limited to 'i386')
-rw-r--r-- | i386/Makefrag.am | 3 | ||||
-rw-r--r-- | i386/i386/io_emulate.c | 107 | ||||
-rw-r--r-- | i386/i386/io_emulate.h | 43 | ||||
-rw-r--r-- | i386/i386/trap.c | 484 | ||||
-rw-r--r-- | i386/i386at/conf.c | 9 | ||||
-rw-r--r-- | i386/i386at/iopl.c | 290 |
6 files changed, 0 insertions, 936 deletions
diff --git a/i386/Makefrag.am b/i386/Makefrag.am index 3b97d86..50eaecf 100644 --- a/i386/Makefrag.am +++ b/i386/Makefrag.am @@ -32,7 +32,6 @@ libkernel_a_SOURCES += \ i386/i386at/immc.c \ i386/i386at/int_init.c \ i386/i386at/interrupt.S \ - i386/i386at/iopl.c \ i386/i386at/kd.c \ i386/i386at/kd.h \ i386/i386at/kd_event.c \ @@ -85,8 +84,6 @@ libkernel_a_SOURCES += \ i386/i386/idt-gen.h \ i386/i386/idt.c \ i386/i386/idt_inittab.S \ - i386/i386/io_emulate.c \ - i386/i386/io_emulate.h \ i386/i386/io_map.c \ i386/i386/io_port.h \ i386/i386/iopb.c \ diff --git a/i386/i386/io_emulate.c b/i386/i386/io_emulate.c deleted file mode 100644 index 0d67257..0000000 --- a/i386/i386/io_emulate.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include <mach/boolean.h> -#include <mach/port.h> -#include <kern/thread.h> -#include <kern/task.h> - -#include <ipc/ipc_port.h> -#include <ipc/ipc_space.h> -#include <ipc/ipc_right.h> -#include <ipc/ipc_object.h> -#include <ipc/ipc_entry.h> - -#include <device/dev_hdr.h> - -#include <i386/thread.h> -#include <i386/io_port.h> -#include <i386/io_emulate.h> - -extern ipc_port_t iopl_device_port; -extern mach_device_t iopl_device; - -int -emulate_io(regs, opcode, io_port) - struct i386_saved_state *regs; - int opcode; - int io_port; -{ - thread_t thread = current_thread(); - -#if AT386 - if (iopl_emulate(regs, opcode, io_port)) - return EM_IO_DONE; -#endif /* AT386 */ - - if (iopb_check_mapping(thread, iopl_device)) - return EM_IO_ERROR; - - /* - * Check for send rights to the IOPL device port. - */ - if (iopl_device_port == IP_NULL) - return EM_IO_ERROR; - { - ipc_space_t space = current_space(); - mach_port_t name; - ipc_entry_t entry; - boolean_t has_rights = FALSE; - - is_write_lock(space); - assert(space->is_active); - - if (ipc_right_reverse(space, (ipc_object_t) iopl_device_port, - &name, &entry)) { - /* iopl_device_port is locked and active */ - if (entry->ie_bits & MACH_PORT_TYPE_SEND) - has_rights = TRUE; - ip_unlock(iopl_device_port); - } - - is_write_unlock(space); - if (!has_rights) { - return EM_IO_ERROR; - } - } - - - /* - * Map the IOPL port set into the thread. - */ - - if (i386_io_port_add(thread, iopl_device) - != KERN_SUCCESS) - return EM_IO_ERROR; - - /* - * Make the thread use its IO_TSS to get the IO permissions; - * it may not have had one before this. - */ - switch_ktss(thread->pcb); - - return EM_IO_RETRY; -} diff --git a/i386/i386/io_emulate.h b/i386/i386/io_emulate.h deleted file mode 100644 index de0d12d..0000000 --- a/i386/i386/io_emulate.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#ifndef _I386_IO_EMULATE_H_ -#define _I386_IO_EMULATE_H_ - -/* - * Return codes from IO emulation. - */ -extern int emulate_io(/* - struct i386_saved_state *regs, - int opcode, - int io_port - */); - -#define EM_IO_DONE 0 /* IO instruction executed, proceed */ -#define EM_IO_RETRY 1 /* IO port mapped, retry instruction */ -#define EM_IO_ERROR 2 /* IO port not mapped */ - -#endif /* _I386_IO_EMULATE_H_ */ diff --git a/i386/i386/trap.c b/i386/i386/trap.c index 2cb81e6..3b51b1a 100644 --- a/i386/i386/trap.c +++ b/i386/i386/trap.c @@ -50,8 +50,6 @@ #include <kern/sched.h> #include <kern/sched_prim.h> -#include <i386/io_emulate.h> - #if MACH_KDB #include <ddb/db_run.h> #include <ddb/db_watch.h> @@ -385,15 +383,6 @@ int user_trap(regs) printf("user trap %d error %d sub %08x\n", type, code, subcode); #endif - if (regs->efl & EFL_VM) { - /* - * If hardware assist can handle exception, - * continue execution. - */ - if (v86_assist(thread, regs)) - return 0; - } - type = regs->trapno; code = 0; subcode = 0; @@ -497,10 +486,6 @@ printf("user trap %d error %d sub %08x\n", type, code, subcode); break; case T_GENERAL_PROTECTION: - if (!(regs->efl & EFL_VM)) { - if (check_io_fault(regs)) - return 0; - } /* Check for an emulated int80 system call. NetBSD-current and Linux use trap instead of call gate. */ if (thread->task->eml_dispatch) { @@ -585,400 +570,6 @@ boolean_t v86_do_sti_immediate = FALSE; int cli_count = 0; int sti_count = 0; -boolean_t -v86_assist(thread, regs) - thread_t thread; - register struct i386_saved_state *regs; -{ - register struct v86_assist_state *v86 = &thread->pcb->ims.v86s; - -/* - * Build an 8086 address. Use only when off is known to be 16 bits. - */ -#define Addr8086(seg,off) ((((seg) & 0xffff) << 4) + (off)) - -#define EFL_V86_SAFE ( EFL_OF | EFL_DF | EFL_TF \ - | EFL_SF | EFL_ZF | EFL_AF \ - | EFL_PF | EFL_CF ) - struct iret_32 { - int eip; - int cs; - int eflags; - }; - struct iret_16 { - unsigned short ip; - unsigned short cs; - unsigned short flags; - }; - union iret_struct { - struct iret_32 iret_32; - struct iret_16 iret_16; - }; - - struct int_vec { - unsigned short ip; - unsigned short cs; - }; - - if (!v86_assist_on) - return FALSE; - - /* - * If delayed STI pending, enable interrupts. - * Turn off tracing if on only to delay STI. - */ - if (v86->flags & V86_IF_PENDING) { - v86->flags &= ~V86_IF_PENDING; - v86->flags |= EFL_IF; - if ((v86->flags & EFL_TF) == 0) - regs->efl &= ~EFL_TF; - } - - if (regs->trapno == T_DEBUG) { - - if (v86->flags & EFL_TF) { - /* - * Trace flag was also set - it has priority - */ - return FALSE; /* handle as single-step */ - } - /* - * Fall through to check for interrupts. - */ - } - else if (regs->trapno == T_GENERAL_PROTECTION) { - /* - * General protection error - must be an 8086 instruction - * to emulate. - */ - register int eip; - boolean_t addr_32 = FALSE; - boolean_t data_32 = FALSE; - int io_port; - - /* - * Set up error handler for bad instruction/data - * fetches. - */ - asm("movl $(addr_error), %0" : "=m" (thread->recover)); - - eip = regs->eip; - while (TRUE) { - unsigned char opcode; - - if (eip > 0xFFFF) { - thread->recover = 0; - return FALSE; /* GP fault: IP out of range */ - } - - opcode = *(unsigned char *)Addr8086(regs->cs,eip); - eip++; - switch (opcode) { - case 0xf0: /* lock */ - case 0xf2: /* repne */ - case 0xf3: /* repe */ - case 0x2e: /* cs */ - case 0x36: /* ss */ - case 0x3e: /* ds */ - case 0x26: /* es */ - case 0x64: /* fs */ - case 0x65: /* gs */ - /* ignore prefix */ - continue; - - case 0x66: /* data size */ - data_32 = TRUE; - continue; - - case 0x67: /* address size */ - addr_32 = TRUE; - continue; - - case 0xe4: /* inb imm */ - case 0xe5: /* inw imm */ - case 0xe6: /* outb imm */ - case 0xe7: /* outw imm */ - io_port = *(unsigned char *)Addr8086(regs->cs, eip); - eip++; - goto do_in_out; - - case 0xec: /* inb dx */ - case 0xed: /* inw dx */ - case 0xee: /* outb dx */ - case 0xef: /* outw dx */ - case 0x6c: /* insb */ - case 0x6d: /* insw */ - case 0x6e: /* outsb */ - case 0x6f: /* outsw */ - io_port = regs->edx & 0xffff; - - do_in_out: - if (!data_32) - opcode |= 0x6600; /* word IO */ - - switch (emulate_io(regs, opcode, io_port)) { - case EM_IO_DONE: - /* instruction executed */ - break; - case EM_IO_RETRY: - /* port mapped, retry instruction */ - thread->recover = 0; - return TRUE; - case EM_IO_ERROR: - /* port not mapped */ - thread->recover = 0; - return FALSE; - } - break; - - case 0xfa: /* cli */ - if (!v86_do_sti_cli) { - thread->recover = 0; - return (FALSE); - } - - v86->flags &= ~EFL_IF; - /* disable simulated interrupts */ - cli_count++; - break; - - case 0xfb: /* sti */ - if (!v86_do_sti_cli) { - thread->recover = 0; - return (FALSE); - } - - if ((v86->flags & EFL_IF) == 0) { - if (v86_do_sti_immediate) { - v86->flags |= EFL_IF; - } else { - v86->flags |= V86_IF_PENDING; - regs->efl |= EFL_TF; - } - /* single step to set IF next inst. */ - } - sti_count++; - break; - - case 0x9c: /* pushf */ - { - int flags; - vm_offset_t sp; - int size; - - flags = regs->efl; - if ((v86->flags & EFL_IF) == 0) - flags &= ~EFL_IF; - - if ((v86->flags & EFL_TF) == 0) - flags &= ~EFL_TF; - else flags |= EFL_TF; - - sp = regs->uesp; - if (!addr_32) - sp &= 0xffff; - else if (sp > 0xffff) - goto stack_error; - size = (data_32) ? 4 : 2; - if (sp < size) - goto stack_error; - sp -= size; - if (copyout((char *)&flags, - (char *)Addr8086(regs->ss,sp), - size)) - goto addr_error; - if (addr_32) - regs->uesp = sp; - else - regs->uesp = (regs->uesp & 0xffff0000) | sp; - break; - } - - case 0x9d: /* popf */ - { - vm_offset_t sp; - int nflags; - - sp = regs->uesp; - if (!addr_32) - sp &= 0xffff; - else if (sp > 0xffff) - goto stack_error; - - if (data_32) { - if (sp > 0xffff - sizeof(int)) - goto stack_error; - nflags = *(int *)Addr8086(regs->ss,sp); - sp += sizeof(int); - } - else { - if (sp > 0xffff - sizeof(short)) - goto stack_error; - nflags = *(unsigned short *) - Addr8086(regs->ss,sp); - sp += sizeof(short); - } - if (addr_32) - regs->uesp = sp; - else - regs->uesp = (regs->uesp & 0xffff0000) | sp; - - if (v86->flags & V86_IRET_PENDING) { - v86->flags = nflags & (EFL_TF | EFL_IF); - v86->flags |= V86_IRET_PENDING; - } else { - v86->flags = nflags & (EFL_TF | EFL_IF); - } - regs->efl = (regs->efl & ~EFL_V86_SAFE) - | (nflags & EFL_V86_SAFE); - break; - } - case 0xcf: /* iret */ - { - vm_offset_t sp; - int nflags; - union iret_struct iret_struct; - - v86->flags &= ~V86_IRET_PENDING; - sp = regs->uesp; - if (!addr_32) - sp &= 0xffff; - else if (sp > 0xffff) - goto stack_error; - - if (data_32) { - if (sp > 0xffff - sizeof(struct iret_32)) - goto stack_error; - iret_struct.iret_32 = - *(struct iret_32 *) Addr8086(regs->ss,sp); - sp += sizeof(struct iret_32); - } - else { - if (sp > 0xffff - sizeof(struct iret_16)) - goto stack_error; - iret_struct.iret_16 = - *(struct iret_16 *) Addr8086(regs->ss,sp); - sp += sizeof(struct iret_16); - } - if (addr_32) - regs->uesp = sp; - else - regs->uesp = (regs->uesp & 0xffff0000) | sp; - - if (data_32) { - eip = iret_struct.iret_32.eip; - regs->cs = iret_struct.iret_32.cs & 0xffff; - nflags = iret_struct.iret_32.eflags; - } - else { - eip = iret_struct.iret_16.ip; - regs->cs = iret_struct.iret_16.cs; - nflags = iret_struct.iret_16.flags; - } - - v86->flags = nflags & (EFL_TF | EFL_IF); - regs->efl = (regs->efl & ~EFL_V86_SAFE) - | (nflags & EFL_V86_SAFE); - break; - } - default: - /* - * Instruction not emulated here. - */ - thread->recover = 0; - return FALSE; - } - break; /* exit from 'while TRUE' */ - } - regs->eip = (regs->eip & 0xffff0000 | eip); - } - else { - /* - * Not a trap we handle. - */ - thread->recover = 0; - return FALSE; - } - - if ((v86->flags & EFL_IF) && ((v86->flags & V86_IRET_PENDING)==0)) { - - struct v86_interrupt_table *int_table; - int int_count; - int vec; - int i; - - int_table = (struct v86_interrupt_table *) v86->int_table; - int_count = v86->int_count; - - vec = 0; - for (i = 0; i < int_count; int_table++, i++) { - if (!int_table->mask && int_table->count > 0) { - int_table->count--; - vec = int_table->vec; - break; - } - } - if (vec != 0) { - /* - * Take this interrupt - */ - vm_offset_t sp; - struct iret_16 iret_16; - struct int_vec int_vec; - - sp = regs->uesp & 0xffff; - if (sp < sizeof(struct iret_16)) - goto stack_error; - sp -= sizeof(struct iret_16); - iret_16.ip = regs->eip; - iret_16.cs = regs->cs; - iret_16.flags = regs->efl & 0xFFFF; - if ((v86->flags & EFL_TF) == 0) - iret_16.flags &= ~EFL_TF; - else iret_16.flags |= EFL_TF; - -#ifdef gcc_1_36_worked - int_vec = ((struct int_vec *)0)[vec]; -#else - memcpy(&int_vec, - (void *)(sizeof(struct int_vec) * vec), - sizeof (struct int_vec)); -#endif - if (copyout((char *)&iret_16, - (char *)Addr8086(regs->ss,sp), - sizeof(struct iret_16))) - goto addr_error; - regs->uesp = (regs->uesp & 0xFFFF0000) | (sp & 0xffff); - regs->eip = int_vec.ip; - regs->cs = int_vec.cs; - regs->efl &= ~EFL_TF; - v86->flags &= ~(EFL_IF | EFL_TF); - v86->flags |= V86_IRET_PENDING; - } - } - - thread->recover = 0; - return TRUE; - - /* - * On address error, report a page fault. - * XXX report GP fault - we don`t save - * the faulting address. - */ - addr_error: - asm("addr_error:;"); - thread->recover = 0; - return FALSE; - - /* - * On stack address error, return stack fault (12). - */ - stack_error: - thread->recover = 0; - regs->trapno = T_STACK_FAULT; - return FALSE; -} - /* * Handle AST traps for i386. * Check for delayed floating-point exception from @@ -1039,81 +630,6 @@ i386_exception(exc, code, subcode) /*NOTREACHED*/ } -boolean_t -check_io_fault(regs) - struct i386_saved_state *regs; -{ - int eip, opcode, io_port; - boolean_t data_16 = FALSE; - - /* - * Get the instruction. - */ - eip = regs->eip; - - for (;;) { - opcode = inst_fetch(eip, regs->cs); - eip++; - switch (opcode) { - case 0x66: /* data-size prefix */ - data_16 = TRUE; - continue; - - case 0xf3: /* rep prefix */ - case 0x26: /* es */ - case 0x2e: /* cs */ - case 0x36: /* ss */ - case 0x3e: /* ds */ - case 0x64: /* fs */ - case 0x65: /* gs */ - continue; - - case 0xE4: /* inb imm */ - case 0xE5: /* inl imm */ - case 0xE6: /* outb imm */ - case 0xE7: /* outl imm */ - /* port is immediate byte */ - io_port = inst_fetch(eip, regs->cs); - eip++; - break; - - case 0xEC: /* inb dx */ - case 0xED: /* inl dx */ - case 0xEE: /* outb dx */ - case 0xEF: /* outl dx */ - case 0x6C: /* insb */ - case 0x6D: /* insl */ - case 0x6E: /* outsb */ - case 0x6F: /* outsl */ - /* port is in DX register */ - io_port = regs->edx & 0xFFFF; - break; - - default: - return FALSE; - } - break; - } - - if (data_16) - opcode |= 0x6600; /* word IO */ - - switch (emulate_io(regs, opcode, io_port)) { - case EM_IO_DONE: - /* instruction executed */ - regs->eip = eip; - return TRUE; - - case EM_IO_RETRY: - /* port mapped, retry instruction */ - return TRUE; - - case EM_IO_ERROR: - /* port not mapped */ - return FALSE; - } -} - #if MACH_PCSAMPLE > 0 /* * return saved state for interrupted user thread diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c index c3049ef..eee218a 100644 --- a/i386/i386at/conf.c +++ b/i386/i386at/conf.c @@ -58,10 +58,6 @@ extern int kbdgetstat(), kbdsetstat(); extern int mouseopen(), mouseclose(), mouseread(), mousegetstat(); #define mousename "mouse" -extern int ioplopen(), ioplclose(); -extern vm_offset_t ioplmmap(); -#define ioplname "iopl" - extern int kmsgopen(), kmsgclose(), kmsgread(), kmsggetstat(); #define kmsgname "kmsg" @@ -117,11 +113,6 @@ struct dev_ops dev_name_list[] = nodev, nulldev, nulldev, 0, nodev }, - { ioplname, ioplopen, ioplclose, nodev, - nodev, nodev, nodev, ioplmmap, - nodev, nulldev, nulldev, 0, - nodev }, - #ifdef MACH_KMSG { kmsgname, kmsgopen, kmsgclose, kmsgread, nodev, kmsggetstat, nodev, nomap, diff --git a/i386/i386at/iopl.c b/i386/i386at/iopl.c deleted file mode 100644 index 8080911..0000000 --- a/i386/i386at/iopl.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include <mach/vm_prot.h> -#include <mach/machine/vm_types.h> -#include <mach/machine/vm_param.h> -#include <mach/machine/eflags.h> - -#include <ipc/ipc_port.h> - -#include <device/io_req.h> - -#include <i386/io_port.h> -#include <i386/pit.h> -#include <i386/pio.h> - -/* - * IOPL device. - */ -ipc_port_t iopl_device_port = IP_NULL; -mach_device_t iopl_device = 0; - -/* - * Ports that we allow access to. - */ -io_reg_t iopl_port_list[] = { - /* timer 2 */ - 0x42, - /* speaker output */ - 0x61, - /* ATI - savage */ - 0x1ce, 0x1cf, - /* game port */ - 0x201, - /* sound board */ - 0x220, 0x221, 0x222, 0x223, 0x224, 0x225, 0x226, 0x227, - 0x228, 0x229, 0x22a, 0x22b, 0x22c, 0x22d, 0x22e, 0x22f, - /* printer */ - 0x278, 0x279, 0x27a, - 0x378, 0x379, 0x37a, - /* ega/vga */ - 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, - 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf, - 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, - 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, 0x3cd, 0x3ce, 0x3cf, - 0x3d0, 0x3d1, 0x3d2, 0x3d3, 0x3d4, 0x3d5, 0x3d6, 0x3d7, - 0x3d8, 0x3d9, 0x3da, 0x3db, 0x3dc, 0x3dd, 0x3de, 0x3df, - /* end of list */ - IO_REG_NULL, - /* patch space */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -int -ioplopen(dev, flag, ior) - int dev; - int flag; - io_req_t ior; -{ - iopl_device_port = ior->io_device->port; - iopl_device = ior->io_device; - - io_port_create(iopl_device, iopl_port_list); - return (0); -} - - -/*ARGSUSED*/ -int -ioplclose(dev, flags) - int dev; - int flags; -{ - io_port_destroy(iopl_device); - iopl_device_port = IP_NULL; - iopl_device = 0; - return 0; -} - -/*ARGSUSED*/ -int iopl_all = 1; -int -ioplmmap(dev, off, prot) -int dev; -vm_offset_t off; -vm_prot_t prot; -{ - extern vm_offset_t phys_last_addr; - - if (iopl_all) { - if (off == 0) - return 0; - else if (off < 0xa0000) - return -1; - else if (off >= 0x100000 && off <= phys_last_addr) - return -1; - else - return i386_btop(off); - - } - if (off > 0x60000) - return(-1); - - /* Get page frame number for the page to be mapped. */ - - return(i386_btop(0xa0000 + off)); -} - -/* - * For DOS compatibility, it's easier to list the ports we don't - * allow access to. - */ -#define IOPL_PORTS_USED_MAX 256 -io_reg_t iopl_ports_used[IOPL_PORTS_USED_MAX] = { - IO_REG_NULL -}; - -boolean_t -iopl_port_forbidden(io_port) - int io_port; -{ - int i; - -#if 0 /* we only read from these... it should be OK */ - - if (io_port <= 0xff) - return TRUE; /* system ports. 42,61,70,71 allowed above */ - - if (io_port >= 0x130 && io_port <= 0x137) - return TRUE; /* AHA disk */ - - if (io_port >= 0x170 && io_port <= 0x177) - return TRUE; /* HD disk */ - - if (io_port >= 0x1f0 && io_port <= 0x1f7) - return TRUE; /* HD disk */ - - if (io_port >= 0x230 && io_port <= 0x237) - return TRUE; /* AHA disk */ - - if (io_port >= 0x280 && io_port <= 0x2df) - return TRUE; /* 8390 network */ - - if (io_port >= 0x300 && io_port <= 0x31f) - return TRUE; /* 8390 network */ - - if (io_port >= 0x330 && io_port <= 0x337) - return TRUE; /* AHA disk */ - - if (io_port >= 0x370 && io_port <= 0x377) - return TRUE; /* FD disk */ - - if (io_port >= 0x3f0 && io_port <= 0x3f7) - return TRUE; /* FD disk */ - -#endif - - /* - * Must be OK, as far as we know... - * Record the port in the list, for - * curiosity seekers. - */ - for (i = 0; i < IOPL_PORTS_USED_MAX; i++) { - if (iopl_ports_used[i] == io_port) - break; /* in list */ - if (iopl_ports_used[i] == IO_REG_NULL) { - iopl_ports_used[i] = io_port; - iopl_ports_used[i+1] = IO_REG_NULL; - break; - } - } - - return FALSE; -} - -/* - * Emulate certain IO instructions for the AT bus. - * - * We emulate writes to the timer control port, 43. - * Only writes to timer 2 are allowed. - * - * Temporarily, we allow reads of any IO port, - * but ONLY if the thread has the IOPL device mapped - * and is not in V86 mode. - * - * This is a HACK and MUST go away when the DOS emulator - * emulates these IO ports, or when we decide that - * the DOS world can get access to all uncommitted IO - * ports. In that case, config() should remove the IO - * ports for devices it exists from the allowable list. - */ -boolean_t -iopl_emulate(regs, opcode, io_port) - struct i386_saved_state *regs; - int opcode; - int io_port; -{ - iopb_tss_t iopb; - - iopb = current_thread()->pcb->ims.io_tss; - if (iopb == 0) - return FALSE; /* no IO mapped */ - - /* - * Handle outb to the timer control port, - * for timer 2 only. - */ - if (io_port == PITCTL_PORT) { - - int io_byte = regs->eax & 0xff; - - if (((iopb->bitmap[PITCTR2_PORT >> 3] & (1 << (PITCTR2_PORT & 0x7))) - == 0) /* allowed */ - && (opcode == 0xe6 || opcode == 0xee) /* outb */ - && (io_byte & 0xc0) == 0x80) /* timer 2 */ - { - outb(io_port, io_byte); - return TRUE; - } - return FALSE; /* invalid IO to port 42 */ - } - - /* - * If the thread has the IOPL device mapped, and - * the io port is not on the 'forbidden' list, allow - * reads from it. Reject writes. - * - * Don`t do this for V86 mode threads - * (hack for DOS emulator XXX!) - */ - if (!(regs->efl & EFL_VM) && - iopb_check_mapping(current_thread(), iopl_device) && - !iopl_port_forbidden(io_port)) - { - /* - * handle inb, inw, inl - */ - switch (opcode) { - case 0xE4: /* inb imm */ - case 0xEC: /* inb dx */ - regs->eax = (regs->eax & 0xffffff00) - | inb(io_port); - return TRUE; - - case 0x66E5: /* inw imm */ - case 0x66ED: /* inw dx */ - regs->eax = (regs->eax & 0xffff0000) - | inw(io_port); - return TRUE; - - case 0xE5: /* inl imm */ - case 0xED: /* inl dx */ - regs->eax = inl(io_port); - return TRUE; - - default: - return FALSE; /* OUT not allowed */ - } - } - - /* - * Not OK. - */ - return FALSE; -} - |