diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/alpha_access.h | 50 | ||||
-rw-r--r-- | dev/alpha_console.cc | 92 | ||||
-rw-r--r-- | dev/console.cc | 27 | ||||
-rw-r--r-- | dev/console.hh | 12 |
4 files changed, 105 insertions, 76 deletions
diff --git a/dev/alpha_access.h b/dev/alpha_access.h index eb551a359..7502635e9 100644 --- a/dev/alpha_access.h +++ b/dev/alpha_access.h @@ -33,52 +33,44 @@ * 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); diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 268370b0e..ccf6c33fd 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -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 §ion) UNSERIALIZE_SCALAR(diskBlock); UNSERIALIZE_SCALAR(diskOperation); UNSERIALIZE_SCALAR(outputChar); + UNSERIALIZE_SCALAR(inputChar); UNSERIALIZE_SCALAR(bootStrapImpure); UNSERIALIZE_SCALAR(bootStrapCPU); } diff --git a/dev/console.cc b/dev/console.cc index ab2a284aa..f4156207d 100644 --- a/dev/console.cc +++ b/dev/console.cc @@ -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 diff --git a/dev/console.hh b/dev/console.hh index f443afe4f..9913fe379 100644 --- a/dev/console.hh +++ b/dev/console.hh @@ -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); |