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:
Ali Saidi 2007-03-09 16:56:39 -05:00
parent 9d026ac006
commit 58f69391ca
9 changed files with 120 additions and 13 deletions

View file

@ -123,6 +123,9 @@ namespace AlphaISA
// Alpha IPR register accessors // Alpha IPR register accessors
inline bool PcPAL(Addr addr) { return addr & 0x3; } inline bool PcPAL(Addr addr) { return addr & 0x3; }
inline void startupCPU(ThreadContext *tc, int cpuId) {
tc->activate(0);
}
#if FULL_SYSTEM #if FULL_SYSTEM
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2003-2005 The Regents of The University of Michigan * Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -27,6 +28,7 @@
* *
* Authors: Nathan Binkert * Authors: Nathan Binkert
* Steve Reinhardt * Steve Reinhardt
* Korey Sewell
*/ */
#ifndef __ARCH_MIPS_UTILITY_HH__ #ifndef __ARCH_MIPS_UTILITY_HH__
@ -98,6 +100,11 @@ namespace MipsISA {
return ExtMachInst(inst); return ExtMachInst(inst);
#endif #endif
} }
inline void startupCPU(ThreadContext *tc, int cpuId)
{
tc->activate(0);
}
}; };

View file

@ -620,10 +620,6 @@ decode OP default Unknown::unknown()
}}); }});
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}}); 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
0x1A: Priv::wrstrand_sts_reg({{ 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; StrandStsReg = Rs1 ^ Rs2_or_imm13;
}}); }});
//0x1A is supposed to be reserved, but it writes the strand //0x1A is supposed to be reserved, but it writes the strand

View file

@ -163,6 +163,23 @@ namespace SparcISA
const static int ie = 0x2; 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 NumMiscArchRegs = MISCREG_NUMMISCREGS;
const int NumMiscRegs = MISCREG_NUMMISCREGS; const int NumMiscRegs = MISCREG_NUMMISCREGS;

View file

@ -26,11 +26,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "arch/sparc/kernel_stats.hh"
#include "arch/sparc/miscregfile.hh" #include "arch/sparc/miscregfile.hh"
#include "base/bitfield.hh" #include "base/bitfield.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "sim/system.hh"
using namespace SparcISA; using namespace SparcISA;
@ -185,10 +187,21 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
#endif #endif
break; break;
case MISCREG_HTSTATE: case MISCREG_HTSTATE:
case MISCREG_STRAND_STS_REG:
setRegNoEffect(miscReg, val); setRegNoEffect(miscReg, val);
break; 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: default:
panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); 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 MiscReg
MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
{ {
uint64_t temp;
switch (miscReg) { switch (miscReg) {
/* Privileged registers. */ /* Privileged registers. */
case MISCREG_QUEUE_CPU_MONDO_HEAD: case MISCREG_QUEUE_CPU_MONDO_HEAD:
@ -214,7 +229,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
case MISCREG_HPSTATE: case MISCREG_HPSTATE:
case MISCREG_HINTP: case MISCREG_HINTP:
case MISCREG_HTSTATE: case MISCREG_HTSTATE:
case MISCREG_STRAND_STS_REG:
case MISCREG_HSTICK_CMPR: case MISCREG_HSTICK_CMPR:
return readRegNoEffect(miscReg) ; return readRegNoEffect(miscReg) ;
@ -223,6 +237,38 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
case MISCREG_HVER: case MISCREG_HVER:
return NWindows | MaxTL << 8 | MaxGL << 16; 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: default:
panic("Invalid read to FS misc register\n"); panic("Invalid read to FS misc register\n");
} }

View file

@ -112,7 +112,20 @@ namespace SparcISA
inline void initCPU(ThreadContext *tc, int cpuId) inline void initCPU(ThreadContext *tc, int cpuId)
{ {
static Fault por = new PowerOnReset(); static Fault por = new PowerOnReset();
por->invoke(tc); 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 } // namespace SparcISA

View file

@ -126,6 +126,11 @@ namespace X86ISA
{ {
panic("initCPU not implemented!\n"); panic("initCPU not implemented!\n");
} }
inline void startupCPU(ThreadContext *tc, int cpuId)
{
tc->activate(0);
}
}; };
#endif // __ARCH_X86_UTILITY_HH__ #endif // __ARCH_X86_UTILITY_HH__

View file

@ -38,6 +38,7 @@
#include <cstring> #include <cstring>
#include "arch/sparc/isa_traits.hh" #include "arch/sparc/isa_traits.hh"
#include "arch/sparc/faults.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/intr_control.hh" #include "cpu/intr_control.hh"
#include "dev/sparc/iob.hh" #include "dev/sparc/iob.hh"
@ -45,6 +46,7 @@
#include "mem/port.hh" #include "mem/port.hh"
#include "mem/packet_access.hh" #include "mem/packet_access.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
#include "sim/faults.hh"
#include "sim/system.hh" #include "sim/system.hh"
Iob::Iob(Params *p) Iob::Iob(Params *p)
@ -261,13 +263,30 @@ Iob::receiveDeviceInterrupt(DeviceId devid)
void void
Iob::generateIpi(Type type, int cpu_id, int vector) Iob::generateIpi(Type type, int cpu_id, int vector)
{ {
// Only handle interrupts for the moment... Cpu Idle/reset/resume will be SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
// later if (cpu_id >= sys->getNumCPUs())
if (type != 0)
return; return;
assert(type == 0); switch (type) {
ic->post(cpu_id, SparcISA::IT_INT_VEC, vector); 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 bool

View file

@ -33,6 +33,7 @@
#include "arch/isa_traits.hh" #include "arch/isa_traits.hh"
#include "arch/remote_gdb.hh" #include "arch/remote_gdb.hh"
#include "arch/utility.hh"
#include "base/loader/object_file.hh" #include "base/loader/object_file.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/trace.hh" #include "base/trace.hh"
@ -203,7 +204,7 @@ System::startup()
{ {
int i; int i;
for (i = 0; i < threadContexts.size(); i++) for (i = 0; i < threadContexts.size(); i++)
threadContexts[i]->activate(0); TheISA::startupCPU(threadContexts[i], i);
} }
void void