From 58f69391cac4dcc3696470d08756d0c5ff308963 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 9 Mar 2007 16:56:39 -0500 Subject: [PATCH] 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 --- src/arch/alpha/utility.hh | 3 ++ src/arch/mips/utility.hh | 7 +++++ src/arch/sparc/isa/decoder.isa | 4 --- src/arch/sparc/miscregfile.hh | 17 ++++++++++++ src/arch/sparc/ua2005.cc | 50 ++++++++++++++++++++++++++++++++-- src/arch/sparc/utility.hh | 15 +++++++++- src/arch/x86/utility.hh | 5 ++++ src/dev/sparc/iob.cc | 29 ++++++++++++++++---- src/sim/system.cc | 3 +- 9 files changed, 120 insertions(+), 13 deletions(-) diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index c8a50e8a2..b7844c7eb 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -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 //////////////////////////////////////////////////////////////////////// diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh index 56689ba4d..b5c1e31e1 100644 --- a/src/arch/mips/utility.hh +++ b/src/arch/mips/utility.hh @@ -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); + } }; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 2e85e1274..70afe19b6 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -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 diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 6063c21c8..867f959e1 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -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; diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 6c8a987fe..439f38457 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -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"); } diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index 64b91695e..dc9201401 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -112,7 +112,20 @@ namespace SparcISA inline void initCPU(ThreadContext *tc, int cpuId) { 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 diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh index 1d9d8d3d5..1fbe1fffe 100644 --- a/src/arch/x86/utility.hh +++ b/src/arch/x86/utility.hh @@ -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__ diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index 2cff02a99..6bd40b631 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -38,6 +38,7 @@ #include #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 *por = new SparcISA::PowerOnReset(); + if (cpu_id >= sys->getNumCPUs()) return; - assert(type == 0); - ic->post(cpu_id, SparcISA::IT_INT_VEC, vector); + 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 diff --git a/src/sim/system.cc b/src/sim/system.cc index 1a87e1754..2d0eaaf5b 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -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 -- 2.30.2