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 &section)
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 &section)
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 &section)
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