Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


svm_io.c now correctly handles segment prefix overrides in ins/outs instructions.
Peter Dinda [Mon, 7 Jul 2008 23:25:55 +0000 (23:25 +0000)]
generic.c now supports both print+passthrough and print+ignore.  The latter
means we can make devices disappear.

palacios/include/devices/generic.h
palacios/include/palacios/vmm_decoder.h
palacios/src/devices/generic.c

index 05d9198..51bed00 100644 (file)
 //
 
 
-// A port range is low..high, inclusive
-typedef uint_t generic_port_range_type[2];
+#define GENERIC_PRINT_AND_PASSTHROUGH 0
+#define GENERIC_PRINT_AND_IGNORE      1
+
+// A port range is low..high, inclusive, third value is one of the above
+typedef uint_t generic_port_range_type[3];
 // A memory range is low..high, inclusive
-typedef void *generic_address_range_type[2];
+typedef void *generic_address_range_type[3];
 // An interrupt ory map range is low..high, inclusive
-typedef uint_t generic_irq_range_type[2];
+typedef uint_t generic_irq_range_type[3];
 
 struct vm_device *create_generic(generic_port_range_type    port_ranges[], 
                                 uint_t                     num_port_ranges,
index f37a205..130e1ae 100644 (file)
@@ -107,22 +107,22 @@ MAKE_INSTR(LMSW,   3, 0x0f, 0x01, 0x00);
 MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
 
 
-static const uchar_t PREFIX_LOCK = 0xF0;
-static const uchar_t PREFIX_REPNE = 0xF2;
-static const uchar_t PREFIX_REPNZ = 0xF2;
-static const uchar_t PREFIX_REP = 0xF3;
-static const uchar_t PREFIX_REPE = 0xF3;
-static const uchar_t PREFIX_REPZ = 0xF3;
-static const uchar_t PREFIX_CS_OVERRIDE = 0x2E;
-static const uchar_t PREFIX_SS_OVERRIDE = 0x36;
-static const uchar_t PREFIX_DS_OVERRIDE = 0x3E;
-static const uchar_t PREFIX_ES_OVERRIDE = 0x26;
-static const uchar_t PREFIX_FS_OVERRIDE = 0x64;
-static const uchar_t PREFIX_GS_OVERRIDE = 0x65;
-static const uchar_t PREFIX_BR_NOT_TAKEN = 0x2E;
-static const uchar_t PREFIX_BR_TAKEN = 0x3E;
-static const uchar_t PREFIX_OP_SIZE = 0x66;
-static const uchar_t PREFIX_ADDR_SIZE = 0x67;
+#define PREFIX_LOCK         0xF0
+#define PREFIX_REPNE        0xF2
+#define PREFIX_REPNZ        0xF2
+#define PREFIX_REP          0xF3
+#define PREFIX_REPE         0xF3
+#define PREFIX_REPZ         0xF3
+#define PREFIX_CS_OVERRIDE  0x2E
+#define PREFIX_SS_OVERRIDE  0x36
+#define PREFIX_DS_OVERRIDE  0x3E
+#define PREFIX_ES_OVERRIDE  0x26
+#define PREFIX_FS_OVERRIDE  0x64
+#define PREFIX_GS_OVERRIDE  0x65
+#define PREFIX_BR_NOT_TAKEN 0x2E
+#define PREFIX_BR_TAKEN     0x3E
+#define PREFIX_OP_SIZE      0x66
+#define PREFIX_ADDR_SIZE    0x67
 
 static inline int is_prefix_byte(char byte) {
   switch (byte) {
index 7c24fd2..4f3ae7a 100644 (file)
@@ -61,10 +61,10 @@ int generic_stop_device(struct vm_device *dev)
 
 
 
-int generic_write_port(ushort_t port,
-                      void * src, 
-                      uint_t length,
-                      struct vm_device * dev)
+int generic_write_port_passthrough(ushort_t port,
+                                  void * src, 
+                                  uint_t length,
+                                  struct vm_device * dev)
 {
   uint_t i;
 
@@ -97,10 +97,10 @@ int generic_write_port(ushort_t port,
   return length;
 }
 
-int generic_read_port(ushort_t port,
-                     void * src, 
-                     uint_t length,
-                     struct vm_device * dev)
+int generic_read_port_passthrough(ushort_t port,
+                                 void * src, 
+                                 uint_t length,
+                                 struct vm_device * dev)
 {
   uint_t i;
 
@@ -133,6 +133,40 @@ int generic_read_port(ushort_t port,
   return length;
 }
 
+int generic_write_port_ignore(ushort_t port,
+                             void * src, 
+                             uint_t length,
+                             struct vm_device * dev)
+{
+  uint_t i;
+
+  GENERIC_DEBUG_PRINT("generic: writing 0x");
+
+  for (i = 0; i < length; i++) { 
+    GENERIC_DEBUG_PRINT("%x", ((uchar_t*)src)[i]);
+  }
+  
+  GENERIC_DEBUG_PRINT(" to port 0x%x ... ", port);
+
+  GENERIC_DEBUG_PRINT(" ignored\n");
+  
+  return length;
+}
+
+int generic_read_port_ignore(ushort_t port,
+                            void * src, 
+                            uint_t length,
+                            struct vm_device * dev)
+{
+
+  GENERIC_DEBUG_PRINT("generic: reading 0x%x bytes from port 0x%x ...", length, port);
+
+  memset((char*)src,0,length);
+  GENERIC_DEBUG_PRINT(" ignored (return zeroed buffer)\n");
+
+  return length;
+}
+
 
 
 int generic_interrupt(uint_t irq,
@@ -159,13 +193,19 @@ int generic_init_device(struct vm_device * dev)
   generic_reset_device(dev);
 
   for (i = 0; i < state->num_port_ranges; i++) { 
-    GENERIC_DEBUG_PRINT("generic: hooking ports 0x%x to 0x%x\n", state->port_ranges[i][0], state->port_ranges[i][1]);
+    GENERIC_DEBUG_PRINT("generic: hooking ports 0x%x to 0x%x as %x\n", state->port_ranges[i][0], state->port_ranges[i][1], state->port_ranges[i][2]==GENERIC_PRINT_AND_PASSTHROUGH ? "print-and-passthrough" : "print-and-ignore");
 
 #if PORT_HOOKS
     for (j = state->port_ranges[i][0]; j <= state->port_ranges[i][1]; j++) { 
-      if (dev_hook_io(dev, j, &generic_read_port, &generic_write_port)) { 
-       GENERIC_DEBUG_PRINT("generic: can't hook port 0x%x (already hooked?)\n", j);
-      }
+      if (state->port_ranges[i][2]==GENERIC_PRINT_AND_PASSTHROUGH) { 
+       if (dev_hook_io(dev, j, &generic_read_port_passthrough, &generic_write_port_passthrough)) { 
+         GENERIC_DEBUG_PRINT("generic: can't hook port 0x%x (already hooked?)\n", j);
+       }
+      } else if (state->port_ranges[i][2]==GENERIC_PRINT_AND_IGNORE) { 
+       if (dev_hook_io(dev, j, &generic_read_port_ignore, &generic_write_port_ignore)) { 
+         GENERIC_DEBUG_PRINT("generic: can't hook port 0x%x (already hooked?)\n", j);
+       }
+      } 
     }
 #else
     GENERIC_DEBUG_PRINT("generic: hooking ports not supported\n");