add support for simple character input via the system console
authorNathan Binkert <binkertn@umich.edu>
Mon, 22 Dec 2003 22:51:14 +0000 (17:51 -0500)
committerNathan Binkert <binkertn@umich.edu>
Mon, 22 Dec 2003 22:51:14 +0000 (17:51 -0500)
dev/alpha_access.h:
    -  use our standard types instead of this extra typedef
    -  advance the ALPHA_ACCESS version since the interface
    has changed.  *this means you need a new console binary*
    -  shuffle a couple things around to pack the data structure
    a bit better
    -  add a placeholder for character input
dev/alpha_console.cc:
    Clean up the read code path a bit and add support for character
    input via the console

    Clean up the write path and use a switch instead of a bunch of
    if statements

--HG--
extra : convert_revision : a1a5bc8fed9ec9c4c46548fdf79604661668b81a

dev/alpha_access.h
dev/alpha_console.cc
dev/console.cc
dev/console.hh

index eb551a3599600799ae8cf9c41b3ec900377fd632..7502635e92bf992efd742c9d0ae4cebc6a436373 100644 (file)
  * System Console Memory Mapped Register Definition
  */
 
-#define ALPHA_ACCESS_VERSION (1291+1) /* CH++*/
-
-#ifdef CONSOLE
-typedef uint32 UINT32;
-typedef uint64 UINT64;
-#else
-typedef uint32_t UINT32;
-typedef uint64_t UINT64;
+#define ALPHA_ACCESS_VERSION (1301) /* CH++*/
 
+#ifndef CONSOLE
 #include <ostream>
 #include <string>
 class Checkpoint;
-
 #endif
 
 // This structure hacked up from simos
 struct AlphaAccess
 {
-    UINT32     last_offset;            // 00: must be first field
-    UINT32     version;                // 04:
-    UINT32     numCPUs;                // 08:
-    UINT32     align0;                 // 0C: Placeholder for alignment
-    UINT64     mem_size;               // 10:
-    UINT64     cpuClock;               // 18: MHz
-    UINT32     intrClockFrequency;     // 20: Hz
-    UINT32     align1;                 // 24: Placeholder for alignment
+    uint32_t   last_offset;            // 00: must be first field
+    uint32_t   version;                // 04:
+    uint32_t   numCPUs;                // 08:
+    uint32_t   intrClockFrequency;     // 0C: Hz
+    uint64_t   cpuClock;               // 10: MHz
+    uint64_t   mem_size;               // 18:
 
     // Loaded kernel
-    UINT64     kernStart;              // 28:
-    UINT64     kernEnd;                // 30:
-    UINT64     entryPoint;             // 38:
+    uint64_t   kernStart;              // 20:
+    uint64_t   kernEnd;                // 28:
+    uint64_t   entryPoint;             // 30:
 
     // console disk stuff
-    UINT64     diskUnit;               // 40:
-    UINT64     diskCount;              // 48:
-    UINT64     diskPAddr;              // 50:
-    UINT64     diskBlock;              // 58:
-    UINT64     diskOperation;          // 60:
+    uint64_t   diskUnit;               // 38:
+    uint64_t   diskCount;              // 40:
+    uint64_t   diskPAddr;              // 48:
+    uint64_t   diskBlock;              // 50:
+    uint64_t   diskOperation;          // 58:
 
     // console simple output stuff
-    UINT64     outputChar;             // 68:
+    uint64_t   outputChar;             // 60: Placeholder for output
+    uint64_t   inputChar;              // 68: Placeholder for input
 
     // MP boot
-    UINT64     bootStrapImpure;        // 70:
-    UINT32     bootStrapCPU;           // 78:
-    UINT32     align2;                 // 7C: Dummy placeholder for alignment
+    uint64_t   bootStrapImpure;        // 70:
+    uint32_t   bootStrapCPU;           // 78:
+    uint32_t   align2;                 // 7C: Dummy placeholder for alignment
 
 #ifndef CONSOLE
     void serialize(std::ostream &os);
index 268370b0ef7dfdc26c14639b8fb57678732e4c9e..ccf6c33fd3582ad86112119b26604fb6b3b6c2ec 100644 (file)
@@ -76,17 +76,35 @@ Fault
 AlphaConsole::read(MemReqPtr req, uint8_t *data)
 {
     memset(data, 0, req->size);
+    uint64_t val;
+
+    Addr daddr = req->paddr & addr_mask;
+    switch (daddr) {
+      case offsetof(AlphaAccess, inputChar):
+        val = console->in();
+        break;
+
+      default:
+        val = *(uint64_t *)(consoleData + daddr);
+        break;
+    }
+
+    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);
+
+    switch (req->size) {
+      case sizeof(uint32_t):
+        *(uint32_t *)data = (uint32_t)val;
+        break;
 
-    if (req->size == sizeof(uint32_t)) {
-        Addr daddr = req->paddr & addr_mask;
-        *(uint32_t *)data = *(uint32_t *)(consoleData + daddr);
+      case sizeof(uint64_t):
+        *(uint64_t *)data = val;
+        break;
 
-#if 0
-        DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n",
-                daddr, *(uint32_t *)data);
-#endif
+      default:
+        return Machine_Check_Fault;
     }
 
+
     return No_Fault;
 }
 
@@ -99,6 +117,7 @@ AlphaConsole::write(MemReqPtr req, const uint8_t *data)
       case sizeof(uint32_t):
         val = *(uint32_t *)data;
         break;
+
       case sizeof(uint64_t):
         val = *(uint64_t *)data;
         break;
@@ -106,60 +125,57 @@ AlphaConsole::write(MemReqPtr req, const uint8_t *data)
         return Machine_Check_Fault;
     }
 
-    Addr paddr = req->paddr & addr_mask;
+    Addr daddr = req->paddr & addr_mask;
+    ExecContext *other_xc;
 
-    if (paddr == offsetof(AlphaAccess, diskUnit)) {
+    switch (daddr) {
+      case offsetof(AlphaAccess, diskUnit):
         alphaAccess->diskUnit = val;
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, diskCount)) {
+      case offsetof(AlphaAccess, diskCount):
         alphaAccess->diskCount = val;
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, diskPAddr)) {
+      case offsetof(AlphaAccess, diskPAddr):
         alphaAccess->diskPAddr = val;
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, diskBlock)) {
+      case offsetof(AlphaAccess, diskBlock):
         alphaAccess->diskBlock = val;
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, diskOperation)) {
+      case offsetof(AlphaAccess, diskOperation):
         if (val == 0x13)
             disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
                        alphaAccess->diskCount);
         else
             panic("Invalid disk operation!");
 
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, outputChar)) {
+      case offsetof(AlphaAccess, outputChar):
         console->out((char)(val & 0xff), false);
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, bootStrapImpure)) {
+      case offsetof(AlphaAccess, bootStrapImpure):
         alphaAccess->bootStrapImpure = val;
-        return No_Fault;
-    }
+        break;
 
-    if (paddr == offsetof(AlphaAccess, bootStrapCPU)) {
+      case offsetof(AlphaAccess, bootStrapCPU):
         warn("%d: Trying to launch another CPU!", curTick);
-        int cpu = val;
-        assert(cpu > 0 && "Must not access primary cpu");
+        assert(val > 0 && "Must not access primary cpu");
 
-        ExecContext *other_xc = req->xc->system->execContexts[cpu];
-        other_xc->regs.intRegFile[16] = cpu;
-        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = cpu;
-        other_xc->regs.intRegFile[0] = cpu;
+        other_xc = req->xc->system->execContexts[val];
+        other_xc->regs.intRegFile[16] = val;
+        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
+        other_xc->regs.intRegFile[0] = val;
         other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
         other_xc->activate(); //Start the cpu
-        return No_Fault;
+        break;
+
+      default:
+        return Machine_Check_Fault;
     }
 
     return No_Fault;
@@ -183,6 +199,7 @@ AlphaAccess::serialize(ostream &os)
     SERIALIZE_SCALAR(diskBlock);
     SERIALIZE_SCALAR(diskOperation);
     SERIALIZE_SCALAR(outputChar);
+    SERIALIZE_SCALAR(inputChar);
     SERIALIZE_SCALAR(bootStrapImpure);
     SERIALIZE_SCALAR(bootStrapCPU);
 }
@@ -205,6 +222,7 @@ AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(diskBlock);
     UNSERIALIZE_SCALAR(diskOperation);
     UNSERIALIZE_SCALAR(outputChar);
+    UNSERIALIZE_SCALAR(inputChar);
     UNSERIALIZE_SCALAR(bootStrapImpure);
     UNSERIALIZE_SCALAR(bootStrapCPU);
 }
index ab2a284aa85e08f73f272cf597a6c69451b4b9ce..f4156207dfb1071785a21c1536cef6c91c735b51 100644 (file)
@@ -223,21 +223,32 @@ SimConsole::configTerm()
     }
 }
 
-int
+#define MORE_PENDING (ULL(1) << 61)
+#define RECEIVE_SUCCESS (ULL(0) << 62)
+#define RECEIVE_NONE (ULL(2) << 62)
+#define RECEIVE_ERROR (ULL(3) << 62)
+
+uint64_t
 SimConsole::in()
 {
+    char c = 0;
+    uint64_t val = 0;
     if (rxbuf.empty()) {
         clearInt(ReceiveInterrupt);
-        return -1;
+        val |= RECEIVE_NONE;
+        return 0x8;
+    } else {
+        uint64_t val;
+        rxbuf.read(&c, 1);
+        val |= RECEIVE_SUCCESS | c;
+        if (!rxbuf.empty())
+            val |= MORE_PENDING;
     }
 
-    char c;
-    rxbuf.read(&c, 1);
-
-    DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x status: %#x\n",
-            isprint(c) ? c : ' ', c, _status);
+    DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x retval: %#x\n",
+            isprint(c) ? c : ' ', c, val);
 
-    return c;
+    return val;
 }
 
 void
index f443afe4ff54b32a533a8ada5c08b188b894e039..9913fe379bc2f5ab7f49e3a2e13fa937931e6225 100644 (file)
@@ -109,9 +109,17 @@ class SimConsole : public SimObject
     // OS interface
 
     // Get a character from the console.
-    // return of -1 means there is no character pending.
+    // the return value corresponds to the console GETC return value:
+    // retval<63:61>
+    //     000: success: character received
+    //     001: success: character received, more pending
+    //     100: failure: no character ready
+    //     110: failure: character received with error
+    //     111: failure: character received with error, more pending
+    // retval<31:0>
+    //     character read from console
     // Interrupts are cleared when the buffer is empty.
-    int in();
+    uint64_t in();
 
     // Send a character to the console
     void out(char c, bool raise_int = true);