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.


Update host device framework to support PCI and other interrupt types
[palacios.git] / palacios / include / interfaces / vmm_host_dev.h
index 9f7ea91..3474952 100644 (file)
 
 #include <palacios/vmm.h>
 
-
 /*
 
   The purpose of this interface is to make it possible to implement
   virtual devices in the host OS.   It is intended to be used by 
   passthrough device implementations, such as the generic device 
-  and the PCI passthrough device.  
+  and the PCI front-end device.  
 
   One use of this interface, and the generic and PCI passthrough devices
-  might be to build an interface with simulated devices in SST 
+  might be to build an interface with simulated devices in QEMU, SST, etc
   under a Linux host.  That scenario would look like this:
 
 Guest config:
 
   generic device:
-    <device class="generic" id="mydev" impl="host_sst">
+    <device class="generic" id="mydev" forward="host_device" hostdev="url" >
        ports, memory regions, interrupts set with PASSTHROUGH option 
     </device>
 
-  PCI passthrough devive:
-    <device class="pci_passthrough" id="mydev", impl="host_sst">
+  PCI front devive:
+    <device class="pci_front" id="mydev", hostdev="url">
        vendor and device ids, etc
     </device>
 
-impl="physical" or lack of an impl key would indicate that direct hardware
-access is expected, which is how these devices currently operate. 
-
 
 Host (Linux) side:
 
@@ -71,21 +67,28 @@ Host (Linux) side:
 typedef void * v3_host_dev_t;
 /* A guest device is opaque to the host */
 typedef void * v3_guest_dev_t;
-
+/* Optional support for special interrupt handling ; raise=1 => raise otherwise lower */
+typedef void (*v3_guest_dev_intr_t)(v3_host_dev_t hdev, v3_guest_dev_t gdev, uint8_t irq, int raise);
 
 /* There is a notion of a bus class to which the device is attached */
-typedef enum { DIRECT, PCI } v3_bus_class_t;
+typedef enum { V3_BUS_CLASS_DIRECT, V3_BUS_CLASS_PCI } v3_bus_class_t;
 
 #ifdef __V3VEE__
 
+struct v3_vm_info;
+
 v3_host_dev_t v3_host_dev_open(char *impl, 
                               v3_bus_class_t bus,
-                              v3_guest_dev_t gdev); 
+                              v3_guest_dev_t gdev,
+                              v3_guest_dev_intr_t intr,
+                              struct v3_vm_info *vm); 
 
-uin64_t v3_host_dev_read_io(v3_host_dev_t hostdev, 
-                           uint16_t      port,
-                           void          *dest
-                           uint64_t      len);
+int v3_host_dev_close(v3_host_dev_t hdev);
+    
+uint64_t v3_host_dev_read_io(v3_host_dev_t hostdev,  
+                            uint16_t      port,
+                            void          *dest,
+                            uint64_t      len);
 
 uint64_t v3_host_dev_write_io(v3_host_dev_t hostdev, 
                              uint16_t      port,
@@ -102,13 +105,15 @@ uint64_t v3_host_dev_write_mem(v3_host_dev_t hostdev,
                               void          *src,
                               uint64_t      len);
 
-int v3_host_dev_ack_irq(v3_host_dev_t hostdev, uint32_t irq);
+int v3_host_dev_ack_irq(v3_host_dev_t hostdev, uint8_t irq);
 
-uint64_t v3_host_dev_config_read(v3_host_dev_t hostdev, 
+uint64_t v3_host_dev_read_config(v3_host_dev_t hostdev, 
+                                uint64_t      offset,
                                 void          *dest,
                                 uint64_t      len);
 
-uint64_t v3_host_dev_config_write(v3_host_dev_t hostdev, 
+uint64_t v3_host_dev_write_config(v3_host_dev_t hostdev, 
+                                 uint64_t      offset,
                                  void          *src,
                                  uint64_t      len);
  
@@ -120,10 +125,15 @@ struct v3_host_dev_hooks {
     // this device is attached to and an opaque pointer back to the
     // guest device.  It returns an opaque representation of 
     // the host device it has attached to, with zero indicating
-    // failure
+    // failure.  The host_priv_data arguement supplies to the 
+    // host the pointer that the VM was originally registered with
     v3_host_dev_t (*open)(char *impl, 
                          v3_bus_class_t bus,
-                         v3_guest_dev_t gdev);
+                         v3_guest_dev_t gdev,
+                         v3_guest_dev_intr_t intr,
+                         void *host_priv_data);
+
+    int (*close)(v3_host_dev_t hdev);
     
     // Read/Write from/to an IO port. The read must either
     // completely succeed, returning len or completely
@@ -131,7 +141,7 @@ struct v3_host_dev_hooks {
     // Callee gets the host dev id and the port in the guest
     uint64_t (*read_io)(v3_host_dev_t hostdev, 
                        uint16_t      port,
-                       void          *dest
+                       void          *dest,
                        uint64_t      len);
 
     uint64_t (*write_io)(v3_host_dev_t hostdev, 
@@ -144,24 +154,20 @@ struct v3_host_dev_hooks {
     // fail, returning != len
     // Callee gets the host dev id, and the guest physical address
     uint64_t (*read_mem)(v3_host_dev_t hostdev, 
-                        addr_t        gpa,
+                        void *        gpa,
                         void          *dest,
                         uint64_t      len);
     
     uint64_t (*write_mem)(v3_host_dev_t hostdev, 
-                         addr_t        gpa,
+                         void *        gpa,
                          void          *src,
                          uint64_t      len);
     
-    // Palacis will call this when it has taken posession of the 
-    // IRQ ad wants the host device to lower it
-    // This interface is unclear 
+    //
+    // Palacios or the guest device will call this
+    // function when it has injected the irq
+    // requested by the guest
     // 
-    // One potential use would be to allow for a palacios
-    // side device to raise the irq asynchronously from
-    // the host device.  If this is permitted, then we
-    // need a way of informing the host device that the
-    // irq has actually been signalled.
     int (*ack_irq)(v3_host_dev_t hostdev, uint8_t irq);
 
     // Configuration space reads/writes for devices that
@@ -175,38 +181,45 @@ struct v3_host_dev_hooks {
     // config space info.   However, a read will return
     // the host device's config, while a write will affect
     // both the palacios-internal config and the hsot device's config
-    uint64_t (*config_read)(v3_host_dev_t hostdev, 
+    //
+    // for V3_BUS_CLASS_PCI they correspond to PCI config space (e.g., BARS, etc)
+    // reads and writes
+    //
+    uint64_t (*read_config)(v3_host_dev_t hostdev, 
+                           uint64_t      offset,
                            void          *dest,
                            uint64_t      len);
-
-    uint64_t (*config_write)(v3_host_dev_t hostdev, 
+    
+    uint64_t (*write_config)(v3_host_dev_t hostdev,
+                            uint64_t      offset,
                             void          *src,
                             uint64_t      len);
  
 };
 
 /* This function is how the host will raise an irq to palacios
-   for the device.   The IRQ argument will be ignored for devices
-   whose irqs are managed by palacios */
+   for the device.   */
 int v3_host_dev_raise_irq(v3_host_dev_t hostdev,
                          v3_guest_dev_t guest_dev,
+                         v3_guest_dev_intr_t intr,
+                         uint8_t irq);
+int v3_host_dev_lower_irq(v3_host_dev_t hostdev,
+                         v3_guest_dev_t guest_dev,
+                         v3_guest_dev_intr_t intr,
                          uint8_t irq);
 
 /* These functions allow the host to read and write the guest
    memory by physical address, for example to implement DMA 
-
-   These functions are incremental - that is, they can return
-   a smaller amount than requested
 */
 uint64_t v3_host_dev_read_guest_mem(v3_host_dev_t  hostdev,
                                    v3_guest_dev_t guest_dev,
-                                   addr_t         gpa,
+                                   void *         gpa,
                                    void           *dest,
                                    uint64_t       len);
 
 uint64_t v3_host_dev_write_guest_mem(v3_host_dev_t  hostdev,
                                     v3_guest_dev_t guest_dev,
-                                    addr_t         gpa,
+                                    void *         gpa,
                                     void           *src,
                                     uint64_t       len);