From 91cb532f9f44874e768ba749df03ca1f4dc07bc9 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 24 Oct 2003 23:02:36 -0700 Subject: [PATCH 1/3] Make FullCPU schedule its TickEvent when one of its contexts becomes active. This fixes detailed-mpboot, which was broken as of my last change. Also clean up some of the ExecContext status initialization. cpu/base_cpu.hh: CPU::execCtxStatusChg() now takes thread_num as an arg so the CPU knows which execContext had the status change. BaseCPU::registerExecContexts() no longer needs to be virtual. cpu/exec_context.cc: Initialize _status directly... don't use setStatus() as this will notify the CPU of the change before it is ready. CPU::execCtxStatusChg() now takes thread_num as an arg so the CPU knows which execContext had the status change. cpu/exec_context.hh: Don't need initStatus() any more. cpu/simple_cpu/simple_cpu.cc: Move execCtxStatusChg() from header to .cc file. No longer need specialized version of registerExecContexts to schedule TickEvent. cpu/simple_cpu/simple_cpu.hh: Move execCtxStatusChg() from header to .cc file. CPU::execCtxStatusChg() now takes thread_num as arg (must be 0 for SimpleCPU). No longer need specialized version of registerExecContexts to schedule TickEvent. kern/tru64/tru64_system.cc: Don't need initRegs; the PC etc. get initialized in the CPU constructor. ExecContexts start out as Unallocated, so no need to set them to Unallocated here. kern/tru64/tru64_system.hh: Don't need initRegs; the PC etc. get initialized in the CPU constructor. sim/prog.cc: ExecContexts start out as Unallocated, so no need to set them to Unallocated here. --HG-- extra : convert_revision : e960ebbeb845960344633798e251b6c8bf1c0378 --- cpu/base_cpu.hh | 4 ++-- cpu/exec_context.cc | 14 ++++++-------- cpu/exec_context.hh | 4 ---- cpu/simple_cpu/simple_cpu.cc | 31 ++++++++++++------------------- cpu/simple_cpu/simple_cpu.hh | 11 +---------- kern/tru64/tru64_system.cc | 16 +--------------- kern/tru64/tru64_system.hh | 1 - sim/prog.cc | 5 +---- 8 files changed, 23 insertions(+), 63 deletions(-) diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh index 5a20aaa54..143fc9662 100644 --- a/cpu/base_cpu.hh +++ b/cpu/base_cpu.hh @@ -73,7 +73,7 @@ class BaseCPU : public SimObject std::vector execContexts; public: - virtual void execCtxStatusChg() {} + virtual void execCtxStatusChg(int thread_num) {} public: @@ -94,7 +94,7 @@ class BaseCPU : public SimObject virtual void regStats(); - virtual void registerExecContexts(); + void registerExecContexts(); /// Prepare for another CPU to take over execution. Called by /// takeOverFrom() on its argument. diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 6c24500cc..a4670f291 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -44,24 +44,22 @@ using namespace std; ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_mem) - : kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num), + : _status(ExecContext::Unallocated), + kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), memCtrl(_sys->memCtrl), physmem(_sys->physmem), func_exe_insn(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); - setStatus(ExecContext::Unallocated); } #else ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid) - : cpu(_cpu), thread_num(_thread_num), cpu_id(-1), - process(_process), asid (_asid), + : _status(ExecContext::Unallocated), + cpu(_cpu), thread_num(_thread_num), cpu_id(-1), + process(_process), mem(process->getMemory()), asid(_asid), func_exe_insn(0), storeCondFailures(0) { - setStatus(ExecContext::Unallocated); - - mem = process->getMemory(); } ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, @@ -114,7 +112,7 @@ ExecContext::setStatus(Status new_status) #endif _status = new_status; - cpu->execCtxStatusChg(); + cpu->execCtxStatusChg(thread_num); } void diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 5c6e84cee..f2afaa334 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -68,10 +68,6 @@ class ExecContext public: Status status() const { return _status; } - // Unlike setStatus(), initStatus() has no side effects other than - // setting the _status variable. - void initStatus(Status init_status) { _status = init_status; } - void setStatus(Status new_status); #ifdef FULL_SYSTEM diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 41e3de24e..891e6cdb3 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -163,25 +163,6 @@ SimpleCPU::~SimpleCPU() } -void -SimpleCPU::registerExecContexts() -{ - BaseCPU::registerExecContexts(); - - // if any of this CPU's ExecContexts are active, mark the CPU as - // running and schedule its tick event. - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - if (xc->status() == ExecContext::Active && _status != Running) { - _status = Running; - // this should only happen at initialization time - assert(curTick == 0); - tickEvent.schedule(0); - } - } -} - - void SimpleCPU::switchOut() { @@ -212,6 +193,18 @@ SimpleCPU::takeOverFrom(BaseCPU *oldCPU) } +void +SimpleCPU::execCtxStatusChg(int thread_num) { + assert(thread_num == 0); + assert(xc); + + if (xc->status() == ExecContext::Active) + setStatus(Running); + else + setStatus(Idle); +} + + void SimpleCPU::regStats() { diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index e1b351cab..60c038163 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -136,8 +136,6 @@ class SimpleCPU : public BaseCPU // execution context ExecContext *xc; - void registerExecContexts(); - void switchOut(); void takeOverFrom(BaseCPU *oldCPU); @@ -178,14 +176,7 @@ class SimpleCPU : public BaseCPU Status status() const { return _status; } - virtual void execCtxStatusChg() { - if (xc) { - if (xc->status() == ExecContext::Active) - setStatus(Running); - else - setStatus(Idle); - } - } + virtual void execCtxStatusChg(int thread_num); void setStatus(Status new_status) { Status old_status = status(); diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index 8b4ff668d..a7940ed1f 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -72,10 +72,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, fatal("Could not load PALcode file %s", palcode); pal->loadSections(physmem, true); - // copy of initial reg file contents - initRegs = new RegFile; - memset(initRegs, 0, sizeof(RegFile)); - // Load console file console->loadSections(physmem, true); @@ -90,10 +86,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, "Kernel entry = %#x\n", kernelStart, kernelEnd, kernelEntry); - // Setup kernel boot parameters - initRegs->pc = 0x4001; - initRegs->npc = initRegs->pc + sizeof(MachInst); - DPRINTF(Loader, "Kernel loaded...\n"); kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); @@ -164,8 +156,6 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, Tru64System::~Tru64System() { - delete initRegs; - delete kernel; delete console; @@ -190,11 +180,7 @@ Tru64System::registerExecContext(ExecContext *xc) int xcIndex = System::registerExecContext(xc); if (xcIndex == 0) { - // xc->regs = *initRegs; - xc->initStatus(ExecContext::Active); - } - else { - xc->initStatus(ExecContext::Unallocated); + xc->setStatus(ExecContext::Active); } RemoteGDB *rgdb = new RemoteGDB(this, xc); diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh index a67792aaf..e0d2bedf7 100644 --- a/kern/tru64/tru64_system.hh +++ b/kern/tru64/tru64_system.hh @@ -67,7 +67,6 @@ class Tru64System : public System DumpMbufEvent *dumpMbufEvent; private: - RegFile *initRegs; Addr kernelStart; Addr kernelEnd; diff --git a/sim/prog.cc b/sim/prog.cc index 599a0ca9a..fca4b4505 100644 --- a/sim/prog.cc +++ b/sim/prog.cc @@ -148,10 +148,7 @@ Process::registerExecContext(ExecContext *xc) xc->regs = *init_regs; // mark this context as active - xc->initStatus(ExecContext::Active); - } - else { - xc->initStatus(ExecContext::Unallocated); + xc->setStatus(ExecContext::Active); } // return CPU number to caller and increment available CPU count From 02d80c96b79b8ae4b6f99e657579f36d28844795 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 24 Oct 2003 23:20:27 -0700 Subject: [PATCH 2/3] Move some common full-system CPU initialization from the SimpleCPU & FullCPU constructors to AlphaISA::initCPU(). cpu/simple_cpu/simple_cpu.cc: Move some common full-system CPU initialization from the SimpleCPU & FullCPU constructors to AlphaISA::initCPU(). Make 'fault' local to SimpleCPU::tick. cpu/simple_cpu/simple_cpu.hh: Make 'fault' local to SimpleCPU::tick (not an object member). --HG-- extra : convert_revision : e878dedfff06aac0548aca8b14d66c18b8916895 --- arch/alpha/ev5.cc | 6 ++++++ cpu/simple_cpu/simple_cpu.cc | 15 ++++----------- cpu/simple_cpu/simple_cpu.hh | 3 --- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index cc33f6890..7330d7ce0 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -47,6 +47,11 @@ void AlphaISA::initCPU(RegFile *regs) { initIPRs(regs); + // CPU comes up with PAL regs enabled + swap_palshadow(regs, true); + + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; + regs->npc = regs->pc + sizeof(MachInst); } void @@ -97,6 +102,7 @@ AlphaISA::initIPRs(RegFile *regs) bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); ipr[IPR_PAL_BASE] = PAL_BASE; + ipr[IPR_MCSR] = 0x6; } diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 891e6cdb3..d3d9bc2ca 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -126,19 +126,10 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process, #ifdef FULL_SYSTEM xc = new ExecContext(this, 0, system, itb, dtb, mem); + // initialize CPU, including PC TheISA::initCPU(&xc->regs); - - IntReg *ipr = xc->regs.ipr; - ipr[TheISA::IPR_MCSR] = 0x6; - - AlphaISA::swap_palshadow(&xc->regs, true); - - fault = Reset_Fault; - xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; - xc->regs.npc = xc->regs.pc + sizeof(MachInst); #else xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0); - fault = No_Fault; #endif // !FULL_SYSTEM icacheInterface = icache_interface; @@ -524,8 +515,10 @@ SimpleCPU::tick() { traceData = NULL; + Fault fault = No_Fault; + #ifdef FULL_SYSTEM - if (fault == No_Fault && AlphaISA::check_interrupts && + if (AlphaISA::check_interrupts && xc->cpu->check_interrupts() && !PC_PAL(xc->regs.pc) && status() != IcacheMissComplete) { diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 60c038163..9e2c7fd06 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -154,9 +154,6 @@ class SimpleCPU : public BaseCPU // current instruction MachInst inst; - // current fault status - Fault fault; - // Refcounted pointer to the one memory request. MemReqPtr memReq;