From 74e63a607af58c2df49cd2decbebd71a6d061915 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 9 Apr 2018 18:42:28 +0100 Subject: [PATCH] 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/RealView.py | 21 ++--- src/dev/arm/kmi.cc | 184 +++++++--------------------------------- src/dev/arm/kmi.hh | 51 ++--------- 3 files changed, 51 insertions(+), 205 deletions(-) diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index a59e1713f..7661db15a 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -62,6 +62,7 @@ from ClockDomain import SrcClockDomain from SubSystem import SubSystem from Graphics import ImageFormat from ClockedObject import ClockedObject +from PS2 import * # Platforms with KVM support should generally use in-kernel GIC # emulation. Use a GIC model that automatically switches between @@ -465,11 +466,11 @@ class PL031(AmbaIntDevice): class Pl050(AmbaIntDevice): type = 'Pl050' cxx_header = "dev/arm/kmi.hh" - vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") - is_mouse = Param.Bool(False, "Is this interface a mouse, if not a keyboard") int_delay = '1us' amba_id = 0x00141050 + ps2 = Param.PS2Device("PS/2 device") + def generateDeviceTree(self, state): node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr, 0x1000, [int(self.int_num)]) @@ -624,8 +625,8 @@ class RealViewPBX(RealView): local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, pio_addr=0x1f000600) clcd = Pl111(pio_addr=0x10020000, int_num=55) - kmi0 = Pl050(pio_addr=0x10006000, int_num=52) - kmi1 = Pl050(pio_addr=0x10007000, int_num=53, is_mouse=True) + kmi0 = Pl050(pio_addr=0x10006000, int_num=52, ps2=PS2Keyboard()) + kmi1 = Pl050(pio_addr=0x10007000, int_num=53, ps2=PS2TouchKit()) a9scu = A9SCU(pio_addr=0x1f000000) cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2, io_shift = 1, ctrl_offset = 2, Command = 0x1, @@ -753,8 +754,8 @@ class RealViewEB(RealView): timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000) timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000) clcd = Pl111(pio_addr=0x10020000, int_num=23) - kmi0 = Pl050(pio_addr=0x10006000, int_num=20) - kmi1 = Pl050(pio_addr=0x10007000, int_num=21, is_mouse=True) + kmi0 = Pl050(pio_addr=0x10006000, int_num=20, ps2=PS2Keyboard()) + kmi1 = Pl050(pio_addr=0x10007000, int_num=21, ps2=PS2TouchKit()) l2x0_fake = IsaFake(pio_addr=0x1f002000, pio_size=0xfff, warn_access="1") flash_fake = IsaFake(pio_addr=0x40000000, pio_size=0x20000000-1, @@ -904,8 +905,8 @@ class VExpress_EMM(RealView): timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz') timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz') clcd = Pl111(pio_addr=0x1c1f0000, int_num=46) - kmi0 = Pl050(pio_addr=0x1c060000, int_num=44) - kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True) + kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard()) + kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit()) cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2, io_shift = 2, ctrl_offset = 2, Command = 0x1, BAR0 = 0x1C1A0000, BAR0Size = '256B', @@ -1136,8 +1137,8 @@ Interrupts: uart0 = Pl011(pio_addr=0x1c090000, int_num=37) - kmi0 = Pl050(pio_addr=0x1c060000, int_num=44) - kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True) + kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard()) + kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit()) rtc = PL031(pio_addr=0x1c170000, int_num=36) 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() { diff --git a/src/dev/arm/kmi.hh b/src/dev/arm/kmi.hh index 0593165c0..16a61a181 100644 --- a/src/dev/arm/kmi.hh +++ b/src/dev/arm/kmi.hh @@ -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 @@ -54,7 +54,9 @@ #include "dev/arm/amba_device.hh" #include "params/Pl050.hh" -class Pl050 : public AmbaIntDevice, public VncKeyboard, public VncMouse +class PS2Device; + +class Pl050 : public AmbaIntDevice { protected: static const int kmiCr = 0x000; @@ -104,21 +106,6 @@ class Pl050 : public AmbaIntDevice, public VncKeyboard, public VncMouse /** raw interrupt register (unmasked) */ InterruptReg rawInterrupts; - /** If the controller should ignore the next data byte and acknowledge it. - * The driver is attempting to setup some feature we don't care about - */ - int ackNext; - - /** is the shift key currently down */ - bool shiftDown; - - /** The vnc server we're connected to (if any) */ - VncInput *vnc; - - /** If the linux driver has initialized the device yet and thus can we send - * mouse data */ - bool driverInitialized; - /** Update the status of the interrupt registers and schedule an interrupt * if required */ void updateIntStatus(); @@ -127,40 +114,20 @@ class Pl050 : public AmbaIntDevice, public VncKeyboard, public VncMouse void generateInterrupt(); /** Get interrupt value */ - InterruptReg 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; - } + InterruptReg getInterrupt() const; + /** Wrapper to create an event out of the thing */ EventFunctionWrapper intEvent; - /** Receive queue. This list contains all the pending commands that - * need to be sent to the driver - */ - std::list rxQueue; - - /** Handle a command sent to the kmi and respond appropriately - */ - void processCommand(uint8_t byte); + /** PS2 device connected to this KMI interface */ + PS2Device *ps2; public: - typedef Pl050Params Params; - const Params * - params() const - { - return dynamic_cast(_params); - } - - Pl050(const Params *p); + Pl050(const Pl050Params *p); Tick read(PacketPtr pkt) override; Tick write(PacketPtr pkt) override; - void mouseAt(uint16_t x, uint16_t y, uint8_t buttons) override; - void keyPress(uint32_t key, bool down) override; - void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override; }; -- 2.30.2