Changed the hello_sparc executable back to the cross compiled one
[gem5.git] / dev / alpha_console.cc
index 8309ea16d153a8d167cbe30b9894e9b556074573..fde8af6ae1c0c1f6ce700eb2db6cfddc3fabe3b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2004 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* @file
- * System Console Definition
+/** @file
+ * Alpha Console Definition
  */
 
 #include <cstddef>
 #include <cstdio>
 #include <string>
 
+#include "arch/alpha/system.hh"
 #include "base/inifile.hh"
-#include "base/str.hh" // for to_number()
+#include "base/str.hh"
 #include "base/trace.hh"
-#include "cpu/base_cpu.hh"
+#include "cpu/base.hh"
 #include "cpu/exec_context.hh"
 #include "dev/alpha_console.hh"
+#include "dev/platform.hh"
 #include "dev/simconsole.hh"
 #include "dev/simple_disk.hh"
-#include "dev/tlaser_clock.hh"
-#include "mem/bus/bus.hh"
-#include "mem/bus/pio_interface.hh"
-#include "mem/bus/pio_interface_impl.hh"
-#include "mem/functional_mem/memory_control.hh"
+#include "mem/physical.hh"
 #include "sim/builder.hh"
-#include "sim/system.hh"
-#include "dev/tsunami_io.hh"
 #include "sim/sim_object.hh"
-#include "targetarch/byte_swap.hh"
 
 using namespace std;
+using namespace AlphaISA;
 
-AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
-                           System *system, BaseCPU *cpu, Platform *p,
-                           int num_cpus, MemoryController *mmu, Addr a,
-                           HierParams *hier, Bus *bus)
-    : PioDevice(name, p), disk(d), console(cons), addr(a)
+AlphaConsole::AlphaConsole(Params *p)
+    : BasicPioDevice(p), disk(p->disk),
+      console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu)
 {
-    mmu->add_child(this, RangeSize(addr, size));
 
-    if (bus) {
-        pioInterface = newPioInterface(name, hier, bus, this,
-                                       &AlphaConsole::cacheAccess);
-        pioInterface->addAddrRange(RangeSize(addr, size));
-    }
+    pioSize = sizeof(struct AlphaAccess);
 
-    alphaAccess = new AlphaAccess;
-    alphaAccess->last_offset = size - 1;
-    alphaAccess->kernStart = system->getKernelStart();
-    alphaAccess->kernEnd = system->getKernelEnd();
-    alphaAccess->entryPoint = system->getKernelEntry();
+    alphaAccess = new Access();
+    alphaAccess->last_offset = pioSize - 1;
 
     alphaAccess->version = ALPHA_ACCESS_VERSION;
-    alphaAccess->numCPUs = num_cpus;
-    alphaAccess->mem_size = system->physmem->size();
-    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
-    alphaAccess->intrClockFrequency = platform->intrFrequency();
     alphaAccess->diskUnit = 1;
 
     alphaAccess->diskCount = 0;
@@ -88,118 +70,145 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
     alphaAccess->diskOperation = 0;
     alphaAccess->outputChar = 0;
     alphaAccess->inputChar = 0;
-    alphaAccess->bootStrapImpure = 0;
-    alphaAccess->bootStrapCPU = 0;
-    alphaAccess->align2 = 0;
+    bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack));
+
 }
 
-Fault
-AlphaConsole::read(MemReqPtr &req, uint8_t *data)
+void
+AlphaConsole::startup()
 {
-    memset(data, 0, req->size);
+    system->setAlphaAccess(pioAddr);
+    alphaAccess->numCPUs = system->getNumCPUs();
+    alphaAccess->kernStart = system->getKernelStart();
+    alphaAccess->kernEnd = system->getKernelEnd();
+    alphaAccess->entryPoint = system->getKernelEntry();
+    alphaAccess->mem_size = system->physmem->size();
+    alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
+    alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
+}
+
+Tick
+AlphaConsole::read(Packet &pkt)
+{
+
+    /** XXX Do we want to push the addr munging to a bus brige or something? So
+     * the device has it's physical address and then the bridge adds on whatever
+     * machine dependent address swizzle is required?
+     */
 
-    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
+    assert(pkt.result == Unknown);
+    assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
 
-    switch (req->size)
+    pkt.time = curTick + pioDelay;
+    Addr daddr = pkt.addr - pioAddr;
+
+    uint32_t *data32;
+    uint64_t *data64;
+
+    switch (pkt.size)
     {
         case sizeof(uint32_t):
-            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data);
+            if (!pkt.data) {
+                data32 = new uint32_t;
+                pkt.data = (uint8_t*)data32;
+            } else
+                data32 = (uint32_t*)pkt.data;
+
             switch (daddr)
             {
                 case offsetof(AlphaAccess, last_offset):
-                    *(uint32_t*)data = alphaAccess->last_offset;
+                    *data32 = alphaAccess->last_offset;
                     break;
                 case offsetof(AlphaAccess, version):
-                    *(uint32_t*)data = alphaAccess->version;
+                    *data32 = alphaAccess->version;
                     break;
                 case offsetof(AlphaAccess, numCPUs):
-                    *(uint32_t*)data = alphaAccess->numCPUs;
-                    break;
-                case offsetof(AlphaAccess, bootStrapCPU):
-                    *(uint32_t*)data = alphaAccess->bootStrapCPU;
+                    *data32 = alphaAccess->numCPUs;
                     break;
                 case offsetof(AlphaAccess, intrClockFrequency):
-                    *(uint32_t*)data = alphaAccess->intrClockFrequency;
+                    *data32 = alphaAccess->intrClockFrequency;
                     break;
                 default:
-                    // Old console code read in everyting as a 32bit int
-                    *(uint32_t*)data = *(uint32_t*)(consoleData + daddr);
-
+                    /* Old console code read in everyting as a 32bit int
+                     * we now break that for better error checking.
+                     */
+                    pkt.result = BadAddress;
             }
+            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data32);
             break;
         case sizeof(uint64_t):
-            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data);
+            if (!pkt.data) {
+                data64 = new uint64_t;
+                pkt.data = (uint8_t*)data64;
+            } else
+                data64 = (uint64_t*)pkt.data;
             switch (daddr)
             {
                 case offsetof(AlphaAccess, inputChar):
-                    *(uint64_t*)data = console->console_in();
+                    *data64 = console->console_in();
                     break;
                 case offsetof(AlphaAccess, cpuClock):
-                    *(uint64_t*)data = alphaAccess->cpuClock;
+                    *data64 = alphaAccess->cpuClock;
                     break;
                 case offsetof(AlphaAccess, mem_size):
-                    *(uint64_t*)data = alphaAccess->mem_size;
+                    *data64 = alphaAccess->mem_size;
                     break;
                 case offsetof(AlphaAccess, kernStart):
-                    *(uint64_t*)data = alphaAccess->kernStart;
+                    *data64 = alphaAccess->kernStart;
                     break;
                 case offsetof(AlphaAccess, kernEnd):
-                    *(uint64_t*)data = alphaAccess->kernEnd;
+                    *data64 = alphaAccess->kernEnd;
                     break;
                 case offsetof(AlphaAccess, entryPoint):
-                    *(uint64_t*)data = alphaAccess->entryPoint;
+                    *data64 = alphaAccess->entryPoint;
                     break;
                 case offsetof(AlphaAccess, diskUnit):
-                    *(uint64_t*)data = alphaAccess->diskUnit;
+                    *data64 = alphaAccess->diskUnit;
                     break;
                 case offsetof(AlphaAccess, diskCount):
-                    *(uint64_t*)data = alphaAccess->diskCount;
+                    *data64 = alphaAccess->diskCount;
                     break;
                 case offsetof(AlphaAccess, diskPAddr):
-                    *(uint64_t*)data = alphaAccess->diskPAddr;
+                    *data64 = alphaAccess->diskPAddr;
                     break;
                 case offsetof(AlphaAccess, diskBlock):
-                    *(uint64_t*)data = alphaAccess->diskBlock;
+                    *data64 = alphaAccess->diskBlock;
                     break;
                 case offsetof(AlphaAccess, diskOperation):
-                    *(uint64_t*)data = alphaAccess->diskOperation;
+                    *data64 = alphaAccess->diskOperation;
                     break;
                 case offsetof(AlphaAccess, outputChar):
-                    *(uint64_t*)data = alphaAccess->outputChar;
-                    break;
-                case offsetof(AlphaAccess, bootStrapImpure):
-                    *(uint64_t*)data = alphaAccess->bootStrapImpure;
+                    *data64 = alphaAccess->outputChar;
                     break;
                 default:
-                    panic("Unknown 64bit access, %#x\n", daddr);
+                    int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
+                                 sizeof(alphaAccess->cpuStack[0]);
+
+                    if (cpunum >= 0 && cpunum < 64)
+                        *data64 = alphaAccess->cpuStack[cpunum];
+                    else
+                        panic("Unknown 64bit access, %#x\n", daddr);
             }
+            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64);
             break;
         default:
-            return Machine_Check_Fault;
+            pkt.result = BadAddress;
     }
-
-    return No_Fault;
+    if (pkt.result == Unknown) pkt.result = Success;
+    return pioDelay;
 }
 
-Fault
-AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
+Tick
+AlphaConsole::write(Packet &pkt)
 {
-    uint64_t val;
-
-    switch (req->size) {
-      case sizeof(uint32_t):
-        val = *(uint32_t *)data;
-        break;
+    pkt.time = curTick + pioDelay;
 
-      case sizeof(uint64_t):
-        val = *(uint64_t *)data;
-        break;
-      default:
-        return Machine_Check_Fault;
-    }
+    assert(pkt.result == Unknown);
+    assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
+    Addr daddr = pkt.addr - pioAddr;
 
-    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
-    ExecContext *other_xc;
+    uint64_t val = *(uint64_t *)pkt.data;
+    assert(pkt.size == sizeof(uint64_t));
 
     switch (daddr) {
       case offsetof(AlphaAccess, diskUnit):
@@ -231,37 +240,24 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
         console->out((char)(val & 0xff));
         break;
 
-      case offsetof(AlphaAccess, bootStrapImpure):
-        alphaAccess->bootStrapImpure = val;
-        break;
-
-      case offsetof(AlphaAccess, bootStrapCPU):
-        warn("%d: Trying to launch another CPU!", curTick);
-        assert(val > 0 && "Must not access primary 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
-        break;
-
       default:
-        return Machine_Check_Fault;
+        int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
+                     sizeof(alphaAccess->cpuStack[0]);
+        warn("%d: Trying to launch CPU number %d!", curTick, cpunum);
+        assert(val > 0 && "Must not access primary cpu");
+        if (cpunum >= 0 && cpunum < 64)
+            alphaAccess->cpuStack[cpunum] = val;
+        else
+            panic("Unknown 64bit access, %#x\n", daddr);
     }
 
-    return No_Fault;
-}
+    pkt.result = Success;
 
-Tick
-AlphaConsole::cacheAccess(MemReqPtr &req)
-{
-    return curTick + 1000;
+    return pioDelay;
 }
 
 void
-AlphaAccess::serialize(ostream &os)
+AlphaConsole::Access::serialize(ostream &os)
 {
     SERIALIZE_SCALAR(last_offset);
     SERIALIZE_SCALAR(version);
@@ -279,12 +275,11 @@ AlphaAccess::serialize(ostream &os)
     SERIALIZE_SCALAR(diskOperation);
     SERIALIZE_SCALAR(outputChar);
     SERIALIZE_SCALAR(inputChar);
-    SERIALIZE_SCALAR(bootStrapImpure);
-    SERIALIZE_SCALAR(bootStrapCPU);
+    SERIALIZE_ARRAY(cpuStack,64);
 }
 
 void
-AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
+AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string &section)
 {
     UNSERIALIZE_SCALAR(last_offset);
     UNSERIALIZE_SCALAR(version);
@@ -302,8 +297,7 @@ AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(diskOperation);
     UNSERIALIZE_SCALAR(outputChar);
     UNSERIALIZE_SCALAR(inputChar);
-    UNSERIALIZE_SCALAR(bootStrapImpure);
-    UNSERIALIZE_SCALAR(bootStrapCPU);
+    UNSERIALIZE_ARRAY(cpuStack, 64);
 }
 
 void
@@ -322,15 +316,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
 
     SimObjectParam<SimConsole *> sim_console;
     SimObjectParam<SimpleDisk *> disk;
-    Param<int> num_cpus;
-    SimObjectParam<MemoryController *> mmu;
-    Param<Addr> addr;
-    SimObjectParam<System *> system;
+    Param<Addr> pio_addr;
+    SimObjectParam<AlphaSystem *> system;
     SimObjectParam<BaseCPU *> cpu;
     SimObjectParam<Platform *> platform;
-    SimObjectParam<Bus*> io_bus;
     Param<Tick> pio_latency;
-    SimObjectParam<HierParams *> hier;
 
 END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
 
@@ -338,23 +328,27 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
 
     INIT_PARAM(sim_console, "The Simulator Console"),
     INIT_PARAM(disk, "Simple Disk"),
-    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
-    INIT_PARAM(mmu, "Memory Controller"),
-    INIT_PARAM(addr, "Device Address"),
+    INIT_PARAM(pio_addr, "Device Address"),
     INIT_PARAM(system, "system object"),
     INIT_PARAM(cpu, "Processor"),
     INIT_PARAM(platform, "platform"),
-    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
-    INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
-    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
+    INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000)
 
 END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
 
 CREATE_SIM_OBJECT(AlphaConsole)
 {
-    return new AlphaConsole(getInstanceName(), sim_console, disk,
-                            system, cpu, platform, num_cpus, mmu,
-                            addr, hier, io_bus);
+    AlphaConsole::Params *p = new AlphaConsole::Params;
+    p->name = getInstanceName();
+    p->platform = platform;
+    p->pio_addr = pio_addr;
+    p->pio_delay = pio_latency;
+    p->cons = sim_console;
+    p->disk = disk;
+    p->alpha_sys = system;
+    p->system = system;
+    p->cpu = cpu;
+    return new AlphaConsole(p);
 }
 
 REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)