#include <cstdio>
#include <string>
+#include "arch/alpha/system.hh"
#include "base/inifile.hh"
#include "base/str.hh"
#include "base/trace.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/tsunami_io.hh"
-#include "mem/bus/bus.hh"
-#include "mem/bus/pio_interface.hh"
-#include "mem/bus/pio_interface_impl.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
+#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
-#include "sim/system.hh"
using namespace std;
+using namespace AlphaISA;
-AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
- System *s, BaseCPU *c, Platform *p,
- MemoryController *mmu, Addr a,
- HierParams *hier, Bus *pio_bus)
- : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), 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 (pio_bus) {
- pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this,
- &AlphaConsole::cacheAccess);
- pioInterface->addAddrRange(RangeSize(addr, size));
- }
+ pioSize = sizeof(struct AlphaAccess);
- alphaAccess = new Access;
- alphaAccess->last_offset = size - 1;
+ alphaAccess = new Access();
+ alphaAccess->last_offset = pioSize - 1;
alphaAccess->version = ALPHA_ACCESS_VERSION;
alphaAccess->diskUnit = 1;
alphaAccess->diskOperation = 0;
alphaAccess->outputChar = 0;
alphaAccess->inputChar = 0;
- alphaAccess->bootStrapImpure = 0;
- alphaAccess->bootStrapCPU = 0;
- alphaAccess->align2 = 0;
+ bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack));
- system->setAlphaAccess(addr);
}
void
AlphaConsole::startup()
{
+ 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 = platform->intrFrequency();
+ alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
}
-Fault *
-AlphaConsole::read(MemReqPtr &req, uint8_t *data)
+Tick
+AlphaConsole::read(Packet &pkt)
{
- memset(data, 0, req->size);
- Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
+ /** 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?
+ */
+
+ assert(pkt.result == Unknown);
+ assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
+
+ pkt.time = curTick + pioDelay;
+ Addr daddr = pkt.addr - pioAddr;
- switch (req->size)
+ 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 MachineCheckFault;
+ pkt.result = BadAddress;
}
-
- return NoFault;
+ 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 MachineCheckFault;
- }
+ 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):
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 MachineCheckFault;
+ 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 NoFault;
-}
+ pkt.result = Success;
-Tick
-AlphaConsole::cacheAccess(MemReqPtr &req)
-{
- return curTick + 1000;
+ return pioDelay;
}
void
SERIALIZE_SCALAR(diskOperation);
SERIALIZE_SCALAR(outputChar);
SERIALIZE_SCALAR(inputChar);
- SERIALIZE_SCALAR(bootStrapImpure);
- SERIALIZE_SCALAR(bootStrapCPU);
+ SERIALIZE_ARRAY(cpuStack,64);
}
void
UNSERIALIZE_SCALAR(diskOperation);
UNSERIALIZE_SCALAR(outputChar);
UNSERIALIZE_SCALAR(inputChar);
- UNSERIALIZE_SCALAR(bootStrapImpure);
- UNSERIALIZE_SCALAR(bootStrapCPU);
+ UNSERIALIZE_ARRAY(cpuStack, 64);
}
void
SimObjectParam<SimConsole *> sim_console;
SimObjectParam<SimpleDisk *> disk;
- SimObjectParam<MemoryController *> mmu;
- Param<Addr> addr;
- SimObjectParam<System *> system;
+ Param<Addr> pio_addr;
+ SimObjectParam<AlphaSystem *> system;
SimObjectParam<BaseCPU *> cpu;
SimObjectParam<Platform *> platform;
- SimObjectParam<Bus*> pio_bus;
Param<Tick> pio_latency;
- SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
INIT_PARAM(sim_console, "The Simulator Console"),
INIT_PARAM(disk, "Simple Disk"),
- 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(pio_bus, "The IO Bus to attach to"),
- 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, mmu, addr, hier, pio_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)