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.


added support for multiple interrupt controllers
Jack Lange [Fri, 13 Feb 2009 22:23:12 +0000 (16:23 -0600)]
palacios/include/palacios/vmm_intr.h
palacios/src/devices/8259a.c
palacios/src/devices/apic.c
palacios/src/devices/simple_pic.c
palacios/src/palacios/vmm_intr.c

index e90d304..cc3b7c9 100644 (file)
@@ -24,7 +24,7 @@
 #ifdef __V3VEE__
 
 #include <palacios/vmm_types.h>
-
+#include <palacios/vmm_list.h>
 
 #define DE_EXCEPTION          0x00  
 #define DB_EXCEPTION          0x01
@@ -52,10 +52,6 @@ typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE_INTR, VIRTUAL
 struct guest_info;
 struct v3_interrupt;
 
-/* We need a way to allow the APIC/PIC to decide when they are supposed to receive interrupts...
- * Maybe a notification call when they have been turned on, to deliver irqs to them...
- * We can rehook the guest raise_irq op, to the appropriate controller
- */
 
 
 struct v3_irq_hook {
@@ -64,6 +60,9 @@ struct v3_irq_hook {
 };
 
 
+
+
+
 struct v3_intr_state {
 
   /* We need to rework the exception state, to handle stacking */
@@ -72,11 +71,10 @@ struct v3_intr_state {
   uint_t excp_error_code_valid : 1;
   uint_t excp_error_code;
   
-  struct intr_ctrl_ops * controller;
-  void * controller_state;
+  struct list_head controller_list;
 
-  /* some way to get the [A]PIC intr */
 
+  /* some way to get the [A]PIC intr */
   struct v3_irq_hook * hooks[256];
   
 };
@@ -102,7 +100,7 @@ struct intr_ctrl_ops {
 
 
 
-void v3_set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
+void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
 
 int v3_raise_exception(struct guest_info * info, uint_t excp);
 int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code);
index 4b9649b..c651049 100644 (file)
@@ -632,7 +632,7 @@ static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm
 static int pic_init(struct vm_device * dev) {
   struct pic_internal * state = (struct pic_internal*)dev->private_data;
 
-  v3_set_intr_controller(dev->vm, &intr_ops, state);
+  v3_register_intr_controller(dev->vm, &intr_ops, state);
 
   state->master_irr = 0;
   state->master_isr = 0;
index 7434b7d..41f4daa 100644 (file)
@@ -741,22 +741,10 @@ static int apic_get_intr_number(void * private_data) {
 }
 
 static int apic_raise_intr(void * private_data, int irq) {
-  struct vm_device * dev = (struct vm_device *)private_data;
-  struct apic_state * apic = (struct apic_state *)dev->private_data;
-
-  return activate_apic_irq(apic, irq);
+  return 0;
 }
 
 static int apic_lower_intr(void * private_data, int irq) {
-  struct vm_device * dev = (struct vm_device *)private_data;
-  struct apic_state * apic = (struct apic_state *)dev->private_data;
-  int major_offset = irq & ~0x00000007;
-  int minor_offset = irq & 0x00000007;
-  uchar_t * req_location = apic->int_req_reg + major_offset;
-  uchar_t flag = 0x01 << minor_offset;
-
-  *req_location &= ~flag;
-
   return 0;
 }
 
@@ -874,7 +862,7 @@ static int apic_init(struct vm_device * dev) {
   struct guest_info * info = dev->vm;
   struct apic_state * apic = (struct apic_state *)(dev->private_data);
 
-  v3_set_intr_controller(dev->vm, &intr_ops, dev);
+  v3_register_intr_controller(dev->vm, &intr_ops, dev);
   v3_add_timer(dev->vm, &timer_ops, dev);
 
   init_apic_state(apic);
index 7003111..11848e0 100644 (file)
@@ -62,7 +62,7 @@ static struct intr_ctrl_ops intr_ops = {
 
 static int pic_init_device(struct vm_device * dev) {
   struct pic_internal * data = (struct pic_internal *)dev->private_data;
-  v3_set_intr_controller(dev->vm, &intr_ops, data);
+  v3_register_intr_controller(dev->vm, &intr_ops, data);
   data->pending_irq = 0;
 
   return 0;
index 46e1e42..ccbfd9f 100644 (file)
 
 
 
+struct intr_controller {
+  struct intr_ctrl_ops * ctrl_ops;
+
+  void * priv_data;
+  struct list_head ctrl_node;
+};
+
+
 void v3_init_interrupt_state(struct guest_info * info) {
   info->intr_state.excp_pending = 0;
   info->intr_state.excp_num = 0;
@@ -39,9 +47,14 @@ void v3_init_interrupt_state(struct guest_info * info) {
   memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
 }
 
-void v3_set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
-  info->intr_state.controller = ops;
-  info->intr_state.controller_state = state;
+void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
+  struct intr_controller * ctrlr = (struct intr_controller *)V3_Malloc(sizeof(struct intr_controller));
+
+  ctrlr->priv_data = state;
+  ctrlr->ctrl_ops = ops;
+
+  list_add(&(ctrlr->ctrl_node), &(info->intr_state.controller_list));
+
 }
 
 
@@ -97,10 +110,7 @@ static int passthrough_irq_handler(struct guest_info * info, struct v3_interrupt
 int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq)
 {
 
-  int rc = v3_hook_irq(info, 
-                      irq,
-                      passthrough_irq_handler,
-                      NULL);
+  int rc = v3_hook_irq(info, irq, passthrough_irq_handler, NULL);
 
   if (rc) { 
     PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%p)\n", irq, (void *)info);
@@ -170,38 +180,26 @@ int v3_raise_exception(struct guest_info * info, uint_t excp) {
 
 
 int v3_lower_irq(struct guest_info * info, int irq) {
-  // Look up PIC and resend
-  V3_ASSERT(info);
-  V3_ASSERT(info->intr_state.controller);
-  V3_ASSERT(info->intr_state.controller->lower_intr);
+  struct intr_controller * ctrl = NULL;
+  struct v3_intr_state * intr_state = &(info->intr_state);
 
   PrintDebug("[v3_lower_irq]\n");
 
-  if ((info->intr_state.controller) && 
-      (info->intr_state.controller->lower_intr)) {
-    info->intr_state.controller->lower_intr(info->intr_state.controller_state, irq);
-  } else {
-    PrintError("There is no registered Interrupt Controller... (NULL POINTER)\n");
-    return -1;
+  list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+    ctrl->ctrl_ops->lower_intr(ctrl->priv_data, irq);
   }
-
   return 0;
 }
 
 int v3_raise_irq(struct guest_info * info, int irq) {
-  // Look up PIC and resend
-  V3_ASSERT(info);
-  V3_ASSERT(info->intr_state.controller);
-  V3_ASSERT(info->intr_state.controller->raise_intr);
+  struct intr_controller * ctrl = NULL;
+  struct v3_intr_state * intr_state = &(info->intr_state);
 
   PrintDebug("[v3_raise_irq]\n");
 
-  if ((info->intr_state.controller) && 
-      (info->intr_state.controller->raise_intr)) {
-    info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq);
-  } else {
-    PrintError("There is no registered Interrupt Controller... (NULL POINTER)\n");
-    return -1;
+  list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+    ctrl->ctrl_ops->raise_intr(ctrl->priv_data, irq);
   }
 
   return 0;
@@ -215,11 +213,15 @@ int v3_intr_pending(struct guest_info * info) {
   //  PrintDebug("[intr_pending]\n");
   if (intr_state->excp_pending == 1) {
     return 1;
-  } else if (intr_state->controller->intr_pending(intr_state->controller_state) == 1) {
-    return 1;
-  }
+  } else {
+    struct intr_controller * ctrl = NULL;
 
-  /* Check [A]PIC */
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+      if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+       return 1;
+      }
+    }
+  }
 
   return 0;
 }
@@ -230,12 +232,19 @@ uint_t v3_get_intr_number(struct guest_info * info) {
 
   if (intr_state->excp_pending == 1) {
     return intr_state->excp_num;
-  } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
-    PrintDebug("[get_intr_number] intr_number = %d\n", intr_state->controller->get_intr_number(intr_state->controller_state));
-    return intr_state->controller->get_intr_number(intr_state->controller_state);
-  }
+  } else {
+    struct intr_controller * ctrl = NULL;
 
-  /* someway to get the [A]PIC intr */
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+      if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
+       uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
+
+       PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
+
+       return intr_num;
+      }
+    }
+  }
 
   return 0;
 }
@@ -247,11 +256,18 @@ intr_type_t v3_get_intr_type(struct guest_info * info) {
   if (intr_state->excp_pending) {
     PrintDebug("[get_intr_type] Exception\n");
     return EXCEPTION;
-  } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
-    PrintDebug("[get_intr_type] External_irq\n");
-    return EXTERNAL_IRQ;
+  } else {
+    struct intr_controller * ctrl = NULL;
+
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+      if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+       PrintDebug("[get_intr_type] External_irq\n");
+       return EXTERNAL_IRQ;
+      }
+    }
   }
-    PrintDebug("[get_intr_type] Invalid_Intr\n");
+
+  PrintDebug("[get_intr_type] Invalid_Intr\n");
   return INVALID_INTR;
 }
 
@@ -271,8 +287,12 @@ int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t typ
     intr_state->excp_error_code_valid = 0;
     
   } else if (type == EXTERNAL_IRQ) {
-    PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
-    return intr_state->controller->begin_irq(intr_state->controller_state, intr_num);
+    struct intr_controller * ctrl = NULL;
+
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+      PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
+      ctrl->ctrl_ops->begin_irq(ctrl->priv_data, intr_num);
+    }
   }
 
   return 0;