From 74e63a607af58c2df49cd2decbebd71a6d061915 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 9 Apr 2018 18:42:28 +0100 Subject: dev, arm: Use the PS/2 framework in the Pl050 model The Pl050 KMI model currently has its own keyboard and mouse models. Use the generic PS/2 interface instead. Change-Id: I6523d26f8e38bcc8ba399d4d1a131723645d36c7 Signed-off-by: Andreas Sandberg Reviewed-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/9767 Reviewed-by: Gabe Black --- src/dev/arm/kmi.cc | 184 +++++++++-------------------------------------------- 1 file changed, 31 insertions(+), 153 deletions(-) (limited to 'src/dev/arm/kmi.cc') diff --git a/src/dev/arm/kmi.cc b/src/dev/arm/kmi.cc index 8b373b819..d80bc14e9 100644 --- a/src/dev/arm/kmi.cc +++ b/src/dev/arm/kmi.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017 ARM Limited + * Copyright (c) 2010, 2017-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -48,21 +48,17 @@ #include "debug/Pl050.hh" #include "dev/arm/amba_device.hh" #include "dev/ps2.hh" +#include "dev/ps2/device.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" -Pl050::Pl050(const Params *p) +Pl050::Pl050(const Pl050Params *p) : AmbaIntDevice(p, 0xfff), control(0), status(0x43), clkdiv(0), - rawInterrupts(0), ackNext(false), shiftDown(false), - vnc(p->vnc), driverInitialized(false), - intEvent([this]{ generateInterrupt(); }, name()) + rawInterrupts(0), + intEvent([this]{ generateInterrupt(); }, name()), + ps2(p->ps2) { - if (vnc) { - if (!p->is_mouse) - vnc->setKeyboard(this); - else - vnc->setMouse(this); - } + ps2->hostRegDataAvailable([this]() { this->updateIntStatus(); }); } Tick @@ -79,32 +75,28 @@ Pl050::read(PacketPtr pkt) DPRINTF(Pl050, "Read Commmand: %#x\n", (uint32_t)control); data = control; break; - case kmiStat: - if (rxQueue.empty()) - status.rxfull = 0; - else - status.rxfull = 1; + case kmiStat: + status.rxfull = ps2->hostDataAvailable() ? 1 : 0; DPRINTF(Pl050, "Read Status: %#x\n", (uint32_t)status); data = status; break; + case kmiData: - if (rxQueue.empty()) { - data = 0; - } else { - data = rxQueue.front(); - rxQueue.pop_front(); - } + data = ps2->hostDataAvailable() ? ps2->hostRead() : 0; DPRINTF(Pl050, "Read Data: %#x\n", (uint32_t)data); updateIntStatus(); break; + case kmiClkDiv: data = clkdiv; break; + case kmiISR: data = getInterrupt(); DPRINTF(Pl050, "Read Interrupts: %#x\n", getInterrupt()); break; + default: if (readId(pkt, ambaId, pioAddr)) { // Hack for variable size accesses @@ -152,99 +144,33 @@ Pl050::write(PacketPtr pkt) control = pkt->get(); updateIntStatus(); break; + case kmiData: DPRINTF(Pl050, "Write Data: %#x\n", (uint32_t)pkt->get()); - processCommand(pkt->get()); + ps2->hostWrite(pkt->get()); updateIntStatus(); break; + case kmiClkDiv: clkdiv = pkt->get(); break; + default: warn("Tried to write PL050 at offset %#x that doesn't exist\n", daddr); break; } + pkt->makeAtomicResponse(); return pioDelay; } -void -Pl050::processCommand(uint8_t byte) -{ - using namespace Ps2; - - if (ackNext) { - ackNext--; - rxQueue.push_back(Ack); - updateIntStatus(); - return; - } - - switch (byte) { - case Ps2Reset: - rxQueue.push_back(Ack); - rxQueue.push_back(SelfTestPass); - break; - case SetResolution: - case SetRate: - case SetStatusLed: - rxQueue.push_back(Ack); - ackNext = 1; - break; - case ReadId: - rxQueue.push_back(Ack); - if (params()->is_mouse) - rxQueue.push_back(MouseId); - else - rxQueue.push_back(KeyboardId); - break; - case TpReadId: - if (!params()->is_mouse) - break; - // We're not a trackpoint device, this should make the probe go away - rxQueue.push_back(Ack); - rxQueue.push_back(0); - rxQueue.push_back(0); - // fall through - case Disable: - case Enable: - case SetDefaults: - case SetScaling1_1: - case SetScaling1_2: - rxQueue.push_back(Ack); - break; - case StatusRequest: - rxQueue.push_back(Ack); - rxQueue.push_back(0); - rxQueue.push_back(2); // default resolution - rxQueue.push_back(100); // default sample rate - break; - case TouchKitId: - ackNext = 2; - rxQueue.push_back(Ack); - rxQueue.push_back(TouchKitId); - rxQueue.push_back(1); - rxQueue.push_back('A'); - - driverInitialized = true; - break; - default: - panic("Unknown byte received: %d\n", byte); - } - - updateIntStatus(); -} - void Pl050::updateIntStatus() { const bool old_interrupt(getInterrupt()); - if (!rxQueue.empty()) - rawInterrupts.rx = 1; - else - rawInterrupts.rx = 0; + rawInterrupts.rx = ps2->hostDataAvailable() ? 1 : 0; if ((!old_interrupt && getInterrupt()) && !intEvent.scheduled()) { schedule(intEvent, curTick() + intDelay); @@ -253,6 +179,17 @@ Pl050::updateIntStatus() } } +Pl050::InterruptReg +Pl050::getInterrupt() const +{ + InterruptReg tmp_interrupt(0); + + tmp_interrupt.tx = rawInterrupts.tx & control.txint_enable; + tmp_interrupt.rx = rawInterrupts.rx & control.rxint_enable; + + return tmp_interrupt; +} + void Pl050::generateInterrupt() { @@ -265,51 +202,6 @@ Pl050::generateInterrupt() } } -void -Pl050::mouseAt(uint16_t x, uint16_t y, uint8_t buttons) -{ - using namespace Ps2; - - // If the driver hasn't initialized the device yet, no need to try and send - // it anything. Similarly we can get vnc mouse events orders of maginture - // faster than m5 can process them. Only queue up two sets mouse movements - // and don't add more until those are processed. - if (!driverInitialized || rxQueue.size() > 10) - return; - - // We shouldn't be here unless a vnc server called us in which case - // we should have a pointer to it - assert(vnc); - - // Convert screen coordinates to touchpad coordinates - uint16_t _x = (2047.0/vnc->videoWidth()) * x; - uint16_t _y = (2047.0/vnc->videoHeight()) * y; - - rxQueue.push_back(buttons); - rxQueue.push_back(_x >> 7); - rxQueue.push_back(_x & 0x7f); - rxQueue.push_back(_y >> 7); - rxQueue.push_back(_y & 0x7f); - - updateIntStatus(); -} - - -void -Pl050::keyPress(uint32_t key, bool down) -{ - using namespace Ps2; - - std::list keys; - - // convert the X11 keysym into ps2 codes - keySymToPs2(key, down, shiftDown, keys); - - // Insert into our queue of charecters - rxQueue.splice(rxQueue.end(), keys); - updateIntStatus(); -} - void Pl050::serialize(CheckpointOut &cp) const { @@ -322,12 +214,6 @@ Pl050::serialize(CheckpointOut &cp) const uint8_t raw_ints = rawInterrupts; SERIALIZE_SCALAR(raw_ints); - - SERIALIZE_SCALAR(ackNext); - SERIALIZE_SCALAR(shiftDown); - SERIALIZE_SCALAR(driverInitialized); - - SERIALIZE_CONTAINER(rxQueue); } void @@ -346,16 +232,8 @@ Pl050::unserialize(CheckpointIn &cp) uint8_t raw_ints; UNSERIALIZE_SCALAR(raw_ints); rawInterrupts = raw_ints; - - UNSERIALIZE_SCALAR(ackNext); - UNSERIALIZE_SCALAR(shiftDown); - UNSERIALIZE_SCALAR(driverInitialized); - - UNSERIALIZE_CONTAINER(rxQueue); } - - Pl050 * Pl050Params::create() { -- cgit v1.2.3