i8042.cc (14290:fa11f961ae4e) i8042.cc (14291:722551795497)
1/*
2 * Copyright (c) 2008 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31#include "dev/x86/i8042.hh"
32
33#include "base/bitunion.hh"
34#include "debug/I8042.hh"
35#include "mem/packet.hh"
36#include "mem/packet_access.hh"
37
38/**
39 * Note: For details on the implementation see
40 * https://wiki.osdev.org/%228042%22_PS/2_Controller
41 */
42
43// The 8042 has a whopping 32 bytes of internal RAM.
44const uint8_t RamSize = 32;
45const uint8_t NumOutputBits = 14;
46
47
48X86ISA::I8042::I8042(Params *p)
49 : BasicPioDevice(p, 0), // pioSize arg is dummy value... not used
50 latency(p->pio_latency),
51 dataPort(p->data_port), commandPort(p->command_port),
52 statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
53 mouse(p->mouse), keyboard(p->keyboard)
54{
55 fatal_if(!mouse, "The i8042 model requires a mouse instance");
56 fatal_if(!keyboard, "The i8042 model requires a keyboard instance");
57
58 statusReg.passedSelfTest = 1;
59 statusReg.commandLast = 1;
60 statusReg.keyboardUnlocked = 1;
61
62 commandByte.convertScanCodes = 1;
63 commandByte.passedSelfTest = 1;
64 commandByte.keyboardFullInt = 1;
65
66 for (int i = 0; i < p->port_keyboard_int_pin_connection_count; i++) {
1/*
2 * Copyright (c) 2008 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31#include "dev/x86/i8042.hh"
32
33#include "base/bitunion.hh"
34#include "debug/I8042.hh"
35#include "mem/packet.hh"
36#include "mem/packet_access.hh"
37
38/**
39 * Note: For details on the implementation see
40 * https://wiki.osdev.org/%228042%22_PS/2_Controller
41 */
42
43// The 8042 has a whopping 32 bytes of internal RAM.
44const uint8_t RamSize = 32;
45const uint8_t NumOutputBits = 14;
46
47
48X86ISA::I8042::I8042(Params *p)
49 : BasicPioDevice(p, 0), // pioSize arg is dummy value... not used
50 latency(p->pio_latency),
51 dataPort(p->data_port), commandPort(p->command_port),
52 statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
53 mouse(p->mouse), keyboard(p->keyboard)
54{
55 fatal_if(!mouse, "The i8042 model requires a mouse instance");
56 fatal_if(!keyboard, "The i8042 model requires a keyboard instance");
57
58 statusReg.passedSelfTest = 1;
59 statusReg.commandLast = 1;
60 statusReg.keyboardUnlocked = 1;
61
62 commandByte.convertScanCodes = 1;
63 commandByte.passedSelfTest = 1;
64 commandByte.keyboardFullInt = 1;
65
66 for (int i = 0; i < p->port_keyboard_int_pin_connection_count; i++) {
67 keyboardIntPin.push_back(new ::IntSourcePin<I8042>(
67 keyboardIntPin.push_back(new IntSourcePin(
68 csprintf("%s.keyboard_int_pin[%d]", name(), i), i, this));
69 }
70 for (int i = 0; i < p->port_mouse_int_pin_connection_count; i++) {
68 csprintf("%s.keyboard_int_pin[%d]", name(), i), i, this));
69 }
70 for (int i = 0; i < p->port_mouse_int_pin_connection_count; i++) {
71 mouseIntPin.push_back(new ::IntSourcePin<I8042>(
71 mouseIntPin.push_back(new IntSourcePin(
72 csprintf("%s.mouse_int_pin[%d]", name(), i), i, this));
73 }
74}
75
76
77AddrRangeList
78X86ISA::I8042::getAddrRanges() const
79{
80 AddrRangeList ranges;
81 // TODO: Are these really supposed to be a single byte and not 4?
82 ranges.push_back(RangeSize(dataPort, 1));
83 ranges.push_back(RangeSize(commandPort, 1));
84 return ranges;
85}
86
87void
88X86ISA::I8042::writeData(uint8_t newData, bool mouse)
89{
90 DPRINTF(I8042, "Set data %#02x.\n", newData);
91 dataReg = newData;
92 statusReg.outputFull = 1;
93 statusReg.mouseOutputFull = (mouse ? 1 : 0);
94 if (!mouse && commandByte.keyboardFullInt) {
95 DPRINTF(I8042, "Sending keyboard interrupt.\n");
96 for (auto *wire: keyboardIntPin) {
97 wire->raise();
98 //This is a hack
99 wire->lower();
100 }
101 } else if (mouse && commandByte.mouseFullInt) {
102 DPRINTF(I8042, "Sending mouse interrupt.\n");
103 for (auto *wire: mouseIntPin) {
104 wire->raise();
105 //This is a hack
106 wire->lower();
107 }
108 }
109}
110
111uint8_t
112X86ISA::I8042::readDataOut()
113{
114 uint8_t data = dataReg;
115 statusReg.outputFull = 0;
116 statusReg.mouseOutputFull = 0;
117 if (keyboard->hostDataAvailable()) {
118 writeData(keyboard->hostRead(), false);
119 } else if (mouse->hostDataAvailable()) {
120 writeData(mouse->hostRead(), true);
121 }
122 return data;
123}
124
125Tick
126X86ISA::I8042::read(PacketPtr pkt)
127{
128 assert(pkt->getSize() == 1);
129 Addr addr = pkt->getAddr();
130 if (addr == dataPort) {
131 uint8_t data = readDataOut();
132 //DPRINTF(I8042, "Read from data port got %#02x.\n", data);
133 pkt->setLE<uint8_t>(data);
134 } else if (addr == commandPort) {
135 //DPRINTF(I8042, "Read status as %#02x.\n", (uint8_t)statusReg);
136 pkt->setLE<uint8_t>((uint8_t)statusReg);
137 } else {
138 panic("Read from unrecognized port %#x.\n", addr);
139 }
140 pkt->makeAtomicResponse();
141 return latency;
142}
143
144Tick
145X86ISA::I8042::write(PacketPtr pkt)
146{
147 assert(pkt->getSize() == 1);
148 Addr addr = pkt->getAddr();
149 uint8_t data = pkt->getLE<uint8_t>();
150 if (addr == dataPort) {
151 statusReg.commandLast = 0;
152 switch (lastCommand) {
153 case NoCommand:
154 keyboard->hostWrite(data);
155 if (keyboard->hostDataAvailable())
156 writeData(keyboard->hostRead(), false);
157 break;
158 case WriteToMouse:
159 mouse->hostWrite(data);
160 if (mouse->hostDataAvailable())
161 writeData(mouse->hostRead(), true);
162 break;
163 case WriteCommandByte:
164 commandByte = data;
165 DPRINTF(I8042, "Got data %#02x for \"Write "
166 "command byte\" command.\n", data);
167 statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
168 break;
169 case WriteMouseOutputBuff:
170 DPRINTF(I8042, "Got data %#02x for \"Write "
171 "mouse output buffer\" command.\n", data);
172 writeData(data, true);
173 break;
174 case WriteKeyboardOutputBuff:
175 DPRINTF(I8042, "Got data %#02x for \"Write "
176 "keyboad output buffer\" command.\n", data);
177 writeData(data, false);
178 break;
179 case WriteOutputPort:
180 DPRINTF(I8042, "Got data %#02x for \"Write "
181 "output port\" command.\n", data);
182 panic_if(bits(data, 0) != 1, "Reset bit should be 1");
183 // Safe to ignore otherwise
184 break;
185 default:
186 panic("Data written for unrecognized "
187 "command %#02x\n", lastCommand);
188 }
189 lastCommand = NoCommand;
190 } else if (addr == commandPort) {
191 DPRINTF(I8042, "Got command %#02x.\n", data);
192 statusReg.commandLast = 1;
193 // These purposefully leave off the first byte of the controller RAM
194 // so it can be handled specially.
195 if (data > ReadControllerRamBase &&
196 data < ReadControllerRamBase + RamSize) {
197 panic("Attempted to use i8042 read controller RAM command to "
198 "get byte %d.\n", data - ReadControllerRamBase);
199 } else if (data > WriteControllerRamBase &&
200 data < WriteControllerRamBase + RamSize) {
201 panic("Attempted to use i8042 read controller RAM command to "
202 "get byte %d.\n", data - ReadControllerRamBase);
203 } else if (data >= PulseOutputBitBase &&
204 data < PulseOutputBitBase + NumOutputBits) {
205 panic("Attempted to use i8042 pulse output bit command to "
206 "to pulse bit %d.\n", data - PulseOutputBitBase);
207 }
208 switch (data) {
209 case GetCommandByte:
210 DPRINTF(I8042, "Getting command byte.\n");
211 writeData(commandByte);
212 break;
213 case WriteCommandByte:
214 DPRINTF(I8042, "Setting command byte.\n");
215 lastCommand = WriteCommandByte;
216 break;
217 case CheckForPassword:
218 panic("i8042 \"Check for password\" command not implemented.\n");
219 case LoadPassword:
220 panic("i8042 \"Load password\" command not implemented.\n");
221 case CheckPassword:
222 panic("i8042 \"Check password\" command not implemented.\n");
223 case DisableMouse:
224 DPRINTF(I8042, "Disabling mouse at controller.\n");
225 commandByte.disableMouse = 1;
226 break;
227 case EnableMouse:
228 DPRINTF(I8042, "Enabling mouse at controller.\n");
229 commandByte.disableMouse = 0;
230 break;
231 case TestMouse:
232 panic("i8042 \"Test mouse\" command not implemented.\n");
233 case SelfTest:
234 panic("i8042 \"Self test\" command not implemented.\n");
235 case InterfaceTest:
236 panic("i8042 \"Interface test\" command not implemented.\n");
237 case DiagnosticDump:
238 panic("i8042 \"Diagnostic dump\" command not implemented.\n");
239 case DisableKeyboard:
240 DPRINTF(I8042, "Disabling keyboard at controller.\n");
241 commandByte.disableKeyboard = 1;
242 break;
243 case EnableKeyboard:
244 DPRINTF(I8042, "Enabling keyboard at controller.\n");
245 commandByte.disableKeyboard = 0;
246 break;
247 case ReadInputPort:
248 panic("i8042 \"Read input port\" command not implemented.\n");
249 case ContinuousPollLow:
250 panic("i8042 \"Continuous poll low\" command not implemented.\n");
251 case ContinuousPollHigh:
252 panic("i8042 \"Continuous poll high\" command not implemented.\n");
253 case ReadOutputPort:
254 panic("i8042 \"Read output port\" command not implemented.\n");
255 case WriteOutputPort:
256 lastCommand = WriteOutputPort;
257 break;
258 case WriteKeyboardOutputBuff:
259 lastCommand = WriteKeyboardOutputBuff;
260 break;
261 case WriteMouseOutputBuff:
262 DPRINTF(I8042, "Got command to write to mouse output buffer.\n");
263 lastCommand = WriteMouseOutputBuff;
264 break;
265 case WriteToMouse:
266 DPRINTF(I8042, "Expecting mouse command.\n");
267 lastCommand = WriteToMouse;
268 break;
269 case DisableA20:
270 panic("i8042 \"Disable A20\" command not implemented.\n");
271 case EnableA20:
272 panic("i8042 \"Enable A20\" command not implemented.\n");
273 case ReadTestInputs:
274 panic("i8042 \"Read test inputs\" command not implemented.\n");
275 case SystemReset:
276 panic("i8042 \"System reset\" command not implemented.\n");
277 default:
278 warn("Write to unknown i8042 "
279 "(keyboard controller) command port.\n");
280 }
281 } else {
282 panic("Write to unrecognized port %#x.\n", addr);
283 }
284 pkt->makeAtomicResponse();
285 return latency;
286}
287
288void
289X86ISA::I8042::serialize(CheckpointOut &cp) const
290{
291 SERIALIZE_SCALAR(dataPort);
292 SERIALIZE_SCALAR(commandPort);
293 SERIALIZE_SCALAR(statusReg);
294 SERIALIZE_SCALAR(commandByte);
295 SERIALIZE_SCALAR(dataReg);
296 SERIALIZE_SCALAR(lastCommand);
297}
298
299void
300X86ISA::I8042::unserialize(CheckpointIn &cp)
301{
302 UNSERIALIZE_SCALAR(dataPort);
303 UNSERIALIZE_SCALAR(commandPort);
304 UNSERIALIZE_SCALAR(statusReg);
305 UNSERIALIZE_SCALAR(commandByte);
306 UNSERIALIZE_SCALAR(dataReg);
307 UNSERIALIZE_SCALAR(lastCommand);
308}
309
310X86ISA::I8042 *
311I8042Params::create()
312{
313 return new X86ISA::I8042(this);
314}
72 csprintf("%s.mouse_int_pin[%d]", name(), i), i, this));
73 }
74}
75
76
77AddrRangeList
78X86ISA::I8042::getAddrRanges() const
79{
80 AddrRangeList ranges;
81 // TODO: Are these really supposed to be a single byte and not 4?
82 ranges.push_back(RangeSize(dataPort, 1));
83 ranges.push_back(RangeSize(commandPort, 1));
84 return ranges;
85}
86
87void
88X86ISA::I8042::writeData(uint8_t newData, bool mouse)
89{
90 DPRINTF(I8042, "Set data %#02x.\n", newData);
91 dataReg = newData;
92 statusReg.outputFull = 1;
93 statusReg.mouseOutputFull = (mouse ? 1 : 0);
94 if (!mouse && commandByte.keyboardFullInt) {
95 DPRINTF(I8042, "Sending keyboard interrupt.\n");
96 for (auto *wire: keyboardIntPin) {
97 wire->raise();
98 //This is a hack
99 wire->lower();
100 }
101 } else if (mouse && commandByte.mouseFullInt) {
102 DPRINTF(I8042, "Sending mouse interrupt.\n");
103 for (auto *wire: mouseIntPin) {
104 wire->raise();
105 //This is a hack
106 wire->lower();
107 }
108 }
109}
110
111uint8_t
112X86ISA::I8042::readDataOut()
113{
114 uint8_t data = dataReg;
115 statusReg.outputFull = 0;
116 statusReg.mouseOutputFull = 0;
117 if (keyboard->hostDataAvailable()) {
118 writeData(keyboard->hostRead(), false);
119 } else if (mouse->hostDataAvailable()) {
120 writeData(mouse->hostRead(), true);
121 }
122 return data;
123}
124
125Tick
126X86ISA::I8042::read(PacketPtr pkt)
127{
128 assert(pkt->getSize() == 1);
129 Addr addr = pkt->getAddr();
130 if (addr == dataPort) {
131 uint8_t data = readDataOut();
132 //DPRINTF(I8042, "Read from data port got %#02x.\n", data);
133 pkt->setLE<uint8_t>(data);
134 } else if (addr == commandPort) {
135 //DPRINTF(I8042, "Read status as %#02x.\n", (uint8_t)statusReg);
136 pkt->setLE<uint8_t>((uint8_t)statusReg);
137 } else {
138 panic("Read from unrecognized port %#x.\n", addr);
139 }
140 pkt->makeAtomicResponse();
141 return latency;
142}
143
144Tick
145X86ISA::I8042::write(PacketPtr pkt)
146{
147 assert(pkt->getSize() == 1);
148 Addr addr = pkt->getAddr();
149 uint8_t data = pkt->getLE<uint8_t>();
150 if (addr == dataPort) {
151 statusReg.commandLast = 0;
152 switch (lastCommand) {
153 case NoCommand:
154 keyboard->hostWrite(data);
155 if (keyboard->hostDataAvailable())
156 writeData(keyboard->hostRead(), false);
157 break;
158 case WriteToMouse:
159 mouse->hostWrite(data);
160 if (mouse->hostDataAvailable())
161 writeData(mouse->hostRead(), true);
162 break;
163 case WriteCommandByte:
164 commandByte = data;
165 DPRINTF(I8042, "Got data %#02x for \"Write "
166 "command byte\" command.\n", data);
167 statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
168 break;
169 case WriteMouseOutputBuff:
170 DPRINTF(I8042, "Got data %#02x for \"Write "
171 "mouse output buffer\" command.\n", data);
172 writeData(data, true);
173 break;
174 case WriteKeyboardOutputBuff:
175 DPRINTF(I8042, "Got data %#02x for \"Write "
176 "keyboad output buffer\" command.\n", data);
177 writeData(data, false);
178 break;
179 case WriteOutputPort:
180 DPRINTF(I8042, "Got data %#02x for \"Write "
181 "output port\" command.\n", data);
182 panic_if(bits(data, 0) != 1, "Reset bit should be 1");
183 // Safe to ignore otherwise
184 break;
185 default:
186 panic("Data written for unrecognized "
187 "command %#02x\n", lastCommand);
188 }
189 lastCommand = NoCommand;
190 } else if (addr == commandPort) {
191 DPRINTF(I8042, "Got command %#02x.\n", data);
192 statusReg.commandLast = 1;
193 // These purposefully leave off the first byte of the controller RAM
194 // so it can be handled specially.
195 if (data > ReadControllerRamBase &&
196 data < ReadControllerRamBase + RamSize) {
197 panic("Attempted to use i8042 read controller RAM command to "
198 "get byte %d.\n", data - ReadControllerRamBase);
199 } else if (data > WriteControllerRamBase &&
200 data < WriteControllerRamBase + RamSize) {
201 panic("Attempted to use i8042 read controller RAM command to "
202 "get byte %d.\n", data - ReadControllerRamBase);
203 } else if (data >= PulseOutputBitBase &&
204 data < PulseOutputBitBase + NumOutputBits) {
205 panic("Attempted to use i8042 pulse output bit command to "
206 "to pulse bit %d.\n", data - PulseOutputBitBase);
207 }
208 switch (data) {
209 case GetCommandByte:
210 DPRINTF(I8042, "Getting command byte.\n");
211 writeData(commandByte);
212 break;
213 case WriteCommandByte:
214 DPRINTF(I8042, "Setting command byte.\n");
215 lastCommand = WriteCommandByte;
216 break;
217 case CheckForPassword:
218 panic("i8042 \"Check for password\" command not implemented.\n");
219 case LoadPassword:
220 panic("i8042 \"Load password\" command not implemented.\n");
221 case CheckPassword:
222 panic("i8042 \"Check password\" command not implemented.\n");
223 case DisableMouse:
224 DPRINTF(I8042, "Disabling mouse at controller.\n");
225 commandByte.disableMouse = 1;
226 break;
227 case EnableMouse:
228 DPRINTF(I8042, "Enabling mouse at controller.\n");
229 commandByte.disableMouse = 0;
230 break;
231 case TestMouse:
232 panic("i8042 \"Test mouse\" command not implemented.\n");
233 case SelfTest:
234 panic("i8042 \"Self test\" command not implemented.\n");
235 case InterfaceTest:
236 panic("i8042 \"Interface test\" command not implemented.\n");
237 case DiagnosticDump:
238 panic("i8042 \"Diagnostic dump\" command not implemented.\n");
239 case DisableKeyboard:
240 DPRINTF(I8042, "Disabling keyboard at controller.\n");
241 commandByte.disableKeyboard = 1;
242 break;
243 case EnableKeyboard:
244 DPRINTF(I8042, "Enabling keyboard at controller.\n");
245 commandByte.disableKeyboard = 0;
246 break;
247 case ReadInputPort:
248 panic("i8042 \"Read input port\" command not implemented.\n");
249 case ContinuousPollLow:
250 panic("i8042 \"Continuous poll low\" command not implemented.\n");
251 case ContinuousPollHigh:
252 panic("i8042 \"Continuous poll high\" command not implemented.\n");
253 case ReadOutputPort:
254 panic("i8042 \"Read output port\" command not implemented.\n");
255 case WriteOutputPort:
256 lastCommand = WriteOutputPort;
257 break;
258 case WriteKeyboardOutputBuff:
259 lastCommand = WriteKeyboardOutputBuff;
260 break;
261 case WriteMouseOutputBuff:
262 DPRINTF(I8042, "Got command to write to mouse output buffer.\n");
263 lastCommand = WriteMouseOutputBuff;
264 break;
265 case WriteToMouse:
266 DPRINTF(I8042, "Expecting mouse command.\n");
267 lastCommand = WriteToMouse;
268 break;
269 case DisableA20:
270 panic("i8042 \"Disable A20\" command not implemented.\n");
271 case EnableA20:
272 panic("i8042 \"Enable A20\" command not implemented.\n");
273 case ReadTestInputs:
274 panic("i8042 \"Read test inputs\" command not implemented.\n");
275 case SystemReset:
276 panic("i8042 \"System reset\" command not implemented.\n");
277 default:
278 warn("Write to unknown i8042 "
279 "(keyboard controller) command port.\n");
280 }
281 } else {
282 panic("Write to unrecognized port %#x.\n", addr);
283 }
284 pkt->makeAtomicResponse();
285 return latency;
286}
287
288void
289X86ISA::I8042::serialize(CheckpointOut &cp) const
290{
291 SERIALIZE_SCALAR(dataPort);
292 SERIALIZE_SCALAR(commandPort);
293 SERIALIZE_SCALAR(statusReg);
294 SERIALIZE_SCALAR(commandByte);
295 SERIALIZE_SCALAR(dataReg);
296 SERIALIZE_SCALAR(lastCommand);
297}
298
299void
300X86ISA::I8042::unserialize(CheckpointIn &cp)
301{
302 UNSERIALIZE_SCALAR(dataPort);
303 UNSERIALIZE_SCALAR(commandPort);
304 UNSERIALIZE_SCALAR(statusReg);
305 UNSERIALIZE_SCALAR(commandByte);
306 UNSERIALIZE_SCALAR(dataReg);
307 UNSERIALIZE_SCALAR(lastCommand);
308}
309
310X86ISA::I8042 *
311I8042Params::create()
312{
313 return new X86ISA::I8042(this);
314}