diff options
Diffstat (limited to 'src/dev/arm/pl011.hh')
-rw-r--r-- | src/dev/arm/pl011.hh | 150 |
1 files changed, 83 insertions, 67 deletions
diff --git a/src/dev/arm/pl011.hh b/src/dev/arm/pl011.hh index b5c55beab..f2587c08d 100644 --- a/src/dev/arm/pl011.hh +++ b/src/dev/arm/pl011.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010-2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -38,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ali Saidi + * Andreas Sandberg */ @@ -48,18 +49,73 @@ #ifndef __DEV_ARM_PL011_H__ #define __DEV_ARM_PL011_H__ -#include "base/bitfield.hh" -#include "base/bitunion.hh" #include "dev/arm/amba_device.hh" -#include "dev/io_device.hh" #include "dev/uart.hh" -#include "params/Pl011.hh" class BaseGic; +struct Pl011Params; class Pl011 : public Uart, public AmbaDevice { - protected: + public: + Pl011(const Pl011Params *p); + + void serialize(std::ostream &os) M5_ATTR_OVERRIDE; + void unserialize(Checkpoint *cp, const std::string &sec) M5_ATTR_OVERRIDE; + + public: // PioDevice + Tick read(PacketPtr pkt) M5_ATTR_OVERRIDE; + Tick write(PacketPtr pkt) M5_ATTR_OVERRIDE; + + public: // Uart + void dataAvailable() M5_ATTR_OVERRIDE; + + + protected: // Interrupt handling + /** Function to generate interrupt */ + void generateInterrupt(); + + /** + * Assign new interrupt values and update interrupt signals + * + * A new interrupt is scheduled signalled if the set of unmasked + * interrupts goes empty to non-empty. Conversely, if the set of + * unmasked interrupts goes from non-empty to empty, the interrupt + * signal is cleared. + * + * @param ints New <i>raw</i> interrupt status + * @param mask New interrupt mask + */ + void setInterrupts(uint16_t ints, uint16_t mask); + /** + * Convenience function to update the interrupt mask + * + * @see setInterrupts + * @param mask New interrupt mask + */ + void setInterruptMask(uint16_t mask) { setInterrupts(rawInt, mask); } + /** + * Convenience function to raise a new interrupt + * + * @see setInterrupts + * @param ints Set of interrupts to raise + */ + void raiseInterrupts(uint16_t ints) { setInterrupts(rawInt | ints, imsc); } + /** + * Convenience function to clear interrupts + * + * @see setInterrupts + * @param ints Set of interrupts to clear + */ + void clearInterrupts(uint16_t ints) { setInterrupts(rawInt & ~ints, imsc); } + + /** Masked interrupt status register */ + const inline uint16_t maskInt() const { return rawInt & imsc; } + + /** Wrapper to create an event out of the thing */ + EventWrapper<Pl011, &Pl011::generateInterrupt> intEvent; + + protected: // Registers static const uint64_t AMBA_ID = ULL(0xb105f00d00341011); static const int UART_DR = 0x000; static const int UART_FR = 0x018; @@ -76,6 +132,18 @@ class Pl011 : public Uart, public AmbaDevice static const int UART_MIS = 0x040; static const int UART_ICR = 0x044; + static const uint16_t UART_RIINTR = 1 << 0; + static const uint16_t UART_CTSINTR = 1 << 1; + static const uint16_t UART_CDCINTR = 1 << 2; + static const uint16_t UART_DSRINTR = 1 << 3; + static const uint16_t UART_RXINTR = 1 << 4; + static const uint16_t UART_TXINTR = 1 << 5; + static const uint16_t UART_RTINTR = 1 << 6; + static const uint16_t UART_FEINTR = 1 << 7; + static const uint16_t UART_PEINTR = 1 << 8; + static const uint16_t UART_BEINTR = 1 << 9; + static const uint16_t UART_OEINTR = 1 << 10; + uint16_t control; /** fractional baud rate divisor. Not used for anything but reporting @@ -94,76 +162,24 @@ class Pl011 : public Uart, public AmbaDevice * written value */ uint16_t ifls; - BitUnion16(INTREG) - Bitfield<0> rimim; - Bitfield<1> ctsmim; - Bitfield<2> dcdmim; - Bitfield<3> dsrmim; - Bitfield<4> rxim; - Bitfield<5> txim; - Bitfield<6> rtim; - Bitfield<7> feim; - Bitfield<8> peim; - Bitfield<9> beim; - Bitfield<10> oeim; - Bitfield<15,11> rsvd; - EndBitUnion(INTREG) - /** interrupt mask register. */ - INTREG imsc; + uint16_t imsc; /** raw interrupt status register */ - INTREG rawInt; - - /** Masked interrupt status register */ - INTREG maskInt; - - /** Interrupt number to generate */ - int intNum; + uint16_t rawInt; + protected: // Configuration /** Gic to use for interrupting */ - BaseGic *gic; + BaseGic * const gic; /** Should the simulation end on an EOT */ - bool endOnEOT; - - /** Delay before interrupting */ - Tick intDelay; - - /** Function to generate interrupt */ - void generateInterrupt(); - - /** Wrapper to create an event out of the thing */ - EventWrapper<Pl011, &Pl011::generateInterrupt> intEvent; + const bool endOnEOT; - public: - typedef Pl011Params Params; - const Params * - params() const - { - return dynamic_cast<const Params *>(_params); - } - Pl011(const Params *p); - - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); - - /** - * Inform the uart that there is data available. - */ - virtual void dataAvailable(); - - - /** - * Return if we have an interrupt pending - * @return interrupt status - * @todo fix me when implementation improves - */ - virtual bool intStatus() { return false; } - - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); + /** Interrupt number to generate */ + const int intNum; + /** Delay before interrupting */ + const Tick intDelay; }; #endif //__DEV_ARM_PL011_H__ |