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
|
// Machine dependent functions
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
AlphaISA::initCPU(RegFile *regs)
|
AlphaISA::initCPU(RegFile *regs, int cpuId)
|
||||||
{
|
{
|
||||||
initIPRs(regs);
|
initIPRs(regs, cpuId);
|
||||||
// CPU comes up with PAL regs enabled
|
// CPU comes up with PAL regs enabled
|
||||||
swap_palshadow(regs, true);
|
swap_palshadow(regs, true);
|
||||||
|
|
||||||
|
regs->intRegFile[16] = cpuId;
|
||||||
|
regs->intRegFile[0] = cpuId;
|
||||||
|
|
||||||
regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault];
|
regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault];
|
||||||
regs->npc = regs->pc + sizeof(MachInst);
|
regs->npc = regs->pc + sizeof(MachInst);
|
||||||
}
|
}
|
||||||
|
@ -116,13 +119,14 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = {
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
AlphaISA::initIPRs(RegFile *regs)
|
AlphaISA::initIPRs(RegFile *regs, int cpuId)
|
||||||
{
|
{
|
||||||
uint64_t *ipr = regs->ipr;
|
uint64_t *ipr = regs->ipr;
|
||||||
|
|
||||||
bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
|
bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
|
||||||
ipr[IPR_PAL_BASE] = PalBase;
|
ipr[IPR_PAL_BASE] = PalBase;
|
||||||
ipr[IPR_MCSR] = 0x6;
|
ipr[IPR_MCSR] = 0x6;
|
||||||
|
ipr[IPR_PALtemp16] = cpuId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -137,8 +137,6 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms)
|
||||||
system->execContexts[i] =
|
system->execContexts[i] =
|
||||||
new ExecContext(this, i, system, itb, dtb, mem);
|
new ExecContext(this, i, system, itb, dtb, mem);
|
||||||
|
|
||||||
// initialize CPU, including PC
|
|
||||||
TheISA::initCPU(&system->execContexts[i]->regs);
|
|
||||||
execContexts.push_back(system->execContexts[i]);
|
execContexts.push_back(system->execContexts[i]);
|
||||||
#else
|
#else
|
||||||
if (i < params.workload.size()) {
|
if (i < params.workload.size()) {
|
||||||
|
@ -250,6 +248,7 @@ FullO3CPU<Impl>::init()
|
||||||
// that it can start properly.
|
// that it can start properly.
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
ExecContext *src_xc = system->execContexts[0];
|
ExecContext *src_xc = system->execContexts[0];
|
||||||
|
TheISA::initCPU(&src_xc->regs, src_xc->cpu_id);
|
||||||
#else
|
#else
|
||||||
ExecContext *src_xc = thread[0];
|
ExecContext *src_xc = thread[0];
|
||||||
#endif
|
#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
|
void
|
||||||
SimpleCPU::TickEvent::process()
|
SimpleCPU::TickEvent::process()
|
||||||
{
|
{
|
||||||
|
@ -124,8 +139,6 @@ SimpleCPU::SimpleCPU(Params *p)
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
|
xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
|
||||||
|
|
||||||
// initialize CPU, including PC
|
|
||||||
TheISA::initCPU(&xc->regs);
|
|
||||||
#else
|
#else
|
||||||
xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
|
xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
|
||||||
#endif // !FULL_SYSTEM
|
#endif // !FULL_SYSTEM
|
||||||
|
|
|
@ -66,6 +66,7 @@ class SimpleCPU : public BaseCPU
|
||||||
public:
|
public:
|
||||||
// main simulation loop (one cycle)
|
// main simulation loop (one cycle)
|
||||||
void tick();
|
void tick();
|
||||||
|
virtual void init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TickEvent : public Event
|
struct TickEvent : public Event
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
* System Console Memory Mapped Register Definition
|
* System Console Memory Mapped Register Definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ALPHA_ACCESS_VERSION (1303)
|
#define ALPHA_ACCESS_VERSION (1305)
|
||||||
|
|
||||||
#ifdef CONSOLE
|
#ifdef CONSOLE
|
||||||
typedef unsigned uint32_t;
|
typedef unsigned uint32_t;
|
||||||
|
@ -67,9 +67,7 @@ struct AlphaAccess
|
||||||
uint64_t inputChar; // 68: Placeholder for input
|
uint64_t inputChar; // 68: Placeholder for input
|
||||||
|
|
||||||
// MP boot
|
// MP boot
|
||||||
uint64_t bootStrapImpure; // 70:
|
uint64_t cpuStack[64]; // 70:
|
||||||
uint32_t bootStrapCPU; // 78:
|
|
||||||
uint32_t align2; // 7C: Dummy placeholder for alignment
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ALPHA_ACCESS_H__
|
#endif // __ALPHA_ACCESS_H__
|
||||||
|
|
|
@ -80,9 +80,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
||||||
alphaAccess->diskOperation = 0;
|
alphaAccess->diskOperation = 0;
|
||||||
alphaAccess->outputChar = 0;
|
alphaAccess->outputChar = 0;
|
||||||
alphaAccess->inputChar = 0;
|
alphaAccess->inputChar = 0;
|
||||||
alphaAccess->bootStrapImpure = 0;
|
bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack));
|
||||||
alphaAccess->bootStrapCPU = 0;
|
|
||||||
alphaAccess->align2 = 0;
|
|
||||||
|
|
||||||
system->setAlphaAccess(addr);
|
system->setAlphaAccess(addr);
|
||||||
}
|
}
|
||||||
|
@ -122,9 +120,6 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
||||||
case offsetof(AlphaAccess, numCPUs):
|
case offsetof(AlphaAccess, numCPUs):
|
||||||
*(uint32_t*)data = alphaAccess->numCPUs;
|
*(uint32_t*)data = alphaAccess->numCPUs;
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, bootStrapCPU):
|
|
||||||
*(uint32_t*)data = alphaAccess->bootStrapCPU;
|
|
||||||
break;
|
|
||||||
case offsetof(AlphaAccess, intrClockFrequency):
|
case offsetof(AlphaAccess, intrClockFrequency):
|
||||||
*(uint32_t*)data = alphaAccess->intrClockFrequency;
|
*(uint32_t*)data = alphaAccess->intrClockFrequency;
|
||||||
break;
|
break;
|
||||||
|
@ -175,10 +170,13 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
||||||
case offsetof(AlphaAccess, outputChar):
|
case offsetof(AlphaAccess, outputChar):
|
||||||
*(uint64_t*)data = alphaAccess->outputChar;
|
*(uint64_t*)data = alphaAccess->outputChar;
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, bootStrapImpure):
|
|
||||||
*(uint64_t*)data = alphaAccess->bootStrapImpure;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
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);
|
panic("Unknown 64bit access, %#x\n", daddr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -239,24 +237,18 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
|
||||||
console->out((char)(val & 0xff));
|
console->out((char)(val & 0xff));
|
||||||
break;
|
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
|
other_xc->activate(); //Start the cpu
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return No_Fault;
|
||||||
|
@ -287,8 +279,7 @@ AlphaConsole::Access::serialize(ostream &os)
|
||||||
SERIALIZE_SCALAR(diskOperation);
|
SERIALIZE_SCALAR(diskOperation);
|
||||||
SERIALIZE_SCALAR(outputChar);
|
SERIALIZE_SCALAR(outputChar);
|
||||||
SERIALIZE_SCALAR(inputChar);
|
SERIALIZE_SCALAR(inputChar);
|
||||||
SERIALIZE_SCALAR(bootStrapImpure);
|
SERIALIZE_ARRAY(cpuStack,64);
|
||||||
SERIALIZE_SCALAR(bootStrapCPU);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -310,8 +301,7 @@ AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
UNSERIALIZE_SCALAR(diskOperation);
|
UNSERIALIZE_SCALAR(diskOperation);
|
||||||
UNSERIALIZE_SCALAR(outputChar);
|
UNSERIALIZE_SCALAR(outputChar);
|
||||||
UNSERIALIZE_SCALAR(inputChar);
|
UNSERIALIZE_SCALAR(inputChar);
|
||||||
UNSERIALIZE_SCALAR(bootStrapImpure);
|
UNSERIALIZE_ARRAY(cpuStack, 64);
|
||||||
UNSERIALIZE_SCALAR(bootStrapCPU);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -96,7 +96,7 @@ class AlphaConsole : public PioDevice
|
||||||
BaseCPU *cpu;
|
BaseCPU *cpu;
|
||||||
|
|
||||||
Addr addr;
|
Addr addr;
|
||||||
static const Addr size = 0x80; // equal to sizeof(alpha_access);
|
static const Addr size = sizeof(struct AlphaAccess);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
|
|
|
@ -306,11 +306,9 @@ System::registerExecContext(ExecContext *xc, int id)
|
||||||
void
|
void
|
||||||
System::startup()
|
System::startup()
|
||||||
{
|
{
|
||||||
if (!execContexts.empty()) {
|
int i;
|
||||||
// activate with zero delay so that we start ticking right
|
for (i = 0; i < execContexts.size(); i++)
|
||||||
// away on cycle 0
|
execContexts[i]->activate(0);
|
||||||
execContexts[0]->activate(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue