112239Sandreas.sandberg@arm.com/* 212239Sandreas.sandberg@arm.com * Copyright (c) 2014, 2017 ARM Limited 312239Sandreas.sandberg@arm.com * All rights reserved 412239Sandreas.sandberg@arm.com * 512239Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 612239Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 712239Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 812239Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 912239Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1012239Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1112239Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1212239Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1312239Sandreas.sandberg@arm.com * 1412239Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1512239Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1612239Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1712239Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1812239Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1912239Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2012239Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2112239Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2212239Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2312239Sandreas.sandberg@arm.com * this software without specific prior written permission. 2412239Sandreas.sandberg@arm.com * 2512239Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612239Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712239Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812239Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912239Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012239Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112239Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212239Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312239Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412239Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512239Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612239Sandreas.sandberg@arm.com * 3712239Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3812239Sandreas.sandberg@arm.com */ 3912239Sandreas.sandberg@arm.com 4012239Sandreas.sandberg@arm.com#ifndef __DEV_SERIAL_HH__ 4112239Sandreas.sandberg@arm.com#define __DEV_SERIAL_HH__ 4212239Sandreas.sandberg@arm.com 4312239Sandreas.sandberg@arm.com#include "base/callback.hh" 4412239Sandreas.sandberg@arm.com#include "sim/sim_object.hh" 4512239Sandreas.sandberg@arm.com 4612239Sandreas.sandberg@arm.comstruct SerialDeviceParams; 4712239Sandreas.sandberg@arm.comstruct SerialNullDeviceParams; 4812239Sandreas.sandberg@arm.com 4912239Sandreas.sandberg@arm.com/** 5012239Sandreas.sandberg@arm.com * Base class for serial devices such as terminals. 5112239Sandreas.sandberg@arm.com * 5212239Sandreas.sandberg@arm.com * This class provides a unified interface that all serial (RS232 or 5312239Sandreas.sandberg@arm.com * similar) devices must implement. A device can be wired to exactly 5412239Sandreas.sandberg@arm.com * one host serial interface (serial port model). 5512239Sandreas.sandberg@arm.com * 5612239Sandreas.sandberg@arm.com * SerialDevices are passive devices that are <i>driven</i> by the 5712239Sandreas.sandberg@arm.com * serial interface using the writeData(c) (the interface sends a 5812239Sandreas.sandberg@arm.com * character) and readData() (the interface reads a character) 5912239Sandreas.sandberg@arm.com * methods. Serial devices need to override these methods to 6012239Sandreas.sandberg@arm.com * communicate with the host interface layer. 6112239Sandreas.sandberg@arm.com * 6212239Sandreas.sandberg@arm.com * To implement basic flow control, serial devices must implement the 6312239Sandreas.sandberg@arm.com * dataAvailable() method. This method returns true if a valid 6412239Sandreas.sandberg@arm.com * character can be read using the readData() method. When data 6512239Sandreas.sandberg@arm.com * becomes available, the serial device must call the 6612239Sandreas.sandberg@arm.com * notifyInterface() method to send a callback to the interface layer. 6712239Sandreas.sandberg@arm.com * 6812239Sandreas.sandberg@arm.com * To send a character (host to device), the interface layer calls 6912239Sandreas.sandberg@arm.com * writeData(char) to send a character to the serial device. 7012239Sandreas.sandberg@arm.com * 7112239Sandreas.sandberg@arm.com * To read a character (device to host), the interface layer calls 7212239Sandreas.sandberg@arm.com * dataAvailable() to determine if there is a character pending. If 7312239Sandreas.sandberg@arm.com * there is data available, it immediately calls readData() to get the 7412239Sandreas.sandberg@arm.com * character. The receive loop in the serial device typically looks 7512239Sandreas.sandberg@arm.com * like this: 7612239Sandreas.sandberg@arm.com * 7712239Sandreas.sandberg@arm.com * \code{.cc} 7812239Sandreas.sandberg@arm.com * while (device.dataAvailable()) { 7912239Sandreas.sandberg@arm.com * printf("%c", (int)device.readData()); 8012239Sandreas.sandberg@arm.com * } 8112239Sandreas.sandberg@arm.com * \endcode 8212239Sandreas.sandberg@arm.com * 8312239Sandreas.sandberg@arm.com * To avoid polling, the interface layer may register a data available 8412239Sandreas.sandberg@arm.com * callback using the regInterfaceCallback() method. The device uses 8512239Sandreas.sandberg@arm.com * this callback to notify the interface layer whenever there is new 8612239Sandreas.sandberg@arm.com * data pending. Note that devices will normally only notify the 8712239Sandreas.sandberg@arm.com * interface layer when there is a state transition in the 8812239Sandreas.sandberg@arm.com * device. E.g., the dataAvailable() transitions from false to 8912239Sandreas.sandberg@arm.com * true. This means that there can be multiple pending characters when 9012239Sandreas.sandberg@arm.com * the interface layer receives the callback. 9112239Sandreas.sandberg@arm.com */ 9212239Sandreas.sandberg@arm.comclass SerialDevice : public SimObject 9312239Sandreas.sandberg@arm.com{ 9412239Sandreas.sandberg@arm.com public: 9512239Sandreas.sandberg@arm.com SerialDevice(const SerialDeviceParams *p); 9612239Sandreas.sandberg@arm.com ~SerialDevice(); 9712239Sandreas.sandberg@arm.com 9812239Sandreas.sandberg@arm.com public: // Serial device API (UART->Device) 9912239Sandreas.sandberg@arm.com /** 10012239Sandreas.sandberg@arm.com * Register a data available callback into the host interface layer. 10112239Sandreas.sandberg@arm.com * 10212239Sandreas.sandberg@arm.com * Serial devices need to call the underlying host interface layer 10312239Sandreas.sandberg@arm.com * to inform it of state change such as pending data that can be 10412239Sandreas.sandberg@arm.com * read from the device by the interface layer using the readData() 10512239Sandreas.sandberg@arm.com * method. The interface layer may use this method to register a 10612239Sandreas.sandberg@arm.com * callback that informs it of pending data. 10712239Sandreas.sandberg@arm.com * 10812239Sandreas.sandberg@arm.com * @param c Callback instance from interface layer. 10912239Sandreas.sandberg@arm.com */ 11012239Sandreas.sandberg@arm.com void regInterfaceCallback(Callback *c); 11112239Sandreas.sandberg@arm.com 11212239Sandreas.sandberg@arm.com /** 11312239Sandreas.sandberg@arm.com * Check if there is pending data from the serial device. 11412239Sandreas.sandberg@arm.com * 11512239Sandreas.sandberg@arm.com * @return true if there is data pending that can be read using 11612239Sandreas.sandberg@arm.com * the readData() method. 11712239Sandreas.sandberg@arm.com */ 11812239Sandreas.sandberg@arm.com virtual bool dataAvailable() const = 0; 11912239Sandreas.sandberg@arm.com 12012239Sandreas.sandberg@arm.com /** 12112239Sandreas.sandberg@arm.com * Transmit a character from the host interface to the device. 12212239Sandreas.sandberg@arm.com * 12312239Sandreas.sandberg@arm.com * @param c Received data. 12412239Sandreas.sandberg@arm.com */ 12512239Sandreas.sandberg@arm.com virtual void writeData(uint8_t c) = 0; 12612239Sandreas.sandberg@arm.com 12712239Sandreas.sandberg@arm.com /** 12812239Sandreas.sandberg@arm.com * Read a character from the device. 12912239Sandreas.sandberg@arm.com * 13012239Sandreas.sandberg@arm.com * @return Character from the device's output buffer, undefined if 13112239Sandreas.sandberg@arm.com * no data is pending. 13212239Sandreas.sandberg@arm.com */ 13312239Sandreas.sandberg@arm.com virtual uint8_t readData() = 0; 13412239Sandreas.sandberg@arm.com 13512239Sandreas.sandberg@arm.com protected: 13612239Sandreas.sandberg@arm.com /** Notify the host interface of pending data. */ 13712239Sandreas.sandberg@arm.com void notifyInterface(); 13812239Sandreas.sandberg@arm.com 13912239Sandreas.sandberg@arm.com private: 14012239Sandreas.sandberg@arm.com /** Currently regisxtered host interface layer callback */ 14112239Sandreas.sandberg@arm.com Callback *interfaceCallback; 14212239Sandreas.sandberg@arm.com}; 14312239Sandreas.sandberg@arm.com 14412239Sandreas.sandberg@arm.com/** 14512239Sandreas.sandberg@arm.com * Dummy serial device that discards all data sent to it. 14612239Sandreas.sandberg@arm.com */ 14712239Sandreas.sandberg@arm.comclass SerialNullDevice : public SerialDevice 14812239Sandreas.sandberg@arm.com{ 14912239Sandreas.sandberg@arm.com public: 15012239Sandreas.sandberg@arm.com SerialNullDevice(const SerialNullDeviceParams *p); 15112239Sandreas.sandberg@arm.com 15212239Sandreas.sandberg@arm.com public: 15312239Sandreas.sandberg@arm.com bool dataAvailable() const override { return false; } 15412239Sandreas.sandberg@arm.com void writeData(uint8_t c) override {}; 15512239Sandreas.sandberg@arm.com uint8_t readData() override; 15612239Sandreas.sandberg@arm.com}; 15712239Sandreas.sandberg@arm.com 15812239Sandreas.sandberg@arm.com#endif // __DEV_SERIAL_HH__ 159