diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh --- a/src/dev/x86/i8042.hh +++ b/src/dev/x86/i8042.hh @@ -160,7 +160,7 @@ const std::string §ion); }; -class PS2Keyboard : public PS2Device +class PS2Keyboard : public PS2Device, public VncKeyboard { protected: static const uint8_t ID[]; @@ -186,9 +186,23 @@ Reset = 0xFF }; + bool enabled; + I8042 *i8042; + bool shiftDown; + + void reset(); + public: + PS2Keyboard(I8042 *_i8042) : PS2Device(), enabled(false), i8042(_i8042), + shiftDown(false) + {} + bool processData(uint8_t data); + const std::string name() const; + + void keyPress(uint32_t key, bool down); + void serialize(const std::string &base, std::ostream &os); void unserialize(const std::string &base, Checkpoint *cp, const std::string §ion); # Node ID 76e90695e93b10f566bfafbcb93e083e46ba71ad # Parent 595f40e7248176dc4d7ad57a729d8ab24c9c9ec2 diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc --- a/src/dev/x86/i8042.cc +++ b/src/dev/x86/i8042.cc @@ -28,9 +28,12 @@ * Authors: Gabe Black */ +#include + #include "base/bitunion.hh" #include "debug/I8042.hh" #include "dev/x86/i8042.hh" +#include "dev/ps2.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" @@ -49,7 +52,7 @@ dataPort(p->data_port), commandPort(p->command_port), outputs(0), statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand), mouseIntPin(p->mouse_int_pin), keyboardIntPin(p->keyboard_int_pin), - mouse(this) + mouse(this), keyboard(this) { outputs.reset = 1; outputs.a20 = 1; @@ -58,12 +61,13 @@ statusReg.commandLast = 1; statusReg.keyboardUnlocked = 1; - commandByte.convertScanCodes = 1; commandByte.passedSelfTest = 1; commandByte.keyboardFullInt = 1; - if (p->vnc) + if (p->vnc) { p->vnc->setMouse(&mouse); + p->vnc->setKeyboard(&keyboard); + } } @@ -141,6 +145,14 @@ return data; } +void +X86ISA::PS2Keyboard::reset() +{ + enabled = false; + while (!outBuffer.empty()) + outBuffer.pop(); +} + bool X86ISA::PS2Keyboard::processData(uint8_t data) { @@ -188,13 +200,16 @@ case Enable: DPRINTF(I8042, "Enabling the keyboard.\n"); ack(); + enabled = true; break; case Disable: DPRINTF(I8042, "Disabling the keyboard.\n"); ack(); + enabled = false; break; case DefaultsAndDisable: DPRINTF(I8042, "Disabling and resetting the keyboard.\n"); + reset(); ack(); break; case AllKeysToTypematic: @@ -215,7 +230,9 @@ case Resend: panic("Keyboard resend unimplemented.\n"); case Reset: - panic("Keyboard reset unimplemented.\n"); + reset(); + ack(); + break; default: panic("Unknown keyboard command %#02x.\n", data); } @@ -223,6 +240,31 @@ } const std::string +X86ISA::PS2Keyboard::name() const +{ + return i8042->name() + ".keyboard"; +} + +void +X86ISA::PS2Keyboard::keyPress(uint32_t key, bool down) +{ + using namespace Ps2; + + if (!enabled) + return; + + std::list keys; + + keySymToPs2(key, down, shiftDown, keys); + + std::list::iterator pos; + for (pos = keys.begin(); pos != keys.end(); pos++) + bufferData(&*pos, 1); + + i8042->getData(); +} + +const std::string X86ISA::PS2Mouse::name() const { return i8042->name() + ".mouse"; @@ -666,6 +708,9 @@ arrayParamOut(os, base + ".outBuffer.elts", buffer, bufferSize*sizeof(uint8_t)); delete[] buffer; + + paramOut(os, base + ".enabled", enabled); + paramOut(os, base + ".shiftDown", shiftDown); } void @@ -682,6 +727,9 @@ outBuffer.push(buffer[i]); } delete[] buffer; + + paramIn(cp, section, base + ".enabled", enabled); + paramIn(cp, section, base + ".shiftDown", shiftDown); } void