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 generic device, some keyboard fixes (still in progress)
[palacios.git] / palacios / src / devices / keyboard.c
index 6c71667..3ef783e 100644 (file)
@@ -3,6 +3,15 @@
 #include <palacios/vmm.h>
 #include <palacios/vmm_types.h>
 
+#define KEYBOARD_DEBUG 1
+
+#if KEYBOARD_DEBUG
+#define KEYBOARD_DEBUG_PRINT(first, rest...) do { SerialPrint(first, ## rest ); } while (0) 
+#else
+#define KEYBOARD_DEBUG_PRINT(first, rest...)
+#endif
+
+
 extern struct vmm_os_hooks *os_hooks;
 
 extern void SerialPrint(const char *format, ...);
@@ -16,22 +25,59 @@ extern void SerialPrint(const char *format, ...);
 
 
 
+// The currently targetted keyboard
+static struct vm_device *thekeyboard=NULL;
+
+
 struct keyboard_internal {
-  int x;
-  // figure this out later - it should be the internal state of the keyboard buffer and
-  // the emulated status, etc.
-  // which should be fed from the underlying OS and drained via this interface
+  // read* is what is seen when reads are done from the VM
+  uchar_t read_status;
+  uchar_t read_scancode;
+  // write* is where we put the writes from the VM
+  uchar_t write_status;
+  uchar_t write_scancode;
+
+  uchar_t status_byte;      //  for on-board uC
+
+  uchar_t input_queue;      //  input queue is for communication *to* the on-board uC
+  uint_t  input_queue_len;  //  num items queued
+  uchar_t output_queue;     //  output queue is for communcation *from* the on-board uC
+  uint_t  output_queue_len; //  num items queued 
 };
 
 
+static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
+{
+  // this currently does nothing
+  return thekeyboard;
+}
 
+int keyboard_interrupt(uint_t irq,struct vm_device * dev);
 
-int keyboard_reset_device(struct vm_device * dev)
+void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
 {
-  //  struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct vm_device *dev = demultiplex_injected_key(status,scancode);
+
+  struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
+
+  KEYBOARD_DEBUG_PRINT("keyboard: injected status 0x%x, and scancode 0x%x\n", status,scancode);
   
-  SerialPrint("keyboard: reset device\n");
+  // This is wrong - the read status should be some combination of the 
+  // status/scancode within the VM, and that of the actual device
+  state->read_status=status;
+  state->read_scancode=scancode;
+
+  keyboard_interrupt(KEYBOARD_IRQ,dev);
+
+}
 
+int keyboard_reset_device(struct vm_device * dev)
+{
+  struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  
+  memset(data,0,sizeof(struct keyboard_internal));
+  
+  KEYBOARD_DEBUG_PRINT("keyboard: reset device\n");
  
   return 0;
 
@@ -43,14 +89,14 @@ int keyboard_reset_device(struct vm_device * dev)
 
 int keyboard_start_device(struct vm_device *dev)
 {
-  SerialPrint("keyboard: start device\n");
+  KEYBOARD_DEBUG_PRINT("keyboard: start device\n");
   return 0;
 }
 
 
 int keyboard_stop_device(struct vm_device *dev)
 {
-  SerialPrint("keyboard: stop device\n");
+  KEYBOARD_DEBUG_PRINT("keyboard: stop device\n");
   return 0;
 }
 
@@ -62,15 +108,15 @@ int keyboard_write_control_port(ushort_t port,
                                uint_t length,
                                struct vm_device * dev)
 {
-  //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
 
   if (length==1) { 
     uchar_t data = *((uchar_t*)src); 
-    PrintDebug("keyboard: write of 0x%x to control port\n",data);
-    Out_Byte(KEYBOARD_CONTROL_REG,data);
+    KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to control port\n",data);
+    state->write_status=data;
     return 1;
   } else {
-    PrintDebug("keyboard: unknown size write to control port!\n");
+    KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to control port!\n");
     return -1;
   }
 }
@@ -80,17 +126,17 @@ int keyboard_read_control_port(ushort_t port,
                               uint_t length,
                               struct vm_device * dev)
 {
-  //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
 
   if (length==1) { 
     uchar_t data;
-    PrintDebug("keyboard: read from control port: ");
-    data=In_Byte(KEYBOARD_CONTROL_REG);
-    PrintDebug("0x%x\n",data);
-    memcpy(dest,&data,1);
+    KEYBOARD_DEBUG_PRINT("keyboard: read from control port: ");
+    data=state->read_status;
+    KEYBOARD_DEBUG_PRINT("0x%x\n",data);
+    memcpy(dest,&data,length);
     return 1;
   } else {
-    PrintDebug("keyboard: unknown size read from control port!\n");
+    KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from control port!\n");
     return -1;
   }
 }
@@ -100,15 +146,15 @@ int keyboard_write_data_port(ushort_t port,
                             uint_t length,
                             struct vm_device * dev)
 {
-  //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
 
   if (length==1) { 
     uchar_t data = *((uchar_t*)src); 
-    PrintDebug("keyboard: write of 0x%x to data port\n",data);
-    Out_Byte(KEYBOARD_DATA_REG,data);
+    KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to data port\n",data);
+    state->write_scancode=data;
     return 1;
   } else {
-    PrintDebug("keyboard: unknown size write to data port!\n");
+    KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to data port!\n");
     return -1;
   }
 }
@@ -118,17 +164,17 @@ int keyboard_read_data_port(ushort_t port,
                            uint_t length,
                            struct vm_device * dev)
 {
-  //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
 
   if (length==1) { 
     uchar_t data;
-    PrintDebug("keyboard: read from data port: ");
-    data=In_Byte(KEYBOARD_DATA_REG);
-    PrintDebug("0x%x\n",data);
+    KEYBOARD_DEBUG_PRINT("keyboard: read from data port: ");
+    data=state->read_scancode;
+    KEYBOARD_DEBUG_PRINT("0x%x\n",data);
     memcpy(dest,&data,1);
     return 1;
   } else {
-    PrintDebug("keyboard: unknown size read from data port!\n");
+    KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from data port!\n");
     return -1;
   }
 }
@@ -137,9 +183,12 @@ int keyboard_read_data_port(ushort_t port,
 int keyboard_interrupt(uint_t irq,
                       struct vm_device * dev) 
 {
-  PrintDebug("keyboard: interrupt\n");
+  KEYBOARD_DEBUG_PRINT("keyboard: interrupt\n");
+
+  dev->vm->vm_ops.raise_irq(dev->vm,irq,0);
+
   return 0;
-  // Inject ?
+
 }
 
 
@@ -148,7 +197,7 @@ int keyboard_init_device(struct vm_device * dev)
  
   //  struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
 
-  SerialPrint("keyboard: init_device\n");
+  KEYBOARD_DEBUG_PRINT("keyboard: init_device\n");
 
   // Would read state here
 
@@ -158,10 +207,10 @@ int keyboard_init_device(struct vm_device * dev)
   dev_hook_io(dev, KEYBOARD_DATA_REG, &keyboard_read_data_port, &keyboard_write_data_port);
   dev_hook_io(dev, KEYBOARD_CONTROL_REG, &keyboard_read_control_port, &keyboard_write_control_port);
   
-  // hook irq
-  // currently assume this is done in vm.c?
-  //dev_hook_irq(dev,KEYBOARD_IRQ,&keyboard_interrupt);
-
+  //
+  // We do not hook the IRQ here.  Instead, the underlying device driver
+  // is responsible to call us back
+  // 
 
   return 0;
 }
@@ -169,8 +218,6 @@ int keyboard_init_device(struct vm_device * dev)
 int keyboard_deinit_device(struct vm_device *dev)
 {
 
-
-  //dev_unhook_irq(dev,KEYBOARD_IRQ);
   dev_unhook_io(dev, KEYBOARD_DATA_REG);
   dev_unhook_io(dev, KEYBOARD_CONTROL_REG);
 
@@ -194,9 +241,16 @@ static struct vm_device_ops dev_ops = {
 
 
 struct vm_device *create_keyboard() {
+  
+  if (thekeyboard!=NULL) { 
+    KEYBOARD_DEBUG_PRINT("keyboard: creating >1 keyboard device.  This will probably fail!\n");
+  }
+  
   struct keyboard_internal * keyboard_state = os_hooks->malloc(sizeof(struct keyboard_internal));
 
   struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);
 
+  thekeyboard=device;
+  
   return device;
 }