implement ipi stufff for SPARC
src/arch/alpha/utility.hh: src/arch/mips/utility.hh: src/arch/sparc/utility.hh: src/arch/x86/utility.hh: add hook for system to startup the cpu or not... in the case of FS sparc, only the first cpu would get spunup.. the rest sit in an idle state until they get an ipi src/arch/sparc/isa/decoder.isa: handle writable bits of strandstatus register in miscregfile src/arch/sparc/miscregfile.hh: some constants for the strand status register src/arch/sparc/ua2005.cc: properly implement the strand status register src/dev/sparc/iob.cc: implement ipi generation properly src/sim/system.cc: call into the ISA to start the CPU (or not) --HG-- extra : convert_revision : 0003b2032337d8a031a9fc044da726dbb2a9e36f
This commit is contained in:
parent
9d026ac006
commit
58f69391ca
9 changed files with 120 additions and 13 deletions
|
@ -123,6 +123,9 @@ namespace AlphaISA
|
|||
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId) {
|
||||
tc->activate(0);
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2007 MIPS Technologies, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -27,6 +28,7 @@
|
|||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
* Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_UTILITY_HH__
|
||||
|
@ -98,6 +100,11 @@ namespace MipsISA {
|
|||
return ExtMachInst(inst);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||
{
|
||||
tc->activate(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -620,10 +620,6 @@ decode OP default Unknown::unknown()
|
|||
}});
|
||||
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
|
||||
0x1A: Priv::wrstrand_sts_reg({{
|
||||
if(Pstate<2:> && !Hpstate<2:>)
|
||||
StrandStsReg = StrandStsReg<63:1> |
|
||||
(Rs1 ^ Rs2_or_imm13)<0:>;
|
||||
else
|
||||
StrandStsReg = Rs1 ^ Rs2_or_imm13;
|
||||
}});
|
||||
//0x1A is supposed to be reserved, but it writes the strand
|
||||
|
|
|
@ -163,6 +163,23 @@ namespace SparcISA
|
|||
const static int ie = 0x2;
|
||||
};
|
||||
|
||||
struct STS {
|
||||
const static int st_idle = 0x00;
|
||||
const static int st_wait = 0x01;
|
||||
const static int st_halt = 0x02;
|
||||
const static int st_run = 0x05;
|
||||
const static int st_spec_run = 0x07;
|
||||
const static int st_spec_rdy = 0x13;
|
||||
const static int st_ready = 0x19;
|
||||
const static int active = 0x01;
|
||||
const static int speculative = 0x04;
|
||||
const static int shft_id = 8;
|
||||
const static int shft_fsm0 = 31;
|
||||
const static int shft_fsm1 = 26;
|
||||
const static int shft_fsm2 = 21;
|
||||
const static int shft_fsm3 = 16;
|
||||
};
|
||||
|
||||
|
||||
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
||||
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "arch/sparc/kernel_stats.hh"
|
||||
#include "arch/sparc/miscregfile.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace SparcISA;
|
||||
|
||||
|
@ -185,10 +187,21 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
|||
#endif
|
||||
break;
|
||||
case MISCREG_HTSTATE:
|
||||
case MISCREG_STRAND_STS_REG:
|
||||
setRegNoEffect(miscReg, val);
|
||||
break;
|
||||
|
||||
case MISCREG_STRAND_STS_REG:
|
||||
if (bits(val,2,2))
|
||||
panic("No support for setting spec_en bit\n");
|
||||
setRegNoEffect(miscReg, bits(val,0,0));
|
||||
if (!bits(val,0,0)) {
|
||||
// Time to go to sleep
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
|
||||
}
|
||||
|
@ -197,6 +210,8 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
|||
MiscReg
|
||||
MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
||||
{
|
||||
uint64_t temp;
|
||||
|
||||
switch (miscReg) {
|
||||
/* Privileged registers. */
|
||||
case MISCREG_QUEUE_CPU_MONDO_HEAD:
|
||||
|
@ -214,7 +229,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
|||
case MISCREG_HPSTATE:
|
||||
case MISCREG_HINTP:
|
||||
case MISCREG_HTSTATE:
|
||||
case MISCREG_STRAND_STS_REG:
|
||||
case MISCREG_HSTICK_CMPR:
|
||||
return readRegNoEffect(miscReg) ;
|
||||
|
||||
|
@ -223,6 +237,38 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
|||
case MISCREG_HVER:
|
||||
return NWindows | MaxTL << 8 | MaxGL << 16;
|
||||
|
||||
case MISCREG_STRAND_STS_REG:
|
||||
System *sys;
|
||||
int x;
|
||||
sys = tc->getSystemPtr();
|
||||
|
||||
temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
|
||||
// Check that the CPU array is fully populated (by calling getNumCPus())
|
||||
assert(sys->getNumCPUs() > tc->readCpuId());
|
||||
|
||||
temp |= tc->readCpuId() << STS::shft_id;
|
||||
|
||||
for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
|
||||
switch (sys->threadContexts[x]->status()) {
|
||||
case ThreadContext::Active:
|
||||
temp |= STS::st_run << (STS::shft_fsm0 -
|
||||
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||
break;
|
||||
case ThreadContext::Suspended:
|
||||
// should this be idle?
|
||||
temp |= STS::st_idle << (STS::shft_fsm0 -
|
||||
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||
break;
|
||||
case ThreadContext::Halted:
|
||||
temp |= STS::st_halt << (STS::shft_fsm0 -
|
||||
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||
break;
|
||||
default:
|
||||
panic("What state are we in?!\n");
|
||||
} // switch
|
||||
} // for
|
||||
|
||||
return temp;
|
||||
default:
|
||||
panic("Invalid read to FS misc register\n");
|
||||
}
|
||||
|
|
|
@ -112,7 +112,20 @@ namespace SparcISA
|
|||
inline void initCPU(ThreadContext *tc, int cpuId)
|
||||
{
|
||||
static Fault por = new PowerOnReset();
|
||||
if (cpuId == 0)
|
||||
por->invoke(tc);
|
||||
|
||||
}
|
||||
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
// Other CPUs will get activated by IPIs
|
||||
if (cpuId == 0)
|
||||
tc->activate(0);
|
||||
#else
|
||||
tc->activate(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace SparcISA
|
||||
|
|
|
@ -126,6 +126,11 @@ namespace X86ISA
|
|||
{
|
||||
panic("initCPU not implemented!\n");
|
||||
}
|
||||
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||
{
|
||||
tc->activate(0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __ARCH_X86_UTILITY_HH__
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/intr_control.hh"
|
||||
#include "dev/sparc/iob.hh"
|
||||
|
@ -45,6 +46,7 @@
|
|||
#include "mem/port.hh"
|
||||
#include "mem/packet_access.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
Iob::Iob(Params *p)
|
||||
|
@ -261,13 +263,30 @@ Iob::receiveDeviceInterrupt(DeviceId devid)
|
|||
void
|
||||
Iob::generateIpi(Type type, int cpu_id, int vector)
|
||||
{
|
||||
// Only handle interrupts for the moment... Cpu Idle/reset/resume will be
|
||||
// later
|
||||
if (type != 0)
|
||||
SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
|
||||
if (cpu_id >= sys->getNumCPUs())
|
||||
return;
|
||||
|
||||
assert(type == 0);
|
||||
switch (type) {
|
||||
case 0: // interrupt
|
||||
ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
|
||||
break;
|
||||
case 1: // reset
|
||||
warn("Sending reset to CPU: %d\n", cpu_id);
|
||||
if (vector != por->trapType())
|
||||
panic("Don't know how to set non-POR reset to cpu\n");
|
||||
por->invoke(sys->threadContexts[cpu_id]);
|
||||
sys->threadContexts[cpu_id]->activate();
|
||||
break;
|
||||
case 2: // idle -- this means stop executing and don't wake on interrupts
|
||||
sys->threadContexts[cpu_id]->halt();
|
||||
break;
|
||||
case 3: // resume
|
||||
sys->threadContexts[cpu_id]->activate();
|
||||
break;
|
||||
default:
|
||||
panic("Invalid type to generate ipi\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/remote_gdb.hh"
|
||||
#include "arch/utility.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
|
@ -203,7 +204,7 @@ System::startup()
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < threadContexts.size(); i++)
|
||||
threadContexts[i]->activate(0);
|
||||
TheISA::startupCPU(threadContexts[i], i);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue