summaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@gnu.org>2007-04-01 22:10:40 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-06-18 00:27:07 +0200
commit123d406152b033dc321d57cd86e45d058746547c (patch)
treee6b3c96e63ed7d973760e0f7290e573e24777d18 /i386
parent861203044a89a8e0cb9b6e0200aad791ee9e5804 (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.am3
-rw-r--r--i386/i386/io_emulate.c107
-rw-r--r--i386/i386/io_emulate.h43
-rw-r--r--i386/i386/trap.c484
-rw-r--r--i386/i386at/conf.c9
-rw-r--r--i386/i386at/iopl.c290
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;
-}
-