33#include "debug/I8042.hh"
52 dataPort(
p.data_port), commandPort(
p.command_port),
53 mouse(
p.mouse), keyboard(
p.keyboard)
55 fatal_if(!
mouse,
"The i8042 model requires a mouse instance");
64 for (
int i = 0;
i <
p.port_keyboard_int_pin_connection_count;
i++) {
68 for (
int i = 0;
i <
p.port_mouse_int_pin_connection_count;
i++) {
80 ranges.push_back(
RangeSize(commandPort, 1));
89 statusReg.outputFull = 1;
90 statusReg.mouseOutputFull = (mouse ? 1 : 0);
91 if (!mouse && commandByte.keyboardFullInt) {
93 for (
auto *wire: keyboardIntPin) {
98 }
else if (mouse && commandByte.mouseFullInt) {
100 for (
auto *wire: mouseIntPin) {
111 uint8_t
data = dataReg;
112 statusReg.outputFull = 0;
113 statusReg.mouseOutputFull = 0;
114 if (keyboard->hostDataAvailable()) {
115 writeData(keyboard->hostRead(),
false);
116 }
else if (mouse->hostDataAvailable()) {
117 writeData(mouse->hostRead(),
true);
127 if (
addr == dataPort) {
128 uint8_t
data = readDataOut();
131 }
else if (
addr == commandPort) {
133 pkt->
setLE<uint8_t>((uint8_t)statusReg);
135 panic(
"Read from unrecognized port %#x.\n",
addr);
147 if (
addr == dataPort) {
148 statusReg.commandLast = 0;
149 switch (lastCommand) {
151 keyboard->hostWrite(
data);
152 if (keyboard->hostDataAvailable())
153 writeData(keyboard->hostRead(),
false);
156 mouse->hostWrite(
data);
157 if (mouse->hostDataAvailable())
158 writeData(mouse->hostRead(),
true);
160 case WriteCommandByte:
163 "command byte\" command.\n",
data);
164 statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
166 case WriteMouseOutputBuff:
168 "mouse output buffer\" command.\n",
data);
169 writeData(
data,
true);
171 case WriteKeyboardOutputBuff:
173 "keyboad output buffer\" command.\n",
data);
174 writeData(
data,
false);
176 case WriteOutputPort:
178 "output port\" command.\n",
data);
183 panic(
"Data written for unrecognized "
184 "command %#02x\n", lastCommand);
186 lastCommand = NoCommand;
187 }
else if (
addr == commandPort) {
189 statusReg.commandLast = 1;
192 if (
data > ReadControllerRamBase &&
194 panic(
"Attempted to use i8042 read controller RAM command to "
195 "get byte %d.\n",
data - ReadControllerRamBase);
196 }
else if (
data > WriteControllerRamBase &&
198 panic(
"Attempted to use i8042 write controller RAM command to "
199 "get byte %d.\n",
data - WriteControllerRamBase);
200 }
else if (
data >= PulseOutputBitBase &&
202 panic(
"Attempted to use i8042 pulse output bit command to "
203 "to pulse bit %d.\n",
data - PulseOutputBitBase);
208 writeData(commandByte);
210 case WriteCommandByte:
212 lastCommand = WriteCommandByte;
214 case CheckForPassword:
215 panic(
"i8042 \"Check for password\" command not implemented.\n");
217 panic(
"i8042 \"Load password\" command not implemented.\n");
219 panic(
"i8042 \"Check password\" command not implemented.\n");
222 commandByte.disableMouse = 1;
226 commandByte.disableMouse = 0;
238 commandByte.convertScanCodes = 1;
239 commandByte.disableMouse = 1;
240 commandByte.disableKeyboard = 1;
241 commandByte.passedSelfTest = 1;
242 statusReg.passedSelfTest = 1;
250 panic(
"i8042 \"Diagnostic dump\" command not implemented.\n");
251 case DisableKeyboard:
253 commandByte.disableKeyboard = 1;
257 commandByte.disableKeyboard = 0;
260 panic(
"i8042 \"Read input port\" command not implemented.\n");
261 case ContinuousPollLow:
262 panic(
"i8042 \"Continuous poll low\" command not implemented.\n");
263 case ContinuousPollHigh:
264 panic(
"i8042 \"Continuous poll high\" command not implemented.\n");
266 panic(
"i8042 \"Read output port\" command not implemented.\n");
267 case WriteOutputPort:
268 lastCommand = WriteOutputPort;
270 case WriteKeyboardOutputBuff:
271 lastCommand = WriteKeyboardOutputBuff;
273 case WriteMouseOutputBuff:
274 DPRINTF(
I8042,
"Got command to write to mouse output buffer.\n");
275 lastCommand = WriteMouseOutputBuff;
279 lastCommand = WriteToMouse;
282 panic(
"i8042 \"Disable A20\" command not implemented.\n");
284 panic(
"i8042 \"Enable A20\" command not implemented.\n");
286 panic(
"i8042 \"Read test inputs\" command not implemented.\n");
288 panic(
"i8042 \"System reset\" command not implemented.\n");
290 warn(
"Write to unknown i8042 "
291 "(keyboard controller) command port.\n");
294 panic(
"Write to unrecognized port %#x.\n",
addr);
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
void makeAtomicResponse()
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
This device is the base class which all devices senstive to an address range inherit from.
void writeData(uint8_t newData, bool mouse=false)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
std::vector< IntSourcePin< I8042 > * > keyboardIntPin
std::vector< IntSourcePin< I8042 > * > mouseIntPin
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void serialize(CheckpointOut &cp) const override
Serialize an object.
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
AddrRange RangeSize(Addr start, Addr size)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
const uint8_t NumOutputBits
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
Declaration of the Packet class.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)