ps2: Add VNC support to the keyboard model
authorAndreas Sandberg <andreas.sandberg@arm.com>
Mon, 9 Apr 2018 17:35:30 +0000 (18:35 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 17 Apr 2018 08:46:33 +0000 (08:46 +0000)
Add support for keyboard input from the VNC server in the PS/2
keyboard model. The introduced code is based on the functionality in
the Arm PL050 KMI model.

Change-Id: If04a9713e5a15e2149d1a7471b999e3060d8ee7d
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/9763
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/dev/ps2/PS2.py
src/dev/ps2/keyboard.cc
src/dev/ps2/keyboard.hh
src/dev/x86/I8042.py

index 5db3b6e178d6145cc13f174c5d9dab60367c4428..fcbbc28c3994fe343ca5d65ae6b8752fd5b64653 100644 (file)
@@ -48,6 +48,8 @@ class PS2Keyboard(PS2Device):
     type = 'PS2Keyboard'
     cxx_header = "dev/ps2/keyboard.hh"
 
+    vnc = Param.VncInput(Parent.any, "VNC server providing keyboard input")
+
 class PS2Mouse(PS2Device):
     type = 'PS2Mouse'
     cxx_header = "dev/ps2/mouse.hh"
index a942d3457eb816ce4e3bf17b900d217d5b13a425..46b89faccd351659bacb41115cd78124bff6e506 100644 (file)
 
 #include "base/logging.hh"
 #include "debug/PS2.hh"
+#include "dev/ps2.hh"
 #include "params/PS2Keyboard.hh"
 
 const uint8_t PS2Keyboard::ID[] = {0xab, 0x83};
 
 PS2Keyboard::PS2Keyboard(const PS2KeyboardParams *p)
     : PS2Device(p),
-      lastCommand(NoCommand)
+      lastCommand(NoCommand),
+      shiftDown(false),
+      enabled(false)
 {
+    if (p->vnc)
+        p->vnc->setKeyboard(this);
 }
 
 void
@@ -60,6 +65,8 @@ PS2Keyboard::serialize(CheckpointOut &cp) const
 {
     PS2Device::serialize(cp);
     SERIALIZE_SCALAR(lastCommand);
+    SERIALIZE_SCALAR(shiftDown);
+    SERIALIZE_SCALAR(enabled);
 }
 
 void
@@ -67,6 +74,8 @@ PS2Keyboard::unserialize(CheckpointIn &cp)
 {
     PS2Device::unserialize(cp);
     UNSERIALIZE_SCALAR(lastCommand);
+    UNSERIALIZE_SCALAR(shiftDown);
+    UNSERIALIZE_SCALAR(enabled);
 }
 
 void
@@ -114,14 +123,17 @@ PS2Keyboard::recv(uint8_t data)
         break;
       case Enable:
         DPRINTF(PS2, "Enabling the keyboard.\n");
+        enabled = true;
         sendAck();
         break;
       case Disable:
         DPRINTF(PS2, "Disabling the keyboard.\n");
+        enabled = false;
         sendAck();
         break;
       case DefaultsAndDisable:
         DPRINTF(PS2, "Disabling and resetting the keyboard.\n");
+        enabled = false;
         sendAck();
         break;
       case AllKeysToTypematic:
@@ -148,6 +160,27 @@ PS2Keyboard::recv(uint8_t data)
     }
 }
 
+void
+PS2Keyboard::keyPress(uint32_t key, bool down)
+{
+    std::list<uint8_t> keys;
+
+    // convert the X11 keysym into ps2 codes and update the shift
+    // state (shiftDown)
+    Ps2::keySymToPs2(key, down, shiftDown, keys);
+
+    // Drop key presses if the keyboard hasn't been enabled by the
+    // host. We do that after translating the key code to ensure that
+    // we keep track of the shift state.
+    if (!enabled)
+        return;
+
+    // Insert into our queue of characters
+    for (uint8_t c : keys)
+        send(c);
+}
+
+
 PS2Keyboard *
 PS2KeyboardParams::create()
 {
index 8943e7fcbbde83848fcd2954d5ac863cf355d4fe..f5d83049f6a930729f83fdf1cc2ecc5b84a1aede 100644 (file)
 #ifndef __DEV_PS2_KEYBOARD_HH__
 #define __DEV_PS2_KEYBOARD_HH__
 
+#include "base/vnc/vncinput.hh"
 #include "dev/ps2/device.hh"
 
 struct PS2KeyboardParams;
 
-class PS2Keyboard : public PS2Device
+class PS2Keyboard : public PS2Device, VncKeyboard
 {
   protected:
     static const uint8_t ID[];
@@ -78,6 +79,12 @@ class PS2Keyboard : public PS2Device
 
     uint16_t lastCommand;
 
+    /** is the shift key currently down */
+    bool shiftDown;
+
+    /** Is the device enabled? */
+    bool enabled;
+
   public:
     PS2Keyboard(const PS2KeyboardParams *p);
 
@@ -86,6 +93,9 @@ class PS2Keyboard : public PS2Device
 
   protected: // PS2Device
     void recv(uint8_t data) override;
+
+  public: // VncKeyboard
+    void keyPress(uint32_t key, bool down) override;
 };
 
 #endif // __DEV_PS2_KEYBOARD_hH__
index 9203f40f597d917894eb85d45039d5f5456f2a31..43e70d6e4ec2ac8e3648876d6476e96234cca8c4 100644 (file)
@@ -45,5 +45,5 @@ class I8042(BasicPioDevice):
     keyboard_int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
             'Pin to signal the keyboard has data')
 
-    keyboard = Param.PS2Device(PS2Keyboard(), "PS/2 keyboard device")
+    keyboard = Param.PS2Device(PS2Keyboard(vnc=NULL), "PS/2 keyboard device")
     mouse = Param.PS2Device(PS2Mouse(), "PS/2 mouse device")