* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
*/
/** @file
#include <string>
#include <vector>
-#include "arch/alpha/ev5.hh"
#include "base/inifile.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
#include "dev/simconsole.hh"
#include "dev/uart8250.hh"
#include "dev/platform.hh"
-#include "sim/builder.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
using namespace std;
using namespace TheISA;
const char *
Uart8250::IntrEvent::description()
{
- return "uart interrupt delay event";
+ return "uart interrupt delay";
}
void
DPRINTF(Uart, "UART InterEvent, interrupting\n");
uart->platform->postConsoleInt();
uart->status |= intrBit;
+ uart->lastTxInt = curTick;
}
else
DPRINTF(Uart, "UART InterEvent, not interrupting\n");
}
-Uart8250::Uart8250(Params *p)
- : Uart(p), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
+Uart8250::Uart8250(const Params *p)
+ : Uart(p), IER(0), DLAB(0), LCR(0), MCR(0), lastTxInt(0),
+ txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
{
pioSize = 8;
-
- IER = 0;
- DLAB = 0;
- LCR = 0;
- MCR = 0;
}
Tick
-Uart8250::read(Packet *pkt)
+Uart8250::read(PacketPtr pkt)
{
- assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->getSize() == 1);
- pkt->time += pioDelay;
Addr daddr = pkt->getAddr() - pioAddr;
pkt->allocate();
case 0x0:
if (!(LCR & 0x80)) { // read byte
if (cons->dataAvailable())
- cons->in(*pkt->getPtr<uint8_t>());
+ pkt->set(cons->in());
else {
pkt->set((uint8_t)0);
// A limited amount of these are ok.
if (status & RX_INT) /* Rx data interrupt has a higher priority */
pkt->set(IIR_RXID);
- else if (status & TX_INT)
+ else if (status & TX_INT) {
pkt->set(IIR_TXID);
- else
+ //Tx interrupts are cleared on IIR reads
+ status &= ~TX_INT;
+ } else
pkt->set(IIR_NOPEND);
- //Tx interrupts are cleared on IIR reads
- status &= ~TX_INT;
break;
case 0x3: // Line Control Register (LCR)
pkt->set(LCR);
/* uint32_t d32 = *data;
DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
*/
- pkt->result = Packet::Success;
+ pkt->makeAtomicResponse();
return pioDelay;
}
Tick
-Uart8250::write(Packet *pkt)
+Uart8250::write(PacketPtr pkt)
{
- assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->getSize() == 1);
- pkt->time += pioDelay;
Addr daddr = pkt->getAddr() - pioAddr;
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>());
if (UART_IER_THRI & IER)
{
DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
- txIntrEvent.scheduleIntr();
+ if (curTick - lastTxInt >
+ (Tick)((Clock::Float::s / 2e9) * 450)) {
+ DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n",
+ curTick, lastTxInt);
+ txIntrEvent.process();
+ } else {
+ DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n",
+ curTick, lastTxInt);
+ txIntrEvent.scheduleIntr();
+ }
}
else
{
panic("Tried to access a UART port that doesn't exist\n");
break;
}
- pkt->result = Packet::Success;
+ pkt->makeAtomicResponse();
return pioDelay;
}
txIntrEvent.schedule(txintrwhen);
}
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart8250)
-
- Param<Addr> pio_addr;
- Param<Tick> pio_latency;
- SimObjectParam<Platform *> platform;
- SimObjectParam<SimConsole *> sim_console;
- SimObjectParam<System *> system;
-
-END_DECLARE_SIM_OBJECT_PARAMS(Uart8250)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(Uart8250)
-
- INIT_PARAM(pio_addr, "Device Address"),
- INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
- INIT_PARAM(platform, "platform"),
- INIT_PARAM(sim_console, "The Simulator Console"),
- INIT_PARAM(system, "system object")
-
-END_INIT_SIM_OBJECT_PARAMS(Uart8250)
-
-CREATE_SIM_OBJECT(Uart8250)
+Uart8250 *
+Uart8250Params::create()
{
- Uart8250::Params *p = new Uart8250::Params;
- p->name = getInstanceName();
- p->pio_addr = pio_addr;
- p->pio_delay = pio_latency;
- p->platform = platform;
- p->cons = sim_console;
- p->system = system;
- return new Uart8250(p);
+ return new Uart8250(this);
}
-
-REGISTER_SIM_OBJECT("Uart8250", Uart8250)
-