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)
{