Get rid of the xc from the alphaAccess/alphaConsole backdoor device.
Now allocate an array of stacks indexed by cpu number which specify cpu stacks and are initialized by cpu 0. Othe cpus spin waiting for their stacks before continuing. This change *REQUIRES* a the new console code to operate correctly. arch/alpha/ev5.cc: Add cpuId to initCPU/initIPR functions cpu/o3/cpu.cc: cpu/simple/cpu.cc: cpu/simple/cpu.hh: Move the cpu initilization into an init() function since it now needs the CPU id which isn't known at construction dev/alpha_access.h: dev/alpha_console.cc: dev/alpha_console.hh: instead of the bootstrap variables, add space for 64 cpu stacks in the alpha access structure. sim/system.cc: start all cpus immediately rather than just the first one --HG-- extra : convert_revision : 28c218af49d885a0f203ada419f16f25d5a3f37b
This commit is contained in:
parent
7b42d61f13
commit
1166d4f0bf
8 changed files with 48 additions and 45 deletions
|
@ -70,12 +70,15 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow)
|
|||
// Machine dependent functions
|
||||
//
|
||||
void
|
||||
AlphaISA::initCPU(RegFile *regs)
|
||||
AlphaISA::initCPU(RegFile *regs, int cpuId)
|
||||
{
|
||||
initIPRs(regs);
|
||||
initIPRs(regs, cpuId);
|
||||
// CPU comes up with PAL regs enabled
|
||||
swap_palshadow(regs, true);
|
||||
|
||||
regs->intRegFile[16] = cpuId;
|
||||
regs->intRegFile[0] = cpuId;
|
||||
|
||||
regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault];
|
||||
regs->npc = regs->pc + sizeof(MachInst);
|
||||
}
|
||||
|
@ -116,13 +119,14 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = {
|
|||
//
|
||||
//
|
||||
void
|
||||
AlphaISA::initIPRs(RegFile *regs)
|
||||
AlphaISA::initIPRs(RegFile *regs, int cpuId)
|
||||
{
|
||||
uint64_t *ipr = regs->ipr;
|
||||
|
||||
bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
|
||||
ipr[IPR_PAL_BASE] = PalBase;
|
||||
ipr[IPR_MCSR] = 0x6;
|
||||
ipr[IPR_PALtemp16] = cpuId;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -137,8 +137,6 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms)
|
|||
system->execContexts[i] =
|
||||
new ExecContext(this, i, system, itb, dtb, mem);
|
||||
|
||||
// initialize CPU, including PC
|
||||
TheISA::initCPU(&system->execContexts[i]->regs);
|
||||
execContexts.push_back(system->execContexts[i]);
|
||||
#else
|
||||
if (i < params.workload.size()) {
|
||||
|
@ -250,6 +248,7 @@ FullO3CPU<Impl>::init()
|
|||
// that it can start properly.
|
||||
#if FULL_SYSTEM
|
||||
ExecContext *src_xc = system->execContexts[0];
|
||||
TheISA::initCPU(&src_xc->regs, src_xc->cpu_id);
|
||||
#else
|
||||
ExecContext *src_xc = thread[0];
|
||||
#endif
|
||||
|
|
|
@ -84,6 +84,21 @@ SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SimpleCPU::init()
|
||||
{
|
||||
BaseCPU::init();
|
||||
#if FULL_SYSTEM
|
||||
for (int i = 0; i < execContexts.size(); ++i) {
|
||||
ExecContext *xc = execContexts[i];
|
||||
|
||||
// initialize CPU, including PC
|
||||
TheISA::initCPU(&xc->regs, xc->cpu_id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SimpleCPU::TickEvent::process()
|
||||
{
|
||||
|
@ -124,8 +139,6 @@ SimpleCPU::SimpleCPU(Params *p)
|
|||
#if FULL_SYSTEM
|
||||
xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
|
||||
|
||||
// initialize CPU, including PC
|
||||
TheISA::initCPU(&xc->regs);
|
||||
#else
|
||||
xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
|
||||
#endif // !FULL_SYSTEM
|
||||
|
|
|
@ -66,6 +66,7 @@ class SimpleCPU : public BaseCPU
|
|||
public:
|
||||
// main simulation loop (one cycle)
|
||||
void tick();
|
||||
virtual void init();
|
||||
|
||||
private:
|
||||
struct TickEvent : public Event
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* System Console Memory Mapped Register Definition
|
||||
*/
|
||||
|
||||
#define ALPHA_ACCESS_VERSION (1303)
|
||||
#define ALPHA_ACCESS_VERSION (1305)
|
||||
|
||||
#ifdef CONSOLE
|
||||
typedef unsigned uint32_t;
|
||||
|
@ -67,9 +67,7 @@ struct AlphaAccess
|
|||
uint64_t inputChar; // 68: Placeholder for input
|
||||
|
||||
// MP boot
|
||||
uint64_t bootStrapImpure; // 70:
|
||||
uint32_t bootStrapCPU; // 78:
|
||||
uint32_t align2; // 7C: Dummy placeholder for alignment
|
||||
uint64_t cpuStack[64]; // 70:
|
||||
};
|
||||
|
||||
#endif // __ALPHA_ACCESS_H__
|
||||
|
|
|
@ -80,9 +80,7 @@ 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));
|
||||
|
||||
system->setAlphaAccess(addr);
|
||||
}
|
||||
|
@ -122,9 +120,6 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
|||
case offsetof(AlphaAccess, numCPUs):
|
||||
*(uint32_t*)data = alphaAccess->numCPUs;
|
||||
break;
|
||||
case offsetof(AlphaAccess, bootStrapCPU):
|
||||
*(uint32_t*)data = alphaAccess->bootStrapCPU;
|
||||
break;
|
||||
case offsetof(AlphaAccess, intrClockFrequency):
|
||||
*(uint32_t*)data = alphaAccess->intrClockFrequency;
|
||||
break;
|
||||
|
@ -175,11 +170,14 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
|||
case offsetof(AlphaAccess, outputChar):
|
||||
*(uint64_t*)data = alphaAccess->outputChar;
|
||||
break;
|
||||
case offsetof(AlphaAccess, bootStrapImpure):
|
||||
*(uint64_t*)data = alphaAccess->bootStrapImpure;
|
||||
break;
|
||||
default:
|
||||
panic("Unknown 64bit access, %#x\n", daddr);
|
||||
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
|
||||
sizeof(alphaAccess->cpuStack[0]);
|
||||
|
||||
if (cpunum >= 0 && cpunum < 64)
|
||||
*(uint64_t*)data = alphaAccess->cpuStack[cpunum];
|
||||
else
|
||||
panic("Unknown 64bit access, %#x\n", daddr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -239,24 +237,18 @@ 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;
|
||||
|
@ -287,8 +279,7 @@ AlphaConsole::Access::serialize(ostream &os)
|
|||
SERIALIZE_SCALAR(diskOperation);
|
||||
SERIALIZE_SCALAR(outputChar);
|
||||
SERIALIZE_SCALAR(inputChar);
|
||||
SERIALIZE_SCALAR(bootStrapImpure);
|
||||
SERIALIZE_SCALAR(bootStrapCPU);
|
||||
SERIALIZE_ARRAY(cpuStack,64);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -310,8 +301,7 @@ AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(diskOperation);
|
||||
UNSERIALIZE_SCALAR(outputChar);
|
||||
UNSERIALIZE_SCALAR(inputChar);
|
||||
UNSERIALIZE_SCALAR(bootStrapImpure);
|
||||
UNSERIALIZE_SCALAR(bootStrapCPU);
|
||||
UNSERIALIZE_ARRAY(cpuStack, 64);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -96,7 +96,7 @@ class AlphaConsole : public PioDevice
|
|||
BaseCPU *cpu;
|
||||
|
||||
Addr addr;
|
||||
static const Addr size = 0x80; // equal to sizeof(alpha_access);
|
||||
static const Addr size = sizeof(struct AlphaAccess);
|
||||
|
||||
public:
|
||||
/** Standard Constructor */
|
||||
|
|
|
@ -306,11 +306,9 @@ System::registerExecContext(ExecContext *xc, int id)
|
|||
void
|
||||
System::startup()
|
||||
{
|
||||
if (!execContexts.empty()) {
|
||||
// activate with zero delay so that we start ticking right
|
||||
// away on cycle 0
|
||||
execContexts[0]->activate(0);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < execContexts.size(); i++)
|
||||
execContexts[i]->activate(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue