changeset 38f3f3e1e442 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=38f3f3e1e442
description:
        X86: Refactor and clean up the keyboard controller.

diffstat:

2 files changed, 362 insertions(+), 330 deletions(-)
src/dev/x86/i8042.cc |  521 ++++++++++++++++++++------------------------------
src/dev/x86/i8042.hh |  171 +++++++++++++---

diffs (truncated from 785 to 300 lines):

diff -r ee307cca6d31 -r 38f3f3e1e442 src/dev/x86/i8042.cc
--- a/src/dev/x86/i8042.cc      Sat Jan 31 23:59:01 2009 -0800
+++ b/src/dev/x86/i8042.cc      Sat Jan 31 23:59:25 2009 -0800
@@ -36,79 +36,12 @@
 // The 8042 has a whopping 32 bytes of internal RAM.
 const uint8_t RamSize = 32;
 const uint8_t NumOutputBits = 14;
-const uint8_t KeyboardID[] = {0xab, 0x83};
-const uint8_t MouseID[] = {0x00};
+const uint8_t X86ISA::PS2Keyboard::ID[] = {0xab, 0x83};
+const uint8_t X86ISA::PS2Mouse::ID[] = {0x00};
 const uint8_t CommandAck = 0xfa;
 const uint8_t CommandNack = 0xfe;
 const uint8_t BatSuccessful = 0xaa;
 
-enum Port64Command
-{
-    GetCommandByte = 0x20,
-    ReadControllerRamBase = 0x20,
-    WriteCommandByte = 0x60,
-    WriteControllerRamBase = 0x60,
-    CheckForPassword = 0xA4,
-    LoadPassword = 0xA5,
-    CheckPassword = 0xA6,
-    DisableMouse = 0xA7,
-    EnableMouse = 0xA8,
-    TestMouse = 0xA9,
-    SelfTest = 0xAA,
-    InterfaceTest = 0xAB,
-    DiagnosticDump = 0xAC,
-    DisableKeyboard = 0xAD,
-    EnableKeyboard = 0xAE,
-    ReadInputPort = 0xC0,
-    ContinuousPollLow = 0xC1,
-    ContinuousPollHigh = 0xC2,
-    ReadOutputPort = 0xD0,
-    WriteOutputPort = 0xD1,
-    WriteKeyboardOutputBuff = 0xD2,
-    WriteMouseOutputBuff = 0xD3,
-    WriteToMouse = 0xD4,
-    DisableA20 = 0xDD,
-    EnableA20 = 0xDF,
-    ReadTestInputs = 0xE0,
-    PulseOutputBitBase = 0xF0,
-    SystemReset = 0xFE
-};
-
-enum Port60Command
-{
-    MouseScale1to1 = 0xE6,
-    MouseScale2to1 = 0xE7,
-    SetMouseResolution = 0xE8,
-    MouseGetStatus = 0xE9,
-    MouseReadData = 0xEB,
-    MouseResetWrapMode = 0xEC,
-    LEDWrite = 0xED,
-    DiagnosticEcho = 0xEE,
-    MouseWrapMode = 0xEE,
-    AlternateScanCodes = 0xF0,
-    MouseRemoteMode = 0xF0,
-    ReadKeyboardID = 0xF2,
-    ReadMouseID = 0xF2,
-    TypematicInfo = 0xF3,
-    MouseSampleRate = 0xF3,
-    KeyboardEnable = 0xF4,
-    MouseEnableReporting = 0xF4,
-    KeyboardDisable = 0xF5,
-    MouseDisableReporting = 0xF5,
-    DefaultsAndDisableKeyboard = 0xF6,
-    DefaultsAndDisableMouse = 0xF6,
-    AllKeysToTypematic = 0xF7,
-    AllKeysToMakeRelease = 0xF8,
-    AllKeysToMake = 0xF9,
-    AllKeysToTypematicMakeRelease = 0xFA,
-    KeyToTypematic = 0xFB,
-    KeyToMakeRelease = 0xFC,
-    KeyToMakeOnly = 0xFD,
-    Resend = 0xFE,
-    KeyboardReset = 0xFF,
-    MouseReset = 0xFF
-};
-
 void
 X86ISA::I8042::addressRanges(AddrRangeList &range_list)
 {
@@ -117,80 +50,46 @@
     range_list.push_back(RangeSize(commandPort, 1));
 }
 
-bool
+void
 X86ISA::I8042::writeData(uint8_t newData, bool mouse)
 {
-    if (!statusReg.outputFull) {
-        DPRINTF(I8042, "Set data %#02x.\n", newData);
-        dataReg = newData;
-        statusReg.outputFull = 1;
-        statusReg.mouseOutputFull = (mouse ? 1 : 0);
-        return true;
-    } else {
-        return false;
+    DPRINTF(I8042, "Set data %#02x.\n", newData);
+    dataReg = newData;
+    statusReg.outputFull = 1;
+    statusReg.mouseOutputFull = (mouse ? 1 : 0);
+    if (!mouse && commandByte.keyboardFullInt) {
+        DPRINTF(I8042, "Sending keyboard interrupt.\n");
+        keyboardIntPin->raise();
+        //This is a hack
+        keyboardIntPin->lower();
+    } else if (mouse && commandByte.mouseFullInt) {
+        DPRINTF(I8042, "Sending mouse interrupt.\n");
+        mouseIntPin->raise();
+        //This is a hack
+        mouseIntPin->lower();
     }
 }
 
 void
-X86ISA::I8042::keyboardAck()
+X86ISA::PS2Device::ack()
 {
-    while (!keyboardBuffer.empty())
-        keyboardBuffer.pop();
-    writeKeyboardData(&CommandAck, sizeof(CommandAck));
+    bufferData(&CommandAck, sizeof(CommandAck));
 }
 
 void
-X86ISA::I8042::writeKeyboardData(const uint8_t *data, int size)
+X86ISA::PS2Device::nack()
+{
+    bufferData(&CommandNack, sizeof(CommandNack));
+}
+
+void
+X86ISA::PS2Device::bufferData(const uint8_t *data, int size)
 {
     assert(data || size == 0);
     while (size) {
-        keyboardBuffer.push(*(data++));
+        outBuffer.push(*(data++));
         size--;
     }
-    if (writeData(keyboardBuffer.front())) {
-        keyboardBuffer.pop();
-        if (commandByte.keyboardFullInt) {
-            DPRINTF(I8042, "Sending keyboard interrupt.\n");
-            keyboardIntPin->raise();
-            //XXX This is a hack.
-            keyboardIntPin->lower();
-        }
-    }
-}
-
-void
-X86ISA::I8042::mouseAck()
-{
-    while (!mouseBuffer.empty())
-        mouseBuffer.pop();
-    writeMouseData(&CommandAck, sizeof(CommandAck));
-}
-
-void
-X86ISA::I8042::mouseNack()
-{
-    while (!mouseBuffer.empty())
-        mouseBuffer.pop();
-    writeMouseData(&CommandNack, sizeof(CommandAck));
-}
-
-void
-X86ISA::I8042::writeMouseData(const uint8_t *data, int size)
-{
-    assert(data || size == 0);
-    while (size) {
-        mouseBuffer.push(*(data++));
-        size--;
-    }
-    if (writeData(mouseBuffer.front(), true)) {
-        mouseBuffer.pop();
-        if (commandByte.mouseFullInt) {
-            DPRINTF(I8042, "Sending mouse interrupt.\n");
-            mouseIntPin->raise();
-            //XXX This is a hack
-            mouseIntPin->lower();
-        }
-    }
 }
 
 uint8_t
@@ -199,15 +98,196 @@
     uint8_t data = dataReg;
     statusReg.outputFull = 0;
     statusReg.mouseOutputFull = 0;
-    if (!keyboardBuffer.empty()) {
-        writeKeyboardData(NULL, 0);
-    }
-    if (!mouseBuffer.empty()) {
-        writeMouseData(NULL, 0);
+    if (keyboard.hasData()) {
+        writeData(keyboard.getData(), false);
+    } else if (mouse.hasData()) {
+        writeData(mouse.getData(), true);
     }
     return data;
 }
 
+bool
+X86ISA::PS2Keyboard::processData(uint8_t data)
+{
+    if (lastCommand != NoCommand) {
+        switch (lastCommand) {
+          case LEDWrite:
+            DPRINTF(I8042, "Setting LEDs: "
+                    "caps lock %s, num lock %s, scroll lock %s\n",
+                    bits(data, 2) ? "on" : "off",
+                    bits(data, 1) ? "on" : "off",
+                    bits(data, 0) ? "on" : "off");
+            ack();
+            lastCommand = NoCommand;
+            break;
+          case TypematicInfo:
+            DPRINTF(I8042, "Setting typematic info to %#02x.\n", data);
+            ack();
+            lastCommand = NoCommand;
+            break;
+        }
+        return hasData();
+    }
+    switch (data) {
+      case LEDWrite:
+        DPRINTF(I8042, "Got LED write command.\n");
+        ack();
+        lastCommand = LEDWrite;
+        break;
+      case DiagnosticEcho:
+        panic("Keyboard diagnostic echo unimplemented.\n");
+      case AlternateScanCodes:
+        panic("Accessing alternate scan codes unimplemented.\n");
+      case ReadID:
+        DPRINTF(I8042, "Got keyboard read ID command.\n");
+        ack();
+        bufferData((uint8_t *)&ID, sizeof(ID));
+        break;
+      case TypematicInfo:
+        DPRINTF(I8042, "Setting typematic info.\n");
+        ack();
+        lastCommand = TypematicInfo;
+        break;
+      case Enable:
+        DPRINTF(I8042, "Enabling the keyboard.\n");
+        ack();
+        break;
+      case Disable:
+        DPRINTF(I8042, "Disabling the keyboard.\n");
+        ack();
+        break;
+      case DefaultsAndDisable:
+        DPRINTF(I8042, "Disabling and resetting the keyboard.\n");
+        ack();
+        break;
+      case AllKeysToTypematic:
+        panic("Setting all keys to typemantic unimplemented.\n");
+      case AllKeysToMakeRelease:
+        panic("Setting all keys to make/release unimplemented.\n");
+      case AllKeysToMake:
+        panic("Setting all keys to make unimplemented.\n");
+      case AllKeysToTypematicMakeRelease:
+        panic("Setting all keys to "
+                "typematic/make/release unimplemented.\n");
+      case KeyToTypematic:
+        panic("Setting a key to typematic unimplemented.\n");
+      case KeyToMakeRelease:
+        panic("Setting a key to make/release unimplemented.\n");
+      case KeyToMakeOnly:
+        panic("Setting key to make only unimplemented.\n");
+      case Resend:
+        panic("Keyboard resend unimplemented.\n");
+      case Reset:
+        panic("Keyboard reset unimplemented.\n");
+      default:
+        panic("Unknown keyboard command %#02x.\n", data);
+    }
+    return hasData();
+}
+
+bool
+X86ISA::PS2Mouse::processData(uint8_t data)
+{
+    if (lastCommand != NoCommand) {
+        switch(lastCommand) {
+          case SetResolution:
+            DPRINTF(I8042, "Mouse resolution set to %d.\n", data);
+            resolution = data;
+            ack();
+            lastCommand = NoCommand;
+            break;
+          case SampleRate:
+            DPRINTF(I8042, "Mouse sample rate %d samples "
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to