i8042.cc revision 9090:e4e22240398f
12686Sksewell@umich.edu/* 22100SN/A * Copyright (c) 2008 The Regents of The University of Michigan 35254Sksewell@umich.edu * All rights reserved. 45254Sksewell@umich.edu * 55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145254Sksewell@umich.edu * this software without specific prior written permission. 155254Sksewell@umich.edu * 165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275254Sksewell@umich.edu * 285254Sksewell@umich.edu * Authors: Gabe Black 295254Sksewell@umich.edu */ 305254Sksewell@umich.edu 315254Sksewell@umich.edu#include "base/bitunion.hh" 322706Sksewell@umich.edu#include "debug/I8042.hh" 332022SN/A#include "dev/x86/i8042.hh" 342022SN/A#include "mem/packet.hh" 352043SN/A#include "mem/packet_access.hh" 362024SN/A 372024SN/A// The 8042 has a whopping 32 bytes of internal RAM. 382043SN/Aconst uint8_t RamSize = 32; 392686Sksewell@umich.educonst uint8_t NumOutputBits = 14; 404661Sksewell@umich.educonst uint8_t X86ISA::PS2Keyboard::ID[] = {0xab, 0x83}; 412022SN/Aconst uint8_t X86ISA::PS2Mouse::ID[] = {0x00}; 422083SN/Aconst uint8_t CommandAck = 0xfa; 432686Sksewell@umich.educonst uint8_t CommandNack = 0xfe; 442101SN/Aconst uint8_t BatSuccessful = 0xaa; 452043SN/A 462043SN/AAddrRangeList 472101SN/AX86ISA::I8042::getAddrRanges() const 482101SN/A{ 496384Sgblack@eecs.umich.edu AddrRangeList ranges; 506384Sgblack@eecs.umich.edu // TODO: Are these really supposed to be a single byte and not 4? 516384Sgblack@eecs.umich.edu ranges.push_back(RangeSize(dataPort, 1)); 526384Sgblack@eecs.umich.edu ranges.push_back(RangeSize(commandPort, 1)); 536384Sgblack@eecs.umich.edu return ranges; 546384Sgblack@eecs.umich.edu} 552101SN/A 562101SN/Avoid 572101SN/AX86ISA::I8042::writeData(uint8_t newData, bool mouse) 582046SN/A{ 592686Sksewell@umich.edu DPRINTF(I8042, "Set data %#02x.\n", newData); 602686Sksewell@umich.edu dataReg = newData; 612686Sksewell@umich.edu statusReg.outputFull = 1; 622470SN/A statusReg.mouseOutputFull = (mouse ? 1 : 0); 632686Sksewell@umich.edu if (!mouse && commandByte.keyboardFullInt) { 644661Sksewell@umich.edu DPRINTF(I8042, "Sending keyboard interrupt.\n"); 655222Sksewell@umich.edu keyboardIntPin->raise(); 665222Sksewell@umich.edu //This is a hack 672686Sksewell@umich.edu keyboardIntPin->lower(); 688588Sgblack@eecs.umich.edu } else if (mouse && commandByte.mouseFullInt) { 692470SN/A DPRINTF(I8042, "Sending mouse interrupt.\n"); 702241SN/A mouseIntPin->raise(); 712101SN/A //This is a hack 722495SN/A mouseIntPin->lower(); 732495SN/A } 748588Sgblack@eecs.umich.edu} 752101SN/A 766384Sgblack@eecs.umich.eduvoid 776384Sgblack@eecs.umich.eduX86ISA::PS2Device::ack() 786384Sgblack@eecs.umich.edu{ 798588Sgblack@eecs.umich.edu bufferData(&CommandAck, sizeof(CommandAck)); 806384Sgblack@eecs.umich.edu} 812495SN/A 822101SN/Avoid 832101SN/AX86ISA::PS2Device::nack() 842495SN/A{ 852495SN/A bufferData(&CommandNack, sizeof(CommandNack)); 862495SN/A} 872495SN/A 882495SN/Avoid 892495SN/AX86ISA::PS2Device::bufferData(const uint8_t *data, int size) 902495SN/A{ 912495SN/A assert(data || size == 0); 922495SN/A while (size) { 932495SN/A outBuffer.push(*(data++)); 942495SN/A size--; 952495SN/A } 962495SN/A} 972101SN/A 988588Sgblack@eecs.umich.eduuint8_t 992101SN/AX86ISA::I8042::readDataOut() 1002101SN/A{ 1018588Sgblack@eecs.umich.edu uint8_t data = dataReg; 1022101SN/A statusReg.outputFull = 0; 1036384Sgblack@eecs.umich.edu statusReg.mouseOutputFull = 0; 1046384Sgblack@eecs.umich.edu if (keyboard.hasData()) { 1056384Sgblack@eecs.umich.edu writeData(keyboard.getData(), false); 1068588Sgblack@eecs.umich.edu } else if (mouse.hasData()) { 1078588Sgblack@eecs.umich.edu writeData(mouse.getData(), true); 1086384Sgblack@eecs.umich.edu } 1092101SN/A return data; 1102101SN/A} 1112495SN/A 1122495SN/Abool 1132495SN/AX86ISA::PS2Keyboard::processData(uint8_t data) 1142495SN/A{ 1152495SN/A if (lastCommand != NoCommand) { 1166384Sgblack@eecs.umich.edu switch (lastCommand) { 1176384Sgblack@eecs.umich.edu case LEDWrite: 1186384Sgblack@eecs.umich.edu DPRINTF(I8042, "Setting LEDs: " 1196384Sgblack@eecs.umich.edu "caps lock %s, num lock %s, scroll lock %s\n", 1206384Sgblack@eecs.umich.edu bits(data, 2) ? "on" : "off", 1212495SN/A bits(data, 1) ? "on" : "off", 1226384Sgblack@eecs.umich.edu bits(data, 0) ? "on" : "off"); 1232495SN/A ack(); 1242495SN/A lastCommand = NoCommand; 1252043SN/A break; 1262043SN/A case TypematicInfo: 1272025SN/A DPRINTF(I8042, "Setting typematic info to %#02x.\n", data); 1282043SN/A ack(); 1292686Sksewell@umich.edu lastCommand = NoCommand; 1302686Sksewell@umich.edu break; 1312123SN/A } 1322101SN/A return hasData(); 1336376Sgblack@eecs.umich.edu } 1346376Sgblack@eecs.umich.edu switch (data) { 1356376Sgblack@eecs.umich.edu case LEDWrite: 1367792Sgblack@eecs.umich.edu DPRINTF(I8042, "Got LED write command.\n"); 1376376Sgblack@eecs.umich.edu ack(); 1386376Sgblack@eecs.umich.edu lastCommand = LEDWrite; 1396376Sgblack@eecs.umich.edu break; 1406376Sgblack@eecs.umich.edu case DiagnosticEcho: 1416376Sgblack@eecs.umich.edu panic("Keyboard diagnostic echo unimplemented.\n"); 1426376Sgblack@eecs.umich.edu case AlternateScanCodes: 1436376Sgblack@eecs.umich.edu panic("Accessing alternate scan codes unimplemented.\n"); 1447792Sgblack@eecs.umich.edu case ReadID: 1456376Sgblack@eecs.umich.edu DPRINTF(I8042, "Got keyboard read ID command.\n"); 1466376Sgblack@eecs.umich.edu ack(); 1476376Sgblack@eecs.umich.edu bufferData((uint8_t *)&ID, sizeof(ID)); 1486376Sgblack@eecs.umich.edu break; 1492101SN/A case TypematicInfo: 1502042SN/A DPRINTF(I8042, "Setting typematic info.\n"); 1512101SN/A ack(); 1527720Sgblack@eecs.umich.edu lastCommand = TypematicInfo; 1537792Sgblack@eecs.umich.edu break; 1547792Sgblack@eecs.umich.edu case Enable: 1557720Sgblack@eecs.umich.edu DPRINTF(I8042, "Enabling the keyboard.\n"); 1567720Sgblack@eecs.umich.edu ack(); 1577792Sgblack@eecs.umich.edu break; 1587792Sgblack@eecs.umich.edu case Disable: 1597720Sgblack@eecs.umich.edu DPRINTF(I8042, "Disabling the keyboard.\n"); 1602101SN/A ack(); 1612101SN/A break; 1622042SN/A case DefaultsAndDisable: 1632101SN/A DPRINTF(I8042, "Disabling and resetting the keyboard.\n"); 1642686Sksewell@umich.edu ack(); 1652686Sksewell@umich.edu break; 1668901Sandreas.hansson@arm.com case AllKeysToTypematic: 1678564Sgblack@eecs.umich.edu panic("Setting all keys to typemantic unimplemented.\n"); 1688564Sgblack@eecs.umich.edu case AllKeysToMakeRelease: 16910474Sandreas.hansson@arm.com panic("Setting all keys to make/release unimplemented.\n"); 1708564Sgblack@eecs.umich.edu case AllKeysToMake: 1712686Sksewell@umich.edu panic("Setting all keys to make unimplemented.\n"); 17210474Sandreas.hansson@arm.com case AllKeysToTypematicMakeRelease: 1732101SN/A panic("Setting all keys to " 1742083SN/A "typematic/make/release unimplemented.\n"); 1752043SN/A case KeyToTypematic: 1762025SN/A panic("Setting a key to typematic unimplemented.\n"); 1772043SN/A case KeyToMakeRelease: 1786384Sgblack@eecs.umich.edu panic("Setting a key to make/release unimplemented.\n"); 1796384Sgblack@eecs.umich.edu case KeyToMakeOnly: 1804661Sksewell@umich.edu panic("Setting key to make only unimplemented.\n"); 1816384Sgblack@eecs.umich.edu case Resend: 1826384Sgblack@eecs.umich.edu panic("Keyboard resend unimplemented.\n"); 1834661Sksewell@umich.edu case Reset: 1842083SN/A panic("Keyboard reset unimplemented.\n"); 1852025SN/A default: 1862043SN/A panic("Unknown keyboard command %#02x.\n", data); 1874661Sksewell@umich.edu } 1888588Sgblack@eecs.umich.edu return hasData(); 1898588Sgblack@eecs.umich.edu} 1904661Sksewell@umich.edu 1914661Sksewell@umich.edubool 1922686Sksewell@umich.eduX86ISA::PS2Mouse::processData(uint8_t data) 1936384Sgblack@eecs.umich.edu{ 1948588Sgblack@eecs.umich.edu if (lastCommand != NoCommand) { 1958588Sgblack@eecs.umich.edu switch(lastCommand) { 1968588Sgblack@eecs.umich.edu case SetResolution: 1976384Sgblack@eecs.umich.edu DPRINTF(I8042, "Mouse resolution set to %d.\n", data); 1985222Sksewell@umich.edu resolution = data; 1995222Sksewell@umich.edu ack(); 2006384Sgblack@eecs.umich.edu lastCommand = NoCommand; 2018588Sgblack@eecs.umich.edu break; 2028588Sgblack@eecs.umich.edu case SampleRate: 2038588Sgblack@eecs.umich.edu DPRINTF(I8042, "Mouse sample rate %d samples " 2046384Sgblack@eecs.umich.edu "per second.\n", data); 2055222Sksewell@umich.edu sampleRate = data; 2062101SN/A ack(); 2072084SN/A lastCommand = NoCommand; 2082025SN/A break; 2092495SN/A default: 2102495SN/A panic("Not expecting data for a mouse command.\n"); 2112495SN/A } 2126384Sgblack@eecs.umich.edu return hasData(); 2138564Sgblack@eecs.umich.edu } 2148564Sgblack@eecs.umich.edu switch (data) { 2158738Sgblack@eecs.umich.edu case Scale1to1: 2168564Sgblack@eecs.umich.edu DPRINTF(I8042, "Setting mouse scale to 1:1.\n"); 21710474Sandreas.hansson@arm.com status.twoToOne = 0; 2186384Sgblack@eecs.umich.edu ack(); 2196384Sgblack@eecs.umich.edu break; 2208588Sgblack@eecs.umich.edu case Scale2to1: 2215222Sksewell@umich.edu DPRINTF(I8042, "Setting mouse scale to 2:1.\n"); 2228564Sgblack@eecs.umich.edu status.twoToOne = 1; 2238564Sgblack@eecs.umich.edu ack(); 2248738Sgblack@eecs.umich.edu break; 2258564Sgblack@eecs.umich.edu case SetResolution: 22610474Sandreas.hansson@arm.com DPRINTF(I8042, "Setting mouse resolution.\n"); 2276384Sgblack@eecs.umich.edu lastCommand = SetResolution; 2286384Sgblack@eecs.umich.edu ack(); 2298588Sgblack@eecs.umich.edu break; 2306384Sgblack@eecs.umich.edu case GetStatus: 2316384Sgblack@eecs.umich.edu DPRINTF(I8042, "Getting mouse status.\n"); 2326384Sgblack@eecs.umich.edu ack(); 2336384Sgblack@eecs.umich.edu bufferData((uint8_t *)&(status), 1); 2342495SN/A bufferData(&resolution, sizeof(resolution)); 2352101SN/A bufferData(&sampleRate, sizeof(sampleRate)); 2362043SN/A break; 2372025SN/A case ReadData: 2382495SN/A panic("Reading mouse data unimplemented.\n"); 2392495SN/A case ResetWrapMode: 2402495SN/A panic("Resetting mouse wrap mode unimplemented.\n"); 2418588Sgblack@eecs.umich.edu case WrapMode: 2428588Sgblack@eecs.umich.edu panic("Setting mouse wrap mode unimplemented.\n"); 2432495SN/A case RemoteMode: 2442101SN/A panic("Setting mouse remote mode unimplemented.\n"); 2452084SN/A case ReadID: 2462024SN/A DPRINTF(I8042, "Mouse ID requested.\n"); 2472043SN/A ack(); 2482239SN/A bufferData(ID, sizeof(ID)); 2498588Sgblack@eecs.umich.edu break; 2508588Sgblack@eecs.umich.edu case SampleRate: 2518588Sgblack@eecs.umich.edu DPRINTF(I8042, "Setting mouse sample rate.\n"); 2528588Sgblack@eecs.umich.edu lastCommand = SampleRate; 2538588Sgblack@eecs.umich.edu ack(); 2548588Sgblack@eecs.umich.edu break; 2552101SN/A case DisableReporting: 2562043SN/A DPRINTF(I8042, "Disabling data reporting.\n"); 2572043SN/A status.enabled = 0; 2582025SN/A ack(); 2592043SN/A break; 2602043SN/A case EnableReporting: 2612101SN/A DPRINTF(I8042, "Enabling data reporting.\n"); 2628588Sgblack@eecs.umich.edu status.enabled = 1; 2638588Sgblack@eecs.umich.edu ack(); 2648588Sgblack@eecs.umich.edu break; 2658588Sgblack@eecs.umich.edu case DefaultsAndDisable: 2662101SN/A DPRINTF(I8042, "Disabling and resetting mouse.\n"); 2672043SN/A sampleRate = 100; 2682025SN/A resolution = 4; 2692043SN/A status.twoToOne = 0; 2705222Sksewell@umich.edu status.enabled = 0; 2718588Sgblack@eecs.umich.edu ack(); 2726384Sgblack@eecs.umich.edu break; 2738588Sgblack@eecs.umich.edu case Resend: 2746384Sgblack@eecs.umich.edu panic("Mouse resend unimplemented.\n"); 2758588Sgblack@eecs.umich.edu case Reset: 2766384Sgblack@eecs.umich.edu DPRINTF(I8042, "Resetting the mouse.\n"); 2778588Sgblack@eecs.umich.edu sampleRate = 100; 2786384Sgblack@eecs.umich.edu resolution = 4; 2798588Sgblack@eecs.umich.edu status.twoToOne = 0; 2808588Sgblack@eecs.umich.edu status.enabled = 0; 2812101SN/A ack(); 2822043SN/A bufferData(&BatSuccessful, sizeof(BatSuccessful)); 2832043SN/A bufferData(ID, sizeof(ID)); 2842043SN/A break; 2852101SN/A default: 2868588Sgblack@eecs.umich.edu warn("Unknown mouse command %#02x.\n", data); 2872686Sksewell@umich.edu nack(); 2882686Sksewell@umich.edu break; 2898588Sgblack@eecs.umich.edu } 2902686Sksewell@umich.edu return hasData(); 2918588Sgblack@eecs.umich.edu} 2928588Sgblack@eecs.umich.edu 2932101SN/A 2942043SN/ATick 2952043SN/AX86ISA::I8042::read(PacketPtr pkt) 2962043SN/A{ 2976384Sgblack@eecs.umich.edu assert(pkt->getSize() == 1); 2986384Sgblack@eecs.umich.edu Addr addr = pkt->getAddr(); 2994661Sksewell@umich.edu if (addr == dataPort) { 3002101SN/A uint8_t data = readDataOut(); 3012101SN/A //DPRINTF(I8042, "Read from data port got %#02x.\n", data); 3022101SN/A pkt->set<uint8_t>(data); 3032043SN/A } else if (addr == commandPort) { 3042043SN/A //DPRINTF(I8042, "Read status as %#02x.\n", (uint8_t)statusReg); 3052043SN/A pkt->set<uint8_t>((uint8_t)statusReg); 3062123SN/A } else { 3077792Sgblack@eecs.umich.edu panic("Read from unrecognized port %#x.\n", addr); 3087792Sgblack@eecs.umich.edu } 3097792Sgblack@eecs.umich.edu pkt->makeAtomicResponse(); 3102043SN/A return latency; 3112043SN/A} 3122100SN/A 3132686Sksewell@umich.eduTick 3142686Sksewell@umich.eduX86ISA::I8042::write(PacketPtr pkt) 3158588Sgblack@eecs.umich.edu{ 3162686Sksewell@umich.edu assert(pkt->getSize() == 1); 3178588Sgblack@eecs.umich.edu Addr addr = pkt->getAddr(); 3188588Sgblack@eecs.umich.edu uint8_t data = pkt->get<uint8_t>(); 3198588Sgblack@eecs.umich.edu if (addr == dataPort) { 3202043SN/A statusReg.commandLast = 0; 3212084SN/A switch (lastCommand) { 3222024SN/A case NoCommand: 3232101SN/A if (keyboard.processData(data)) { 3242686Sksewell@umich.edu writeData(keyboard.getData(), false); 3255222Sksewell@umich.edu } 3268564Sgblack@eecs.umich.edu break; 3278564Sgblack@eecs.umich.edu case WriteToMouse: 3288738Sgblack@eecs.umich.edu if (mouse.processData(data)) { 3298564Sgblack@eecs.umich.edu writeData(mouse.getData(), true); 33010474Sandreas.hansson@arm.com } 3316384Sgblack@eecs.umich.edu break; 3326384Sgblack@eecs.umich.edu case WriteCommandByte: 3338588Sgblack@eecs.umich.edu commandByte = data; 3348588Sgblack@eecs.umich.edu DPRINTF(I8042, "Got data %#02x for \"Write " 3358588Sgblack@eecs.umich.edu "command byte\" command.\n", data); 3368588Sgblack@eecs.umich.edu statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest; 3378588Sgblack@eecs.umich.edu break; 3388588Sgblack@eecs.umich.edu case WriteMouseOutputBuff: 3392495SN/A DPRINTF(I8042, "Got data %#02x for \"Write " 3402495SN/A "mouse output buffer\" command.\n", data); 3416384Sgblack@eecs.umich.edu writeData(data, true); 3422495SN/A break; 3432084SN/A default: 3442084SN/A panic("Data written for unrecognized " 3452024SN/A "command %#02x\n", lastCommand); 3462101SN/A } 3472101SN/A lastCommand = NoCommand; 3482101SN/A } else if (addr == commandPort) { 3492101SN/A DPRINTF(I8042, "Got command %#02x.\n", data); 3506384Sgblack@eecs.umich.edu statusReg.commandLast = 1; 3516384Sgblack@eecs.umich.edu // These purposefully leave off the first byte of the controller RAM 3526384Sgblack@eecs.umich.edu // so it can be handled specially. 3536384Sgblack@eecs.umich.edu if (data > ReadControllerRamBase && 3546384Sgblack@eecs.umich.edu data < ReadControllerRamBase + RamSize) { 3556384Sgblack@eecs.umich.edu panic("Attempted to use i8042 read controller RAM command to " 3566384Sgblack@eecs.umich.edu "get byte %d.\n", data - ReadControllerRamBase); 3576384Sgblack@eecs.umich.edu } else if (data > WriteControllerRamBase && 3586384Sgblack@eecs.umich.edu data < WriteControllerRamBase + RamSize) { 3596384Sgblack@eecs.umich.edu panic("Attempted to use i8042 read controller RAM command to " 3606384Sgblack@eecs.umich.edu "get byte %d.\n", data - ReadControllerRamBase); 3616384Sgblack@eecs.umich.edu } else if (data >= PulseOutputBitBase && 3626384Sgblack@eecs.umich.edu data < PulseOutputBitBase + NumOutputBits) { 3636384Sgblack@eecs.umich.edu panic("Attempted to use i8042 pulse output bit command to " 3646384Sgblack@eecs.umich.edu "to pulse bit %d.\n", data - PulseOutputBitBase); 3656384Sgblack@eecs.umich.edu } 3666384Sgblack@eecs.umich.edu switch (data) { 3676384Sgblack@eecs.umich.edu case GetCommandByte: 3686384Sgblack@eecs.umich.edu DPRINTF(I8042, "Getting command byte.\n"); 3696384Sgblack@eecs.umich.edu writeData(commandByte); 3706384Sgblack@eecs.umich.edu break; 3716384Sgblack@eecs.umich.edu case WriteCommandByte: 3726384Sgblack@eecs.umich.edu DPRINTF(I8042, "Setting command byte.\n"); 3736384Sgblack@eecs.umich.edu lastCommand = WriteCommandByte; 3746384Sgblack@eecs.umich.edu break; 3756384Sgblack@eecs.umich.edu case CheckForPassword: 3766384Sgblack@eecs.umich.edu panic("i8042 \"Check for password\" command not implemented.\n"); 3776384Sgblack@eecs.umich.edu case LoadPassword: 3786384Sgblack@eecs.umich.edu panic("i8042 \"Load password\" command not implemented.\n"); 3796384Sgblack@eecs.umich.edu case CheckPassword: 3806384Sgblack@eecs.umich.edu panic("i8042 \"Check password\" command not implemented.\n"); 3816384Sgblack@eecs.umich.edu case DisableMouse: 3826384Sgblack@eecs.umich.edu DPRINTF(I8042, "Disabling mouse at controller.\n"); 3836384Sgblack@eecs.umich.edu commandByte.disableMouse = 1; 3846384Sgblack@eecs.umich.edu break; 3854661Sksewell@umich.edu case EnableMouse: 3866376Sgblack@eecs.umich.edu DPRINTF(I8042, "Enabling mouse at controller.\n"); 3876376Sgblack@eecs.umich.edu commandByte.disableMouse = 0; 3889918Ssteve.reinhardt@amd.com break; 3896376Sgblack@eecs.umich.edu case TestMouse: 3904661Sksewell@umich.edu panic("i8042 \"Test mouse\" command not implemented.\n"); 3916384Sgblack@eecs.umich.edu case SelfTest: 3926384Sgblack@eecs.umich.edu panic("i8042 \"Self test\" command not implemented.\n"); 3936384Sgblack@eecs.umich.edu case InterfaceTest: 3944661Sksewell@umich.edu panic("i8042 \"Interface test\" command not implemented.\n"); 3956383Sgblack@eecs.umich.edu case DiagnosticDump: 3966383Sgblack@eecs.umich.edu panic("i8042 \"Diagnostic dump\" command not implemented.\n"); 3976383Sgblack@eecs.umich.edu case DisableKeyboard: 3986383Sgblack@eecs.umich.edu DPRINTF(I8042, "Disabling keyboard at controller.\n"); 3996383Sgblack@eecs.umich.edu commandByte.disableKeyboard = 1; 4006383Sgblack@eecs.umich.edu break; 4016383Sgblack@eecs.umich.edu case EnableKeyboard: 4026383Sgblack@eecs.umich.edu DPRINTF(I8042, "Enabling keyboard at controller.\n"); 4036383Sgblack@eecs.umich.edu commandByte.disableKeyboard = 0; 4046383Sgblack@eecs.umich.edu break; 4056383Sgblack@eecs.umich.edu case ReadInputPort: 4066383Sgblack@eecs.umich.edu panic("i8042 \"Read input port\" command not implemented.\n"); 4076383Sgblack@eecs.umich.edu case ContinuousPollLow: 4086384Sgblack@eecs.umich.edu panic("i8042 \"Continuous poll low\" command not implemented.\n"); 4092686Sksewell@umich.edu case ContinuousPollHigh: 4104661Sksewell@umich.edu panic("i8042 \"Continuous poll high\" command not implemented.\n"); 4114661Sksewell@umich.edu case ReadOutputPort: 4129918Ssteve.reinhardt@amd.com panic("i8042 \"Read output port\" command not implemented.\n"); 4136384Sgblack@eecs.umich.edu case WriteOutputPort: 4144661Sksewell@umich.edu panic("i8042 \"Write output port\" command not implemented.\n"); 4159918Ssteve.reinhardt@amd.com case WriteKeyboardOutputBuff: 4166384Sgblack@eecs.umich.edu panic("i8042 \"Write keyboard output buffer\" " 4176384Sgblack@eecs.umich.edu "command not implemented.\n"); 4186384Sgblack@eecs.umich.edu case WriteMouseOutputBuff: 4196384Sgblack@eecs.umich.edu DPRINTF(I8042, "Got command to write to mouse output buffer.\n"); 4209918Ssteve.reinhardt@amd.com lastCommand = WriteMouseOutputBuff; 4216384Sgblack@eecs.umich.edu break; 4226384Sgblack@eecs.umich.edu case WriteToMouse: 4236384Sgblack@eecs.umich.edu DPRINTF(I8042, "Expecting mouse command.\n"); 4249918Ssteve.reinhardt@amd.com lastCommand = WriteToMouse; 4256384Sgblack@eecs.umich.edu break; 4266384Sgblack@eecs.umich.edu case DisableA20: 4276384Sgblack@eecs.umich.edu panic("i8042 \"Disable A20\" command not implemented.\n"); 4286384Sgblack@eecs.umich.edu case EnableA20: 4296384Sgblack@eecs.umich.edu panic("i8042 \"Enable A20\" command not implemented.\n"); 4306384Sgblack@eecs.umich.edu case ReadTestInputs: 4316384Sgblack@eecs.umich.edu panic("i8042 \"Read test inputs\" command not implemented.\n"); 4326384Sgblack@eecs.umich.edu case SystemReset: 4336384Sgblack@eecs.umich.edu panic("i8042 \"System reset\" command not implemented.\n"); 4346384Sgblack@eecs.umich.edu default: 4356384Sgblack@eecs.umich.edu panic("Write to unknown i8042 " 4366384Sgblack@eecs.umich.edu "(keyboard controller) command port.\n"); 4376384Sgblack@eecs.umich.edu } 4386384Sgblack@eecs.umich.edu } else { 4396384Sgblack@eecs.umich.edu panic("Write to unrecognized port %#x.\n", addr); 4406384Sgblack@eecs.umich.edu } 4416384Sgblack@eecs.umich.edu pkt->makeAtomicResponse(); 4426384Sgblack@eecs.umich.edu return latency; 4436384Sgblack@eecs.umich.edu} 4446384Sgblack@eecs.umich.edu 4456384Sgblack@eecs.umich.eduvoid 4462101SN/AX86ISA::I8042::serialize(std::ostream &os) 4476384Sgblack@eecs.umich.edu{ 4482686Sksewell@umich.edu uint8_t statusRegData = statusReg.__data; 4492027SN/A uint8_t commandByteData = commandByte.__data; 4506384Sgblack@eecs.umich.edu 4516384Sgblack@eecs.umich.edu SERIALIZE_SCALAR(dataPort); 4524661Sksewell@umich.edu SERIALIZE_SCALAR(commandPort); 4539918Ssteve.reinhardt@amd.com SERIALIZE_SCALAR(statusRegData); 4544661Sksewell@umich.edu SERIALIZE_SCALAR(commandByteData); 4554661Sksewell@umich.edu SERIALIZE_SCALAR(dataReg); 4564661Sksewell@umich.edu SERIALIZE_SCALAR(lastCommand); 4574661Sksewell@umich.edu mouse.serialize("mouse", os); 4584661Sksewell@umich.edu keyboard.serialize("keyboard", os); 4596383Sgblack@eecs.umich.edu} 4604661Sksewell@umich.edu 4616383Sgblack@eecs.umich.eduvoid 4624661Sksewell@umich.eduX86ISA::I8042::unserialize(Checkpoint *cp, const std::string §ion) 4634661Sksewell@umich.edu{ 4646383Sgblack@eecs.umich.edu uint8_t statusRegData; 4654661Sksewell@umich.edu uint8_t commandByteData; 4664661Sksewell@umich.edu 4676383Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(dataPort); 4684661Sksewell@umich.edu UNSERIALIZE_SCALAR(commandPort); 4694661Sksewell@umich.edu UNSERIALIZE_SCALAR(statusRegData); 4706383Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(commandByteData); 4714661Sksewell@umich.edu UNSERIALIZE_SCALAR(dataReg); 4724661Sksewell@umich.edu UNSERIALIZE_SCALAR(lastCommand); 4736383Sgblack@eecs.umich.edu mouse.unserialize("mouse", cp, section); 4744661Sksewell@umich.edu keyboard.unserialize("keyboard", cp, section); 4754661Sksewell@umich.edu 4766383Sgblack@eecs.umich.edu statusReg.__data = statusRegData; 4774661Sksewell@umich.edu commandByte.__data = commandByteData; 4784661Sksewell@umich.edu} 4796383Sgblack@eecs.umich.edu 4804661Sksewell@umich.eduvoid 4814661Sksewell@umich.eduX86ISA::PS2Keyboard::serialize(const std::string &base, std::ostream &os) 4826383Sgblack@eecs.umich.edu{ 4834661Sksewell@umich.edu paramOut(os, base + ".lastCommand", lastCommand); 4844661Sksewell@umich.edu int bufferSize = outBuffer.size(); 4856383Sgblack@eecs.umich.edu paramOut(os, base + ".outBuffer.size", bufferSize); 4864661Sksewell@umich.edu uint8_t *buffer = new uint8_t[bufferSize]; 4874661Sksewell@umich.edu for (int i = 0; i < bufferSize; ++i) { 4886383Sgblack@eecs.umich.edu buffer[i] = outBuffer.front(); 4894661Sksewell@umich.edu outBuffer.pop(); 4904661Sksewell@umich.edu } 4916383Sgblack@eecs.umich.edu arrayParamOut(os, base + ".outBuffer.elts", buffer, 4924661Sksewell@umich.edu bufferSize*sizeof(uint8_t)); 4936383Sgblack@eecs.umich.edu delete buffer; 4946384Sgblack@eecs.umich.edu} 4955222Sksewell@umich.edu 4964661Sksewell@umich.eduvoid 4976384Sgblack@eecs.umich.eduX86ISA::PS2Keyboard::unserialize(const std::string &base, Checkpoint *cp, 4986384Sgblack@eecs.umich.edu const std::string §ion) 4999918Ssteve.reinhardt@amd.com{ 5008607Sgblack@eecs.umich.edu paramIn(cp, section, base + ".lastCommand", lastCommand); 5018607Sgblack@eecs.umich.edu int bufferSize; 5029918Ssteve.reinhardt@amd.com paramIn(cp, section, base + ".outBuffer.size", bufferSize); 5036384Sgblack@eecs.umich.edu uint8_t *buffer = new uint8_t[bufferSize]; 5046384Sgblack@eecs.umich.edu arrayParamIn(cp, section, base + ".outBuffer.elts", buffer, 5056384Sgblack@eecs.umich.edu bufferSize*sizeof(uint8_t)); 5066384Sgblack@eecs.umich.edu for (int i = 0; i < bufferSize; ++i) { 5076384Sgblack@eecs.umich.edu outBuffer.push(buffer[i]); 5086384Sgblack@eecs.umich.edu } 5098588Sgblack@eecs.umich.edu delete buffer; 5106384Sgblack@eecs.umich.edu} 5116384Sgblack@eecs.umich.edu 5126384Sgblack@eecs.umich.eduvoid 5136384Sgblack@eecs.umich.eduX86ISA::PS2Mouse::serialize(const std::string &base, std::ostream &os) 5146384Sgblack@eecs.umich.edu{ 5158588Sgblack@eecs.umich.edu uint8_t statusData = status.__data; 5166384Sgblack@eecs.umich.edu paramOut(os, base + ".lastCommand", lastCommand); 5178588Sgblack@eecs.umich.edu int bufferSize = outBuffer.size(); 5186384Sgblack@eecs.umich.edu paramOut(os, base + ".outBuffer.size", bufferSize); 5196384Sgblack@eecs.umich.edu uint8_t *buffer = new uint8_t[bufferSize]; 5206384Sgblack@eecs.umich.edu for (int i = 0; i < bufferSize; ++i) { 5216384Sgblack@eecs.umich.edu buffer[i] = outBuffer.front(); 5228588Sgblack@eecs.umich.edu outBuffer.pop(); 5236384Sgblack@eecs.umich.edu } 5248588Sgblack@eecs.umich.edu arrayParamOut(os, base + ".outBuffer.elts", buffer, 5256384Sgblack@eecs.umich.edu bufferSize*sizeof(uint8_t)); 5268588Sgblack@eecs.umich.edu delete buffer; 5276384Sgblack@eecs.umich.edu paramOut(os, base + ".status", statusData); 5286384Sgblack@eecs.umich.edu paramOut(os, base + ".resolution", resolution); 5298588Sgblack@eecs.umich.edu paramOut(os, base + ".sampleRate", sampleRate); 5306384Sgblack@eecs.umich.edu} 5316384Sgblack@eecs.umich.edu 5326384Sgblack@eecs.umich.eduvoid 5336384Sgblack@eecs.umich.eduX86ISA::PS2Mouse::unserialize(const std::string &base, Checkpoint *cp, 5346384Sgblack@eecs.umich.edu const std::string §ion) 5358607Sgblack@eecs.umich.edu{ 5366384Sgblack@eecs.umich.edu uint8_t statusData; 5379918Ssteve.reinhardt@amd.com paramIn(cp, section, base + ".lastCommand", lastCommand); 5386384Sgblack@eecs.umich.edu int bufferSize; 5396384Sgblack@eecs.umich.edu paramIn(cp, section, base + ".outBuffer.size", bufferSize); 5404661Sksewell@umich.edu uint8_t *buffer = new uint8_t[bufferSize]; 5414661Sksewell@umich.edu arrayParamIn(cp, section, base + ".outBuffer.elts", buffer, 5422101SN/A bufferSize*sizeof(uint8_t)); 5434661Sksewell@umich.edu for (int i = 0; i < bufferSize; ++i) { 5444661Sksewell@umich.edu outBuffer.push(buffer[i]); 5454661Sksewell@umich.edu } 5464661Sksewell@umich.edu delete buffer; 5474661Sksewell@umich.edu paramIn(cp, section, base + ".status", statusData); 5486376Sgblack@eecs.umich.edu paramIn(cp, section, base + ".resolution", resolution); 5496376Sgblack@eecs.umich.edu paramIn(cp, section, base + ".sampleRate", sampleRate); 5506376Sgblack@eecs.umich.edu 5516376Sgblack@eecs.umich.edu status.__data = statusData; 5526376Sgblack@eecs.umich.edu} 5536376Sgblack@eecs.umich.edu 5546376Sgblack@eecs.umich.eduX86ISA::I8042 * 5556376Sgblack@eecs.umich.eduI8042Params::create() 5566376Sgblack@eecs.umich.edu{ 5576376Sgblack@eecs.umich.edu return new X86ISA::I8042(this); 5586376Sgblack@eecs.umich.edu} 5596376Sgblack@eecs.umich.edu