Standardize clock parameter names to 'clock'.
[gem5.git] / dev / uart.cc
index 8ba59579dc0050de6a5dba2eeccb087128a99d2d..c04a5d06600e1766c294679b54deb1877604966b 100644 (file)
@@ -44,7 +44,6 @@
 #include "mem/bus/pio_interface_impl.hh"
 #include "mem/functional_mem/memory_control.hh"
 #include "sim/builder.hh"
-#include "targetarch/ev5.hh"
 
 using namespace std;
 
@@ -74,32 +73,43 @@ Uart::IntrEvent::process()
 
 }
 
+/* The linux serial driver (8250.c about line 1182) loops reading from
+ * the device until the device reports it has no more data to
+ * read. After a maximum of 255 iterations the code prints "serial8250
+ * too much work for irq X," and breaks out of the loop. Since the
+ * simulated system is so much slower than the actual system, if a
+ * user is typing on the keyboard it is very easy for them to provide
+ * input at a fast enough rate to not allow the loop to exit and thus
+ * the error to be printed. This magic number provides a delay between
+ * the time the UART receives a character to send to the simulated
+ * system and the time it actually notifies the system it has a
+ * character to send to alleviate this problem. --Ali
+ */
 void
 Uart::IntrEvent::scheduleIntr()
 {
+    static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 450);
     DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit,
-            curTick + (ticksPerSecond/2000) * 350);
+            curTick + interval);
     if (!scheduled())
-        /* @todo Make this cleaner, will be much easier with
-         *       nanosecond time everywhere. Hint hint  Nate. */
-        schedule(curTick + (ticksPerSecond/2000000000) * 450);
+        schedule(curTick + interval);
     else
-        reschedule(curTick + (ticksPerSecond/2000000000) * 450);
+        reschedule(curTick + interval);
 }
 
 Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
            Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p)
-    : PioDevice(name), addr(a), size(s), cons(c), txIntrEvent(this, TX_INT),
-      rxIntrEvent(this, RX_INT), platform(p)
+    : PioDevice(name, p), addr(a), size(s), cons(c),
+      txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
 {
-    mmu->add_child(this, Range<Addr>(addr, addr + size));
+    mmu->add_child(this, RangeSize(addr, size));
 
 
     if (bus) {
         pioInterface = newPioInterface(name, hier, bus, this,
                                       &Uart::cacheAccess);
-        pioInterface->addAddrRange(addr, addr + size - 1);
-        pioLatency = pio_latency * bus->clockRatio;
+        pioInterface->addAddrRange(RangeSize(addr, size));
+        pioLatency = pio_latency * bus->clockRate;
     }
 
     readAddr = 0;
@@ -118,7 +128,7 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
 Fault
 Uart::read(MemReqPtr &req, uint8_t *data)
 {
-    Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
+    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
     DPRINTF(Uart, " read register %#x\n", daddr);
 
 
@@ -246,7 +256,7 @@ Uart::read(MemReqPtr &req, uint8_t *data)
 Fault
 Uart::write(MemReqPtr &req, const uint8_t *data)
 {
-    Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
+    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
 
     DPRINTF(Uart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
 
@@ -287,7 +297,7 @@ Uart::write(MemReqPtr &req, const uint8_t *data)
     switch (daddr) {
         case 0x0:
             if (!(LCR & 0x80)) { // write byte
-                cons->out(*(uint64_t *)data);
+                cons->out(*(uint8_t *)data);
                 platform->clearConsoleInt();
                 status &= ~TX_INT;
                 if (UART_IER_THRI & IER)
@@ -395,7 +405,7 @@ Uart::serialize(ostream &os)
     if (txIntrEvent.scheduled())
         txintrwhen = txIntrEvent.when();
     else
-        rxintrwhen = 0;
+        txintrwhen = 0;
      SERIALIZE_SCALAR(rxintrwhen);
      SERIALIZE_SCALAR(txintrwhen);
 #endif