34 #include "debug/I8042.hh"
50 latency(p->pio_latency),
51 dataPort(p->data_port), commandPort(p->command_port),
52 statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
53 mouseIntPin(p->mouse_int_pin), keyboardIntPin(p->keyboard_int_pin)
71 ranges.push_back(
RangeSize(commandPort, 1));
80 statusReg.outputFull = 1;
81 statusReg.mouseOutputFull = (mouse ? 1 : 0);
82 if (!mouse && commandByte.keyboardFullInt) {
84 keyboardIntPin->raise();
86 keyboardIntPin->lower();
87 }
else if (mouse && commandByte.mouseFullInt) {
98 paramOut(cp, base +
".lastCommand", lastCommand);
101 std::copy(outBuffer.begin(), outBuffer.end(), buffer.begin());
108 paramIn(cp, base +
".lastCommand", lastCommand);
112 assert(outBuffer.empty());
113 for (
auto c : buffer)
114 outBuffer.push_back(
c);
133 assert(data || size == 0);
135 outBuffer.push_back(*(data++));
143 uint8_t
data = dataReg;
144 statusReg.outputFull = 0;
145 statusReg.mouseOutputFull = 0;
146 if (keyboard.hasData()) {
147 writeData(keyboard.getData(),
false);
148 }
else if (mouse.hasData()) {
149 writeData(mouse.getData(),
true);
157 if (lastCommand != NoCommand) {
158 switch (lastCommand) {
161 "caps lock %s, num lock %s, scroll lock %s\n",
162 bits(data, 2) ?
"on" :
"off",
163 bits(data, 1) ?
"on" :
"off",
164 bits(data, 0) ?
"on" :
"off");
166 lastCommand = NoCommand;
169 DPRINTF(
I8042,
"Setting typematic info to %#02x.\n", data);
171 lastCommand = NoCommand;
180 lastCommand = LEDWrite;
183 panic(
"Keyboard diagnostic echo unimplemented.\n");
184 case AlternateScanCodes:
185 panic(
"Accessing alternate scan codes unimplemented.\n");
189 bufferData((uint8_t *)&ID,
sizeof(ID));
194 lastCommand = TypematicInfo;
204 case DefaultsAndDisable:
205 DPRINTF(
I8042,
"Disabling and resetting the keyboard.\n");
208 case AllKeysToTypematic:
209 panic(
"Setting all keys to typemantic unimplemented.\n");
210 case AllKeysToMakeRelease:
211 panic(
"Setting all keys to make/release unimplemented.\n");
213 panic(
"Setting all keys to make unimplemented.\n");
214 case AllKeysToTypematicMakeRelease:
215 panic(
"Setting all keys to "
216 "typematic/make/release unimplemented.\n");
218 panic(
"Setting a key to typematic unimplemented.\n");
219 case KeyToMakeRelease:
220 panic(
"Setting a key to make/release unimplemented.\n");
222 panic(
"Setting key to make only unimplemented.\n");
224 panic(
"Keyboard resend unimplemented.\n");
226 panic(
"Keyboard reset unimplemented.\n");
228 panic(
"Unknown keyboard command %#02x.\n", data);
236 if (lastCommand != NoCommand) {
237 switch(lastCommand) {
242 lastCommand = NoCommand;
246 "per second.\n", data);
249 lastCommand = NoCommand;
252 panic(
"Not expecting data for a mouse command.\n");
275 bufferData((uint8_t *)&(
status), 1);
276 bufferData(&resolution,
sizeof(resolution));
277 bufferData(&sampleRate,
sizeof(sampleRate));
280 panic(
"Reading mouse data unimplemented.\n");
282 panic(
"Resetting mouse wrap mode unimplemented.\n");
284 panic(
"Setting mouse wrap mode unimplemented.\n");
286 panic(
"Setting mouse remote mode unimplemented.\n");
290 bufferData(ID,
sizeof(ID));
294 lastCommand = SampleRate;
297 case DisableReporting:
302 case EnableReporting:
307 case DefaultsAndDisable:
316 panic(
"Mouse resend unimplemented.\n");
325 bufferData(ID,
sizeof(ID));
328 warn(
"Unknown mouse command %#02x.\n", data);
341 if (addr == dataPort) {
342 uint8_t
data = readDataOut();
345 }
else if (addr == commandPort) {
347 pkt->
set<uint8_t>((uint8_t)statusReg);
349 panic(
"Read from unrecognized port %#x.\n", addr);
360 uint8_t
data = pkt->
get<uint8_t>();
361 if (addr == dataPort) {
362 statusReg.commandLast = 0;
363 switch (lastCommand) {
365 if (keyboard.processData(data)) {
366 writeData(keyboard.getData(),
false);
370 if (mouse.processData(data)) {
371 writeData(mouse.getData(),
true);
374 case WriteCommandByte:
377 "command byte\" command.\n", data);
378 statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
380 case WriteMouseOutputBuff:
382 "mouse output buffer\" command.\n", data);
383 writeData(data,
true);
386 panic(
"Data written for unrecognized "
387 "command %#02x\n", lastCommand);
389 lastCommand = NoCommand;
390 }
else if (addr == commandPort) {
392 statusReg.commandLast = 1;
395 if (data > ReadControllerRamBase &&
396 data < ReadControllerRamBase +
RamSize) {
397 panic(
"Attempted to use i8042 read controller RAM command to "
398 "get byte %d.\n", data - ReadControllerRamBase);
399 }
else if (data > WriteControllerRamBase &&
400 data < WriteControllerRamBase +
RamSize) {
401 panic(
"Attempted to use i8042 read controller RAM command to "
402 "get byte %d.\n", data - ReadControllerRamBase);
403 }
else if (data >= PulseOutputBitBase &&
405 panic(
"Attempted to use i8042 pulse output bit command to "
406 "to pulse bit %d.\n", data - PulseOutputBitBase);
411 writeData(commandByte);
413 case WriteCommandByte:
415 lastCommand = WriteCommandByte;
417 case CheckForPassword:
418 panic(
"i8042 \"Check for password\" command not implemented.\n");
420 panic(
"i8042 \"Load password\" command not implemented.\n");
422 panic(
"i8042 \"Check password\" command not implemented.\n");
425 commandByte.disableMouse = 1;
429 commandByte.disableMouse = 0;
432 panic(
"i8042 \"Test mouse\" command not implemented.\n");
434 panic(
"i8042 \"Self test\" command not implemented.\n");
436 panic(
"i8042 \"Interface test\" command not implemented.\n");
438 panic(
"i8042 \"Diagnostic dump\" command not implemented.\n");
439 case DisableKeyboard:
441 commandByte.disableKeyboard = 1;
445 commandByte.disableKeyboard = 0;
448 panic(
"i8042 \"Read input port\" command not implemented.\n");
449 case ContinuousPollLow:
450 panic(
"i8042 \"Continuous poll low\" command not implemented.\n");
451 case ContinuousPollHigh:
452 panic(
"i8042 \"Continuous poll high\" command not implemented.\n");
454 panic(
"i8042 \"Read output port\" command not implemented.\n");
455 case WriteOutputPort:
456 warn(
"i8042 \"Write output port\" command not implemented.\n");
457 lastCommand = WriteOutputPort;
458 case WriteKeyboardOutputBuff:
459 warn(
"i8042 \"Write keyboard output buffer\" "
460 "command not implemented.\n");
461 lastCommand = WriteKeyboardOutputBuff;
462 case WriteMouseOutputBuff:
463 DPRINTF(
I8042,
"Got command to write to mouse output buffer.\n");
464 lastCommand = WriteMouseOutputBuff;
468 lastCommand = WriteToMouse;
471 panic(
"i8042 \"Disable A20\" command not implemented.\n");
473 panic(
"i8042 \"Enable A20\" command not implemented.\n");
475 panic(
"i8042 \"Read test inputs\" command not implemented.\n");
477 panic(
"i8042 \"System reset\" command not implemented.\n");
479 warn(
"Write to unknown i8042 "
480 "(keyboard controller) command port.\n");
483 panic(
"Write to unrecognized port %#x.\n", addr);
492 uint8_t statusRegData = statusReg.__data;
493 uint8_t commandByteData = commandByte.__data;
501 mouse.serialize(
"mouse", cp);
502 keyboard.serialize(
"keyboard", cp);
508 uint8_t statusRegData;
509 uint8_t commandByteData;
517 mouse.unserialize(
"mouse", cp);
518 keyboard.unserialize(
"keyboard", cp);
520 statusReg.__data = statusRegData;
521 commandByte.__data = commandByteData;
530 paramOut(cp, base +
".resolution", resolution);
531 paramOut(cp, base +
".sampleRate", sampleRate);
540 paramIn(cp, base +
".resolution", resolution);
541 paramIn(cp, base +
".sampleRate", sampleRate);
545 I8042Params::create()
AddrRange RangeSize(Addr start, Addr size)
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
const uint8_t BatSuccessful
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
bool processData(uint8_t data) override
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
void serialize(const std::string &base, CheckpointOut &cp) const override
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
#define UNSERIALIZE_SCALAR(scalar)
void bufferData(const uint8_t *data, int size)
void makeAtomicResponse()
uint64_t Tick
Tick count type.
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void writeData(uint8_t newData, bool mouse=false)
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > ¶m)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
static const uint8_t ID[]
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
virtual void serialize(const std::string &base, CheckpointOut &cp) const
#define SERIALIZE_SCALAR(scalar)
virtual void unserialize(const std::string &base, CheckpointIn &cp)
Declaration of the Packet class.
std::ostream CheckpointOut
void unserialize(const std::string &base, CheckpointIn &cp) override
const uint8_t CommandNack
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > ¶m)
static const uint8_t ID[]
const uint8_t NumOutputBits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
bool processData(uint8_t data) override