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.


Working (apparently) emulated keyboard support
Peter Dinda [Fri, 30 May 2008 00:46:47 +0000 (00:46 +0000)]
Slight modifications to rombios to shorten a buffer drain loop
and to provide slightly different error reporting via 80h

palacios/build/Makefile
palacios/build/rombios
palacios/build/vm_kernel
palacios/src/devices/keyboard.c
palacios/src/geekos/vm.c
palacios/src/vmboot/rombios/rombios.c

index 741c1fd..51413b6 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.35 $
+# $Revision: 1.36 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -296,6 +296,8 @@ vmm.img : fd.img
 
 force_rombios: 
        (cd ../src/vmboot/rombios; make)
+       cp ../src/vmboot/rombios/BIOS-bochs-latest rombios
+
 
 world: force_rombios
        ../scripts/make_payload.pl payload_layout.txt vm_kernel
index 8f8992b..0bf32a0 100644 (file)
Binary files a/palacios/build/rombios and b/palacios/build/rombios differ
index b5e8488..12806a7 100755 (executable)
Binary files a/palacios/build/vm_kernel and b/palacios/build/vm_kernel differ
index 1f098bb..65e4d77 100644 (file)
@@ -5,6 +5,8 @@
 
 #define KEYBOARD_DEBUG 1
 
+#define KEYBOARD_DEBUG_80H   1
+
 #if KEYBOARD_DEBUG
 #define KEYBOARD_DEBUG_PRINT(first, rest...) PrintDebug(first, ##rest)
 #else
@@ -21,12 +23,14 @@ 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
 
 
 // extract bits for status byte
-#define STATUS_OUTPUT_BUFFER_FULL   0x01  // 1=full
-#define STATUS_INPUT_BUFFER_FULL    0x02  // 1=full
+#define STATUS_OUTPUT_BUFFER_FULL   0x01  // 1=full (data for system)
+#define STATUS_INPUT_BUFFER_FULL    0x02  // 1=full (data for 8042)
 #define STATUS_SYSTEM               0x04  // 1=self-test-passed
 #define STATUS_COMMAND_DATA_AVAIL   0x08  // internal: 0=data on 60h, 0=cmd on 64h
 #define STATUS_ENABLED              0x10  // 1=keyboard is enabled
@@ -65,15 +69,19 @@ struct keyboard_internal {
   // state of the onboard microcontroller
   // this is needed because sometimes 0x60 reads come
   // from the onboard microcontroller
-  enum {NORMAL,
-       // after receiving cmd 0x20 
-       // keyboard uC cmd byte pushed onto output queue
-       WRITING_CMD_BYTE,  
+  enum {// Normal mode measn we deliver keys
+        // to the vm and accept commands from it
+        NORMAL,
        // after receiving cmd 0x60
-       // keybaord uC cmd will subsequently arive on data port
-       TRANSMIT_PASSWD,
+       // keybaord uC cmd will subsequently arrive
+       WRITING_CMD_BYTE,  
        // after recieving 0xa5
        // password arrives on data port, null terminated
+       TRANSMIT_PASSWD,
+       // after having reset sent to 0x60
+       // we immediately ack, and then
+       // push BAT success (0xaa) after the ack
+       RESET,
   } state;
        
 
@@ -82,10 +90,12 @@ struct keyboard_internal {
                             //     via read/write cmd byte command
   uchar_t status_byte;      //  for on-board uC - read via 64h
 
-  uchar_t input_queue;      //  Read via 60h
-  uint_t  input_queue_len;  //  num items queued
-  uchar_t output_queue;     //  Written by 60h
-  uint_t  output_queue_len; //  num items queued 
+  // Data for 8042
+  uchar_t input_queue;      //  
+  uint_t  input_queue_len;  //  
+  // Data for system
+  uchar_t output_queue;     //  
+  uint_t  output_queue_len; //  
 };
 
 
@@ -108,7 +118,7 @@ static int PushToOutputQueue(struct vm_device *dev, uchar_t value, uchar_t overw
   }
 }
 
-#if 0
+#if 1
 // 
 // pull item from outputqueue 
 // returns 0 if successful
@@ -117,7 +127,7 @@ 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->input_queue;
+    *value=state->output_queue;
     state->output_queue_len=0;
     state->status_byte &= ~STATUS_OUTPUT_BUFFER_FULL;
     return 0;
@@ -128,6 +138,7 @@ static int PullFromOutputQueue(struct vm_device *dev,uchar_t *value)
 }
 #endif
 
+#if 0
 // 
 // push item onto inputqueue, optionally overwriting if there is no room
 // returns 0 if successful
@@ -164,6 +175,8 @@ static int PullFromInputQueue(struct vm_device *dev, uchar_t *value)
   }
 }
 
+#endif
+
 static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
 {
   // this currently does nothing
@@ -183,7 +196,7 @@ void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
   if (    (state->status_byte & STATUS_ENABLED)      // onboard is enabled
          && (!(state->cmd_byte & CMD_DISABLE)))  {   // keyboard is enabled
 
-    PushToInputQueue(dev,scancode,1);
+    PushToOutputQueue(dev,scancode,1);
 
     if (state->cmd_byte & CMD_INTR) { 
       keyboard_interrupt(KEYBOARD_IRQ,dev);
@@ -231,6 +244,39 @@ int keyboard_stop_device(struct vm_device *dev)
 }
 
 
+#if KEYBOARD_DEBUG_80H
+int keyboard_write_delay(ushort_t port,
+                        void * src, 
+                        uint_t length,
+                        struct vm_device * dev)
+{
+  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;
+  }
+}
+
+int keyboard_read_delay(ushort_t port,
+                       void * dest, 
+                       uint_t length,
+                       struct vm_device * dev)
+{
+  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;
+  }
+}
+#endif
+    
+  
+
 
 
 int keyboard_write_command(ushort_t port,
@@ -244,7 +290,7 @@ int keyboard_write_command(ushort_t port,
   // Should always be single byte write
 
   if (length!=1) { 
-    KEYBOARD_DEBUG_PRINT("keyboard: write of >1 bytes to 64h");
+    KEYBOARD_DEBUG_PRINT("keyboard: write of >1 bytes (%d) to 64h\n",length);
     return -1;
   }
 
@@ -259,7 +305,7 @@ int keyboard_write_command(ushort_t port,
   switch (cmd) { 
 
   case 0x20:  // READ COMMAND BYTE (returned in 60h)
-    PushToInputQueue(dev,state->cmd_byte,1);
+    PushToOutputQueue(dev,state->cmd_byte,1);
     state->state=NORMAL;  // the next read on 0x60 will get the right data
     break;
 
@@ -270,7 +316,7 @@ int keyboard_write_command(ushort_t port,
   // case 0x90-9f - write to output port  (?)
 
   case 0xa1: // Get version number
-    PushToInputQueue(dev,0,1);
+    PushToOutputQueue(dev,0,1);
     state->state=NORMAL;
     break;
 
@@ -302,17 +348,17 @@ int keyboard_write_command(ushort_t port,
     break;
 
   case 0xa9:  // mouse interface test  (always succeeds)
-    PushToInputQueue(dev,0,1);
+    PushToOutputQueue(dev,0,1);
     state->state=NORMAL;
     break;
 
   case 0xaa:  // controller self test (always succeeds)
-    PushToInputQueue(dev,0x55,1);
+    PushToOutputQueue(dev,0x55,1);
     state->state=NORMAL;
     break;
 
   case 0xab:  // keyboard interface test (always succeeds)
-    PushToInputQueue(dev,0,1);
+    PushToOutputQueue(dev,0,1);
     state->state=NORMAL;
     break;
 
@@ -327,7 +373,7 @@ int keyboard_write_command(ushort_t port,
     break;
 
   case 0xaf:  // get version
-    PushToInputQueue(dev,0x00,1);
+    PushToOutputQueue(dev,0x00,1);
     state->state=NORMAL;
     break;
 
@@ -405,7 +451,14 @@ int keyboard_write_output(ushort_t port,
     // command is being sent to keyboard controller
     switch (data) { 
     case 0xff: // reset
-      PushToInputQueue(dev,0xfa,1); // ack
+      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
@@ -417,13 +470,12 @@ int keyboard_write_output(ushort_t port,
     case 0xf8: // set all make/break
     case 0xf7: // set all typemaktic
     case 0xf6: // set defaults
-    case 0xf5: // disable scanning
-    case 0xf4: // enable scanning
     case 0xf3: // set typematic delay/rate
     default:
-      KEYBOARD_DEBUG_PRINT("keyboard: unhandled command 0x%x on output buffer (60h)\n");
+      KEYBOARD_DEBUG_PRINT("keyboard: unhandled command 0x%x on output buffer (60h)\n",data);
       break;
     }
+    break;
   default:
     KEYBOARD_DEBUG_PRINT("keyboard: unknown state %x on command 0x%x on output buffer (60h)\n",state->state, data);
   }
@@ -436,10 +488,19 @@ int keyboard_read_input(ushort_t port,
                        uint_t length,
                        struct vm_device * dev)
 {
+  struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
+
   if (length==1) { 
     uchar_t data;
     KEYBOARD_DEBUG_PRINT("keyboard: read from input (60h): ");
-    PullFromInputQueue(dev,&data);
+    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;
+    }
+      
     KEYBOARD_DEBUG_PRINT("0x%x\n",data);
     *((uchar_t*)dest)=data;
     return 1;
@@ -476,6 +537,11 @@ int keyboard_init_device(struct vm_device * dev)
   // hook ports
   dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command);
   dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output);
+
+#if KEYBOARD_DEBUG_80H
+  dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay);
+#endif
+
   
   //
   // We do not hook the IRQ here.  Instead, the underlying device driver
@@ -490,6 +556,9 @@ int keyboard_deinit_device(struct vm_device *dev)
 
   dev_unhook_io(dev, KEYBOARD_60H);
   dev_unhook_io(dev, KEYBOARD_64H);
+#if KEYBOARD_DEBUG_80H
+  dev_unhook_io(dev, KEYBOARD_DELAY_80H);
+#endif
   keyboard_reset_device(dev);
   return 0;
 }
index 910dbd6..1b46b2f 100644 (file)
@@ -317,10 +317,10 @@ int RunVMM(struct Boot_Info * bootInfo) {
       {
        
        struct vm_device * nvram = create_nvram();
-       //struct vm_device * timer = create_timer();
+       struct vm_device * timer = create_timer();
        struct vm_device * pic = create_pic();
-       //struct vm_device * keyboard = create_keyboard();
-       struct vm_device * pit = create_pit();
+       struct vm_device * keyboard = create_keyboard();
+       //struct vm_device * pit = create_pit();
 
        //generic_port_range_type range = {0,1024} ; // hook first 1024 ports if not already hooked
 
@@ -328,10 +328,10 @@ int RunVMM(struct Boot_Info * bootInfo) {
        
 
        attach_device(&(vm_info), nvram);
-       //attach_device(&(vm_info), timer);
+       attach_device(&(vm_info), timer);
        attach_device(&(vm_info), pic);
-       attach_device(&(vm_info), pit);
-       //attach_device(&(vm_info), keyboard);
+       //attach_device(&(vm_info), pit);
+       attach_device(&(vm_info), keyboard);
 
        // Important that this be attached last!
        //attach_device(&(vm_info), generic);
index 69136b7..047bd32 100644 (file)
@@ -1,6 +1,6 @@
 //  -*- fundamental -*-
 /////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.5 2008/05/12 00:21:17 pdinda Exp $
+// $Id: rombios.c,v 1.6 2008/05/30 00:46:55 pdinda Exp $
 /////////////////////////////////////////////////////////////////////////
 //
 //  Copyright (C) 2002  MandrakeSoft S.A.
@@ -945,10 +945,10 @@ Bit16u cdrom_boot();
 
 #endif // BX_ELTORITO_BOOT
 
-static char bios_cvs_version_string[] = "$Revision: 1.5 $";
-static char bios_date_string[] = "$Date: 2008/05/12 00:21:17 $";
+static char bios_cvs_version_string[] = "$Revision: 1.6 $";
+static char bios_date_string[] = "$Date: 2008/05/30 00:46:55 $";
 
-static char CVSID[] = "$Id: rombios.c,v 1.5 2008/05/12 00:21:17 pdinda Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.6 2008/05/30 00:46:55 pdinda Exp $";
 
 /* Offset to skip the CVS $Id: prefix */ 
 #define bios_version_string  (CVSID + 4)
@@ -1680,9 +1680,11 @@ keyboard_init()
     while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00); 
 
     /* flush incoming keys */
-    max=0x2000;
+    // temporarily chaged for debug -PAD
+    //    max=0x2000;  
+    max=10;
     while (--max > 0) {
-        outb(0x80, 0x00);
+        outb(0x80, 0x01);
         if (inb(0x64) & 0x01) {
             inb(0x60);
             max = 0x2000;
@@ -1700,12 +1702,12 @@ keyboard_init()
 
     /* Wait until buffer is empty */
     max=0xffff;
-    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
+    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x02);
     if (max==0x0) keyboard_panic(00);
 
     /* Wait for data */
     max=0xffff;
-    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01);
+    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x03);
     if (max==0x0) keyboard_panic(01);
 
     /* read self-test result, 0x55 should be returned from 0x60 */