Remote GDB: Turn on remote gdb in SE mode.
[gem5.git] / src / dev / uart8250.cc
index b92527b5a95299c48faf942bb352046be12574a2..e14b0871e8cc2244668acabba89f492fc0e93451 100644 (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;
@@ -57,7 +57,7 @@ Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit)
 const char *
 Uart8250::IntrEvent::description()
 {
-    return "uart interrupt delay event";
+    return "uart interrupt delay";
 }
 
 void
@@ -67,6 +67,7 @@ Uart8250::IntrEvent::process()
        DPRINTF(Uart, "UART InterEvent, interrupting\n");
        uart->platform->postConsoleInt();
        uart->status |= intrBit;
+       uart->lastTxInt = curTick;
     }
     else
        DPRINTF(Uart, "UART InterEvent, not interrupting\n");
@@ -98,21 +99,16 @@ Uart8250::IntrEvent::scheduleIntr()
 }
 
 
-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);
 
@@ -152,13 +148,13 @@ Uart8250::read(Packet *pkt)
 
             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);
@@ -187,15 +183,14 @@ Uart8250::read(Packet *pkt)
 /*    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);
 
@@ -221,7 +216,16 @@ Uart8250::write(Packet *pkt)
                 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
                 {
@@ -264,7 +268,7 @@ Uart8250::write(Packet *pkt)
             panic("Tried to access a UART port that doesn't exist\n");
             break;
     }
-    pkt->result = Packet::Success;
+    pkt->makeAtomicResponse();
     return pioDelay;
 }
 
@@ -330,37 +334,8 @@ Uart8250::unserialize(Checkpoint *cp, const std::string &section)
         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)
-