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.


got rid of the silent errors...
[palacios-OLD.git] / palacios / src / devices / keyboard.c
index 74d2096..63ff156 100644 (file)
@@ -3,9 +3,9 @@
 #include <palacios/vmm.h>
 #include <palacios/vmm_types.h>
 
-#define KEYBOARD_DEBUG 0
+#define KEYBOARD_DEBUG 1
 
-#define KEYBOARD_DEBUG_80H   0
+#define KEYBOARD_DEBUG_80H   1
 
 #if KEYBOARD_DEBUG
 #define KEYBOARD_DEBUG_PRINT(first, rest...) PrintDebug(first, ##rest)
 #endif
 
 
-extern struct vmm_os_hooks *os_hooks;
-
-extern void SerialPrint(const char *format, ...);
-
-
-
 #define KEYBOARD_60H          0x60  // keyboard microcontroller
 #define KEYBOARD_64H          0x64  // onboard microcontroller
 
 #define KEYBOARD_DELAY_80H    0x80  // written for timing
 
-#define KEYBOARD_IRQ    0x1
+#define KEYBOARD_IRQ          0x1
 
 
 // extract bits for status byte
@@ -50,7 +44,7 @@ extern void SerialPrint(const char *format, ...);
 #define CMD_RESERVED            0x80  // should be zero
 
 // The currently targetted keyboard
-static struct vm_device *thekeyboard=NULL;
+static struct vm_device *thekeyboard = NULL;
 
 
 struct keyboard_internal {
@@ -78,6 +72,9 @@ struct keyboard_internal {
        // after recieving 0xa5
        // password arrives on data port, null terminated
        TRANSMIT_PASSWD,
+       // after receiving 0xd1
+       // keyboard uC output will arrive
+       WRITE_OUTPUT,
        // after having reset sent to 0x60
        // we immediately ack, and then
        // push BAT success (0xaa) after the ack
@@ -105,12 +102,14 @@ struct keyboard_internal {
 //
 static int PushToOutputQueue(struct vm_device *dev, uchar_t value, uchar_t overwrite) 
 {
-  struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
   
-  if (state->output_queue_len==0 || overwrite) { 
-    state->output_queue=value;
-    state->output_queue_len=1;
+  if ((state->output_queue_len == 0) || overwrite) { 
+
+    state->output_queue = value;
+    state->output_queue_len = 1;
     state->status_byte |= STATUS_OUTPUT_BUFFER_FULL;
+
     return 0;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: PushToOutputQueue Failed - Queue Full\n");
@@ -123,13 +122,16 @@ static int PushToOutputQueue(struct vm_device *dev, uchar_t value, uchar_t overw
 // pull item from outputqueue 
 // returns 0 if successful
 //
-static int PullFromOutputQueue(struct vm_device *dev,uchar_t *value) 
+static int PullFromOutputQueue(struct vm_device *dev, uchar_t *value) 
 {
-  struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
-  if (state->output_queue_len==1) { 
-    *value=state->output_queue;
-    state->output_queue_len=0;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+
+  if (state->output_queue_len == 1) { 
+
+    *value = state->output_queue;
+    state->output_queue_len = 0;
     state->status_byte &= ~STATUS_OUTPUT_BUFFER_FULL;
+
     return 0;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: PullFromOutputQueue Failed - Queue Empty\n");
@@ -145,11 +147,14 @@ static int PullFromOutputQueue(struct vm_device *dev,uchar_t *value)
 //
 static int PushToInputQueue(struct vm_device *dev, uchar_t value, uchar_t overwrite) 
 {
-  struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
-  if (state->input_queue_len==0 || overwrite) { 
-    state->input_queue=value;
-    state->input_queue_len=1;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+
+  if ((state->input_queue_len == 0) || overwrite) { 
+
+    state->input_queue = value;
+    state->input_queue_len = 1;
     state->status_byte |= STATUS_INPUT_BUFFER_FULL;
+
     return 0;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: PushToOutputQueue Failed - Queue Full\n");
@@ -163,14 +168,18 @@ static int PushToInputQueue(struct vm_device *dev, uchar_t value, uchar_t overwr
 //
 static int PullFromInputQueue(struct vm_device *dev, uchar_t *value) 
 {
-  struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
-  if (state->input_queue_len==1) { 
-    *value=state->input_queue;
-    state->input_queue_len=0;
-    state->status_byte &=~STATUS_INPUT_BUFFER_FULL;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+
+  if (state->input_queue_len == 1) { 
+
+    *value = state->input_queue;
+    state->input_queue_len = 0;
+    state->status_byte &= ~STATUS_INPUT_BUFFER_FULL;
+
     return 0;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: PullFromInputQueue Failed - Queue Empty\n");
+
     return -1;
   }
 }
@@ -183,23 +192,22 @@ static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scanco
   return thekeyboard;
 }
 
-int keyboard_interrupt(uint_t irq,struct vm_device * dev);
+int keyboard_interrupt(uint_t irq, struct vm_device * dev);
 
 void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
 {
-  struct vm_device *dev = demultiplex_injected_key(status,scancode);
-
-  struct keyboard_internal *state = (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);
+  KEYBOARD_DEBUG_PRINT("keyboard: injected status 0x%x, and scancode 0x%x\n", status, scancode);
   
-  if (    (state->status_byte & STATUS_ENABLED)      // onboard is enabled
-         && (!(state->cmd_byte & CMD_DISABLE)))  {   // keyboard is enabled
+  if ( (state->status_byte & STATUS_ENABLED)      // onboard is enabled
+       && (!(state->cmd_byte & CMD_DISABLE)) )  {   // keyboard is enabled
 
-    PushToOutputQueue(dev,scancode,1);
+    PushToOutputQueue(dev, scancode, 1);
 
     if (state->cmd_byte & CMD_INTR) { 
-      keyboard_interrupt(KEYBOARD_IRQ,dev);
+      keyboard_interrupt(KEYBOARD_IRQ, dev);
     }
        
   }
@@ -207,9 +215,9 @@ void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
 
 int keyboard_reset_device(struct vm_device * dev)
 {
-  struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *data = (struct keyboard_internal *)(dev->private_data);
   
-  memset(data,0,sizeof(struct keyboard_internal));
+  memset(data, 0, sizeof(struct keyboard_internal));
 
   data->cmd_byte =   
       CMD_INTR        // interrupts on
@@ -250,11 +258,14 @@ int keyboard_write_delay(ushort_t port,
                         uint_t length,
                         struct vm_device * dev)
 {
-  if (length==1) { 
+
+  if (length == 1) { 
     KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to 80h\n", *((uchar_t*)src));
+
     return 1;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: write of >1 byte to 80h\n", *((uchar_t*)src));
+
     return length;
   }
 }
@@ -264,12 +275,16 @@ int keyboard_read_delay(ushort_t port,
                        uint_t length,
                        struct vm_device * dev)
 {
-  if (length==1) { 
+
+  if (length == 1) { 
     *((uchar_t*)dest) = In_Byte(port);
+
     KEYBOARD_DEBUG_PRINT("keyboard: read of 0x%x from 80h\n", *((uchar_t*)dest));
+
     return 1;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: read of >1 byte from 80h\n");
+
     return length;
   }
 }
@@ -284,117 +299,143 @@ int keyboard_write_command(ushort_t port,
                           uint_t length,
                           struct vm_device * dev)
 {
-  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
   uchar_t cmd;
 
   // Should always be single byte write
 
-  if (length!=1) { 
-    KEYBOARD_DEBUG_PRINT("keyboard: write of >1 bytes (%d) to 64h\n",length);
+  if (length != 1) { 
+    KEYBOARD_DEBUG_PRINT("keyboard: write of >1 bytes (%d) to 64h\n", length);
     return -1;
   }
 
-  cmd =  *((uchar_t*)src); 
+  cmd = *((uchar_t*)src); 
 
-  if (state->state!=NORMAL) { 
-    KEYBOARD_DEBUG_PRINT("keyboard: warning - receiving command on 64h but state!=NORMAL\n");
+  if (state->state != NORMAL) { 
+    KEYBOARD_DEBUG_PRINT("keyboard: warning - receiving command on 64h but state != NORMAL\n");
   }
   
-  KEYBOARD_DEBUG_PRINT("keyboard: command 0x%x on 64h\n",cmd);
+  KEYBOARD_DEBUG_PRINT("keyboard: command 0x%x on 64h\n", cmd);
 
   switch (cmd) { 
 
   case 0x20:  // READ COMMAND BYTE (returned in 60h)
-    PushToOutputQueue(dev,state->cmd_byte,1);
-    state->state=NORMAL;  // the next read on 0x60 will get the right data
+    PushToOutputQueue(dev, state->cmd_byte, 1);
+    state->state = NORMAL;  // the next read on 0x60 will get the right data
     break;
 
   case 0x60:  // WRITE COMMAND BYTE (read from 60h)
-    state->state=WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately
+    state->state = WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately
     break;
 
   // case 0x90-9f - write to output port  (?)
 
   case 0xa1: // Get version number
-    PushToOutputQueue(dev,0,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0, 1);
+    state->state = NORMAL;
     break;
 
   case 0xa4:  // is password installed?  send result to 0x60
     // we don't support passwords
-    PushToOutputQueue(dev,0xf1,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0xf1, 1);
+    state->state = NORMAL;
     break;
 
   case 0xa5:  // new password will arrive on 0x60
-    state->state=TRANSMIT_PASSWD;
+    state->state = TRANSMIT_PASSWD;
     break;
 
   case 0xa6:  // check passwd;
     // since we do not support passwords, we will simply ignore this
     // the implication is that any password check immediately succeeds 
     // with a blank password
-    state->state=NORMAL;
+    state->state = NORMAL;
     break;
 
   case 0xa7:  // disable mouse
     state->cmd_byte |= CMD_MOUSE_DISABLE;
-    state->state=NORMAL;
+    state->state = NORMAL;
     break;
 
   case 0xa8:  // enable mouse
     state->cmd_byte &= ~CMD_MOUSE_DISABLE;
-    state->state=NORMAL;
+    state->state = NORMAL;
     break;
 
   case 0xa9:  // mouse interface test  (always succeeds)
-    PushToOutputQueue(dev,0,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0, 1);
+    state->state = NORMAL;
     break;
 
   case 0xaa:  // controller self test (always succeeds)
-    PushToOutputQueue(dev,0x55,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0x55, 1);
+    state->state = NORMAL;
     break;
 
   case 0xab:  // keyboard interface test (always succeeds)
-    PushToOutputQueue(dev,0,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0, 1);
+    state->state = NORMAL;
     break;
 
   case 0xad:  // disable keyboard
     state->cmd_byte |= CMD_DISABLE;
-    state->state=NORMAL;
+    state->state = NORMAL;
     break;
 
   case 0xae:  // enable keyboard
     state->cmd_byte &= ~CMD_DISABLE;
-    state->state=NORMAL;
+    state->state = NORMAL;
     break;
 
   case 0xaf:  // get version
-    PushToOutputQueue(dev,0x00,1);
-    state->state=NORMAL;
+    PushToOutputQueue(dev, 0x00, 1);
+    state->state = NORMAL;
     break;
 
+
   // case c0  read input port ?
   // case c1  copy input port lsn to status
   // case c2  copy input port msn to status
   
   // case d0 read output port
   // case d1 write output port
+  case 0xd1: // Write next 0x60 byte to uC output port
+    state->state = WRITE_OUTPUT;
+    break;
+
   // case d2 write keyboard buffer (inject key)
   // case d3 write mouse buffer (inject mouse)
   // case d4 write mouse device (command to mouse?)
 
   // case e0 read test port
   
+
   // case f0..ff pulse output port ?
+  case 0xf0:
+  case 0xf1:
+  case 0xf2:
+  case 0xf3:
+  case 0xf4:
+  case 0xf5:
+  case 0xf6:
+  case 0xf7:
+  case 0xf8:
+  case 0xf9:
+  case 0xfa:
+  case 0xfb:
+  case 0xfc:
+  case 0xfd:
+  case 0xfe:
+  case 0xff:
+    PrintDebug("FIXME: keyboard output pulse: %x\n", cmd);
+    // either set/unset the a20 line (bit 1)
+    // or reset the machine (bit 0 == 0)
+    break;
 
-   
   default:
     KEYBOARD_DEBUG_PRINT("keyboard: ignoring command (unimplemented)\n");
-    state->state=NORMAL;
+    state->state = NORMAL;
+    return -1;     // JRL: We die here to prevent silent errors
     break;
   }
 
@@ -407,12 +448,16 @@ int keyboard_read_status(ushort_t port,
                         uint_t length,
                         struct vm_device * dev)
 {
-  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+
+  if (length == 1) { 
 
-  if (length==1) { 
     KEYBOARD_DEBUG_PRINT("keyboard: read status (64h): ");
-    *((uchar_t*)dest)=state->status_byte;
-    KEYBOARD_DEBUG_PRINT("0x%x\n",*((uchar_t*)dest));
+
+    *((uchar_t*)dest) = state->status_byte;
+
+    KEYBOARD_DEBUG_PRINT("0x%x\n", *((uchar_t*)dest));
+
     return 1;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: >1 byte read for status (64h)\n");
@@ -425,59 +470,71 @@ int keyboard_write_output(ushort_t port,
                          uint_t length,
                          struct vm_device * dev)
 {
-  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
 
-  if (length!=1) { 
+  if (length != 1) { 
     KEYBOARD_DEBUG_PRINT("keyboard: write of 60h with >1 byte\n");
     return -1;
   }
 
-  uchar_t data=*((uchar_t*)src);
+  uchar_t data = *((uchar_t*)src);
   
   switch (state->state) {
   case WRITING_CMD_BYTE:
-    state->cmd_byte=data;
-    state->state=NORMAL;
+    state->cmd_byte = data;
+    state->state = NORMAL;
     break;
   case TRANSMIT_PASSWD:
     if (data) {
       //ignore passwd
     } else {
       // end of password
-      state->state=NORMAL;
+      state->state = NORMAL;
     }
     break;
+  case WRITE_OUTPUT:
+    PrintDebug("FIXME: keyboard write output: %x\n", data);
+    // either set/unset the a20 line (bit 1)
+    // or reset the machine (bit 0)
+    state->state = NORMAL;
+    break;
+
+
   case NORMAL:
-    // command is being sent to keyboard controller
-    switch (data) { 
-    case 0xff: // reset
-      PushToOutputQueue(dev,0xfa,1); // ack
-      state->state=RESET;
-      break;
-    case 0xf5: // disable scanning
-    case 0xf4: // enable scanning
-      // ack
-      PushToOutputQueue(dev,0xfa,1);
-      // should do something here... PAD
-      state->state=NORMAL;
-      break;
-    case 0xfe: // resend
-    case 0xfd: // set key type make
-    case 0xfc: // set key typ make/break
-    case 0xfb: // set key type typematic
-    case 0xfa: // set all typematic make/break/typematic
-    case 0xf9: // set all make
-    case 0xf8: // set all make/break
-    case 0xf7: // set all typemaktic
-    case 0xf6: // set defaults
-    case 0xf3: // set typematic delay/rate
-    default:
-      KEYBOARD_DEBUG_PRINT("keyboard: unhandled command 0x%x on output buffer (60h)\n",data);
+    {
+      // command is being sent to keyboard controller
+      switch (data) { 
+      case 0xff: // reset
+       PushToOutputQueue(dev, 0xfa, 1); // ack
+       state->state = RESET;
+       break;
+      case 0xf5: // disable scanning
+      case 0xf4: // enable scanning
+       // ack
+       PushToOutputQueue(dev, 0xfa, 1);
+       // should do something here... PAD
+       state->state = NORMAL;
+       break;
+      case 0xfe: // resend
+      case 0xfd: // set key type make
+      case 0xfc: // set key typ make/break
+      case 0xfb: // set key type typematic
+      case 0xfa: // set all typematic make/break/typematic
+      case 0xf9: // set all make
+      case 0xf8: // set all make/break
+      case 0xf7: // set all typemaktic
+      case 0xf6: // set defaults
+      case 0xf3: // set typematic delay/rate
+      default:
+       KEYBOARD_DEBUG_PRINT("keyboard: unhandled command 0x%x on output buffer (60h)\n", data);
+       if (data != 0x5) 
+         return -1;    // JRL: We die here to prevent silent errors
+       break;
+      }
       break;
     }
-    break;
   default:
-    KEYBOARD_DEBUG_PRINT("keyboard: unknown state %x on command 0x%x on output buffer (60h)\n",state->state, data);
+    KEYBOARD_DEBUG_PRINT("keyboard: unknown state %x on command 0x%x on output buffer (60h)\n", state->state, data);
   }
   
   return 1;
@@ -488,21 +545,26 @@ int keyboard_read_input(ushort_t port,
                        uint_t length,
                        struct vm_device * dev)
 {
-  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
+  struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
 
-  if (length==1) { 
+  if (length == 1) { 
     uchar_t data;
+
     KEYBOARD_DEBUG_PRINT("keyboard: read from input (60h): ");
-    PullFromOutputQueue(dev,&data);
-    if (state->state==RESET) { 
+
+    PullFromOutputQueue(dev, &data);
+
+    if (state->state == RESET) { 
       // We just delivered the ack for the reset
       // now we will ready ourselves to deliver the BAT code (success)
-      PushToOutputQueue(dev,0xaa,1);
-      state->state=NORMAL;
+      PushToOutputQueue(dev, 0xaa, 1);
+      state->state = NORMAL;
     }
       
-    KEYBOARD_DEBUG_PRINT("0x%x\n",data);
-    *((uchar_t*)dest)=data;
+    KEYBOARD_DEBUG_PRINT("0x%x\n", data);
+
+    *((uchar_t*)dest) = data;
+
     return 1;
   } else {
     KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from input (60h)\n");
@@ -511,12 +573,11 @@ int keyboard_read_input(ushort_t port,
 }
 
 
-int keyboard_interrupt(uint_t irq,
-                      struct vm_device * dev) 
+int keyboard_interrupt(uint_t irq, struct vm_device * dev) 
 {
   KEYBOARD_DEBUG_PRINT("keyboard: interrupt\n");
 
-  dev->vm->vm_ops.raise_irq(dev->vm,irq);
+  dev->vm->vm_ops.raise_irq(dev->vm, irq);
 
   return 0;
 
@@ -580,7 +641,7 @@ static struct vm_device_ops dev_ops = {
 
 struct vm_device *create_keyboard() {
   
-  if (thekeyboard!=NULL) { 
+  if (thekeyboard != NULL) { 
     KEYBOARD_DEBUG_PRINT("keyboard: creating >1 keyboard device.  This will probably fail!\n");
   }
   
@@ -588,7 +649,7 @@ struct vm_device *create_keyboard() {
 
   struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);
 
-  thekeyboard=device;
+  thekeyboard = device;
   
   return device;
 }