bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Removing the `iopl' device and i/o emulation facility


From: Thomas Schwinge
Subject: Removing the `iopl' device and i/o emulation facility
Date: Sun, 1 Apr 2007 22:17:37 +0200
User-agent: Mutt/1.5.11

Hello!

I'm working towards integrating the OskitMach i/o permissions interface
(i386_io_perm_create, i386_io_perm_modify) into GNU Mach and again
started some spring-cleaning, removing for now the `iopl' device and the
i/o emulation facility.  What might the latter have been useful for?


Here is my patch, comment quickly or it will be gone.  Gianluca, is this
what you had done / had in mind?

#v+
2007-04-01  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.

Index: i386/Makefrag.am
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/Attic/Makefrag.am,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 Makefrag.am
--- i386/Makefrag.am    27 Mar 2007 22:47:09 -0000      1.1.2.8
+++ i386/Makefrag.am    1 Apr 2007 20:04:26 -0000
@@ -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 \
cvs diff: i386/i386/io_emulate.c was removed, no comparison available
cvs diff: i386/i386/io_emulate.h was removed, no comparison available
Index: i386/i386/trap.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/trap.c,v
retrieving revision 1.5.2.8
diff -u -p -r1.5.2.8 trap.c
--- i386/i386/trap.c    6 Jan 2007 14:27:21 -0000       1.5.2.8
+++ i386/i386/trap.c    1 Apr 2007 20:04:26 -0000
@@ -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
                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
Index: i386/i386at/conf.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386at/Attic/conf.c,v
retrieving revision 1.4.2.14
diff -u -p -r1.4.2.14 conf.c
--- i386/i386at/conf.c  24 Mar 2007 00:01:35 -0000      1.4.2.14
+++ i386/i386at/conf.c  1 Apr 2007 20:04:26 -0000
@@ -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,
cvs diff: i386/i386at/iopl.c was removed, no comparison available
#v-


Regards,
 Thomas

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]