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