Hello,
here comes a patch making monitor reporting guest I/O activities
to user space. It's nothing else a little framework to prepare
FreeMWare for a matching plugin. Hope, anyone has a matching plugin... ;)
(Kevin?) Works well with in and out, outs/outsb/outsw/outsd support
follows.
I'm unhapping with hand over data via context.event_info in such way.
Perhaps has anybody a better idea.

jens

------------------------------

diff -urN freemware/CVS/Entries freemware-jens/CVS/Entries
--- freemware/CVS/Entries       Wed Jan 12 11:46:02 2000
+++ freemware-jens/CVS/Entries  Wed Jan 12 15:58:22 2000
@@ -4,10 +4,10 @@
 D/guest////
 D/kernel////
 D/user////
-/Makefile.in/1.5/Mon Jan  3 14:45:27 2000//
-/README/1.3/Mon Jan 10 10:37:07 2000//
-/config.h.in/1.2/Mon Jan 10 10:37:07 2000//
-/configure/1.4/Mon Jan 10 10:37:07 2000//
-/configure.in/1.4/Mon Jan 10 10:37:07 2000//
-/configure.linux/1.3/Mon Jan 10 10:37:07 2000//
-/ChangeLog/1.42/Wed Jan 12 10:46:02 2000//
+/Makefile.in/1.5/Fri Jan  7 13:31:44 2000//
+/README/1.3/Mon Jan 10 10:42:03 2000//
+/config.h.in/1.2/Mon Jan 10 10:42:03 2000//
+/configure/1.4/Mon Jan 10 10:42:04 2000//
+/configure.in/1.4/Mon Jan 10 10:42:04 2000//
+/configure.linux/1.3/Mon Jan 10 10:42:04 2000//
+/ChangeLog/1.42/Wed Jan 12 14:58:22 2000//
diff -urN freemware/guest/CVS/Entries freemware-jens/guest/CVS/Entries
--- freemware/guest/CVS/Entries Thu Dec  2 11:03:52 1999
+++ freemware-jens/guest/CVS/Entries    Fri Jan  7 14:31:44 2000
@@ -2,4 +2,4 @@
 D/cooperative////
 D/preemptive////
 D/virtcode////
-/Makefile.in/1.2/Thu Dec  2 10:03:52 1999//
+/Makefile.in/1.2/Fri Jan  7 13:31:44 2000//
diff -urN freemware/guest/cooperative/CVS/Entries 
freemware-jens/guest/cooperative/CVS/Entries
--- freemware/guest/cooperative/CVS/Entries     Mon Jan 10 11:37:07 2000
+++ freemware-jens/guest/cooperative/CVS/Entries        Mon Jan 10 11:42:04 2000
@@ -1,7 +1,7 @@
 /gdt.c/1.1/Sun Nov 14 15:06:47 1999//
 /main.c/1.1/Sun Nov 14 15:06:47 1999//
 D/include////
-/entry.S/1.2/Mon Jan  3 14:45:27 2000//
-/intr.c/1.2/Mon Jan  3 14:45:27 2000//
-/.cvsignore/1.2/Mon Jan 10 10:37:07 2000//
-/Makefile.in/1.4/Mon Jan 10 10:37:07 2000//
+/entry.S/1.2/Fri Jan  7 13:31:44 2000//
+/intr.c/1.2/Fri Jan  7 13:31:44 2000//
+/.cvsignore/1.2/Mon Jan 10 10:42:04 2000//
+/Makefile.in/1.4/Mon Jan 10 10:42:04 2000//
diff -urN freemware/guest/preemptive/CVS/Entries 
freemware-jens/guest/preemptive/CVS/Entries
--- freemware/guest/preemptive/CVS/Entries      Mon Jan 10 11:37:07 2000
+++ freemware-jens/guest/preemptive/CVS/Entries Mon Jan 10 11:42:04 2000
@@ -1,7 +1,7 @@
 /gdt.c/1.1/Sun Nov 14 15:06:47 1999//
 /main.c/1.1/Sun Nov 14 15:06:47 1999//
 D/include////
-/entry.S/1.2/Mon Jan  3 14:45:27 2000//
-/intr.c/1.2/Mon Jan  3 14:45:27 2000//
-/.cvsignore/1.2/Mon Jan 10 10:37:07 2000//
-/Makefile.in/1.4/Mon Jan 10 10:37:07 2000//
+/entry.S/1.2/Fri Jan  7 13:31:44 2000//
+/intr.c/1.2/Fri Jan  7 13:31:44 2000//
+/.cvsignore/1.2/Mon Jan 10 10:42:04 2000//
+/Makefile.in/1.4/Mon Jan 10 10:42:04 2000//
diff -urN freemware/guest/virtcode/CVS/Entries 
freemware-jens/guest/virtcode/CVS/Entries
--- freemware/guest/virtcode/CVS/Entries        Mon Jan 10 11:37:07 2000
+++ freemware-jens/guest/virtcode/CVS/Entries   Mon Jan 10 11:42:04 2000
@@ -1,4 +1,4 @@
-/virtcode.c/1.1/Mon Nov 29 16:50:59 1999//
-/.cvsignore/1.2/Mon Jan 10 10:37:07 2000//
-/Makefile.in/1.4/Mon Jan 10 10:37:07 2000//
+/virtcode.c/1.1/Sun Nov 14 15:06:47 1999//
+/.cvsignore/1.2/Mon Jan 10 10:42:04 2000//
+/Makefile.in/1.4/Mon Jan 10 10:42:04 2000//
 D
diff -urN freemware/guest/virtcode/virtcode.c freemware-jens/guest/virtcode/virtcode.c
--- freemware/guest/virtcode/virtcode.c Mon Nov 29 17:50:59 1999
+++ freemware-jens/guest/virtcode/virtcode.c    Wed Jan 12 16:04:37 2000
@@ -41,7 +41,7 @@
 do_nothing(void)
 {
     int *nothing_count = (int *)0x8000;
-
+  
     /*
      *  For now, this ring3 code does nothing except
      *  spin it's wheels and increment a counter.
diff -urN freemware/kernel/CVS/Entries freemware-jens/kernel/CVS/Entries
--- freemware/kernel/CVS/Entries        Mon Jan 10 11:37:07 2000
+++ freemware-jens/kernel/CVS/Entries   Mon Jan 10 11:42:04 2000
@@ -1,9 +1,9 @@
 /.cvsignore/1.1/Wed Sep  8 19:26:39 1999//
 D/include////
-/emulation.c/1.7/Mon Jan  3 14:45:27 2000//
 /fault.c/1.3/Tue Dec 28 18:43:29 1999//
-/host-beos.c/1.4/Mon Jan  3 14:45:27 2000//
+/host-beos.c/1.4/Fri Jan  7 13:31:44 2000//
 /nexus.S/1.7/Fri Dec 31 20:12:32 1999//
-/Makefile.in/1.9/Mon Jan 10 10:37:07 2000//
-/host-linux.c/1.22/Mon Jan 10 10:37:07 2000//
-/monitor.c/1.18/Mon Jan 10 10:37:07 2000//
+/emulation.c/1.7/Tue Dec 28 18:43:29 1999//
+/Makefile.in/1.9/Mon Jan 10 10:42:04 2000//
+/host-linux.c/1.22/Mon Jan 10 10:42:04 2000//
+/monitor.c/1.18/Mon Jan 10 10:42:04 2000//
diff -urN freemware/kernel/emulation.c freemware-jens/kernel/emulation.c
--- freemware/kernel/emulation.c        Mon Jan  3 15:45:27 2000
+++ freemware-jens/kernel/emulation.c   Wed Jan 12 15:39:16 2000
@@ -46,8 +46,10 @@
 int emulate_mov_to_cr(void);
 int emulate_mov_from_dr(void);
 int emulate_mov_to_dr(void);
-int emulate_in(void);
-int emulate_out(void);
+int emulate_in_imm8(guest_context_t *,int);
+int emulate_in_dx(guest_context_t *,int);
+int emulate_out_imm8(guest_context_t *,int);
+int emulate_out_dx(guest_context_t *,int);
 int emulate_int3(void);
 int emulate_load_ds(guest_context_t *context, u16 selector);
 int emulate_load_es(guest_context_t *context, u16 selector);
@@ -475,6 +477,38 @@
         action = emulate_iret(context);
         break;
 
+    case 0xe4: /* in imm8,al */
+      action = emulate_in_imm8(context, 8);
+      break;
+
+    case 0xe5: /* in imm8,[e]ax */
+      action = emulate_in_imm8(context, operand_size);
+      break;
+
+    case 0xe6: /* out imm8,al */
+      action = emulate_out_imm8(context, 8);
+      break;
+
+    case 0xe7: /* out imm8,[e]ax */
+      action = emulate_out_imm8(context, operand_size);
+      break;
+
+    case 0xec: /* in al,dx */
+      action = emulate_in_dx(context, 8);
+      break;
+
+    case 0xed: /* in [e]ax,dx */
+      action = emulate_in_dx(context, operand_size);
+      break;
+
+    case 0xee: /* out dx,al */
+      action = emulate_out_dx(context, 8);
+      break;
+
+    case 0xef: /* out dx,[e]ax */
+      action = emulate_out_dx(context, operand_size);
+      break;
+
     case 0xfa: /* cli */
         action = emulate_cli();
         break;
@@ -558,6 +592,9 @@
         context->eip = eip;
         context->esp = esp;
         return 2;
+    case 4:   /* Try to emulate in user space */
+        
+        return 3;
     }
 }
 
@@ -953,3 +990,50 @@
     return 1;
 }
 
+int
+emulate_out_imm8(guest_context_t *context, int operand_size)
+     /*
+      * Emulate out instruction
+      */
+{
+  u32 eip = context->eip+1;
+  unsigned char port;
+
+  port = read_guest_byte(&eip);
+  context->event_info = (u8)operand_size | (RET_BECAUSE_USEREMU << 8) | 
+(EMU_INSTR_OUT_IMM8 << 16)  | (port << 24);
+  return 4;
+}
+
+int
+emulate_out_dx(guest_context_t *context, int operand_size)
+     /*
+      * Emulate out instruction
+      */
+{
+  context->event_info = (u8)operand_size | (RET_BECAUSE_USEREMU << 8) | 
+(EMU_INSTR_OUT_DX << 16);
+  return 4;
+}
+
+int
+emulate_in_imm8(guest_context_t *context, int operand_size)
+     /*
+      * Emulate in instruction
+      */
+{
+  u32 eip = context->eip+1;
+  unsigned char port;
+
+  port = read_guest_byte(&eip);
+  context->event_info = (u8)operand_size | (RET_BECAUSE_USEREMU << 8) | 
+(EMU_INSTR_IN_IMM8 << 16)  | (port << 24);
+  return 4;
+}
+
+int
+emulate_in_dx(guest_context_t *context, int operand_size)
+     /*
+      * Emulate out instruction
+      */
+{
+  context->event_info = (u8)operand_size | (RET_BECAUSE_USEREMU << 8) | 
+(EMU_INSTR_IN_DX << 16);
+  return 4;
+}
diff -urN freemware/kernel/fault.c freemware-jens/kernel/fault.c
--- freemware/kernel/fault.c    Tue Dec 28 19:43:29 1999
+++ freemware-jens/kernel/fault.c       Wed Jan 12 12:12:44 2000
@@ -73,6 +73,8 @@
         case 2:   /* emulation successful, need to remap monitor */
             context->event_info = RET_BECAUSE_REMAP << 8;
             return 0;
+       case 3:   /* emulation in user space */
+           return 0;
         }
 
     default: 
diff -urN freemware/kernel/host-linux.c freemware-jens/kernel/host-linux.c
--- freemware/kernel/host-linux.c       Mon Jan 10 11:37:07 2000
+++ freemware-jens/kernel/host-linux.c  Tue Jan 11 16:51:45 2000
@@ -121,7 +121,7 @@
     // register the /proc entry
     #ifdef CONFIG_PROC_FS
 #if LINUX_VERSION_CODE >= VERSION_CODE(2,3,25)
-    if (!create_proc_info_entry("freemware", 0, NULL, fmw_read_procmem))
+    if (!create_proc_info_entry("freemware", 0, NULL, (void *)fmw_read_procmem))
       printk(KERN_ERR "freemware: registering /proc/freewmare failed\n");
 #else
     proc_register_dynamic(&proc_root, &fmw_proc_entry);
@@ -470,6 +470,10 @@
               printk(KERN_WARNING "freemware: trying to load %04x into %cS failed\n",
                      vm->nexus->debug_msg.para2, vm->nexus->debug_msg.para1);
               break;
+           case EMU_OUT_MSG:
+             printk(KERN_WARNING "freemware: failed to emulate out instruction [0x%x 
+: 0x%x]\n",
+                    vm->nexus->debug_msg.para1, vm->nexus->debug_msg.para2);
+             break;
 
             default:
               printk(KERN_WARNING "freemware: unknown emulation error (%d) [0x%x : 
0x%x]\n",
@@ -477,8 +481,12 @@
                      vm->nexus->debug_msg.para1, vm->nexus->debug_msg.para2);
               break;
             }
-
             return 0;
+
+       case RET_BECAUSE_USEREMU:
+             printk(KERN_WARNING "freemware: try to emulate out instruction in user 
+space [0x%x : 0x%x]\n",
+                    vm->nexus->debug_msg.para1, vm->nexus->debug_msg.para2);
+             return 1;
 
         default:
             restore_flags(eflags_orig);
diff -urN freemware/kernel/include/CVS/Entries 
freemware-jens/kernel/include/CVS/Entries
--- freemware/kernel/include/CVS/Entries        Mon Jan 10 11:37:07 2000
+++ freemware-jens/kernel/include/CVS/Entries   Mon Jan 10 11:42:04 2000
@@ -5,7 +5,7 @@
 /tss.h/1.2/Tue Sep  7 20:13:50 1999//
 /elf.h/1.1/Fri Nov 26 19:16:40 1999//
 /elf_machine.h/1.1/Fri Nov 26 19:16:40 1999//
-/host-linux.h/1.7/Mon Jan  3 14:45:27 2000//
-/monitor.h/1.15/Mon Jan  3 14:45:27 2000//
-/freemware.h/1.3/Mon Jan 10 10:37:07 2000//
+/host-linux.h/1.7/Fri Jan  7 13:31:45 2000//
+/monitor.h/1.15/Fri Jan  7 13:43:08 2000//
+/freemware.h/1.3/Mon Jan 10 10:42:04 2000//
 D
diff -urN freemware/kernel/include/freemware.h 
freemware-jens/kernel/include/freemware.h
--- freemware/kernel/include/freemware.h        Mon Jan 10 11:37:07 2000
+++ freemware-jens/kernel/include/freemware.h   Wed Jan 12 15:39:47 2000
@@ -96,4 +96,9 @@
 #define FMWRUNGUEST     0x6b04
 #define FMWTEARDOWN     0x6b05
 
+#define EMU_INSTR_OUT_IMM8 1
+#define EMU_INSTR_OUT_DX   2
+#define EMU_INSTR_IN_IMM8  3
+#define EMU_INSTR_IN_DX    4
+
 #endif  // #ifndef __FREEMWARE_H__
diff -urN freemware/kernel/include/monitor.h freemware-jens/kernel/include/monitor.h
--- freemware/kernel/include/monitor.h  Mon Jan  3 15:45:27 2000
+++ freemware-jens/kernel/include/monitor.h     Wed Jan 12 12:41:44 2000
@@ -29,6 +29,8 @@
 #define RET_BECAUSE_EMERR     12
 #define RET_BECAUSE_MON_ERROR 13
 #define RET_BECAUSE_REMAP     14
+#define RET_BECAUSE_USEREMU   15
+
 
 /*
  * Passing debug messages between host and guest context.
@@ -50,7 +52,7 @@
 #define EMU_LLDT_MSG 6
 #define EMU_LTR_MSG 7
 #define EMU_LOAD_SEGREG_MSG 8
-
+#define EMU_OUT_MSG 9
 
 
 // Method1: push event info (CPU pushes error code before)
diff -urN freemware/user/CVS/Entries freemware-jens/user/CVS/Entries
--- freemware/user/CVS/Entries  Wed Jan 12 11:48:37 2000
+++ freemware-jens/user/CVS/Entries     Wed Jan 12 15:58:24 2000
@@ -1,10 +1,10 @@
-/.cvsignore/1.2/Mon Jan 10 10:37:07 2000//
-/Makefile.in/1.10/Mon Jan 10 10:37:07 2000//
-/decode.h/1.3/Mon Jan 10 10:37:08 2000//
-/fmw.conf/1.7/Result of merge+Mon Jan 10 10:37:08 2000//
-/resetmod.c/1.5/Mon Jan 10 10:37:08 2000//
+/.cvsignore/1.2/Mon Jan 10 10:42:04 2000//
+/Makefile.in/1.10/Mon Jan 10 10:42:04 2000//
+/decode.h/1.3/Mon Jan 10 10:42:05 2000//
+/fmw.conf/1.7/Mon Jan 10 10:42:05 2000//
+/resetmod.c/1.5/Mon Jan 10 10:42:05 2000//
+/user.c/1.20/Mon Jan 10 10:42:05 2000//
 /user.h/1.2/Sun Jan  9 22:03:03 2000//
 /vga_io.log/1.1/Fri Jan  7 22:45:45 2000//
 D/plugins////
-/decode.c/1.6/Wed Jan 12 10:46:03 2000//
-/user.c/1.20/Wed Jan 12 10:48:37 2000//
+/decode.c/1.6/Wed Jan 12 14:58:23 2000//
diff -urN freemware/user/CVS/Entries.Log freemware-jens/user/CVS/Entries.Log
--- freemware/user/CVS/Entries.Log      Wed Jan 12 11:48:38 2000
+++ freemware-jens/user/CVS/Entries.Log Thu Jan  1 01:00:00 1970
@@ -1,4 +0,0 @@
-A D/gui////
-A D/iodev////
-R D/iodev////
-R D/gui////
diff -urN freemware/user/fmw.conf freemware-jens/user/fmw.conf
--- freemware/user/fmw.conf     Mon Jan 10 11:39:32 2000
+++ freemware-jens/user/fmw.conf        Mon Jan 10 11:42:05 2000
@@ -3,6 +3,7 @@
 ####################################################################
 
 
+
 ####################################################################
 # General settings
 ####################################################################
diff -urN freemware/user/user.c freemware-jens/user/user.c
--- freemware/user/user.c       Wed Jan 12 11:59:56 2000
+++ freemware-jens/user/user.c  Wed Jan 12 15:44:25 2000
@@ -38,7 +38,6 @@
 #include "decode.h"
 
 
-
 /************************************************************************/
 /* Declarations                                                         */
 /************************************************************************/
@@ -571,6 +570,75 @@
             ret = ioctl (fileno, request, data);
         }
         while (!break_vm && ret < 0 && errno == EINTR);
+
+       /* ret == 1 => emulation in user space; info in context.event_info */
+       if(ret == 1) {
+         /* context.event_info
+          * 1. byte operand size
+          * 2. byte RET_BECAUSE_USEREMU
+          * 3. byte EMU_INSTR_ (instruction to emulate)
+          * 4. byte port or empty
+          */
+
+         u32 value;
+
+         switch((u8)(context.event_info & 0xff)) {
+         case 8:
+           value = context.eax & 0xff;
+           break;
+         case 16:
+           value = context.eax & 0xffff;
+           break;
+         case 32:
+           value = context.eax;
+           break;
+         }
+
+         /* insert here calls to emulation routines */
+         switch((unsigned char)(context.event_info >> 16) & 0xff) {
+
+         case EMU_INSTR_IN_IMM8:
+           fprintf(stderr,"Please insert call to emulation code for \"in\" here.\n");
+           /* what does bochs code need?
+           io_plugin_emulate(EMU_INSTR_IN,                                       
+//instruction
+                             (u16)((context.event_info >> 24) & 0xff),           
+//port
+                             operand_size);                                      
+//op_size (al|ax|eax)
+                             */
+           break;
+
+         case EMU_INSTR_IN_DX:
+           fprintf(stderr,"Please insert call to emulation code for \"in (dx)\" 
+here.\n");
+           /* what does bochs code need?
+           io_plugin_emulate(EMU_INSTR_OUT,                                      
+//instruction
+                             (u16)((context.edx & 0xffff),                       
+//port
+                             operand_size);                                      
+//op_size (al|ax|eax)
+                             */
+           break;
+
+         case EMU_INSTR_OUT_IMM8:
+           fprintf(stderr,"Please insert call to emulation code for \"out\" here.\n");
+           /* what does bochs code need?
+           io_plugin_emulate(EMU_INSTR_OUT,                                      
+//instruction
+                             (u16)((context.event_info >> 24) & 0xff),           
+//port
+                             value);                                             
+//value
+                             */
+           break;
+
+         case EMU_INSTR_OUT_DX:
+           fprintf(stderr,"Please insert call to emulation code for \"out (dx)\" 
+here.\n");
+           /* what does bochs code need?
+           io_plugin_emulate(EMU_INSTR_OUT,                                      
+//instruction
+                             (u16)((context.edx & 0xffff),                       
+//port
+                             value);                                             
+//value
+                             */
+           break;
+
+
+         default:
+           fprintf(stderr,"Emulation of instruction 0x%x not yet implemented 
+(0x%08x)\n",
+                   (unsigned char)(context.event_info >> 24),context.event_info);
+         }
+       }
 
         if (ret < 0 && errno != EINTR)
         {

Reply via email to